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