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  }