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}