github.com/pion/dtls/v2@v2.2.12/config.go (about) 1 // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly> 2 // SPDX-License-Identifier: MIT 3 4 package dtls 5 6 import ( 7 "context" 8 "crypto/ecdsa" 9 "crypto/ed25519" 10 "crypto/rsa" 11 "crypto/tls" 12 "crypto/x509" 13 "io" 14 "time" 15 16 "github.com/pion/dtls/v2/pkg/crypto/elliptic" 17 "github.com/pion/logging" 18 ) 19 20 const keyLogLabelTLS12 = "CLIENT_RANDOM" 21 22 // Config is used to configure a DTLS client or server. 23 // After a Config is passed to a DTLS function it must not be modified. 24 type Config struct { 25 // Certificates contains certificate chain to present to the other side of the connection. 26 // Server MUST set this if PSK is non-nil 27 // client SHOULD sets this so CertificateRequests can be handled if PSK is non-nil 28 Certificates []tls.Certificate 29 30 // CipherSuites is a list of supported cipher suites. 31 // If CipherSuites is nil, a default list is used 32 CipherSuites []CipherSuiteID 33 34 // CustomCipherSuites is a list of CipherSuites that can be 35 // provided by the user. This allow users to user Ciphers that are reserved 36 // for private usage. 37 CustomCipherSuites func() []CipherSuite 38 39 // SignatureSchemes contains the signature and hash schemes that the peer requests to verify. 40 SignatureSchemes []tls.SignatureScheme 41 42 // SRTPProtectionProfiles are the supported protection profiles 43 // Clients will send this via use_srtp and assert that the server properly responds 44 // Servers will assert that clients send one of these profiles and will respond as needed 45 SRTPProtectionProfiles []SRTPProtectionProfile 46 47 // ClientAuth determines the server's policy for 48 // TLS Client Authentication. The default is NoClientCert. 49 ClientAuth ClientAuthType 50 51 // RequireExtendedMasterSecret determines if the "Extended Master Secret" extension 52 // should be disabled, requested, or required (default requested). 53 ExtendedMasterSecret ExtendedMasterSecretType 54 55 // FlightInterval controls how often we send outbound handshake messages 56 // defaults to time.Second 57 FlightInterval time.Duration 58 59 // PSK sets the pre-shared key used by this DTLS connection 60 // If PSK is non-nil only PSK CipherSuites will be used 61 PSK PSKCallback 62 PSKIdentityHint []byte 63 64 // InsecureSkipVerify controls whether a client verifies the 65 // server's certificate chain and host name. 66 // If InsecureSkipVerify is true, TLS accepts any certificate 67 // presented by the server and any host name in that certificate. 68 // In this mode, TLS is susceptible to man-in-the-middle attacks. 69 // This should be used only for testing. 70 InsecureSkipVerify bool 71 72 // InsecureHashes allows the use of hashing algorithms that are known 73 // to be vulnerable. 74 InsecureHashes bool 75 76 // VerifyPeerCertificate, if not nil, is called after normal 77 // certificate verification by either a client or server. It 78 // receives the certificate provided by the peer and also a flag 79 // that tells if normal verification has succeedded. If it returns a 80 // non-nil error, the handshake is aborted and that error results. 81 // 82 // If normal verification fails then the handshake will abort before 83 // considering this callback. If normal verification is disabled by 84 // setting InsecureSkipVerify, or (for a server) when ClientAuth is 85 // RequestClientCert or RequireAnyClientCert, then this callback will 86 // be considered but the verifiedChains will always be nil. 87 VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error 88 89 // VerifyConnection, if not nil, is called after normal certificate 90 // verification/PSK and after VerifyPeerCertificate by either a TLS client 91 // or server. If it returns a non-nil error, the handshake is aborted 92 // and that error results. 93 // 94 // If normal verification fails then the handshake will abort before 95 // considering this callback. This callback will run for all connections 96 // regardless of InsecureSkipVerify or ClientAuth settings. 97 VerifyConnection func(*State) error 98 99 // RootCAs defines the set of root certificate authorities 100 // that one peer uses when verifying the other peer's certificates. 101 // If RootCAs is nil, TLS uses the host's root CA set. 102 RootCAs *x509.CertPool 103 104 // ClientCAs defines the set of root certificate authorities 105 // that servers use if required to verify a client certificate 106 // by the policy in ClientAuth. 107 ClientCAs *x509.CertPool 108 109 // ServerName is used to verify the hostname on the returned 110 // certificates unless InsecureSkipVerify is given. 111 ServerName string 112 113 LoggerFactory logging.LoggerFactory 114 115 // ConnectContextMaker is a function to make a context used in Dial(), 116 // Client(), Server(), and Accept(). If nil, the default ConnectContextMaker 117 // is used. It can be implemented as following. 118 // 119 // func ConnectContextMaker() (context.Context, func()) { 120 // return context.WithTimeout(context.Background(), 30*time.Second) 121 // } 122 ConnectContextMaker func() (context.Context, func()) 123 124 // MTU is the length at which handshake messages will be fragmented to 125 // fit within the maximum transmission unit (default is 1200 bytes) 126 MTU int 127 128 // ReplayProtectionWindow is the size of the replay attack protection window. 129 // Duplication of the sequence number is checked in this window size. 130 // Packet with sequence number older than this value compared to the latest 131 // accepted packet will be discarded. (default is 64) 132 ReplayProtectionWindow int 133 134 // KeyLogWriter optionally specifies a destination for TLS master secrets 135 // in NSS key log format that can be used to allow external programs 136 // such as Wireshark to decrypt TLS connections. 137 // See https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format. 138 // Use of KeyLogWriter compromises security and should only be 139 // used for debugging. 140 KeyLogWriter io.Writer 141 142 // SessionStore is the container to store session for resumption. 143 SessionStore SessionStore 144 145 // List of application protocols the peer supports, for ALPN 146 SupportedProtocols []string 147 148 // List of Elliptic Curves to use 149 // 150 // If an ECC ciphersuite is configured and EllipticCurves is empty 151 // it will default to X25519, P-256, P-384 in this specific order. 152 EllipticCurves []elliptic.Curve 153 154 // GetCertificate returns a Certificate based on the given 155 // ClientHelloInfo. It will only be called if the client supplies SNI 156 // information or if Certificates is empty. 157 // 158 // If GetCertificate is nil or returns nil, then the certificate is 159 // retrieved from NameToCertificate. If NameToCertificate is nil, the 160 // best element of Certificates will be used. 161 GetCertificate func(*ClientHelloInfo) (*tls.Certificate, error) 162 163 // GetClientCertificate, if not nil, is called when a server requests a 164 // certificate from a client. If set, the contents of Certificates will 165 // be ignored. 166 // 167 // If GetClientCertificate returns an error, the handshake will be 168 // aborted and that error will be returned. Otherwise 169 // GetClientCertificate must return a non-nil Certificate. If 170 // Certificate.Certificate is empty then no certificate will be sent to 171 // the server. If this is unacceptable to the server then it may abort 172 // the handshake. 173 GetClientCertificate func(*CertificateRequestInfo) (*tls.Certificate, error) 174 175 // InsecureSkipVerifyHello, if true and when acting as server, allow client to 176 // skip hello verify phase and receive ServerHello after initial ClientHello. 177 // This have implication on DoS attack resistance. 178 InsecureSkipVerifyHello bool 179 } 180 181 func defaultConnectContextMaker() (context.Context, func()) { 182 return context.WithTimeout(context.Background(), 30*time.Second) 183 } 184 185 func (c *Config) connectContextMaker() (context.Context, func()) { 186 if c.ConnectContextMaker == nil { 187 return defaultConnectContextMaker() 188 } 189 return c.ConnectContextMaker() 190 } 191 192 func (c *Config) includeCertificateSuites() bool { 193 return c.PSK == nil || len(c.Certificates) > 0 || c.GetCertificate != nil || c.GetClientCertificate != nil 194 } 195 196 const defaultMTU = 1200 // bytes 197 198 var defaultCurves = []elliptic.Curve{elliptic.X25519, elliptic.P256, elliptic.P384} //nolint:gochecknoglobals 199 200 // PSKCallback is called once we have the remote's PSKIdentityHint. 201 // If the remote provided none it will be nil 202 type PSKCallback func([]byte) ([]byte, error) 203 204 // ClientAuthType declares the policy the server will follow for 205 // TLS Client Authentication. 206 type ClientAuthType int 207 208 // ClientAuthType enums 209 const ( 210 NoClientCert ClientAuthType = iota 211 RequestClientCert 212 RequireAnyClientCert 213 VerifyClientCertIfGiven 214 RequireAndVerifyClientCert 215 ) 216 217 // ExtendedMasterSecretType declares the policy the client and server 218 // will follow for the Extended Master Secret extension 219 type ExtendedMasterSecretType int 220 221 // ExtendedMasterSecretType enums 222 const ( 223 RequestExtendedMasterSecret ExtendedMasterSecretType = iota 224 RequireExtendedMasterSecret 225 DisableExtendedMasterSecret 226 ) 227 228 func validateConfig(config *Config) error { 229 switch { 230 case config == nil: 231 return errNoConfigProvided 232 case config.PSKIdentityHint != nil && config.PSK == nil: 233 return errIdentityNoPSK 234 } 235 236 for _, cert := range config.Certificates { 237 if cert.Certificate == nil { 238 return errInvalidCertificate 239 } 240 if cert.PrivateKey != nil { 241 switch cert.PrivateKey.(type) { 242 case ed25519.PrivateKey: 243 case *ecdsa.PrivateKey: 244 case *rsa.PrivateKey: 245 default: 246 return errInvalidPrivateKey 247 } 248 } 249 } 250 251 _, err := parseCipherSuites(config.CipherSuites, config.CustomCipherSuites, config.includeCertificateSuites(), config.PSK != nil) 252 return err 253 }