1
- use std:: convert:: TryInto ;
1
+ use std:: convert:: TryFrom ;
2
2
use std:: fmt;
3
3
use std:: io;
4
4
use std:: io:: prelude:: * ;
5
5
use std:: sync:: Arc ;
6
- use std:: time:: SystemTime ;
7
6
8
- #[ cfg( feature = "tls-rustls-webpki-roots" ) ]
9
- use rustls:: OwnedTrustAnchor ;
10
7
use rustls:: {
11
- client:: { ServerCertVerified , ServerCertVerifier , WebPkiVerifier } ,
12
- ClientConfig , ClientConnection , RootCertStore , ServerName , StreamOwned ,
8
+ client:: {
9
+ danger:: { DangerousClientConfigBuilder , HandshakeSignatureValid , ServerCertVerified , ServerCertVerifier } ,
10
+ WebPkiServerVerifier ,
11
+ } ,
12
+ ClientConfig , ClientConnection , DigitallySignedStruct , RootCertStore , SignatureScheme , StreamOwned ,
13
13
} ;
14
14
#[ cfg( feature = "tls-rustls-native-roots" ) ]
15
15
use rustls_native_certs:: load_native_certs;
16
+ use rustls_pki_types:: { CertificateDer , ServerName , UnixTime } ;
16
17
#[ cfg( feature = "tls-rustls-webpki-roots" ) ]
17
18
use webpki_roots:: TLS_SERVER_ROOTS ;
18
19
19
20
use crate :: { Error , ErrorKind , Result } ;
20
21
21
- pub type Certificate = rustls :: Certificate ;
22
+ pub type Certificate = CertificateDer < ' static > ;
22
23
23
24
pub struct TlsHandshaker {
24
25
inner : Option < Arc < ClientConfig > > ,
@@ -59,36 +60,33 @@ impl TlsHandshaker {
59
60
let mut root_store = RootCertStore :: empty ( ) ;
60
61
61
62
#[ cfg( feature = "tls-rustls-webpki-roots" ) ]
62
- root_store. add_server_trust_anchors ( TLS_SERVER_ROOTS . iter ( ) . map ( |root| {
63
- OwnedTrustAnchor :: from_subject_spki_name_constraints ( root. subject , root. spki , root. name_constraints )
64
- } ) ) ;
63
+ root_store. extend ( TLS_SERVER_ROOTS . iter ( ) . cloned ( ) ) ;
65
64
66
65
#[ cfg( feature = "tls-rustls-native-roots" ) ]
67
- for native_cert in load_native_certs ( ) ? {
68
- let cert = rustls:: Certificate ( native_cert. 0 ) ;
66
+ for cert in load_native_certs ( ) ? {
69
67
// Inspired by https://github.com/seanmonstar/reqwest/blob/231b18f83572836c674404b33cb1ca8b35ca3e36/src/async_impl/client.rs#L363-L365
70
68
// Native certificate stores often include certificates with invalid formats,
71
69
// but we don't want those invalid entries to invalidate the entire process of
72
70
// loading native root certificates
73
- if let Err ( e) = root_store. add ( & cert) {
71
+ if let Err ( e) = root_store. add ( cert) {
74
72
warn ! ( "Could not load native root certificate: {}" , e) ;
75
73
}
76
74
}
77
75
78
- for cert in & self . additional_certs {
76
+ for cert in self . additional_certs . iter ( ) . cloned ( ) {
79
77
root_store. add ( cert) ?;
80
78
}
81
79
82
- let config = Arc :: new (
83
- ClientConfig :: builder ( )
84
- . with_safe_defaults ( )
85
- . with_custom_certificate_verifier ( Arc :: new ( CustomCertVerifier {
86
- upstream : WebPkiVerifier :: new ( root_store, None ) ,
87
- accept_invalid_certs : self . accept_invalid_certs ,
88
- accept_invalid_hostnames : self . accept_invalid_hostnames ,
89
- } ) )
90
- . with_no_client_auth ( ) ,
91
- ) ;
80
+ let config = DangerousClientConfigBuilder {
81
+ cfg : ClientConfig :: builder ( ) ,
82
+ }
83
+ . with_custom_certificate_verifier ( Arc :: new ( CustomCertVerifier {
84
+ upstream : WebPkiServerVerifier :: builder ( root_store. into ( ) ) . build ( ) ? ,
85
+ accept_invalid_certs : self . accept_invalid_certs ,
86
+ accept_invalid_hostnames : self . accept_invalid_hostnames ,
87
+ } ) )
88
+ . with_no_client_auth ( )
89
+ . into ( ) ;
92
90
93
91
self . inner = Some ( Arc :: clone ( & config) ) ;
94
92
@@ -101,9 +99,9 @@ impl TlsHandshaker {
101
99
where
102
100
S : Read + Write ,
103
101
{
104
- let domain = domain
105
- . try_into ( )
106
- . map_err ( |_| Error ( Box :: new ( ErrorKind :: InvalidDNSName ( domain . to_owned ( ) ) ) ) ) ? ;
102
+ let domain = ServerName :: try_from ( domain)
103
+ . map_err ( |_| Error ( Box :: new ( ErrorKind :: InvalidDNSName ( domain . to_owned ( ) ) ) ) ) ?
104
+ . to_owned ( ) ;
107
105
let config = self . client_config ( ) ?;
108
106
let mut session = ClientConnection :: new ( config, domain) ?;
109
107
@@ -184,24 +182,29 @@ where
184
182
}
185
183
186
184
struct CustomCertVerifier {
187
- upstream : WebPkiVerifier ,
185
+ upstream : Arc < WebPkiServerVerifier > ,
188
186
accept_invalid_certs : bool ,
189
187
accept_invalid_hostnames : bool ,
190
188
}
191
189
190
+ impl fmt:: Debug for CustomCertVerifier {
191
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
192
+ f. debug_struct ( "CustomCertVerifier" ) . finish ( )
193
+ }
194
+ }
195
+
192
196
impl ServerCertVerifier for CustomCertVerifier {
193
197
fn verify_server_cert (
194
198
& self ,
195
- end_entity : & Certificate ,
196
- intermediates : & [ Certificate ] ,
199
+ end_entity : & CertificateDer ,
200
+ intermediates : & [ CertificateDer ] ,
197
201
server_name : & ServerName ,
198
- scts : & mut dyn Iterator < Item = & [ u8 ] > ,
199
202
ocsp_response : & [ u8 ] ,
200
- now : SystemTime ,
203
+ now : UnixTime ,
201
204
) -> std:: result:: Result < ServerCertVerified , rustls:: Error > {
202
205
match self
203
206
. upstream
204
- . verify_server_cert ( end_entity, intermediates, server_name, scts , ocsp_response, now)
207
+ . verify_server_cert ( end_entity, intermediates, server_name, ocsp_response, now)
205
208
{
206
209
Err ( rustls:: Error :: NoCertificatesPresented | rustls:: Error :: InvalidCertificate ( _) )
207
210
if self . accept_invalid_certs =>
@@ -218,4 +221,36 @@ impl ServerCertVerifier for CustomCertVerifier {
218
221
upstream => upstream,
219
222
}
220
223
}
224
+
225
+ fn verify_tls12_signature (
226
+ & self ,
227
+ message : & [ u8 ] ,
228
+ cert : & CertificateDer < ' _ > ,
229
+ dss : & DigitallySignedStruct ,
230
+ ) -> std:: result:: Result < HandshakeSignatureValid , rustls:: Error > {
231
+ rustls:: crypto:: verify_tls12_signature (
232
+ message,
233
+ cert,
234
+ dss,
235
+ & rustls:: crypto:: ring:: default_provider ( ) . signature_verification_algorithms ,
236
+ )
237
+ }
238
+
239
+ fn verify_tls13_signature (
240
+ & self ,
241
+ message : & [ u8 ] ,
242
+ cert : & CertificateDer < ' _ > ,
243
+ dss : & DigitallySignedStruct ,
244
+ ) -> std:: result:: Result < HandshakeSignatureValid , rustls:: Error > {
245
+ rustls:: crypto:: verify_tls13_signature (
246
+ message,
247
+ cert,
248
+ dss,
249
+ & rustls:: crypto:: ring:: default_provider ( ) . signature_verification_algorithms ,
250
+ )
251
+ }
252
+
253
+ fn supported_verify_schemes ( & self ) -> Vec < SignatureScheme > {
254
+ self . upstream . supported_verify_schemes ( )
255
+ }
221
256
}
0 commit comments