@@ -303,6 +303,18 @@ public struct TLSConfiguration {
303303 /// Whether renegotiation is supported.
304304 public var renegotiationSupport : NIORenegotiationSupport
305305
306+ /// Whether to trust the commonName field when validating certificate hostnames.
307+ ///
308+ /// The commonName field of certificates has been deprecated for use as a validation source
309+ /// for nearly two decades. As browsers and the WebPKI now forbid the usage of common names
310+ /// in certificates, swift-nio-ssl defaults to this strict level of enforcement as well.
311+ ///
312+ /// However, some older infrastructure does not issue certificates with valid subject alternative
313+ /// name fields. For this reason, we currently allow an override for trusting the common name. This
314+ /// is a temporary measure to allow users to work around these limitations, but we will remove this
315+ /// functionality in future.
316+ public var trustCommonName : Bool
317+
306318 private init ( cipherSuiteValues: [ NIOTLSCipher ] = [ ] ,
307319 cipherSuites: String = defaultCipherSuites,
308320 verifySignatureAlgorithms: [ SignatureAlgorithm ] ? ,
@@ -317,7 +329,8 @@ public struct TLSConfiguration {
317329 shutdownTimeout: TimeAmount ,
318330 keyLogCallback: NIOSSLKeyLogCallback ? ,
319331 renegotiationSupport: NIORenegotiationSupport ,
320- additionalTrustRoots: [ NIOSSLAdditionalTrustRoots ] ) {
332+ additionalTrustRoots: [ NIOSSLAdditionalTrustRoots ] ,
333+ trustCommonName: Bool ) {
321334 self . cipherSuites = cipherSuites
322335 self . verifySignatureAlgorithms = verifySignatureAlgorithms
323336 self . signingSignatureAlgorithms = signingSignatureAlgorithms
@@ -331,6 +344,7 @@ public struct TLSConfiguration {
331344 self . encodedApplicationProtocols = [ ]
332345 self . shutdownTimeout = shutdownTimeout
333346 self . renegotiationSupport = renegotiationSupport
347+ self . trustCommonName = trustCommonName
334348 self . applicationProtocols = applicationProtocols
335349 self . keyLogCallback = keyLogCallback
336350 if !cipherSuiteValues. isEmpty {
@@ -368,7 +382,8 @@ public struct TLSConfiguration {
368382 shutdownTimeout: shutdownTimeout,
369383 keyLogCallback: keyLogCallback,
370384 renegotiationSupport: . none, // Servers never support renegotiation: there's no point.
371- additionalTrustRoots: additionalTrustRoots)
385+ additionalTrustRoots: additionalTrustRoots,
386+ trustCommonName: false )
372387 }
373388
374389 /// Create a TLS configuration for use with server-side contexts.
@@ -398,7 +413,8 @@ public struct TLSConfiguration {
398413 shutdownTimeout: shutdownTimeout,
399414 keyLogCallback: keyLogCallback,
400415 renegotiationSupport: . none, // Servers never support renegotiation: there's no point.
401- additionalTrustRoots: [ ] )
416+ additionalTrustRoots: [ ] ,
417+ trustCommonName: false )
402418 }
403419
404420 /// Create a TLS configuration for use with server-side contexts.
@@ -430,7 +446,8 @@ public struct TLSConfiguration {
430446 shutdownTimeout: shutdownTimeout,
431447 keyLogCallback: keyLogCallback,
432448 renegotiationSupport: . none, // Servers never support renegotiation: there's no point.
433- additionalTrustRoots: [ ] )
449+ additionalTrustRoots: [ ] ,
450+ trustCommonName: false )
434451 }
435452
436453 /// Create a TLS configuration for use with server-side contexts.
@@ -463,7 +480,43 @@ public struct TLSConfiguration {
463480 shutdownTimeout: shutdownTimeout,
464481 keyLogCallback: keyLogCallback,
465482 renegotiationSupport: . none, // Servers never support renegotiation: there's no point.
466- additionalTrustRoots: additionalTrustRoots)
483+ additionalTrustRoots: additionalTrustRoots,
484+ trustCommonName: false )
485+ }
486+
487+ /// Create a TLS configuration for use with server-side contexts.
488+ ///
489+ /// This provides sensible defaults while requiring that you provide any data that is necessary
490+ /// for server-side function. For client use, try `forClient` instead.
491+ public static func forServer( certificateChain: [ NIOSSLCertificateSource ] ,
492+ privateKey: NIOSSLPrivateKeySource ,
493+ cipherSuites: String = defaultCipherSuites,
494+ verifySignatureAlgorithms: [ SignatureAlgorithm ] ? = nil ,
495+ signingSignatureAlgorithms: [ SignatureAlgorithm ] ? = nil ,
496+ minimumTLSVersion: TLSVersion = . tlsv1,
497+ maximumTLSVersion: TLSVersion ? = nil ,
498+ certificateVerification: CertificateVerification = . none,
499+ trustRoots: NIOSSLTrustRoots = . default,
500+ applicationProtocols: [ String ] = [ ] ,
501+ shutdownTimeout: TimeAmount = . seconds( 5 ) ,
502+ keyLogCallback: NIOSSLKeyLogCallback ? = nil ,
503+ additionalTrustRoots: [ NIOSSLAdditionalTrustRoots ] = [ ] ,
504+ trustCommonName: Bool ) -> TLSConfiguration {
505+ return TLSConfiguration ( cipherSuites: cipherSuites,
506+ verifySignatureAlgorithms: verifySignatureAlgorithms,
507+ signingSignatureAlgorithms: signingSignatureAlgorithms,
508+ minimumTLSVersion: minimumTLSVersion,
509+ maximumTLSVersion: maximumTLSVersion,
510+ certificateVerification: certificateVerification,
511+ trustRoots: trustRoots,
512+ certificateChain: certificateChain,
513+ privateKey: privateKey,
514+ applicationProtocols: applicationProtocols,
515+ shutdownTimeout: shutdownTimeout,
516+ keyLogCallback: keyLogCallback,
517+ renegotiationSupport: . none, // Servers never support renegotiation: there's no point.
518+ additionalTrustRoots: additionalTrustRoots,
519+ trustCommonName: trustCommonName)
467520 }
468521
469522 /// Creates a TLS configuration for use with client-side contexts. This allows setting the `NIOTLSCipher` property specifically.
@@ -497,7 +550,8 @@ public struct TLSConfiguration {
497550 shutdownTimeout: shutdownTimeout,
498551 keyLogCallback: keyLogCallback,
499552 renegotiationSupport: renegotiationSupport,
500- additionalTrustRoots: additionalTrustRoots)
553+ additionalTrustRoots: additionalTrustRoots,
554+ trustCommonName: false )
501555 }
502556
503557 /// Creates a TLS configuration for use with client-side contexts.
@@ -527,7 +581,8 @@ public struct TLSConfiguration {
527581 shutdownTimeout: shutdownTimeout,
528582 keyLogCallback: keyLogCallback,
529583 renegotiationSupport: . none, // Default value is here for backward-compatibility.
530- additionalTrustRoots: [ ] )
584+ additionalTrustRoots: [ ] ,
585+ trustCommonName: false )
531586 }
532587
533588
@@ -559,7 +614,8 @@ public struct TLSConfiguration {
559614 shutdownTimeout: shutdownTimeout,
560615 keyLogCallback: keyLogCallback,
561616 renegotiationSupport: renegotiationSupport,
562- additionalTrustRoots: [ ] )
617+ additionalTrustRoots: [ ] ,
618+ trustCommonName: false )
563619 }
564620
565621 /// Creates a TLS configuration for use with client-side contexts.
@@ -592,7 +648,8 @@ public struct TLSConfiguration {
592648 shutdownTimeout: shutdownTimeout,
593649 keyLogCallback: keyLogCallback,
594650 renegotiationSupport: renegotiationSupport,
595- additionalTrustRoots: [ ] )
651+ additionalTrustRoots: [ ] ,
652+ trustCommonName: false )
596653 }
597654
598655 /// Creates a TLS configuration for use with client-side contexts.
@@ -626,7 +683,44 @@ public struct TLSConfiguration {
626683 shutdownTimeout: shutdownTimeout,
627684 keyLogCallback: keyLogCallback,
628685 renegotiationSupport: renegotiationSupport,
629- additionalTrustRoots: additionalTrustRoots)
686+ additionalTrustRoots: additionalTrustRoots,
687+ trustCommonName: false )
688+ }
689+
690+ /// Creates a TLS configuration for use with client-side contexts. This allows setting the `NIOTLSCipher` property specifically.
691+ ///
692+ /// This provides sensible defaults, and can be used without customisation. For server-side
693+ /// contexts, you should use `forServer` instead.
694+ public static func forClient( cipherSuites: String = defaultCipherSuites,
695+ verifySignatureAlgorithms: [ SignatureAlgorithm ] ? = nil ,
696+ signingSignatureAlgorithms: [ SignatureAlgorithm ] ? = nil ,
697+ minimumTLSVersion: TLSVersion = . tlsv1,
698+ maximumTLSVersion: TLSVersion ? = nil ,
699+ certificateVerification: CertificateVerification = . fullVerification,
700+ trustRoots: NIOSSLTrustRoots = . default,
701+ certificateChain: [ NIOSSLCertificateSource ] = [ ] ,
702+ privateKey: NIOSSLPrivateKeySource ? = nil ,
703+ applicationProtocols: [ String ] = [ ] ,
704+ shutdownTimeout: TimeAmount = . seconds( 5 ) ,
705+ keyLogCallback: NIOSSLKeyLogCallback ? = nil ,
706+ renegotiationSupport: NIORenegotiationSupport = . none,
707+ additionalTrustRoots: [ NIOSSLAdditionalTrustRoots ] = [ ] ,
708+ trustCommonName: Bool ) -> TLSConfiguration {
709+ return TLSConfiguration ( cipherSuites: cipherSuites,
710+ verifySignatureAlgorithms: verifySignatureAlgorithms,
711+ signingSignatureAlgorithms: signingSignatureAlgorithms,
712+ minimumTLSVersion: minimumTLSVersion,
713+ maximumTLSVersion: maximumTLSVersion,
714+ certificateVerification: certificateVerification,
715+ trustRoots: trustRoots,
716+ certificateChain: certificateChain,
717+ privateKey: privateKey,
718+ applicationProtocols: applicationProtocols,
719+ shutdownTimeout: shutdownTimeout,
720+ keyLogCallback: keyLogCallback,
721+ renegotiationSupport: renegotiationSupport,
722+ additionalTrustRoots: additionalTrustRoots,
723+ trustCommonName: trustCommonName)
630724 }
631725}
632726
@@ -657,7 +751,8 @@ extension TLSConfiguration {
657751 self . encodedApplicationProtocols == comparing. encodedApplicationProtocols &&
658752 self . shutdownTimeout == comparing. shutdownTimeout &&
659753 isKeyLoggerCallbacksEqual &&
660- self . renegotiationSupport == comparing. renegotiationSupport
754+ self . renegotiationSupport == comparing. renegotiationSupport &&
755+ self . trustCommonName == comparing. trustCommonName
661756 }
662757
663758 /// Returns a best effort hash of this TLS configuration.
@@ -682,5 +777,6 @@ extension TLSConfiguration {
682777 hasher. combine ( bytes: closureBits)
683778 }
684779 hasher. combine ( renegotiationSupport)
780+ hasher. combine ( trustCommonName)
685781 }
686782}
0 commit comments