@@ -49,7 +49,10 @@ use rustls::{
4949 client:: HandshakeSignatureValid , client:: ServerCertVerified , client:: ServerCertVerifier ,
5050 DigitallySignedStruct , Error as TLSError , ServerName ,
5151} ;
52- use std:: fmt;
52+ use std:: {
53+ fmt,
54+ io:: { BufRead , BufReader } ,
55+ } ;
5356
5457/// Represents a server X509 certificate.
5558#[ derive( Clone ) ]
@@ -138,6 +141,32 @@ impl Certificate {
138141 } )
139142 }
140143
144+ /// Create a collection of `Certificate`s from a PEM encoded certificate bundle.
145+ /// Example byte sources may be `.crt`, `.cer` or `.pem` files.
146+ ///
147+ /// # Examples
148+ ///
149+ /// ```
150+ /// # use std::fs::File;
151+ /// # use std::io::Read;
152+ /// # fn cert() -> Result<(), Box<std::error::Error>> {
153+ /// let mut buf = Vec::new();
154+ /// File::open("ca-bundle.crt")?
155+ /// .read_to_end(&mut buf)?;
156+ /// let certs = reqwest::Certificate::from_pem_bundle(&buf)?;
157+ /// # drop(certs);
158+ /// # Ok(())
159+ /// # }
160+ /// ```
161+ pub fn from_pem_bundle ( pem_bundle : & [ u8 ] ) -> crate :: Result < Vec < Certificate > > {
162+ let mut reader = BufReader :: new ( pem_bundle) ;
163+
164+ Self :: read_pem_certs ( & mut reader) ?
165+ . iter ( )
166+ . map ( |cert_vec| Certificate :: from_pem ( & cert_vec) )
167+ . collect :: < crate :: Result < Vec < Certificate > > > ( )
168+ }
169+
141170 #[ cfg( feature = "native-tls-crate" ) ]
142171 pub ( crate ) fn add_to_native_tls ( self , tls : & mut native_tls_crate:: TlsConnectorBuilder ) {
143172 tls. add_root_certificate ( self . native ) ;
@@ -155,12 +184,8 @@ impl Certificate {
155184 . add ( & rustls:: Certificate ( buf) )
156185 . map_err ( crate :: error:: builder) ?,
157186 Cert :: Pem ( buf) => {
158- let mut pem = Cursor :: new ( buf) ;
159- let certs = rustls_pemfile:: certs ( & mut pem) . map_err ( |_| {
160- crate :: error:: builder ( TLSError :: General ( String :: from (
161- "No valid certificate was found" ,
162- ) ) )
163- } ) ?;
187+ let mut reader = Cursor :: new ( buf) ;
188+ let certs = Self :: read_pem_certs ( & mut reader) ?;
164189 for c in certs {
165190 root_cert_store
166191 . add ( & rustls:: Certificate ( c) )
@@ -170,6 +195,11 @@ impl Certificate {
170195 }
171196 Ok ( ( ) )
172197 }
198+
199+ fn read_pem_certs ( reader : & mut impl BufRead ) -> crate :: Result < Vec < Vec < u8 > > > {
200+ rustls_pemfile:: certs ( reader)
201+ . map_err ( |_| crate :: error:: builder ( "invalid certificate encoding" ) )
202+ }
173203}
174204
175205impl Identity {
0 commit comments