config.go 9.5 KB

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