1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
use crate::{CertificateFingerprint, Error, SignatureAlgorithm}; use openssl::{hash::MessageDigest, x509::X509}; /// A wrapper type for an `X509` certificate. #[derive(Clone)] pub struct Certificate(pub X509); impl Certificate { /// Deserializes a DER-encoded X509 structure. /// /// # Underlying SSL /// This corresponds to [`d2i_X509`]. /// /// [`d2i_X509`]: https://www.openssl.org/docs/manmaster/man3/d2i_X509.html pub fn from_der(buf: &[u8]) -> Result<Certificate, Error> { let cert = X509::from_der(buf)?; Ok(Certificate(cert)) } /// Deserializes a PEM-encoded X509 structure. /// /// The input should have a header of `-----BEGIN CERTIFICATE-----`. /// /// # Underlying SSL /// This corresponds to [`PEM_read_bio_X509`]. /// /// [`PEM_read_bio_X509`]: https://www.openssl.org/docs/man1.0.2/crypto/PEM_read_bio_X509.html pub fn from_pem(buf: &[u8]) -> Result<Certificate, Error> { let cert = X509::from_pem(buf)?; Ok(Certificate(cert)) } /// Serializes the certificate into a DER-encoded X509 structure. /// /// # Underlying SSL /// This corresponds to [`i2d_X509`]. /// /// [`i2d_X509`]: https://www.openssl.org/docs/man1.1.0/crypto/i2d_X509.html pub fn to_der(&self) -> Result<Vec<u8>, Error> { let der = self.0.to_der()?; Ok(der) } /// Returns the digest of the DER representation of the certificate and the cryptographic hash function used to calculate those bytes. /// /// # Underlying SSL /// The `bytes` are a digest of the DER representation of the certificate. /// /// The bytes are calculated by the [`X509_digest`] function. /// /// [`X509_digest`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_digest.html pub fn fingerprint( &self, signature_algorithm: SignatureAlgorithm, ) -> Result<CertificateFingerprint, Error> { let md = match signature_algorithm { SignatureAlgorithm::Sha1 => MessageDigest::sha1(), SignatureAlgorithm::Sha256 => MessageDigest::sha256(), // there is a whole bunch more }; let digest = self.0.digest(md)?; Ok(CertificateFingerprint { bytes: digest.to_vec(), signature_algorithm, }) } }