Add 'mtls::Certificate::as_bytes()' method.

This commit is contained in:
Sergio Benitez 2023-06-07 17:59:59 -07:00
parent b89a0039a7
commit 40410e4365
1 changed files with 33 additions and 7 deletions

View File

@ -142,9 +142,11 @@ pub type Result<T, E = Error> = std::result::Result<T, E>;
/// // _does_ run if a valid (Ok) or invalid (Err) one was presented. /// // _does_ run if a valid (Ok) or invalid (Err) one was presented.
/// } /// }
/// ``` /// ```
#[repr(transparent)]
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub struct Certificate<'a>(X509Certificate<'a>); pub struct Certificate<'a> {
x509: X509Certificate<'a>,
data: &'a CertificateData,
}
/// An X.509 Distinguished Name (DN) found in a [`Certificate`]. /// An X.509 Distinguished Name (DN) found in a [`Certificate`].
/// ///
@ -218,16 +220,15 @@ impl<'a> Certificate<'a> {
#[inline(always)] #[inline(always)]
fn inner(&self) -> &TbsCertificate<'a> { fn inner(&self) -> &TbsCertificate<'a> {
&self.0.tbs_certificate &self.x509.tbs_certificate
} }
/// PRIVATE: For internal Rocket use only! /// PRIVATE: For internal Rocket use only!
#[doc(hidden)] #[doc(hidden)]
pub fn parse(chain: &[CertificateData]) -> Result<Certificate<'_>> { pub fn parse(chain: &[CertificateData]) -> Result<Certificate<'_>> {
match chain.first() { let data = chain.first().ok_or_else(|| Error::Empty)?;
Some(cert) => Certificate::parse_one(&cert.0).map(Certificate), let x509 = Certificate::parse_one(&data.0)?;
None => Err(Error::Empty) Ok(Certificate { x509, data })
}
} }
/// Returns the serial number of the X.509 certificate. /// Returns the serial number of the X.509 certificate.
@ -364,6 +365,31 @@ impl<'a> Certificate<'a> {
let uint: bigint::BigUint = number.parse().ok()?; let uint: bigint::BigUint = number.parse().ok()?;
Some(&uint == self.serial()) Some(&uint == self.serial())
} }
/// Returns the raw, unmodified, DER-encoded X.509 certificate data bytes.
///
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// # use rocket::get;
/// use rocket::mtls::Certificate;
///
/// const SHA256_FINGERPRINT: &str =
/// "CE C2 4E 01 00 FF F7 78 CB A4 AA CB D2 49 DD 09 \
/// 02 EF 0E 9B DA 89 2A E4 0D F4 09 83 97 C1 97 0D";
///
/// #[get("/auth")]
/// fn auth(cert: Certificate<'_>) {
/// # fn sha256_fingerprint(bytes: &[u8]) -> String { todo!() }
/// if sha256_fingerprint(cert.as_bytes()) == SHA256_FINGERPRINT {
/// println!("certificate fingerprint matched");
/// }
/// }
/// ```
pub fn as_bytes(&self) -> &'a [u8] {
&self.data.0
}
} }
impl<'a> Deref for Certificate<'a> { impl<'a> Deref for Certificate<'a> {