1
1
use std:: {
2
+ convert:: TryFrom ,
2
3
fs:: File ,
3
4
io:: { BufReader , Seek , SeekFrom } ,
4
5
pin:: Pin ,
5
6
sync:: Arc ,
6
7
task:: { Context , Poll } ,
8
+ time:: SystemTime ,
7
9
} ;
8
10
9
11
use futures_io:: { AsyncRead , AsyncWrite } ;
10
12
use rustls:: {
11
- internal :: pemfile ,
13
+ client :: { ClientConfig , ServerCertVerified , ServerCertVerifier , ServerName } ,
12
14
Certificate ,
15
+ Error as TlsError ,
16
+ OwnedTrustAnchor ,
13
17
RootCertStore ,
14
- ServerCertVerified ,
15
- ServerCertVerifier ,
16
- TLSError ,
17
18
} ;
18
- use rustls_pemfile:: { read_one, Item } ;
19
+ use rustls_pemfile:: { certs , read_one, Item } ;
19
20
use tokio:: io:: AsyncWrite as TokioAsyncWrite ;
20
21
use tokio_rustls:: TlsConnector ;
21
- use webpki:: DNSNameRef ;
22
22
use webpki_roots:: TLS_SERVER_ROOTS ;
23
23
24
24
use crate :: {
@@ -39,7 +39,7 @@ impl AsyncTlsStream {
39
39
tcp_stream : AsyncTcpStream ,
40
40
cfg : TlsOptions ,
41
41
) -> Result < Self > {
42
- let name = DNSNameRef :: try_from_ascii_str ( host) . map_err ( |e| ErrorKind :: DnsResolve {
42
+ let name = ServerName :: try_from ( host) . map_err ( |e| ErrorKind :: DnsResolve {
43
43
message : format ! ( "could not resolve {:?}: {}" , host, e) ,
44
44
} ) ?;
45
45
let mut tls_config = make_rustls_config ( cfg) ?;
@@ -82,39 +82,38 @@ impl AsyncWrite for AsyncTlsStream {
82
82
83
83
/// Converts `TlsOptions` into a rustls::ClientConfig.
84
84
fn make_rustls_config ( cfg : TlsOptions ) -> Result < rustls:: ClientConfig > {
85
- let mut config = rustls:: ClientConfig :: new ( ) ;
86
-
87
- if let Some ( true ) = cfg. allow_invalid_certificates {
88
- config
89
- . dangerous ( )
90
- . set_certificate_verifier ( Arc :: new ( NoCertVerifier { } ) ) ;
91
- }
92
-
93
85
let mut store = RootCertStore :: empty ( ) ;
94
86
if let Some ( path) = cfg. ca_file_path {
95
- store
96
- . add_pem_file ( & mut BufReader :: new ( File :: open ( & path) ?) )
97
- . map_err ( |_| ErrorKind :: InvalidTlsConfig {
87
+ let ders = certs ( & mut BufReader :: new ( File :: open ( & path) ?) ) . map_err ( |_| {
88
+ ErrorKind :: InvalidTlsConfig {
98
89
message : format ! (
99
90
"Unable to parse PEM-encoded root certificate from {}" ,
100
91
path. display( )
101
92
) ,
102
- } ) ?;
93
+ }
94
+ } ) ?;
95
+ store. add_parsable_certificates ( & ders) ;
103
96
} else {
104
- store. add_server_trust_anchors ( & TLS_SERVER_ROOTS ) ;
97
+ let trust_anchors = TLS_SERVER_ROOTS . 0 . iter ( ) . map ( |ta| {
98
+ OwnedTrustAnchor :: from_subject_spki_name_constraints (
99
+ ta. subject ,
100
+ ta. spki ,
101
+ ta. name_constraints ,
102
+ )
103
+ } ) ;
104
+ store. add_server_trust_anchors ( trust_anchors) ;
105
105
}
106
106
107
- config. root_store = store;
108
-
109
- if let Some ( path) = cfg. cert_key_file_path {
107
+ let mut config = if let Some ( path) = cfg. cert_key_file_path {
110
108
let mut file = BufReader :: new ( File :: open ( & path) ?) ;
111
- let certs = match pemfile :: certs ( & mut file) {
112
- Ok ( certs) => certs,
113
- Err ( ( ) ) => {
109
+ let certs = match certs ( & mut file) {
110
+ Ok ( certs) => certs. into_iter ( ) . map ( Certificate ) . collect ( ) ,
111
+ Err ( error ) => {
114
112
return Err ( ErrorKind :: InvalidTlsConfig {
115
113
message : format ! (
116
- "Unable to parse PEM-encoded client certificate from {}" ,
117
- path. display( )
114
+ "Unable to parse PEM-encoded client certificate from {}: {}" ,
115
+ path. display( ) ,
116
+ error,
118
117
) ,
119
118
}
120
119
. into ( ) )
@@ -146,11 +145,24 @@ fn make_rustls_config(cfg: TlsOptions) -> Result<rustls::ClientConfig> {
146
145
}
147
146
} ;
148
147
148
+ ClientConfig :: builder ( )
149
+ . with_safe_defaults ( )
150
+ . with_root_certificates ( store)
151
+ . with_single_cert ( certs, key)
152
+ . map_err ( |error| ErrorKind :: InvalidTlsConfig {
153
+ message : error. to_string ( ) ,
154
+ } ) ?
155
+ } else {
156
+ ClientConfig :: builder ( )
157
+ . with_safe_defaults ( )
158
+ . with_root_certificates ( store)
159
+ . with_no_client_auth ( )
160
+ } ;
161
+
162
+ if let Some ( true ) = cfg. allow_invalid_certificates {
149
163
config
150
- . set_single_client_cert ( certs, key)
151
- . map_err ( |e| ErrorKind :: InvalidTlsConfig {
152
- message : e. to_string ( ) ,
153
- } ) ?;
164
+ . dangerous ( )
165
+ . set_certificate_verifier ( Arc :: new ( NoCertVerifier { } ) ) ;
154
166
}
155
167
156
168
Ok ( config)
@@ -161,11 +173,13 @@ struct NoCertVerifier {}
161
173
impl ServerCertVerifier for NoCertVerifier {
162
174
fn verify_server_cert (
163
175
& self ,
164
- _: & RootCertStore ,
176
+ _: & Certificate ,
165
177
_: & [ Certificate ] ,
166
- _: webpki:: DNSNameRef ,
178
+ _: & ServerName ,
179
+ _: & mut dyn Iterator < Item = & [ u8 ] > ,
167
180
_: & [ u8 ] ,
168
- ) -> std:: result:: Result < ServerCertVerified , TLSError > {
181
+ _: SystemTime ,
182
+ ) -> std:: result:: Result < ServerCertVerified , TlsError > {
169
183
Ok ( ServerCertVerified :: assertion ( ) )
170
184
}
171
185
}
0 commit comments