udp_dtls/
certificate.rs

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