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