@@ -58,6 +58,13 @@ use std::{
5858 io:: { BufRead , BufReader } ,
5959} ;
6060
61+ /// Represents a X509 certificate revocation list.
62+ #[ cfg( feature = "__rustls" ) ]
63+ pub struct CertificateRevocationList {
64+ #[ cfg( feature = "__rustls" ) ]
65+ inner : rustls_pki_types:: CertificateRevocationListDer < ' static > ,
66+ }
67+
6168/// Represents a server X509 certificate.
6269#[ derive( Clone ) ]
6370pub struct Certificate {
@@ -409,6 +416,75 @@ impl Identity {
409416 }
410417}
411418
419+ #[ cfg( feature = "__rustls" ) ]
420+ impl CertificateRevocationList {
421+ /// Parses a PEM encoded CRL.
422+ ///
423+ /// # Examples
424+ ///
425+ /// ```
426+ /// # use std::fs::File;
427+ /// # use std::io::Read;
428+ /// # fn crl() -> Result<(), Box<dyn std::error::Error>> {
429+ /// let mut buf = Vec::new();
430+ /// File::open("my_crl.pem")?
431+ /// .read_to_end(&mut buf)?;
432+ /// let crl = reqwest::tls::CertificateRevocationList::from_pem(&buf)?;
433+ /// # drop(crl);
434+ /// # Ok(())
435+ /// # }
436+ /// ```
437+ ///
438+ /// # Optional
439+ ///
440+ /// This requires the `rustls-tls(-...)` Cargo feature enabled.
441+ #[ cfg( feature = "__rustls" ) ]
442+ pub fn from_pem ( pem : & [ u8 ] ) -> crate :: Result < CertificateRevocationList > {
443+ Ok ( CertificateRevocationList {
444+ #[ cfg( feature = "__rustls" ) ]
445+ inner : rustls_pki_types:: CertificateRevocationListDer :: from ( pem. to_vec ( ) ) ,
446+ } )
447+ }
448+
449+ /// Creates a collection of `CertificateRevocationList`s from a PEM encoded CRL bundle.
450+ /// Example byte sources may be `.crl` or `.pem` files.
451+ ///
452+ /// # Examples
453+ ///
454+ /// ```
455+ /// # use std::fs::File;
456+ /// # use std::io::Read;
457+ /// # fn crls() -> Result<(), Box<dyn std::error::Error>> {
458+ /// let mut buf = Vec::new();
459+ /// File::open("crl-bundle.crl")?
460+ /// .read_to_end(&mut buf)?;
461+ /// let crls = reqwest::tls::CertificateRevocationList::from_pem_bundle(&buf)?;
462+ /// # drop(crls);
463+ /// # Ok(())
464+ /// # }
465+ /// ```
466+ ///
467+ /// # Optional
468+ ///
469+ /// This requires the `rustls-tls(-...)` Cargo feature enabled.
470+ #[ cfg( feature = "__rustls" ) ]
471+ pub fn from_pem_bundle ( pem_bundle : & [ u8 ] ) -> crate :: Result < Vec < CertificateRevocationList > > {
472+ let mut reader = BufReader :: new ( pem_bundle) ;
473+
474+ rustls_pemfile:: crls ( & mut reader)
475+ . map ( |result| match result {
476+ Ok ( crl) => Ok ( CertificateRevocationList { inner : crl } ) ,
477+ Err ( _) => Err ( crate :: error:: builder ( "invalid crl encoding" ) ) ,
478+ } )
479+ . collect :: < crate :: Result < Vec < CertificateRevocationList > > > ( )
480+ }
481+
482+ #[ cfg( feature = "__rustls" ) ]
483+ pub ( crate ) fn as_rustls_crl < ' a > ( & self ) -> rustls_pki_types:: CertificateRevocationListDer < ' a > {
484+ self . inner . clone ( )
485+ }
486+ }
487+
412488impl fmt:: Debug for Certificate {
413489 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
414490 f. debug_struct ( "Certificate" ) . finish ( )
@@ -421,6 +497,13 @@ impl fmt::Debug for Identity {
421497 }
422498}
423499
500+ #[ cfg( feature = "__rustls" ) ]
501+ impl fmt:: Debug for CertificateRevocationList {
502+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
503+ f. debug_struct ( "CertificateRevocationList" ) . finish ( )
504+ }
505+ }
506+
424507/// A TLS protocol version.
425508#[ derive( Debug , Clone , Copy , PartialEq , Eq , PartialOrd , Ord ) ]
426509pub struct Version ( InnerVersion ) ;
@@ -736,4 +819,24 @@ mod tests {
736819
737820 assert ! ( Certificate :: from_pem_bundle( PEM_BUNDLE ) . is_ok( ) )
738821 }
822+
823+ #[ cfg( feature = "__rustls" ) ]
824+ #[ test]
825+ fn crl_from_pem ( ) {
826+ let pem = b"-----BEGIN X509 CRL-----\n -----END X509 CRL-----\n " ;
827+
828+ CertificateRevocationList :: from_pem ( pem) . unwrap ( ) ;
829+ }
830+
831+ #[ cfg( feature = "__rustls" ) ]
832+ #[ test]
833+ fn crl_from_pem_bundle ( ) {
834+ let pem_bundle = std:: fs:: read ( "tests/support/crl.pem" ) . unwrap ( ) ;
835+
836+ let result = CertificateRevocationList :: from_pem_bundle ( & pem_bundle) ;
837+
838+ assert ! ( result. is_ok( ) ) ;
839+ let result = result. unwrap ( ) ;
840+ assert_eq ! ( result. len( ) , 1 ) ;
841+ }
739842}
0 commit comments