@@ -42,32 +42,28 @@ extension KafkaConfiguration {
42
42
}
43
43
}
44
44
45
- public struct Root : Sendable , Hashable {
46
- internal enum _Root : Sendable , Hashable {
45
+ public struct TrustRoots : Sendable , Hashable {
46
+ internal enum _TrustRoots : Sendable , Hashable {
47
47
case probe
48
- case disableBrokerVerification
49
48
case file( location: String )
50
49
case pem( String )
51
50
}
52
51
53
- let _internal : _Root
52
+ let _internal : _TrustRoots
54
53
55
54
/// A list of standard paths will be probed and the first one found will be used as the default root certificate location path.
56
- public static let probe = Root ( _internal: . probe)
57
-
58
- /// Disable OpenSSL's built-in broker (server) certificate verification.
59
- public static let disableBrokerVerification = Root ( _internal: . disableBrokerVerification)
55
+ public static let probe = TrustRoots ( _internal: . probe)
60
56
61
57
/// File or directory path to root certificate(s) for verifying the broker's key.
62
- public static func file( location: String ) -> Root {
63
- return Root (
58
+ public static func file( location: String ) -> TrustRoots {
59
+ return TrustRoots (
64
60
_internal: . file( location: location)
65
61
)
66
62
}
67
63
68
- /// Root certificate String for verifying the broker's key.
69
- public static func pem( _ pem: String ) -> Root {
70
- return Root (
64
+ /// Trust roots certificate String for verifying the broker's key.
65
+ public static func pem( _ pem: String ) -> TrustRoots {
66
+ return TrustRoots (
71
67
_internal: . pem( pem)
72
68
)
73
69
}
@@ -122,112 +118,134 @@ extension KafkaConfiguration {
122
118
}
123
119
}
124
120
125
- internal enum _TLSConfiguration : Sendable , Hashable {
126
- case keyPair(
121
+ /// Configuration for the TLS identity of the client.
122
+ public struct ClientIdentity : Sendable , Hashable {
123
+ internal enum _ClientIdentity : Sendable , Hashable {
124
+ case keyPair(
125
+ privateKey: PrivateKey ,
126
+ certificates: LeafAndIntermediates
127
+ )
128
+ case keyStore( keyStore: KeyStore )
129
+ }
130
+
131
+ let _internal : _ClientIdentity
132
+
133
+ /// Use TLS client verification with a given private/public key pair.
134
+ ///
135
+ /// - Parameters:
136
+ /// - privateKey: The client's private key (PEM) used for authentication.
137
+ /// - certificate: The client's public key (PEM) used for authentication.
138
+ public static func keyPair(
127
139
privateKey: PrivateKey ,
128
- publicKeyCertificate: LeafAndIntermediates ,
129
- caCertificate: Root ,
130
- crlLocation: String ?
131
- )
132
- case keyStore(
133
- keyStore: KeyStore ,
134
- caCertificate: Root ,
135
- crlLocation: String ?
136
- )
140
+ certificates: LeafAndIntermediates
141
+ ) -> ClientIdentity {
142
+ return . init(
143
+ _internal: . keyPair(
144
+ privateKey: privateKey,
145
+ certificates: certificates
146
+ )
147
+ )
148
+ }
149
+
150
+ /// Use TLS client verification with a given key store.
151
+ ///
152
+ /// - Parameters:
153
+ /// - keyStore: The client's keystore (PKCS#12) used for authentication.
154
+ public static func keyStore( keyStore: KeyStore ) -> ClientIdentity {
155
+ return . init( _internal: . keyStore( keyStore: keyStore) )
156
+ }
137
157
}
138
158
139
- let _internal : _TLSConfiguration
140
-
141
- /// Use TLS with a given private/public key pair.
142
- ///
143
- /// - Parameters:
144
- ///
145
- /// - privateKey: The client's private key (PEM) used for authentication.
146
- /// - publicKeyCertificate: The client's public key (PEM) used for authentication.
147
- /// - caCertificate: File or directory path to CA certificate(s) for verifying the broker's key.
148
- /// - crLocation: Path to CRL for verifying broker's certificate validity.
149
- public static func keyPair(
150
- privateKey: PrivateKey ,
151
- publicKeyCertificate: LeafAndIntermediates ,
152
- caCertificate: Root = . probe,
153
- crlLocation: String ?
154
- ) -> TLSConfiguration {
155
- return TLSConfiguration (
156
- _internal: . keyPair(
157
- privateKey: privateKey,
158
- publicKeyCertificate: publicKeyCertificate,
159
- caCertificate: caCertificate,
160
- crlLocation: crlLocation
159
+ /// Configuration for the TLS verification of the broker.
160
+ public struct BrokerVerification : Sendable , Hashable {
161
+ internal enum _BrokerVerification : Sendable , Hashable {
162
+ case disabled
163
+ case verify(
164
+ trustRoots: TrustRoots ,
165
+ certificateRevocationListPath: String ?
161
166
)
162
- )
163
- }
167
+ }
168
+
169
+ let _internal : _BrokerVerification
170
+
171
+ /// Do not verify the identity of the broker.
172
+ public static let disabled : BrokerVerification = . init( _internal: . disabled)
164
173
165
- ///
166
- /// - Parameters:
167
- ///
168
- /// - keyStore: The client's keystore (PKCS#12) used for authentication.
169
- /// - caCertificate: File or directory path to CA certificate(s) for verifying the broker's key.
170
- /// - crlLocation: Path to CRL for verifying broker's certificate validity.
171
- public static func keyStore(
172
- keyStore: KeyStore ,
173
- caCertificate: Root = . probe,
174
- crlLocation: String ?
175
- ) -> TLSConfiguration {
176
- return TLSConfiguration (
177
- _internal: . keyStore(
178
- keyStore: keyStore,
179
- caCertificate: caCertificate,
180
- crlLocation: crlLocation
174
+ /// Verify the identity of the broker.
175
+ ///
176
+ /// Parameters:
177
+ /// - trustRoots: File or directory path to CA certificate(s) for verifying the broker's key.
178
+ /// - certificateRevocationListPath: Path to CRL for verifying broker's certificate validity.
179
+ public static func verify(
180
+ trustRoots: TrustRoots = . probe,
181
+ certificateRevocationListPath: String ? = nil
182
+ ) -> BrokerVerification {
183
+ return . init(
184
+ _internal: . verify(
185
+ trustRoots: trustRoots,
186
+ certificateRevocationListPath: certificateRevocationListPath
187
+ )
181
188
)
182
- )
189
+ }
183
190
}
184
191
192
+ /// Configuration for the TLS verification of the client.
193
+ /// Default: `nil`
194
+ public var clientIdentity : ClientIdentity ? = nil
195
+
196
+ /// Configuration for the TLS verification of the broker.
197
+ /// Default: `verify(trustRoots: .probe, certificateRevocationListPath: nil)``
198
+ public var brokerVerification : BrokerVerification = . verify(
199
+ trustRoots: . probe,
200
+ certificateRevocationListPath: nil
201
+ )
202
+
203
+ public init ( ) { }
204
+
185
205
// MARK: TLSConfiguration + Dictionary
186
206
187
207
internal var dictionary : [ String : String ] {
188
208
var resultDict : [ String : String ] = [ : ]
189
209
190
- switch self . _internal {
191
- case . keyPair( let privateKey, let publicKeyCertificate, let caCertificate, let crlLocation) :
210
+ // Client TLS Verification
211
+ switch self . clientIdentity? . _internal {
212
+ case . none:
213
+ break
214
+ case . keyPair( let privateKey, let certificate) :
192
215
switch privateKey. key. _internal {
193
216
case . file( location: let location) :
194
217
resultDict [ " ssl.key.location " ] = location
195
218
case . pem( let pem) :
196
219
resultDict [ " ssl.key.pem " ] = pem
197
220
}
198
221
resultDict [ " ssl.key.password " ] = privateKey. password
199
- switch publicKeyCertificate . _internal {
222
+ switch certificate . _internal {
200
223
case . file( location: let location) :
201
224
resultDict [ " ssl.key.location " ] = location
202
225
resultDict [ " ssl.certificate.location " ] = location
203
226
case . pem( let pem) :
204
227
resultDict [ " ssl.certificate.pem " ] = pem
205
228
}
206
- switch caCertificate. _internal {
207
- case . disableBrokerVerification:
208
- resultDict [ " enable.ssl.certificate.verification " ] = String ( false )
209
- case . probe:
210
- resultDict [ " ssl.ca.location " ] = " probe "
211
- case . file( location: let location) :
212
- resultDict [ " ssl.ca.location " ] = location
213
- case . pem( let pem) :
214
- resultDict [ " ssl.ca.pem " ] = pem
215
- }
216
- resultDict [ " ssl.crl.location " ] = crlLocation
217
- case . keyStore( let keyStore, let caCertificate, let crlLocation) :
229
+ case . keyStore( let keyStore) :
218
230
resultDict [ " ssl.keystore.location " ] = keyStore. location
219
231
resultDict [ " ssl.keystore.password " ] = keyStore. password
220
- switch caCertificate. _internal {
221
- case . disableBrokerVerification:
222
- resultDict [ " enable.ssl.certificate.verification " ] = String ( false )
232
+ }
233
+
234
+ // Broker TLS Verification
235
+ switch self . brokerVerification. _internal {
236
+ case . disabled:
237
+ resultDict [ " enable.ssl.certificate.verification " ] = String ( false )
238
+ case . verify( let trustRoots, let certificateRevocationListPath) :
239
+ resultDict [ " enable.ssl.certificate.verification " ] = String ( true )
240
+ switch trustRoots. _internal {
223
241
case . probe:
224
242
resultDict [ " ssl.ca.location " ] = " probe "
225
243
case . file( location: let location) :
226
244
resultDict [ " ssl.ca.location " ] = location
227
245
case . pem( let pem) :
228
246
resultDict [ " ssl.ca.pem " ] = pem
229
247
}
230
- resultDict [ " ssl.crl.location " ] = crlLocation
248
+ resultDict [ " ssl.crl.location " ] = certificateRevocationListPath
231
249
}
232
250
233
251
return resultDict
@@ -277,7 +295,7 @@ extension KafkaConfiguration {
277
295
}
278
296
279
297
/// Disable automatic key refresh by setting this property.
280
- public static let disable : KeyRefreshAttempts = . init( rawValue: 0 )
298
+ public static let disabled : KeyRefreshAttempts = . init( rawValue: 0 )
281
299
}
282
300
283
301
/// Minimum time in between key refresh attempts.
@@ -311,7 +329,6 @@ extension KafkaConfiguration {
311
329
/// Default OAuthBearer method.
312
330
///
313
331
/// - Parameters:
314
- ///
315
332
/// - configuration: SASL/OAUTHBEARER configuration.
316
333
/// The format is implementation-dependent and must be parsed accordingly.
317
334
/// The default unsecured token implementation (see https://tools.ietf.org/html/rfc7515#appendix-A.5) recognizes space-separated name=value pairs with valid names including principalClaimName, principal, scopeClaimName, scope, and lifeSeconds.
@@ -327,7 +344,6 @@ extension KafkaConfiguration {
327
344
/// OpenID Connect (OIDC).
328
345
///
329
346
/// - Parameters:
330
- ///
331
347
/// - configuration: SASL/OAUTHBEARER configuration.
332
348
/// The format is implementation-dependent and must be parsed accordingly.
333
349
/// The default unsecured token implementation (see https://tools.ietf.org/html/rfc7515#appendix-A.5) recognizes space-separated name=value pairs with valid names including principalClaimName, principal, scopeClaimName, scope, and lifeSeconds.
@@ -481,7 +497,7 @@ extension KafkaConfiguration {
481
497
)
482
498
483
499
/// Use the Transport Layer Security (TLS) protocol.
484
- public static func tls( configuration: TLSConfiguration ) -> SecurityProtocol {
500
+ public static func tls( configuration: TLSConfiguration = TLSConfiguration ( ) ) -> SecurityProtocol {
485
501
return SecurityProtocol (
486
502
_internal: . tls( configuration: configuration)
487
503
)
@@ -497,7 +513,7 @@ extension KafkaConfiguration {
497
513
/// Use the Simple Authentication and Security Layer (SASL) with TLS.
498
514
public static func saslTLS(
499
515
saslMechanism: SASLMechanism ,
500
- tlsConfiguaration: TLSConfiguration
516
+ tlsConfiguaration: TLSConfiguration = TLSConfiguration ( )
501
517
) -> SecurityProtocol {
502
518
return SecurityProtocol (
503
519
_internal: . saslTLS( saslMechanism: saslMechanism, tlsConfiguaration: tlsConfiguaration)
0 commit comments