1
- use super :: io:: BoxedIo ;
2
- use crate :: transport:: {
3
- server:: { Connected , TlsStream } ,
4
- Certificate , Identity ,
1
+ use std:: {
2
+ io:: Cursor ,
3
+ { fmt, sync:: Arc } ,
5
4
} ;
6
- use std:: { fmt, sync:: Arc } ;
5
+
6
+ use rustls_pki_types:: { CertificateDer , PrivateKeyDer , ServerName } ;
7
7
use tokio:: io:: { AsyncRead , AsyncWrite } ;
8
8
use tokio_rustls:: {
9
- rustls:: { ClientConfig , RootCertStore , ServerConfig , ServerName } ,
9
+ rustls:: { server :: WebPkiClientVerifier , ClientConfig , RootCertStore , ServerConfig } ,
10
10
TlsAcceptor as RustlsAcceptor , TlsConnector as RustlsConnector ,
11
11
} ;
12
12
13
+ use super :: io:: BoxedIo ;
14
+ use crate :: transport:: {
15
+ server:: { Connected , TlsStream } ,
16
+ Certificate , Identity ,
17
+ } ;
18
+
13
19
/// h2 alpn in plain format for rustls.
14
- const ALPN_H2 : & str = "h2" ;
20
+ const ALPN_H2 : & [ u8 ] = b "h2";
15
21
16
22
#[ derive( Debug ) ]
17
23
enum TlsError {
@@ -23,70 +29,58 @@ enum TlsError {
23
29
#[ derive( Clone ) ]
24
30
pub ( crate ) struct TlsConnector {
25
31
config : Arc < ClientConfig > ,
26
- domain : Arc < ServerName > ,
32
+ domain : Arc < ServerName < ' static > > ,
27
33
}
28
34
29
35
impl TlsConnector {
30
36
pub ( crate ) fn new (
31
37
ca_cert : Option < Certificate > ,
32
38
identity : Option < Identity > ,
33
- domain : String ,
39
+ domain : & str ,
34
40
) -> Result < Self , crate :: Error > {
35
- let builder = ClientConfig :: builder ( ) . with_safe_defaults ( ) ;
41
+ let builder = ClientConfig :: builder ( ) ;
36
42
let mut roots = RootCertStore :: empty ( ) ;
37
43
38
44
#[ cfg( feature = "tls-roots" ) ]
39
- roots. add_parsable_certificates ( & rustls_native_certs:: load_native_certs ( ) ?) ;
45
+ roots. add_parsable_certificates ( rustls_native_certs:: load_native_certs ( ) ?) ;
40
46
41
47
#[ cfg( feature = "tls-webpki-roots" ) ]
42
- roots. add_trust_anchors ( webpki_roots:: TLS_SERVER_ROOTS . iter ( ) . map ( |ta| {
43
- tokio_rustls:: rustls:: OwnedTrustAnchor :: from_subject_spki_name_constraints (
44
- ta. subject ,
45
- ta. spki ,
46
- ta. name_constraints ,
47
- )
48
- } ) ) ;
48
+ roots. extend ( webpki_roots:: TLS_SERVER_ROOTS . iter ( ) . cloned ( ) ) ;
49
49
50
50
if let Some ( cert) = ca_cert {
51
- rustls_keys :: add_certs_from_pem ( std :: io :: Cursor :: new ( cert. as_ref ( ) ) , & mut roots) ?;
51
+ add_certs_from_pem ( & mut Cursor :: new ( cert) , & mut roots) ?;
52
52
}
53
53
54
54
let builder = builder. with_root_certificates ( roots) ;
55
55
let mut config = match identity {
56
56
Some ( identity) => {
57
- let ( client_cert, client_key) = rustls_keys :: load_identity ( identity) ?;
57
+ let ( client_cert, client_key) = load_identity ( identity) ?;
58
58
builder. with_client_auth_cert ( client_cert, client_key) ?
59
59
}
60
60
None => builder. with_no_client_auth ( ) ,
61
61
} ;
62
62
63
- config. alpn_protocols . push ( ALPN_H2 . as_bytes ( ) . to_vec ( ) ) ;
63
+ config. alpn_protocols . push ( ALPN_H2 . into ( ) ) ;
64
64
Ok ( Self {
65
65
config : Arc :: new ( config) ,
66
- domain : Arc :: new ( domain . as_str ( ) . try_into ( ) ? ) ,
66
+ domain : Arc :: new ( ServerName :: try_from ( domain ) ? . to_owned ( ) ) ,
67
67
} )
68
68
}
69
69
70
70
pub ( crate ) async fn connect < I > ( & self , io : I ) -> Result < BoxedIo , crate :: Error >
71
71
where
72
72
I : AsyncRead + AsyncWrite + Send + Unpin + ' static ,
73
73
{
74
- let tls_io = {
75
- let io = RustlsConnector :: from ( self . config . clone ( ) )
76
- . connect ( self . domain . as_ref ( ) . to_owned ( ) , io)
77
- . await ?;
74
+ let io = RustlsConnector :: from ( self . config . clone ( ) )
75
+ . connect ( self . domain . as_ref ( ) . to_owned ( ) , io)
76
+ . await ?;
78
77
79
- let ( _, session) = io. get_ref ( ) ;
80
-
81
- match session. alpn_protocol ( ) {
82
- Some ( b) if b == b"h2" => ( ) ,
83
- _ => return Err ( TlsError :: H2NotNegotiated . into ( ) ) ,
84
- } ;
85
-
86
- BoxedIo :: new ( io)
87
- } ;
78
+ let ( _, session) = io. get_ref ( ) ;
79
+ if session. alpn_protocol ( ) != Some ( ALPN_H2 ) {
80
+ return Err ( TlsError :: H2NotNegotiated ) ?;
81
+ }
88
82
89
- Ok ( tls_io )
83
+ Ok ( BoxedIo :: new ( io ) )
90
84
}
91
85
}
92
86
@@ -107,30 +101,27 @@ impl TlsAcceptor {
107
101
client_ca_root : Option < Certificate > ,
108
102
client_auth_optional : bool ,
109
103
) -> Result < Self , crate :: Error > {
110
- let builder = ServerConfig :: builder ( ) . with_safe_defaults ( ) ;
104
+ let builder = ServerConfig :: builder ( ) ;
111
105
112
- let builder = match ( client_ca_root, client_auth_optional) {
113
- ( None , _) => builder. with_no_client_auth ( ) ,
114
- ( Some ( cert) , true ) => {
115
- use tokio_rustls:: rustls:: server:: AllowAnyAnonymousOrAuthenticatedClient ;
116
- let mut roots = RootCertStore :: empty ( ) ;
117
- rustls_keys:: add_certs_from_pem ( std:: io:: Cursor :: new ( cert. as_ref ( ) ) , & mut roots) ?;
118
- builder. with_client_cert_verifier (
119
- AllowAnyAnonymousOrAuthenticatedClient :: new ( roots) . boxed ( ) ,
120
- )
121
- }
122
- ( Some ( cert) , false ) => {
123
- use tokio_rustls:: rustls:: server:: AllowAnyAuthenticatedClient ;
106
+ let builder = match client_ca_root {
107
+ None => builder. with_no_client_auth ( ) ,
108
+ Some ( cert) => {
124
109
let mut roots = RootCertStore :: empty ( ) ;
125
- rustls_keys:: add_certs_from_pem ( std:: io:: Cursor :: new ( cert. as_ref ( ) ) , & mut roots) ?;
126
- builder. with_client_cert_verifier ( AllowAnyAuthenticatedClient :: new ( roots) . boxed ( ) )
110
+ add_certs_from_pem ( & mut Cursor :: new ( cert) , & mut roots) ?;
111
+ let verifier = if client_auth_optional {
112
+ WebPkiClientVerifier :: builder ( roots. into ( ) ) . allow_unauthenticated ( )
113
+ } else {
114
+ WebPkiClientVerifier :: builder ( roots. into ( ) )
115
+ }
116
+ . build ( ) ?;
117
+ builder. with_client_cert_verifier ( verifier)
127
118
}
128
119
} ;
129
120
130
- let ( cert, key) = rustls_keys :: load_identity ( identity) ?;
121
+ let ( cert, key) = load_identity ( identity) ?;
131
122
let mut config = builder. with_single_cert ( cert, key) ?;
132
123
133
- config. alpn_protocols . push ( ALPN_H2 . as_bytes ( ) . to_vec ( ) ) ;
124
+ config. alpn_protocols . push ( ALPN_H2 . into ( ) ) ;
134
125
Ok ( Self {
135
126
inner : Arc :: new ( config) ,
136
127
} )
@@ -166,137 +157,29 @@ impl fmt::Display for TlsError {
166
157
167
158
impl std:: error:: Error for TlsError { }
168
159
169
- mod rustls_keys {
170
- use std:: io:: Cursor ;
171
-
172
- use tokio_rustls:: rustls:: { Certificate , PrivateKey , RootCertStore } ;
173
-
174
- use crate :: transport:: service:: tls:: TlsError ;
175
- use crate :: transport:: Identity ;
176
-
177
- pub ( super ) fn load_rustls_private_key (
178
- mut cursor : std:: io:: Cursor < & [ u8 ] > ,
179
- ) -> Result < PrivateKey , crate :: Error > {
180
- while let Ok ( Some ( item) ) = rustls_pemfile:: read_one ( & mut cursor) {
181
- match item {
182
- rustls_pemfile:: Item :: RSAKey ( key)
183
- | rustls_pemfile:: Item :: PKCS8Key ( key)
184
- | rustls_pemfile:: Item :: ECKey ( key) => return Ok ( PrivateKey ( key) ) ,
185
- _ => continue ,
186
- }
187
- }
188
-
189
- // Otherwise we have a Private Key parsing problem
190
- Err ( Box :: new ( TlsError :: PrivateKeyParseError ) )
191
- }
192
-
193
- pub ( crate ) fn load_identity (
194
- identity : Identity ,
195
- ) -> Result < ( Vec < Certificate > , PrivateKey ) , crate :: Error > {
196
- let cert = {
197
- let mut cert = std:: io:: Cursor :: new ( identity. cert . as_ref ( ) ) ;
198
- match rustls_pemfile:: certs ( & mut cert) {
199
- Ok ( certs) => certs. into_iter ( ) . map ( Certificate ) . collect ( ) ,
200
- Err ( _) => return Err ( Box :: new ( TlsError :: CertificateParseError ) ) ,
201
- }
202
- } ;
203
-
204
- let key = {
205
- let key = std:: io:: Cursor :: new ( identity. key . as_ref ( ) ) ;
206
- match load_rustls_private_key ( key) {
207
- Ok ( key) => key,
208
- Err ( e) => {
209
- return Err ( e) ;
210
- }
211
- }
212
- } ;
160
+ fn load_identity (
161
+ identity : Identity ,
162
+ ) -> Result < ( Vec < CertificateDer < ' static > > , PrivateKeyDer < ' static > ) , TlsError > {
163
+ let cert = rustls_pemfile:: certs ( & mut Cursor :: new ( identity. cert ) )
164
+ . collect :: < Result < Vec < _ > , _ > > ( )
165
+ . map_err ( |_| TlsError :: CertificateParseError ) ?;
213
166
214
- Ok ( ( cert, key) )
215
- }
167
+ let Ok ( Some ( key) ) = rustls_pemfile:: private_key ( & mut Cursor :: new ( identity. key ) ) else {
168
+ return Err ( TlsError :: PrivateKeyParseError ) ;
169
+ } ;
216
170
217
- pub ( crate ) fn add_certs_from_pem (
218
- mut certs : Cursor < & [ u8 ] > ,
219
- roots : & mut RootCertStore ,
220
- ) -> Result < ( ) , crate :: Error > {
221
- let ( _, ignored) = roots. add_parsable_certificates ( & rustls_pemfile:: certs ( & mut certs) ?) ;
222
- match ignored == 0 {
223
- true => Ok ( ( ) ) ,
224
- false => Err ( Box :: new ( TlsError :: CertificateParseError ) ) ,
225
- }
226
- }
171
+ Ok ( ( cert, key) )
227
172
}
228
173
229
- #[ cfg( test) ]
230
- mod tests {
231
- use std:: io:: Cursor ;
232
-
233
- // generated by: openssl ecparam -keygen -name 'prime256v1'
234
- const SIMPLE_EC_KEY : & str = r#"-----BEGIN EC PARAMETERS-----
235
- BggqhkjOPQMBBw==
236
- -----END EC PARAMETERS-----
237
- -----BEGIN EC PRIVATE KEY-----
238
- MHcCAQEEICIDyh40kMVWGDAYr1gXnMfeMeO3zXYigOaWrg5SNB+zoAoGCCqGSM49
239
- AwEHoUQDQgAEacJyVg299dkPTzUaMbOmACUfF67yp+ZrDhXVjn/5WxBAgjcmFBHg
240
- Tw8dfwpMzaJPXX5lWYzP276fcmbRO25CXw==
241
- -----END EC PRIVATE KEY-----"# ;
242
-
243
- // generated by: openssl genpkey -algorithm rsa
244
- const SIMPLE_PKCS8_KEY : & str = r#"-----BEGIN PRIVATE KEY-----
245
- MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKHkX1YIvqOIAllD
246
- 5fKcIxu2kYjIxxAAQrOBRTloGZUKdPFQY1RANB4t/LEaI5/NJ6NK4915pTn35QAQ
247
- zHJl+X4rNFMgVt+o/nY40PgrQxyyv5A0/URp+iS8Yn3GKt3q6p4zguiO9uNXhiiD
248
- b+VKIFRDm4bHR2yM7pNJ0kMdoattAgMBAAECgYAMpw6UaMaNfVnBpD7agT11MwWY
249
- zShRpdOQt++zFuG49kJBgejhcssf+LQhG0vhd2U7q+S3MISrTSaGpMl1v2aKR/nV
250
- G7X4Bb6X8vrVSMrfze2loT0aNri9jKDZkD/muy6+9JkhRa03NOdhDdseokmcqF3L
251
- xsU4BUOOFYb23ycoeQJBANOGxbZu/3BqsPJMQmXWo1CXuaviZ83lTczPtrz9mJVl
252
- Zs/KmGnJ8I2Azu/dlYXsHRvbIbqA93l1M3GnsWl5IxsCQQDD7hKvOY6qzUNyj+R4
253
- vul/3xaqjiTj59f3jN7Fh6+9AY+WfvEkWfyUUAXY74z43wBgtORfMXnZnjFO96tJ
254
- sswXAkBDYDtb19E/cox4MTg5DfwpMJrwmAYufCqi4Uq4uiI++/SanVKc57jaqbvA
255
- hZkZ9lJzTAJbULcDFgTT3/FPwkkfAkEAqbSDMIzdGuox2n/x9/f8jcpweogmQdUl
256
- xgCZUGSnfkFk2ojXW5Ip6Viqx+0toL6fOCRWjnFvRmPz958kGPCqPwJBAID4y7XV
257
- peOO6Yadu0YbSmFNluRebia6410p5jR21LhG1ty2h22xVhlBWjOC+TyDuKwhmiYT
258
- ed50S3LR1PWt4zE=
259
- -----END PRIVATE KEY-----"# ;
260
-
261
- // generated by: openssl genrsa
262
- const SIMPLE_RSA_KEY : & str = r#"-----BEGIN RSA PRIVATE KEY-----
263
- MIIEogIBAAKCAQEAoEILGds1/RGBHT7jM4R+EL24sQ6Bsn14GgTHc7WoZ7lainEH
264
- H/n+DtHCYUXYyJnN5AMIi3pkigCP1hdXXBQga3zs3lXoi/mAMkT6vjuqQ7Xg5/95
265
- ABx5Ztyy25mZNaXm77glyAzSscKHxWYooXVJYG4C3SGuBJJ1zVjxen6Rkzse5Lpr
266
- yZOUUeqeV3M6KbJ/dkR37HFQVwmlctQukFnb4kozFBQDDnkXi9jT/PH00g6JpW3z
267
- YMzdMq2RMadJ0dzYv62OtdtqmQpVz0dRu/yODV4DkhrWwgPRj2uY4DnYthzILESB
268
- x41gxHj+jqo6NW+C+0fr6uh2CXtD0p+ZVANtBQIDAQABAoIBAE7IaOCrLV1dr5WL
269
- BvKancbpHdSdBxGSMOrJkqvFkCZ9ro8EhbYolcb/Q4nCZpInWlpPS3IWFzroj811
270
- 6BJyKoXtAh1DKnE1lNohowrGFiv3S7uBkiCF3wC8Wokud20yQ9dxNdGkzCdrNIfM
271
- cwj8ubfYHTxMhFnnDlaG9R98/V/dFy0FLxL37eMP/heMbcwKKm9P/G2FqvuCn8a4
272
- FoPbAfvaR64IGCybjoiTjUD7xMHIV4Gr5K07br2TzG2zVlFTacoqXyGBbVVy+ibt
273
- QMh0sn+rMkAy+cFse+yCYZeAFa4FzwGz43sdFviU7uvLG7yXpvZ+uDACFzxlxUVg
274
- v57r1cECgYEA1MMJEe6IunDUyuzRaFNTfQX16QcAv/xLN/1TtVB3HUX5p2bIZKDr
275
- XEl0NCVOrCoz5RsYqbtGmp8B4Yxl3DeX+WeWeD9/f2ZTVGWyBx1N6dZ5hRsyfzG/
276
- xVBUqYxkChjXQ20cNtf8u7JKdnVjOJen9M92nXhFRTwgH83Id4gPp70CgYEAwNN8
277
- lvVJnd05ekyf1qIKOSyKiSGnGa5288PpqsjYMZisXy12y4n8cK2pX5Z5PICHeJVu
278
- K99WdTtO7Q4ghCXRB1jR5pTd4/3/3089SQyDnWz9jlA3pGWcSLDTB1dBJXpMQ6yG
279
- cR2dX5hPDNIdKsc+9Bl/OF5PScvGVUYv4SLF6ukCgYAVhh2WyNDgO6XrWYXdzgA2
280
- N7Im/uReh8F8So57W0aRmZCmFMnVFEp7LZsp41RQKnzRgqo+EYoU/l0MWk27t4wS
281
- WR5pz9KwKsPnV9poydgl/eKRSq0THQ9PgM7v0BoWw2iTk6g1DCivPFw4G6wL/5uo
282
- MozHZXFsjaaaUREktokO6QKBgC3Dg7RILtqaoIOYH+9OseJz4cU+CWyc7XpZKuHv
283
- nO/YbkCAh8syyojrjmEzUz66umwx+t3KubhFBSxZx/nVB9EYkWiKOEdeBxY2tjLa
284
- F3qLXXojK7GGtBrEbLE3UizU47jD/3xlLO59NXWzgFygwR4p1vnH2EWJaV7fs4lZ
285
- OWPRAoGAL0nX0vZ0N9qPETiQan1uHjKYuuFiSP+cwRXVSUYIQM9qDRlKG9zjugwO
286
- az+B6uiR4TrgbwG+faCQwcGk9B8QbcoIb8IigwrWe3XpVaEtcsqFORX0r+tJNDoY
287
- I0O2DOQVPKSK2N5AZzXY4IkybWTV4Yxc7rdXEO3dOOpHGKbpwFQ=
288
- -----END RSA PRIVATE KEY-----"# ;
289
-
290
- #[ test]
291
- fn test_parse_ec_key ( ) {
292
- for ( n, key) in [ SIMPLE_EC_KEY , SIMPLE_PKCS8_KEY , SIMPLE_RSA_KEY ]
293
- . iter ( )
294
- . enumerate ( )
295
- {
296
- let c = Cursor :: new ( key. as_bytes ( ) ) ;
297
- let key = super :: rustls_keys:: load_rustls_private_key ( c) ;
298
-
299
- assert ! ( key. is_ok( ) , "at the {}-th case" , n) ;
300
- }
174
+ fn add_certs_from_pem (
175
+ mut certs : & mut dyn std:: io:: BufRead ,
176
+ roots : & mut RootCertStore ,
177
+ ) -> Result < ( ) , crate :: Error > {
178
+ for cert in rustls_pemfile:: certs ( & mut certs) . collect :: < Result < Vec < _ > , _ > > ( ) ? {
179
+ roots
180
+ . add ( cert)
181
+ . map_err ( |_| TlsError :: CertificateParseError ) ?;
301
182
}
183
+
184
+ Ok ( ( ) )
302
185
}
0 commit comments