@@ -17,8 +17,6 @@ use hyper::client::ResponseFuture;
17
17
#[ cfg( feature = "native-tls-crate" ) ]
18
18
use native_tls_crate:: TlsConnector ;
19
19
use pin_project_lite:: pin_project;
20
- #[ cfg( feature = "rustls-tls-native-roots" ) ]
21
- use rustls:: RootCertStore ;
22
20
use std:: future:: Future ;
23
21
use std:: pin:: Pin ;
24
22
use std:: task:: { Context , Poll } ;
@@ -322,68 +320,94 @@ impl ClientBuilder {
322
320
TlsBackend :: Rustls => {
323
321
use crate :: tls:: NoVerifier ;
324
322
325
- let mut tls = rustls:: ClientConfig :: new ( ) ;
326
- match config. http_version_pref {
327
- HttpVersionPref :: Http1 => {
328
- tls. set_protocols ( & [ "http/1.1" . into ( ) ] ) ;
329
- }
330
- HttpVersionPref :: Http2 => {
331
- tls. set_protocols ( & [ "h2" . into ( ) ] ) ;
332
- }
333
- HttpVersionPref :: All => {
334
- tls. set_protocols ( & [ "h2" . into ( ) , "http/1.1" . into ( ) ] ) ;
335
- }
323
+ // Set root certificates.
324
+ let mut root_cert_store = rustls:: RootCertStore :: empty ( ) ;
325
+ for cert in config. root_certs {
326
+ cert. add_to_rustls ( & mut root_cert_store) ?;
336
327
}
328
+
337
329
#[ cfg( feature = "rustls-tls-webpki-roots" ) ]
338
330
if config. tls_built_in_root_certs {
339
- tls. root_store
340
- . add_server_trust_anchors ( & webpki_roots:: TLS_SERVER_ROOTS ) ;
341
- }
342
- #[ cfg( feature = "rustls-tls-native-roots" ) ]
343
- if config. tls_built_in_root_certs {
344
- let roots_slice = NATIVE_ROOTS . as_ref ( ) . unwrap ( ) . roots . as_slice ( ) ;
345
- tls. root_store . roots . extend_from_slice ( roots_slice) ;
346
- }
347
-
348
- if !config. certs_verification {
349
- tls. dangerous ( )
350
- . set_certificate_verifier ( Arc :: new ( NoVerifier ) ) ;
351
- }
331
+ use rustls:: OwnedTrustAnchor ;
332
+
333
+ let trust_anchors =
334
+ webpki_roots:: TLS_SERVER_ROOTS . 0 . iter ( ) . map ( |trust_anchor| {
335
+ OwnedTrustAnchor :: from_subject_spki_name_constraints (
336
+ trust_anchor. subject ,
337
+ trust_anchor. spki ,
338
+ trust_anchor. name_constraints ,
339
+ )
340
+ } ) ;
352
341
353
- for cert in config. root_certs {
354
- cert. add_to_rustls ( & mut tls) ?;
342
+ root_cert_store. add_server_trust_anchors ( trust_anchors) ;
355
343
}
356
344
357
- if let Some ( id) = config. identity {
358
- id. add_to_rustls ( & mut tls) ?;
345
+ #[ cfg( feature = "rustls-tls-native-roots" ) ]
346
+ if config. tls_built_in_root_certs {
347
+ for cert in rustls_native_certs:: load_native_certs ( )
348
+ . map_err ( crate :: error:: builder) ?
349
+ {
350
+ root_cert_store
351
+ . add ( & rustls:: Certificate ( cert. 0 ) )
352
+ . map_err ( crate :: error:: builder) ?
353
+ }
359
354
}
360
355
361
- // rustls does not support TLS versions <1.2 and this is unlikely to change.
362
- // https://github.com/rustls/rustls/issues/33
363
-
364
- // As of writing, TLS 1.2 and 1.3 are the only implemented versions and are both
365
- // enabled by default.
366
- // rustls 0.20 will add ALL_VERSIONS and DEFAULT_VERSIONS. That will enable a more
367
- // sophisticated approach.
368
- // For now we assume the default tls.versions matches the future ALL_VERSIONS and
369
- // act based on that.
356
+ // Set TLS versions.
357
+ let mut versions = rustls:: ALL_VERSIONS . to_vec ( ) ;
370
358
371
359
if let Some ( min_tls_version) = config. min_tls_version {
372
- tls . versions
373
- . retain ( | & version| match tls:: Version :: from_rustls ( version) {
360
+ versions. retain ( | & supported_version| {
361
+ match tls:: Version :: from_rustls ( supported_version . version ) {
374
362
Some ( version) => version >= min_tls_version,
375
363
// Assume it's so new we don't know about it, allow it
376
364
// (as of writing this is unreachable)
377
365
None => true ,
378
- } ) ;
366
+ }
367
+ } ) ;
379
368
}
380
369
381
370
if let Some ( max_tls_version) = config. max_tls_version {
382
- tls . versions
383
- . retain ( | & version| match tls:: Version :: from_rustls ( version) {
371
+ versions. retain ( | & supported_version| {
372
+ match tls:: Version :: from_rustls ( supported_version . version ) {
384
373
Some ( version) => version <= max_tls_version,
385
374
None => false ,
386
- } ) ;
375
+ }
376
+ } ) ;
377
+ }
378
+
379
+ // Build TLS config
380
+ let config_builder = rustls:: ClientConfig :: builder ( )
381
+ . with_safe_default_cipher_suites ( )
382
+ . with_safe_default_kx_groups ( )
383
+ . with_protocol_versions ( & versions)
384
+ . map_err ( crate :: error:: builder) ?
385
+ . with_root_certificates ( root_cert_store) ;
386
+
387
+ // Finalize TLS config
388
+ let mut tls = if let Some ( id) = config. identity {
389
+ id. add_to_rustls ( config_builder) ?
390
+ } else {
391
+ config_builder. with_no_client_auth ( )
392
+ } ;
393
+
394
+ // Certificate verifier
395
+ if !config. certs_verification {
396
+ tls. dangerous ( )
397
+ . set_certificate_verifier ( Arc :: new ( NoVerifier ) ) ;
398
+ }
399
+
400
+ // ALPN protocol
401
+ match config. http_version_pref {
402
+ HttpVersionPref :: Http1 => {
403
+ tls. alpn_protocols = vec ! [ "http/1.1" . into( ) ] ;
404
+ }
405
+ HttpVersionPref :: Http2 => {
406
+ tls. alpn_protocols = vec ! [ "h2" . into( ) ] ;
407
+ }
408
+ HttpVersionPref :: All => {
409
+ tls. alpn_protocols = vec ! [ "h2" . into( ) , "http/1.1" . into( ) ] ;
410
+ }
387
411
}
388
412
389
413
Connector :: new_rustls_tls (
@@ -1848,12 +1872,6 @@ fn add_cookie_header(headers: &mut HeaderMap, cookie_store: &dyn cookie::CookieS
1848
1872
}
1849
1873
}
1850
1874
1851
- #[ cfg( feature = "rustls-tls-native-roots" ) ]
1852
- lazy_static ! {
1853
- static ref NATIVE_ROOTS : std:: io:: Result <RootCertStore > =
1854
- rustls_native_certs:: load_native_certs( ) . map_err( |e| e. 1 ) ;
1855
- }
1856
-
1857
1875
#[ cfg( test) ]
1858
1876
mod tests {
1859
1877
#[ tokio:: test]
0 commit comments