1
1
#![ cfg( feature = "rustls-tls" ) ]
2
2
3
- use std:: { convert :: TryInto , sync:: Arc } ;
3
+ use std:: sync:: Arc ;
4
4
5
5
use rustls:: {
6
- client:: { ServerCertVerifier , WebPkiVerifier } ,
7
- Certificate , ClientConfig , OwnedTrustAnchor , RootCertStore ,
6
+ client:: {
7
+ danger:: { ServerCertVerified , ServerCertVerifier } ,
8
+ WebPkiServerVerifier ,
9
+ } ,
10
+ pki_types:: { CertificateDer , ServerName } ,
11
+ ClientConfig , RootCertStore ,
8
12
} ;
9
13
10
14
use rustls_pemfile:: certs;
11
15
use tokio_rustls:: TlsConnector ;
12
16
13
- use crate :: { io:: Endpoint , Result , SslOpts } ;
17
+ use crate :: { io:: Endpoint , Result , SslOpts , TlsError } ;
14
18
15
19
impl SslOpts {
16
- async fn load_root_certs ( & self ) -> crate :: Result < Vec < Certificate > > {
20
+ async fn load_root_certs ( & self ) -> crate :: Result < Vec < CertificateDer < ' static > > > {
17
21
let mut output = Vec :: new ( ) ;
18
22
19
23
for root_cert in self . root_certs ( ) {
20
24
let root_cert_data = root_cert. read ( ) . await ?;
21
25
let mut seen = false ;
22
- for cert in certs ( & mut & * root_cert_data) ? {
26
+ for cert in certs ( & mut & * root_cert_data) {
23
27
seen = true ;
24
- output. push ( Certificate ( cert) ) ;
28
+ output. push ( cert? ) ;
25
29
}
26
30
27
31
if !seen && !root_cert_data. is_empty ( ) {
28
- output. push ( Certificate ( root_cert_data. into_owned ( ) ) ) ;
32
+ output. push ( CertificateDer :: from ( root_cert_data. into_owned ( ) ) ) ;
29
33
}
30
34
}
31
35
@@ -42,21 +46,13 @@ impl Endpoint {
42
46
}
43
47
44
48
let mut root_store = RootCertStore :: empty ( ) ;
45
- root_store. add_trust_anchors ( webpki_roots:: TLS_SERVER_ROOTS . iter ( ) . map ( |ta| {
46
- OwnedTrustAnchor :: from_subject_spki_name_constraints (
47
- ta. subject ,
48
- ta. spki ,
49
- ta. name_constraints ,
50
- )
51
- } ) ) ;
49
+ root_store. extend ( webpki_roots:: TLS_SERVER_ROOTS . iter ( ) . map ( |x| x. to_owned ( ) ) ) ;
52
50
53
51
for cert in ssl_opts. load_root_certs ( ) . await ? {
54
- root_store. add ( & cert) ?;
52
+ root_store. add ( cert) ?;
55
53
}
56
54
57
- let config_builder = ClientConfig :: builder ( )
58
- . with_safe_defaults ( )
59
- . with_root_certificates ( root_store. clone ( ) ) ;
55
+ let config_builder = ClientConfig :: builder ( ) . with_root_certificates ( root_store. clone ( ) ) ;
60
56
61
57
let mut config = if let Some ( identity) = ssl_opts. client_identity ( ) {
62
58
let ( cert_chain, priv_key) = identity. load ( ) . await ?;
@@ -65,12 +61,13 @@ impl Endpoint {
65
61
config_builder. with_no_client_auth ( )
66
62
} ;
67
63
68
- let server_name = domain
69
- . as_str ( )
70
- . try_into ( )
71
- . map_err ( |_| webpki:: InvalidDnsNameError ) ?;
64
+ let server_name = ServerName :: try_from ( domain. as_str ( ) )
65
+ . map_err ( |_| webpki:: InvalidDnsNameError ) ?
66
+ . to_owned ( ) ;
72
67
let mut dangerous = config. dangerous ( ) ;
73
- let web_pki_verifier = WebPkiVerifier :: new ( root_store, None ) ;
68
+ let web_pki_verifier = WebPkiServerVerifier :: builder ( Arc :: new ( root_store) )
69
+ . build ( )
70
+ . map_err ( TlsError :: from) ?;
74
71
let dangerous_verifier = DangerousVerifier :: new (
75
72
ssl_opts. accept_invalid_certs ( ) ,
76
73
ssl_opts. skip_domain_validation ( ) ,
@@ -97,17 +94,18 @@ impl Endpoint {
97
94
}
98
95
}
99
96
97
+ #[ derive( Debug ) ]
100
98
struct DangerousVerifier {
101
99
accept_invalid_certs : bool ,
102
100
skip_domain_validation : bool ,
103
- verifier : WebPkiVerifier ,
101
+ verifier : Arc < WebPkiServerVerifier > ,
104
102
}
105
103
106
104
impl DangerousVerifier {
107
105
fn new (
108
106
accept_invalid_certs : bool ,
109
107
skip_domain_validation : bool ,
110
- verifier : WebPkiVerifier ,
108
+ verifier : Arc < WebPkiServerVerifier > ,
111
109
) -> Self {
112
110
Self {
113
111
accept_invalid_certs,
@@ -118,34 +116,86 @@ impl DangerousVerifier {
118
116
}
119
117
120
118
impl ServerCertVerifier for DangerousVerifier {
119
+ // fn verify_server_cert(
120
+ // &self,
121
+ // end_entity: &Certificate,
122
+ // intermediates: &[Certificate],
123
+ // server_name: &rustls::ServerName,
124
+ // scts: &mut dyn Iterator<Item = &[u8]>,
125
+ // ocsp_response: &[u8],
126
+ // now: std::time::SystemTime,
127
+ // ) -> std::result::Result<rustls::client::ServerCertVerified, rustls::Error> {
128
+ // if self.accept_invalid_certs {
129
+ // Ok(rustls::client::ServerCertVerified::assertion())
130
+ // } else {
131
+ // match self.verifier.verify_server_cert(
132
+ // end_entity,
133
+ // intermediates,
134
+ // server_name,
135
+ // scts,
136
+ // ocsp_response,
137
+ // now,
138
+ // ) {
139
+ // Ok(assertion) => Ok(assertion),
140
+ // Err(ref e)
141
+ // if e.to_string().contains("NotValidForName") && self.skip_domain_validation =>
142
+ // {
143
+ // Ok(rustls::client::ServerCertVerified::assertion())
144
+ // }
145
+ // Err(e) => Err(e),
146
+ // }
147
+ // }
148
+ // }
121
149
fn verify_server_cert (
122
150
& self ,
123
- end_entity : & Certificate ,
124
- intermediates : & [ Certificate ] ,
125
- server_name : & rustls:: ServerName ,
126
- scts : & mut dyn Iterator < Item = & [ u8 ] > ,
151
+ end_entity : & CertificateDer < ' _ > ,
152
+ intermediates : & [ CertificateDer < ' _ > ] ,
153
+ server_name : & rustls:: pki_types:: ServerName < ' _ > ,
127
154
ocsp_response : & [ u8 ] ,
128
- now : std :: time :: SystemTime ,
129
- ) -> std:: result :: Result < rustls :: client :: ServerCertVerified , rustls:: Error > {
155
+ now : rustls :: pki_types :: UnixTime ,
156
+ ) -> std:: prelude :: v1 :: Result < ServerCertVerified , rustls:: Error > {
130
157
if self . accept_invalid_certs {
131
- Ok ( rustls :: client :: ServerCertVerified :: assertion ( ) )
158
+ Ok ( ServerCertVerified :: assertion ( ) )
132
159
} else {
133
160
match self . verifier . verify_server_cert (
134
161
end_entity,
135
162
intermediates,
136
163
server_name,
137
- scts,
138
164
ocsp_response,
139
165
now,
140
166
) {
141
167
Ok ( assertion) => Ok ( assertion) ,
142
168
Err ( ref e)
143
169
if e. to_string ( ) . contains ( "NotValidForName" ) && self . skip_domain_validation =>
144
170
{
145
- Ok ( rustls :: client :: ServerCertVerified :: assertion ( ) )
171
+ Ok ( ServerCertVerified :: assertion ( ) )
146
172
}
147
173
Err ( e) => Err ( e) ,
148
174
}
149
175
}
150
176
}
177
+
178
+ fn verify_tls12_signature (
179
+ & self ,
180
+ message : & [ u8 ] ,
181
+ cert : & CertificateDer < ' _ > ,
182
+ dss : & rustls:: DigitallySignedStruct ,
183
+ ) -> std:: prelude:: v1:: Result < rustls:: client:: danger:: HandshakeSignatureValid , rustls:: Error >
184
+ {
185
+ self . verifier . verify_tls12_signature ( message, cert, dss)
186
+ }
187
+
188
+ fn verify_tls13_signature (
189
+ & self ,
190
+ message : & [ u8 ] ,
191
+ cert : & CertificateDer < ' _ > ,
192
+ dss : & rustls:: DigitallySignedStruct ,
193
+ ) -> std:: prelude:: v1:: Result < rustls:: client:: danger:: HandshakeSignatureValid , rustls:: Error >
194
+ {
195
+ self . verifier . verify_tls13_signature ( message, cert, dss)
196
+ }
197
+
198
+ fn supported_verify_schemes ( & self ) -> Vec < rustls:: SignatureScheme > {
199
+ self . verifier . supported_verify_schemes ( )
200
+ }
151
201
}
0 commit comments