Skip to main content
This is unreleased documentation for the main (development) branch of crypto-glue.

crypto_glue/x509/
mod.rs

1pub use self::chain::{X509Store, X509VerificationError};
2pub use self::display::X509Display;
3use crate::{
4    ecdsa_p256::{EcdsaP256PublicKey, EcdsaP256Signature, EcdsaP256VerifyingKey},
5    ecdsa_p384::{EcdsaP384PublicKey, EcdsaP384Signature, EcdsaP384VerifyingKey},
6    rsa::{RS256PublicKey, RS256Signature, RS256VerifyingKey},
7    s256::{Sha256, Sha256Output},
8    traits::{Digest, EncodeDer, OwnedToRef, Verifier},
9};
10pub use const_oid::db as oiddb;
11pub use const_oid::{AssociatedOid, ObjectIdentifier};
12pub use der::asn1::{BitString, Ia5String};
13use tracing::error;
14pub use x509_cert::builder::RequestBuilder as CertificateRequestBuilder;
15pub use x509_cert::builder::{Builder, CertificateBuilder, Profile};
16pub use x509_cert::certificate::{Certificate, Version};
17pub use x509_cert::ext::pkix::name::{DistributionPointName, GeneralName, OtherName};
18pub use x509_cert::ext::pkix::{
19    crl::dp::DistributionPoint, crl::CrlDistributionPoints, AccessDescription,
20    AuthorityInfoAccessSyntax, AuthorityKeyIdentifier, BasicConstraints, ExtendedKeyUsage,
21    KeyUsage, KeyUsages, SubjectAltName, SubjectKeyIdentifier,
22};
23pub use x509_cert::name::Name;
24pub use x509_cert::request::CertReq as CertificateRequest;
25pub use x509_cert::serial_number::SerialNumber;
26pub use x509_cert::spki::{
27    AlgorithmIdentifier, SignatureBitStringEncoding, SubjectPublicKeyInfoOwned,
28};
29pub use x509_cert::time::{Time, Validity};
30
31mod chain;
32mod display;
33
34pub fn uuid_to_serial(serial_uuid: uuid::Uuid) -> SerialNumber {
35    let mut serial_bytes: [u8; 17] = [0; 17];
36    // The first byte must be a value else if the leading byte is a null then
37    // der is unhappy.
38    serial_bytes[0] = 0x01;
39    let update_bytes = &mut serial_bytes[1..];
40    update_bytes.copy_from_slice(serial_uuid.as_bytes());
41
42    #[allow(clippy::expect_used)]
43    SerialNumber::new(&serial_bytes).expect("Failed to create serial number from uuid")
44}
45
46pub fn x509_digest_sha256(certificate: &Certificate) -> Result<Sha256Output, der::Error> {
47    let mut hasher = Sha256::new();
48    hasher.update(certificate.to_der()?);
49    Ok(hasher.finalize())
50}
51
52pub fn x509_verify_signature(
53    data: &[u8],
54    signature: &[u8],
55    certificate: &Certificate,
56) -> Result<(), X509VerificationError> {
57    let subject_public_key_info = certificate
58        .tbs_certificate
59        .subject_public_key_info
60        .owned_to_ref();
61
62    match subject_public_key_info.algorithm.oids() {
63        Ok((oiddb::rfc5912::ID_EC_PUBLIC_KEY, Some(oiddb::rfc5912::SECP_256_R_1))) => {
64            let signature = EcdsaP256Signature::from_der(signature)
65                .map_err(|_err| X509VerificationError::DerSignatureInvalid)?;
66
67            let verifier = EcdsaP256PublicKey::try_from(subject_public_key_info)
68                .map(EcdsaP256VerifyingKey::from)
69                .map_err(|_err| X509VerificationError::VerifyingKeyFromSpki)?;
70
71            verifier
72                .verify(data, &signature)
73                .map_err(|_err| X509VerificationError::SignatureVerificationFailed)?;
74        }
75        Ok((oiddb::rfc5912::ID_EC_PUBLIC_KEY, Some(oiddb::rfc5912::SECP_384_R_1))) => {
76            let signature = EcdsaP384Signature::from_der(signature)
77                .map_err(|_err| X509VerificationError::DerSignatureInvalid)?;
78
79            let verifier = EcdsaP384PublicKey::try_from(subject_public_key_info)
80                .map(EcdsaP384VerifyingKey::from)
81                .map_err(|_err| X509VerificationError::VerifyingKeyFromSpki)?;
82
83            verifier
84                .verify(data, &signature)
85                .map_err(|_err| X509VerificationError::SignatureVerificationFailed)?;
86        }
87        Ok((oiddb::rfc5912::SHA_256_WITH_RSA_ENCRYPTION, None)) => {
88            let signature = RS256Signature::try_from(signature)
89                .map_err(|_err| X509VerificationError::DerSignatureInvalid)?;
90
91            let verifier = RS256PublicKey::try_from(subject_public_key_info)
92                .map(RS256VerifyingKey::new)
93                .map_err(|_err| X509VerificationError::VerifyingKeyFromSpki)?;
94
95            verifier
96                .verify(data, &signature)
97                .map_err(|_err| X509VerificationError::SignatureVerificationFailed)?;
98        }
99        algo_oids => {
100            error!(?algo_oids);
101            return Err(X509VerificationError::SignatureAlgorithmNotImplemented);
102        }
103    }
104
105    Ok(())
106}