@@ -81,6 +81,43 @@ public enum NIOSSLAdditionalTrustRoots {
81
81
case certificates( [ NIOSSLCertificate ] )
82
82
}
83
83
84
+ /// Available ciphers to use for TLS instead of a string based representation.
85
+ public struct NIOTLSCipher : RawRepresentable , Hashable {
86
+ public init ( rawValue: UInt16 ) {
87
+ self . rawValue = rawValue
88
+ }
89
+
90
+ public init ( _ rawValue: RawValue ) {
91
+ self . rawValue = rawValue
92
+ }
93
+
94
+ public var rawValue : UInt16
95
+ public typealias RawValue = UInt16
96
+
97
+ public static let TLS_RSA_WITH_AES_128_CBC_SHA = NIOTLSCipher ( rawValue: 0x2F )
98
+ public static let TLS_RSA_WITH_AES_256_CBC_SHA = NIOTLSCipher ( rawValue: 0x35 )
99
+ public static let TLS_RSA_WITH_AES_128_GCM_SHA256 = NIOTLSCipher ( rawValue: 0x9C )
100
+ public static let TLS_RSA_WITH_AES_256_GCM_SHA384 = NIOTLSCipher ( rawValue: 0x9D )
101
+ public static let TLS_AES_128_GCM_SHA256 = NIOTLSCipher ( rawValue: 0x1301 )
102
+ public static let TLS_AES_256_GCM_SHA384 = NIOTLSCipher ( rawValue: 0x1302 )
103
+ public static let TLS_CHACHA20_POLY1305_SHA256 = NIOTLSCipher ( rawValue: 0x1303 )
104
+ public static let TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = NIOTLSCipher ( rawValue: 0xC009 )
105
+ public static let TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = NIOTLSCipher ( rawValue: 0xC00A )
106
+ public static let TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = NIOTLSCipher ( rawValue: 0xC013 )
107
+ public static let TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = NIOTLSCipher ( rawValue: 0xC014 )
108
+ public static let TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = NIOTLSCipher ( rawValue: 0xC02B )
109
+ public static let TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = NIOTLSCipher ( rawValue: 0xC02C )
110
+ public static let TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = NIOTLSCipher ( rawValue: 0xC02F )
111
+ public static let TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = NIOTLSCipher ( rawValue: 0xC030 )
112
+ public static let TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = NIOTLSCipher ( rawValue: 0xCCA8 )
113
+ public static let TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = NIOTLSCipher ( rawValue: 0xCCA9 )
114
+
115
+ var standardName : String {
116
+ let boringSSLCipher = CNIOBoringSSL_SSL_get_cipher_by_value ( self . rawValue)
117
+ return String ( cString: CNIOBoringSSL_SSL_CIPHER_standard_name ( boringSSLCipher) )
118
+ }
119
+ }
120
+
84
121
/// Formats NIOSSL supports for serializing keys and certificates.
85
122
public enum NIOSSLSerializationFormats {
86
123
case pem
@@ -200,7 +237,21 @@ public struct TLSConfiguration {
200
237
201
238
/// The pre-TLS1.3 cipher suites supported by this handler. This uses the OpenSSL cipher string format.
202
239
/// TLS 1.3 cipher suites cannot be configured.
203
- public var cipherSuites : String
240
+ public var cipherSuites : String = defaultCipherSuites
241
+
242
+ /// Public property used to set the internal cipherSuites from NIOTLSCipher.
243
+ public var cipherSuiteValues : [ NIOTLSCipher ] {
244
+ get {
245
+ guard let sslContext = try ? NIOSSLContext ( configuration: self ) else {
246
+ return [ ]
247
+ }
248
+ return sslContext. cipherSuites
249
+ }
250
+ set {
251
+ let assignedCiphers = newValue. map { $0. standardName }
252
+ self . cipherSuites = assignedCiphers. joined ( separator: " : " )
253
+ }
254
+ }
204
255
205
256
/// Allowed algorithms to verify signatures. Passing nil means, that a built-in set of algorithms will be used.
206
257
public var verifySignatureAlgorithms : [ SignatureAlgorithm ] ?
@@ -252,7 +303,8 @@ public struct TLSConfiguration {
252
303
/// Whether renegotiation is supported.
253
304
public var renegotiationSupport : NIORenegotiationSupport
254
305
255
- private init ( cipherSuites: String ,
306
+ private init ( cipherSuiteValues: [ NIOTLSCipher ] = [ ] ,
307
+ cipherSuites: String = defaultCipherSuites,
256
308
verifySignatureAlgorithms: [ SignatureAlgorithm ] ? ,
257
309
signingSignatureAlgorithms: [ SignatureAlgorithm ] ? ,
258
310
minimumTLSVersion: TLSVersion ,
@@ -281,6 +333,42 @@ public struct TLSConfiguration {
281
333
self . renegotiationSupport = renegotiationSupport
282
334
self . applicationProtocols = applicationProtocols
283
335
self . keyLogCallback = keyLogCallback
336
+ if !cipherSuiteValues. isEmpty {
337
+ self . cipherSuiteValues = cipherSuiteValues
338
+ }
339
+ }
340
+
341
+ /// Create a TLS configuration for use with server-side contexts. This allows setting the `NIOTLSCipher` property specifically.
342
+ ///
343
+ /// This provides sensible defaults while requiring that you provide any data that is necessary
344
+ /// for server-side function. For client use, try `forClient` instead.
345
+ public static func forServer( certificateChain: [ NIOSSLCertificateSource ] ,
346
+ privateKey: NIOSSLPrivateKeySource ,
347
+ cipherSuites: [ NIOTLSCipher ] ,
348
+ verifySignatureAlgorithms: [ SignatureAlgorithm ] ? = nil ,
349
+ signingSignatureAlgorithms: [ SignatureAlgorithm ] ? = nil ,
350
+ minimumTLSVersion: TLSVersion = . tlsv1,
351
+ maximumTLSVersion: TLSVersion ? = nil ,
352
+ certificateVerification: CertificateVerification = . none,
353
+ trustRoots: NIOSSLTrustRoots = . default,
354
+ applicationProtocols: [ String ] = [ ] ,
355
+ shutdownTimeout: TimeAmount = . seconds( 5 ) ,
356
+ keyLogCallback: NIOSSLKeyLogCallback ? = nil ,
357
+ additionalTrustRoots: [ NIOSSLAdditionalTrustRoots ] = [ ] ) -> TLSConfiguration {
358
+ return TLSConfiguration ( cipherSuiteValues: cipherSuites,
359
+ verifySignatureAlgorithms: verifySignatureAlgorithms,
360
+ signingSignatureAlgorithms: signingSignatureAlgorithms,
361
+ minimumTLSVersion: minimumTLSVersion,
362
+ maximumTLSVersion: maximumTLSVersion,
363
+ certificateVerification: certificateVerification,
364
+ trustRoots: trustRoots,
365
+ certificateChain: certificateChain,
366
+ privateKey: privateKey,
367
+ applicationProtocols: applicationProtocols,
368
+ shutdownTimeout: shutdownTimeout,
369
+ keyLogCallback: keyLogCallback,
370
+ renegotiationSupport: . none, // Servers never support renegotiation: there's no point.
371
+ additionalTrustRoots: additionalTrustRoots)
284
372
}
285
373
286
374
/// Create a TLS configuration for use with server-side contexts.
@@ -377,6 +465,40 @@ public struct TLSConfiguration {
377
465
renegotiationSupport: . none, // Servers never support renegotiation: there's no point.
378
466
additionalTrustRoots: additionalTrustRoots)
379
467
}
468
+
469
+ /// Creates a TLS configuration for use with client-side contexts. This allows setting the `NIOTLSCipher` property specifically.
470
+ ///
471
+ /// This provides sensible defaults, and can be used without customisation. For server-side
472
+ /// contexts, you should use `forServer` instead.
473
+ public static func forClient( cipherSuites: [ NIOTLSCipher ] ,
474
+ verifySignatureAlgorithms: [ SignatureAlgorithm ] ? = nil ,
475
+ signingSignatureAlgorithms: [ SignatureAlgorithm ] ? = nil ,
476
+ minimumTLSVersion: TLSVersion = . tlsv1,
477
+ maximumTLSVersion: TLSVersion ? = nil ,
478
+ certificateVerification: CertificateVerification = . fullVerification,
479
+ trustRoots: NIOSSLTrustRoots = . default,
480
+ certificateChain: [ NIOSSLCertificateSource ] = [ ] ,
481
+ privateKey: NIOSSLPrivateKeySource ? = nil ,
482
+ applicationProtocols: [ String ] = [ ] ,
483
+ shutdownTimeout: TimeAmount = . seconds( 5 ) ,
484
+ keyLogCallback: NIOSSLKeyLogCallback ? = nil ,
485
+ renegotiationSupport: NIORenegotiationSupport = . none,
486
+ additionalTrustRoots: [ NIOSSLAdditionalTrustRoots ] = [ ] ) -> TLSConfiguration {
487
+ return TLSConfiguration ( cipherSuiteValues: cipherSuites,
488
+ verifySignatureAlgorithms: verifySignatureAlgorithms,
489
+ signingSignatureAlgorithms: signingSignatureAlgorithms,
490
+ minimumTLSVersion: minimumTLSVersion,
491
+ maximumTLSVersion: maximumTLSVersion,
492
+ certificateVerification: certificateVerification,
493
+ trustRoots: trustRoots,
494
+ certificateChain: certificateChain,
495
+ privateKey: privateKey,
496
+ applicationProtocols: applicationProtocols,
497
+ shutdownTimeout: shutdownTimeout,
498
+ keyLogCallback: keyLogCallback,
499
+ renegotiationSupport: renegotiationSupport,
500
+ additionalTrustRoots: additionalTrustRoots)
501
+ }
380
502
381
503
/// Creates a TLS configuration for use with client-side contexts.
382
504
///
0 commit comments