1
1
use crate :: net:: CertificateInput ;
2
2
use rustls:: {
3
- Certificate , ClientConfig , RootCertStore , ServerCertVerified , ServerCertVerifier , TLSError ,
4
- WebPKIVerifier ,
3
+ client :: { ServerCertVerified , ServerCertVerifier , WebPkiVerifier } ,
4
+ ClientConfig , Error as TlsError , OwnedTrustAnchor , RootCertStore , ServerName ,
5
5
} ;
6
6
use std:: io:: Cursor ;
7
7
use std:: sync:: Arc ;
8
- use webpki :: DNSNameRef ;
8
+ use std :: time :: SystemTime ;
9
9
10
10
use crate :: error:: Error ;
11
11
@@ -14,32 +14,47 @@ pub async fn configure_tls_connector(
14
14
accept_invalid_hostnames : bool ,
15
15
root_cert_path : Option < & CertificateInput > ,
16
16
) -> Result < sqlx_rt:: TlsConnector , Error > {
17
- let mut config = ClientConfig :: new ( ) ;
17
+ let config = ClientConfig :: builder ( ) . with_safe_defaults ( ) ;
18
18
19
- if accept_invalid_certs {
19
+ let config = if accept_invalid_certs {
20
20
config
21
- . dangerous ( )
22
- . set_certificate_verifier ( Arc :: new ( DummyTlsVerifier ) ) ;
21
+ . with_custom_certificate_verifier ( Arc :: new ( DummyTlsVerifier ) )
22
+ . with_no_client_auth ( )
23
23
} else {
24
- config
25
- . root_store
26
- . add_server_trust_anchors ( & webpki_roots:: TLS_SERVER_ROOTS ) ;
24
+ let mut cert_store = RootCertStore :: empty ( ) ;
25
+ cert_store. add_server_trust_anchors ( webpki_roots:: TLS_SERVER_ROOTS . 0 . iter ( ) . map ( |ta| {
26
+ OwnedTrustAnchor :: from_subject_spki_name_constraints (
27
+ ta. subject ,
28
+ ta. spki ,
29
+ ta. name_constraints ,
30
+ )
31
+ } ) ) ;
27
32
28
33
if let Some ( ca) = root_cert_path {
29
34
let data = ca. data ( ) . await ?;
30
35
let mut cursor = Cursor :: new ( data) ;
31
- config
32
- . root_store
33
- . add_pem_file ( & mut cursor)
34
- . map_err ( |_| Error :: Tls ( format ! ( "Invalid certificate {}" , ca) . into ( ) ) ) ?;
36
+
37
+ for cert in rustls_pemfile:: certs ( & mut cursor)
38
+ . map_err ( |_| Error :: Tls ( format ! ( "Invalid certificate {}" , ca) . into ( ) ) ) ?
39
+ {
40
+ cert_store
41
+ . add ( & rustls:: Certificate ( cert) )
42
+ . map_err ( |err| Error :: Tls ( err. into ( ) ) ) ?;
43
+ }
35
44
}
36
45
37
46
if accept_invalid_hostnames {
47
+ let verifier = WebPkiVerifier :: new ( cert_store, None ) ;
48
+
49
+ config
50
+ . with_custom_certificate_verifier ( Arc :: new ( NoHostnameTlsVerifier { verifier } ) )
51
+ . with_no_client_auth ( )
52
+ } else {
38
53
config
39
- . dangerous ( )
40
- . set_certificate_verifier ( Arc :: new ( NoHostnameTlsVerifier ) ) ;
54
+ . with_root_certificates ( cert_store )
55
+ . with_no_client_auth ( )
41
56
}
42
- }
57
+ } ;
43
58
44
59
Ok ( Arc :: new ( config) . into ( ) )
45
60
}
@@ -49,28 +64,42 @@ struct DummyTlsVerifier;
49
64
impl ServerCertVerifier for DummyTlsVerifier {
50
65
fn verify_server_cert (
51
66
& self ,
52
- _roots : & RootCertStore ,
53
- _presented_certs : & [ Certificate ] ,
54
- _dns_name : DNSNameRef < ' _ > ,
67
+ _end_entity : & rustls:: Certificate ,
68
+ _intermediates : & [ rustls:: Certificate ] ,
69
+ _server_name : & ServerName ,
70
+ _scts : & mut dyn Iterator < Item = & [ u8 ] > ,
55
71
_ocsp_response : & [ u8 ] ,
56
- ) -> Result < ServerCertVerified , TLSError > {
72
+ _now : SystemTime ,
73
+ ) -> Result < ServerCertVerified , TlsError > {
57
74
Ok ( ServerCertVerified :: assertion ( ) )
58
75
}
59
76
}
60
77
61
- pub struct NoHostnameTlsVerifier ;
78
+ pub struct NoHostnameTlsVerifier {
79
+ verifier : WebPkiVerifier ,
80
+ }
62
81
63
82
impl ServerCertVerifier for NoHostnameTlsVerifier {
64
83
fn verify_server_cert (
65
84
& self ,
66
- roots : & RootCertStore ,
67
- presented_certs : & [ Certificate ] ,
68
- dns_name : DNSNameRef < ' _ > ,
85
+ end_entity : & rustls:: Certificate ,
86
+ intermediates : & [ rustls:: Certificate ] ,
87
+ server_name : & ServerName ,
88
+ scts : & mut dyn Iterator < Item = & [ u8 ] > ,
69
89
ocsp_response : & [ u8 ] ,
70
- ) -> Result < ServerCertVerified , TLSError > {
71
- let verifier = WebPKIVerifier :: new ( ) ;
72
- match verifier. verify_server_cert ( roots, presented_certs, dns_name, ocsp_response) {
73
- Err ( TLSError :: WebPKIError ( webpki:: Error :: CertNotValidForName ) ) => {
90
+ now : SystemTime ,
91
+ ) -> Result < ServerCertVerified , TlsError > {
92
+ match self . verifier . verify_server_cert (
93
+ end_entity,
94
+ intermediates,
95
+ server_name,
96
+ scts,
97
+ ocsp_response,
98
+ now,
99
+ ) {
100
+ Err ( TlsError :: InvalidCertificateData ( reason) )
101
+ if reason. contains ( "CertNotValidForName" ) =>
102
+ {
74
103
Ok ( ServerCertVerified :: assertion ( ) )
75
104
}
76
105
res => res,
0 commit comments