config.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. package dtls
  2. import (
  3. "context"
  4. "crypto/ecdsa"
  5. "crypto/ed25519"
  6. "crypto/rsa"
  7. "crypto/tls"
  8. "crypto/x509"
  9. "io"
  10. "time"
  11. "github.com/pion/logging"
  12. )
  13. const keyLogLabelTLS12 = "CLIENT_RANDOM"
  14. // Config is used to configure a DTLS client or server.
  15. // After a Config is passed to a DTLS function it must not be modified.
  16. type Config struct {
  17. // Certificates contains certificate chain to present to the other side of the connection.
  18. // Server MUST set this if PSK is non-nil
  19. // client SHOULD sets this so CertificateRequests can be handled if PSK is non-nil
  20. Certificates []tls.Certificate
  21. // CipherSuites is a list of supported cipher suites.
  22. // If CipherSuites is nil, a default list is used
  23. CipherSuites []CipherSuiteID
  24. // CustomCipherSuites is a list of CipherSuites that can be
  25. // provided by the user. This allow users to user Ciphers that are reserved
  26. // for private usage.
  27. CustomCipherSuites func() []CipherSuite
  28. // SignatureSchemes contains the signature and hash schemes that the peer requests to verify.
  29. SignatureSchemes []tls.SignatureScheme
  30. // SRTPProtectionProfiles are the supported protection profiles
  31. // Clients will send this via use_srtp and assert that the server properly responds
  32. // Servers will assert that clients send one of these profiles and will respond as needed
  33. SRTPProtectionProfiles []SRTPProtectionProfile
  34. // ClientAuth determines the server's policy for
  35. // TLS Client Authentication. The default is NoClientCert.
  36. ClientAuth ClientAuthType
  37. // RequireExtendedMasterSecret determines if the "Extended Master Secret" extension
  38. // should be disabled, requested, or required (default requested).
  39. ExtendedMasterSecret ExtendedMasterSecretType
  40. // FlightInterval controls how often we send outbound handshake messages
  41. // defaults to time.Second
  42. FlightInterval time.Duration
  43. // PSK sets the pre-shared key used by this DTLS connection
  44. // If PSK is non-nil only PSK CipherSuites will be used
  45. PSK PSKCallback
  46. PSKIdentityHint []byte
  47. CiscoCompat PSKCallback // TODO add cisco anyconnect support
  48. // InsecureSkipVerify controls whether a client verifies the
  49. // server's certificate chain and host name.
  50. // If InsecureSkipVerify is true, TLS accepts any certificate
  51. // presented by the server and any host name in that certificate.
  52. // In this mode, TLS is susceptible to man-in-the-middle attacks.
  53. // This should be used only for testing.
  54. InsecureSkipVerify bool
  55. // InsecureHashes allows the use of hashing algorithms that are known
  56. // to be vulnerable.
  57. InsecureHashes bool
  58. // VerifyPeerCertificate, if not nil, is called after normal
  59. // certificate verification by either a client or server. It
  60. // receives the certificate provided by the peer and also a flag
  61. // that tells if normal verification has succeedded. If it returns a
  62. // non-nil error, the handshake is aborted and that error results.
  63. //
  64. // If normal verification fails then the handshake will abort before
  65. // considering this callback. If normal verification is disabled by
  66. // setting InsecureSkipVerify, or (for a server) when ClientAuth is
  67. // RequestClientCert or RequireAnyClientCert, then this callback will
  68. // be considered but the verifiedChains will always be nil.
  69. VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error
  70. // RootCAs defines the set of root certificate authorities
  71. // that one peer uses when verifying the other peer's certificates.
  72. // If RootCAs is nil, TLS uses the host's root CA set.
  73. RootCAs *x509.CertPool
  74. // ClientCAs defines the set of root certificate authorities
  75. // that servers use if required to verify a client certificate
  76. // by the policy in ClientAuth.
  77. ClientCAs *x509.CertPool
  78. // ServerName is used to verify the hostname on the returned
  79. // certificates unless InsecureSkipVerify is given.
  80. ServerName string
  81. LoggerFactory logging.LoggerFactory
  82. // ConnectContextMaker is a function to make a context used in Dial(),
  83. // Client(), Server(), and Accept(). If nil, the default ConnectContextMaker
  84. // is used. It can be implemented as following.
  85. //
  86. // func ConnectContextMaker() (context.Context, func()) {
  87. // return context.WithTimeout(context.Background(), 30*time.Second)
  88. // }
  89. ConnectContextMaker func() (context.Context, func())
  90. // MTU is the length at which handshake messages will be fragmented to
  91. // fit within the maximum transmission unit (default is 1200 bytes)
  92. MTU int
  93. // ReplayProtectionWindow is the size of the replay attack protection window.
  94. // Duplication of the sequence number is checked in this window size.
  95. // Packet with sequence number older than this value compared to the latest
  96. // accepted packet will be discarded. (default is 64)
  97. ReplayProtectionWindow int
  98. // KeyLogWriter optionally specifies a destination for TLS master secrets
  99. // in NSS key log format that can be used to allow external programs
  100. // such as Wireshark to decrypt TLS connections.
  101. // See https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format.
  102. // Use of KeyLogWriter compromises security and should only be
  103. // used for debugging.
  104. KeyLogWriter io.Writer
  105. }
  106. func defaultConnectContextMaker() (context.Context, func()) {
  107. return context.WithTimeout(context.Background(), 30*time.Second)
  108. }
  109. func (c *Config) connectContextMaker() (context.Context, func()) {
  110. if c.ConnectContextMaker == nil {
  111. return defaultConnectContextMaker()
  112. }
  113. return c.ConnectContextMaker()
  114. }
  115. const defaultMTU = 1200 // bytes
  116. // PSKCallback is called once we have the remote's PSKIdentityHint.
  117. // If the remote provided none it will be nil
  118. type PSKCallback func([]byte) ([]byte, error)
  119. // ClientAuthType declares the policy the server will follow for
  120. // TLS Client Authentication.
  121. type ClientAuthType int
  122. // ClientAuthType enums
  123. const (
  124. NoClientCert ClientAuthType = iota
  125. RequestClientCert
  126. RequireAnyClientCert
  127. VerifyClientCertIfGiven
  128. RequireAndVerifyClientCert
  129. )
  130. // ExtendedMasterSecretType declares the policy the client and server
  131. // will follow for the Extended Master Secret extension
  132. type ExtendedMasterSecretType int
  133. // ExtendedMasterSecretType enums
  134. const (
  135. RequestExtendedMasterSecret ExtendedMasterSecretType = iota
  136. RequireExtendedMasterSecret
  137. DisableExtendedMasterSecret
  138. )
  139. func validateConfig(config *Config) error {
  140. switch {
  141. case config == nil:
  142. return errNoConfigProvided
  143. case config.PSKIdentityHint != nil && config.PSK == nil:
  144. return errIdentityNoPSK
  145. }
  146. for _, cert := range config.Certificates {
  147. if cert.Certificate == nil {
  148. return errInvalidCertificate
  149. }
  150. if cert.PrivateKey != nil {
  151. switch cert.PrivateKey.(type) {
  152. case ed25519.PrivateKey:
  153. case *ecdsa.PrivateKey:
  154. case *rsa.PrivateKey:
  155. default:
  156. return errInvalidPrivateKey
  157. }
  158. }
  159. }
  160. _, err := parseCipherSuites(config.CipherSuites, config.CustomCipherSuites, config.PSK == nil || len(config.Certificates) > 0, config.PSK != nil)
  161. return err
  162. }