@@ -2,15 +2,14 @@ use crate::config::PemReader;
22use anyhow:: anyhow;
33use anyhow:: Context ;
44use camino:: Utf8Path ;
5- use rustls:: server :: AllowAnyAuthenticatedClient ;
6- use rustls:: Certificate ;
7- use rustls:: PrivateKey ;
5+ use rustls:: pki_types :: CertificateDer ;
6+ use rustls:: pki_types :: PrivateKeyDer ;
7+ use rustls:: server :: WebPkiClientVerifier ;
88use rustls:: RootCertStore ;
99use rustls:: ServerConfig ;
1010use rustls_pemfile:: Item ;
1111use std:: fs:: File ;
1212use std:: io;
13- use std:: sync:: Arc ;
1413
1514/// Read a directory into a [RootCertStore]
1615pub fn read_trust_store ( ca_dir : & Utf8Path ) -> anyhow:: Result < RootCertStore > {
@@ -32,54 +31,47 @@ pub fn read_trust_store(ca_dir: &Utf8Path) -> anyhow::Result<RootCertStore> {
3231 let Ok ( mut pem_file) = File :: open ( & path) . map ( std:: io:: BufReader :: new) else {
3332 continue ;
3433 } ;
35- if let Some ( value) = rustls_pemfile:: certs ( & mut pem_file)
36- . with_context ( || format ! ( "reading {path}" ) ) ?
37- . into_iter ( )
38- . next ( )
39- {
40- ders. push ( value) ;
41- } ;
34+
35+ ders. extend ( rustls_pemfile:: certs ( & mut pem_file) . filter_map ( Result :: ok) ) ;
4236 }
43- roots. add_parsable_certificates ( & ders) ;
37+ roots. add_parsable_certificates ( ders) ;
4438
4539 Ok ( roots)
4640}
4741
4842/// Load the SSL configuration for rustls
4943pub fn ssl_config (
50- certificate_chain : Vec < Vec < u8 > > ,
51- key_der : Vec < u8 > ,
44+ server_cert_chain : Vec < CertificateDer < ' static > > ,
45+ server_key : PrivateKeyDer < ' static > ,
5246 root_certs : Option < RootCertStore > ,
5347) -> anyhow:: Result < ServerConfig > {
5448 // Trusted CA for client certificates
55- let config = ServerConfig :: builder ( ) . with_safe_defaults ( ) ;
49+ let config = ServerConfig :: builder ( ) ;
5650
5751 let config = if let Some ( root_certs) = root_certs {
58- config. with_client_cert_verifier ( Arc :: new ( AllowAnyAuthenticatedClient :: new ( root_certs) ) )
52+ config. with_client_cert_verifier ( WebPkiClientVerifier :: builder ( root_certs. into ( ) ) . build ( ) ? )
5953 } else {
6054 config. with_no_client_auth ( )
6155 } ;
6256
63- let server_cert = certificate_chain. into_iter ( ) . map ( Certificate ) . collect ( ) ;
64- let server_key = PrivateKey ( key_der) ;
65-
6657 config
67- . with_single_cert ( server_cert , server_key)
58+ . with_single_cert ( server_cert_chain , server_key)
6859 . context ( "invalid key or certificate" )
6960}
7061
7162/// Load the server certificate
72- pub fn load_cert ( path : & ( impl PemReader + ?Sized ) ) -> anyhow:: Result < Vec < Vec < u8 > > > {
63+ pub fn load_cert ( path : & ( impl PemReader + ?Sized ) ) -> anyhow:: Result < Vec < CertificateDer < ' static > > > {
7364 let file = path
7465 . open ( )
7566 . with_context ( || format ! ( "cannot open certificate file: {path:?}" ) ) ?;
7667 let mut reader = std:: io:: BufReader :: new ( file) ;
7768 rustls_pemfile:: certs ( & mut reader)
69+ . collect :: < Result < Vec < _ > , _ > > ( )
7870 . with_context ( || format ! ( "parsing PEM-encoded certificate from {path:?}" ) )
7971}
8072
8173/// Load the server private key
82- pub fn load_pkey ( path : & ( impl PemReader + ?Sized ) ) -> anyhow:: Result < Vec < u8 > > {
74+ pub fn load_pkey ( path : & ( impl PemReader + ?Sized ) ) -> anyhow:: Result < PrivateKeyDer < ' static > > {
8375 let key_file = path
8476 . open ( )
8577 . with_context ( || format ! ( "cannot open certificate file: {path:?}" ) ) ?;
@@ -90,14 +82,16 @@ pub fn load_pkey(path: &(impl PemReader + ?Sized)) -> anyhow::Result<Vec<u8>> {
9082pub fn pkey_from_pem (
9183 reader : & mut dyn io:: BufRead ,
9284 filename : & ( impl PemReader + ?Sized ) ,
93- ) -> anyhow:: Result < Vec < u8 > > {
85+ ) -> anyhow:: Result < PrivateKeyDer < ' static > > {
9486 rustls_pemfile:: read_one ( reader)
9587 . with_context ( || format ! ( "reading PEM-encoded private key from {filename:?}" ) ) ?
9688 . ok_or ( anyhow ! (
9789 "expected private key in {filename:?}, but found no PEM-encoded data"
9890 ) )
9991 . and_then ( |item| match item {
100- Item :: ECKey ( key) | Item :: PKCS8Key ( key) | Item :: RSAKey ( key) => Ok ( key) ,
92+ Item :: Sec1Key ( key) => Ok ( PrivateKeyDer :: Sec1 ( key) ) ,
93+ Item :: Pkcs8Key ( key) => Ok ( PrivateKeyDer :: Pkcs8 ( key) ) ,
94+ Item :: Pkcs1Key ( key) => Ok ( PrivateKeyDer :: Pkcs1 ( key) ) ,
10195 Item :: Crl ( _) => Err ( anyhow ! ( "expected private key in {filename:?}, found a CRL" ) ) ,
10296 Item :: X509Certificate ( _) => Err ( anyhow ! (
10397 "expected private key in {filename:?}, found an X509 certificate"
@@ -226,60 +220,71 @@ mod tests {
226220 }
227221
228222 mod server_accepts {
223+ use rustls:: crypto:: CryptoProvider ;
224+
229225 use super :: * ;
230226
227+ fn init_crypto ( ) {
228+ let _ = CryptoProvider :: install_default ( rustls:: crypto:: ring:: default_provider ( ) ) ;
229+ }
230+
231231 #[ tokio:: test]
232232 async fn alg_ed25519_pkcs8 ( ) {
233+ init_crypto ( ) ;
233234 let key = test_data ( "ed25519.key" ) ;
234235 let cert = test_data ( "ed25519.crt" ) ;
235236
236237 let ( config, cert) = config_from_pem ( & key, & cert) . unwrap ( ) ;
237238
238- assert_matches ! ( parse_key_to_item( & key) , Item :: PKCS8Key ( _) ) ;
239+ assert_matches ! ( parse_key_to_item( & key) , Item :: Pkcs8Key ( _) ) ;
239240 assert_server_works_with ( config, cert) . await ;
240241 }
241242
242243 #[ tokio:: test]
243244 async fn alg_ec ( ) {
245+ init_crypto ( ) ;
244246 let key = test_data ( "ec.key" ) ;
245247 let cert = test_data ( "ec.crt" ) ;
246248
247249 let ( config, cert) = config_from_pem ( & key, & cert) . unwrap ( ) ;
248250
249- assert_matches ! ( parse_key_to_item( & key) , Item :: ECKey ( _) ) ;
251+ assert_matches ! ( parse_key_to_item( & key) , Item :: Sec1Key ( _) ) ;
250252 assert_server_works_with ( config, cert) . await ;
251253 }
252254
253255 #[ tokio:: test]
254256 async fn alg_ec_pkcs8 ( ) {
257+ init_crypto ( ) ;
255258 let key = test_data ( "ec.pkcs8.key" ) ;
256259 let cert = test_data ( "ec.crt" ) ;
257260
258261 let ( config, cert) = config_from_pem ( & key, & cert) . unwrap ( ) ;
259262
260- assert_matches ! ( parse_key_to_item( & key) , Item :: PKCS8Key ( _) ) ;
263+ assert_matches ! ( parse_key_to_item( & key) , Item :: Pkcs8Key ( _) ) ;
261264 assert_server_works_with ( config, cert) . await ;
262265 }
263266
264267 #[ tokio:: test]
265268 async fn alg_rsa_pkcs8 ( ) {
269+ init_crypto ( ) ;
266270 let key = test_data ( "rsa.pkcs8.key" ) ;
267271 let cert = test_data ( "rsa.crt" ) ;
268272
269273 let ( config, cert) = config_from_pem ( & key, & cert) . unwrap ( ) ;
270274
271- assert_matches ! ( parse_key_to_item( & key) , Item :: PKCS8Key ( _) ) ;
275+ assert_matches ! ( parse_key_to_item( & key) , Item :: Pkcs8Key ( _) ) ;
272276 assert_server_works_with ( config, cert) . await ;
273277 }
274278
275279 #[ tokio:: test]
276280 async fn alg_rsa_pkcs1 ( ) {
281+ init_crypto ( ) ;
277282 let key = test_data ( "rsa.pkcs1.key" ) ;
278283 let cert = test_data ( "rsa.crt" ) ;
279284
280285 let ( config, cert) = config_from_pem ( & key, & cert) . unwrap ( ) ;
281286
282- assert_matches ! ( parse_key_to_item( & key) , Item :: RSAKey ( _) ) ;
287+ assert_matches ! ( parse_key_to_item( & key) , Item :: Pkcs1Key ( _) ) ;
283288 assert_server_works_with ( config, cert) . await ;
284289 }
285290
@@ -300,18 +305,20 @@ mod tests {
300305 key : & str ,
301306 cert : & str ,
302307 ) -> anyhow:: Result < ( ServerConfig , reqwest:: tls:: Certificate ) > {
303- let chain = rustls_pemfile:: certs ( & mut Cursor :: new ( cert) ) . context ( "reading certs" ) ?;
308+ let chain = rustls_pemfile:: certs ( & mut Cursor :: new ( cert) )
309+ . collect :: < Result < Vec < _ > , _ > > ( )
310+ . context ( "reading certs" ) ?;
304311 let key_der = parse_key_to_der ( key) ?;
305312 let cert = reqwest:: tls:: Certificate :: from_der (
306- chain. first ( ) . expect ( "chain should contain certificate" ) ,
313+ & * chain. first ( ) . expect ( "chain should contain certificate" ) ,
307314 )
308315 . context ( "converting certificate to reqwest::tls::Certificate" ) ?;
309316 let config = ssl_config ( chain, key_der, None ) ?;
310317
311318 Ok ( ( config, cert) )
312319 }
313320
314- fn parse_key_to_der ( pem : & str ) -> anyhow:: Result < Vec < u8 > > {
321+ fn parse_key_to_der ( pem : & str ) -> anyhow:: Result < PrivateKeyDer < ' static > > {
315322 pkey_from_pem (
316323 & mut Cursor :: new ( pem) ,
317324 Utf8Path :: new ( "just-in-memory-not-a-file.pem" ) ,
0 commit comments