@@ -244,17 +244,14 @@ pub struct TlsConnector {
244
244
min_protocol : Option < Protocol > ,
245
245
max_protocol : Option < Protocol > ,
246
246
root_certificates : Vec < :: Certificate > ,
247
+ identity : Option < :: Identity > ,
247
248
accept_invalid_certs : bool ,
248
249
accept_invalid_hostnames : bool ,
249
250
use_sni : bool ,
250
251
}
251
252
252
253
impl TlsConnector {
253
254
pub fn new ( builder : & TlsConnectorBuilder ) -> Result < TlsConnector , Error > {
254
- if builder. identity . is_some ( ) {
255
- return Err ( Error :: Custom ( "Client authentication not supported" . to_owned ( ) ) ) ;
256
- }
257
-
258
255
let trust_roots = if builder. root_certificates . len ( ) > 0 {
259
256
builder. root_certificates . clone ( )
260
257
} else {
@@ -265,6 +262,7 @@ impl TlsConnector {
265
262
min_protocol : builder. min_protocol ,
266
263
max_protocol : builder. max_protocol ,
267
264
root_certificates : trust_roots,
265
+ identity : builder. identity . clone ( ) ,
268
266
accept_invalid_certs : builder. accept_invalid_certs ,
269
267
accept_invalid_hostnames : builder. accept_invalid_hostnames ,
270
268
use_sni : builder. use_sni
@@ -277,6 +275,33 @@ impl TlsConnector {
277
275
{
278
276
// If any of the ? fail then memory leaks ...
279
277
278
+ let identity = if let Some ( identity) = & self . identity {
279
+ let mut keys = ( identity. 0 ) . 0 . private_keys ( ) . collect :: < Vec < _ > > ( ) ;
280
+ let certificates = ( identity. 0 ) . 0 . certificates ( ) . collect :: < Vec < _ > > ( ) ;
281
+
282
+ if keys. len ( ) != 1 {
283
+ return Err ( HandshakeError :: Failure ( Error :: Custom ( "Unexpected number of keys in PKCS12 file" . to_owned ( ) ) ) )
284
+ }
285
+ if certificates. len ( ) == 0 {
286
+ return Err ( HandshakeError :: Failure ( Error :: Custom ( "PKCS12 file is missing certificate chain" . to_owned ( ) ) ) )
287
+ }
288
+
289
+ let mut cert_chain = vec ! [ ] ;
290
+ for cert in certificates {
291
+ cert_chain. push ( cert. 0 ?) ;
292
+ }
293
+
294
+ fn pk_clone ( pk : & mut Pk ) -> TlsResult < Pk > {
295
+ let der = pk. write_private_der_vec ( ) ?;
296
+ Pk :: from_private_key ( & der, None )
297
+ }
298
+ let key = Box :: new ( keys. pop ( ) . unwrap ( ) . 0 . map_err ( |_| TlsError :: PkInvalidAlg ) ?) ;
299
+
300
+ Some ( ( cert_chain, key) )
301
+ } else {
302
+ None
303
+ } ;
304
+
280
305
unsafe {
281
306
let ca_vec = Box :: into_raw ( Box :: new ( cert_to_vec ( & self . root_certificates ) ) ) ;
282
307
let ca_list = Box :: into_raw ( Box :: new ( CertList :: from_vec ( & mut * ca_vec) . ok_or ( TlsError :: AesInvalidKeyLength ) ?) ) ;
@@ -286,6 +311,17 @@ impl TlsConnector {
286
311
( * config) . set_rng ( Some ( & mut * rng) ) ;
287
312
( * config) . set_ca_list ( Some ( & mut * ca_list) , None ) ;
288
313
314
+ let mut cred_certs = :: std:: ptr:: null_mut ( ) ;
315
+ let mut cred_cert_list = :: std:: ptr:: null_mut ( ) ;
316
+ let mut cred_pk = :: std:: ptr:: null_mut ( ) ;
317
+
318
+ if let Some ( ( certificates, mut pk) ) = identity {
319
+ cred_certs = Box :: into_raw ( Box :: new ( certificates. to_vec ( ) ) ) ;
320
+ cred_cert_list = Box :: into_raw ( Box :: new ( CertList :: from_vec ( & mut * cred_certs) . ok_or ( TlsError :: CamelliaInvalidInputLength ) ?) ) ;
321
+ cred_pk = Box :: into_raw ( Box :: new ( Pk :: from_private_key ( & pk. write_private_der_vec ( ) ?, None ) ?) ) ;
322
+ ( * config) . push_cert ( & mut * cred_cert_list, & mut * cred_pk) ?;
323
+ }
324
+
289
325
if self . accept_invalid_certs {
290
326
( * config) . set_authmode ( mbedtls:: ssl:: config:: AuthMode :: None ) ;
291
327
}
@@ -309,9 +345,9 @@ impl TlsConnector {
309
345
role : ProtocolRole :: Client ,
310
346
ca_certs : ca_vec,
311
347
ca_cert_list : ca_list,
312
- cred_pk : :: std :: ptr :: null_mut ( ) ,
313
- cred_certs : :: std :: ptr :: null_mut ( ) ,
314
- cred_cert_list : :: std :: ptr :: null_mut ( ) ,
348
+ cred_pk : cred_pk ,
349
+ cred_certs : cred_certs ,
350
+ cred_cert_list : cred_cert_list ,
315
351
entropy : entropy,
316
352
rng : rng,
317
353
config : config,
@@ -358,14 +394,10 @@ impl TlsAcceptor {
358
394
cert_chain. push ( cert. 0 ?) ;
359
395
}
360
396
361
- fn pk_clone ( pk : & mut Pk ) -> TlsResult < Pk > {
362
- let der = pk. write_private_der_vec ( ) ?;
363
- Pk :: from_private_key ( & der, None )
364
- }
397
+ let key : & mut Pk = & mut keys. pop ( ) . unwrap ( ) . 0 . map_err ( |_| TlsError :: PkInvalidAlg ) ?;
365
398
366
399
unsafe {
367
- let key : & mut Pk = & mut keys. pop ( ) . unwrap ( ) . 0 . map_err ( |_| TlsError :: PkInvalidAlg ) ?;
368
- let pk = Box :: into_raw ( Box :: new ( pk_clone ( key) ?) ) ;
400
+ let pk = Box :: into_raw ( Box :: new ( Pk :: from_private_key ( & key. write_private_der_vec ( ) ?, None ) ?) ) ;
369
401
let cert_chain = Box :: into_raw ( Box :: new ( cert_chain. to_vec ( ) ) ) ;
370
402
let cert_list = Box :: into_raw ( Box :: new ( CertList :: from_vec ( & mut * cert_chain) . ok_or ( TlsError :: CamelliaInvalidInputLength ) ?) ) ;
371
403
let entropy = Box :: into_raw ( Box :: new ( OsEntropy :: new ( ) ) ) ;
0 commit comments