Skip to main content

isideload_x509_certificate/
certificate.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5//! Defines high-level interface to X.509 certificates.
6
7use {
8    crate::{
9        InMemorySigningKeyPair, KeyAlgorithm, KeyInfoSigner, SignatureAlgorithm,
10        X509CertificateError as Error, algorithm::DigestAlgorithm, asn1time::Time, rfc2986,
11        rfc3280::Name, rfc5280, rfc5652, rfc5958::Attributes, rfc8017::RsaPublicKey, signing::Sign,
12    },
13    aws_lc_rs::signature as ringsig,
14    bcder::{
15        ConstOid, Mode, Oid,
16        decode::Constructed,
17        encode::Values,
18        int::Integer,
19        string::{BitString, OctetString},
20    },
21    bytes::Bytes,
22    chrono::{DateTime, Duration, Utc},
23    der::{Decode, Document},
24    signature::Signer,
25    spki::EncodePublicKey,
26    std::{
27        cmp::Ordering,
28        collections::HashSet,
29        fmt::{Debug, Formatter},
30        hash::{Hash, Hasher},
31        io::Write,
32        ops::{Deref, DerefMut},
33    },
34};
35
36/// Key Usage extension.
37///
38/// 2.5.29.15
39const OID_EXTENSION_KEY_USAGE: ConstOid = Oid(&[85, 29, 15]);
40
41/// Basic Constraints X.509 extension.
42///
43/// 2.5.29.19
44const OID_EXTENSION_BASIC_CONSTRAINTS: ConstOid = Oid(&[85, 29, 19]);
45
46/// Provides an interface to the RFC 5280 [rfc5280::Certificate] ASN.1 type.
47///
48/// This type provides the main high-level API that this crate exposes
49/// for reading and writing X.509 certificates.
50///
51/// Instances are backed by an actual ASN.1 [rfc5280::Certificate] instance.
52/// Read operations are performed against the raw ASN.1 values. Mutations
53/// result in mutations of the ASN.1 data structures.
54///
55/// Instances can be converted to/from [rfc5280::Certificate] using traits.
56/// [AsRef]/[AsMut] are implemented to obtain a reference to the backing
57/// [rfc5280::Certificate].
58///
59/// We have chosen not to implement [Deref]/[DerefMut] because we don't
60/// want to pollute the type's API with lower-level ASN.1 primitives.
61///
62/// This type does not track the original data from which it came.
63/// If you want a type that does that, consider [CapturedX509Certificate],
64/// which implements [Deref] and therefore behaves like this type.
65#[derive(Clone, Debug, Eq, PartialEq)]
66pub struct X509Certificate(rfc5280::Certificate);
67
68impl X509Certificate {
69    /// Construct an instance by parsing DER encoded ASN.1 data.
70    pub fn from_der(data: impl AsRef<[u8]>) -> Result<Self, Error> {
71        let cert = Constructed::decode(data.as_ref(), Mode::Der, |cons| {
72            rfc5280::Certificate::take_from(cons)
73        })?;
74
75        Ok(Self(cert))
76    }
77
78    /// Construct an instance by parsing BER encoded ASN.1 data.
79    ///
80    /// X.509 certificates are likely (and should be) using DER encoding.
81    /// However, some specifications do mandate the use of BER, so this
82    /// method is provided.
83    pub fn from_ber(data: impl AsRef<[u8]>) -> Result<Self, Error> {
84        let cert = Constructed::decode(data.as_ref(), Mode::Ber, |cons| {
85            rfc5280::Certificate::take_from(cons)
86        })?;
87
88        Ok(Self(cert))
89    }
90
91    /// Construct an instance by parsing PEM encoded ASN.1 data.
92    ///
93    /// The data is a human readable string likely containing
94    /// `--------- BEGIN CERTIFICATE ----------`.
95    pub fn from_pem(data: impl AsRef<[u8]>) -> Result<Self, Error> {
96        let data = pem::parse(data.as_ref()).map_err(Error::PemDecode)?;
97
98        Self::from_der(data.contents())
99    }
100
101    /// Construct instances by parsing PEM with potentially multiple records.
102    ///
103    /// By default, we only look for `--------- BEGIN CERTIFICATE --------`
104    /// entries and silently ignore unknown ones. If you would like to specify
105    /// an alternate set of tags (this is the value after the `BEGIN`) to search,
106    /// call [Self::from_pem_multiple_tags].
107    pub fn from_pem_multiple(data: impl AsRef<[u8]>) -> Result<Vec<Self>, Error> {
108        Self::from_pem_multiple_tags(data, &["CERTIFICATE"])
109    }
110
111    /// Construct instances by parsing PEM armored DER encoded certificates with specific PEM tags.
112    ///
113    /// This is like [Self::from_pem_multiple] except you control the filter for
114    /// which `BEGIN <tag>` values are filtered through to the DER parser.
115    pub fn from_pem_multiple_tags(
116        data: impl AsRef<[u8]>,
117        tags: &[&str],
118    ) -> Result<Vec<Self>, Error> {
119        let pem = pem::parse_many(data.as_ref()).map_err(Error::PemDecode)?;
120
121        pem.into_iter()
122            .filter(|pem| tags.contains(&pem.tag()))
123            .map(|pem| Self::from_der(pem.contents()))
124            .collect::<Result<_, _>>()
125    }
126
127    /// Obtain the serial number as the ASN.1 [Integer] type.
128    pub fn serial_number_asn1(&self) -> &Integer {
129        &self.0.tbs_certificate.serial_number
130    }
131
132    /// Obtain the certificate's subject, as its ASN.1 [Name] type.
133    pub fn subject_name(&self) -> &Name {
134        &self.0.tbs_certificate.subject
135    }
136
137    /// Obtain the Common Name (CN) attribute from the certificate's subject, if set and decodable.
138    pub fn subject_common_name(&self) -> Option<String> {
139        self.0
140            .tbs_certificate
141            .subject
142            .iter_common_name()
143            .next()
144            .and_then(|cn| cn.to_string().ok())
145    }
146
147    /// Obtain the certificate's issuer, as its ASN.1 [Name] type.
148    pub fn issuer_name(&self) -> &Name {
149        &self.0.tbs_certificate.issuer
150    }
151
152    /// Obtain the Common Name (CN) attribute from the certificate's issuer, if set and decodable.
153    pub fn issuer_common_name(&self) -> Option<String> {
154        self.0
155            .tbs_certificate
156            .issuer
157            .iter_common_name()
158            .next()
159            .and_then(|cn| cn.to_string().ok())
160    }
161
162    /// Iterate over extensions defined in this certificate.
163    pub fn iter_extensions(&self) -> impl Iterator<Item = &crate::rfc5280::Extension> {
164        self.0.iter_extensions()
165    }
166
167    /// Encode the certificate data structure using DER encoding.
168    ///
169    /// (This is the common ASN.1 encoding format for X.509 certificates.)
170    ///
171    /// This always serializes the internal ASN.1 data structure. If you
172    /// call this on a wrapper type that has retained a copy of the original
173    /// data, this may emit different data than that copy.
174    pub fn encode_der_to(&self, fh: &mut impl Write) -> Result<(), std::io::Error> {
175        self.0.encode_ref().write_encoded(Mode::Der, fh)
176    }
177
178    /// Encode the certificate data structure use BER encoding.
179    pub fn encode_ber_to(&self, fh: &mut impl Write) -> Result<(), std::io::Error> {
180        self.0.encode_ref().write_encoded(Mode::Ber, fh)
181    }
182
183    /// Encode the internal ASN.1 data structures to DER.
184    pub fn encode_der(&self) -> Result<Vec<u8>, std::io::Error> {
185        let mut buffer = Vec::<u8>::new();
186        self.encode_der_to(&mut buffer)?;
187
188        Ok(buffer)
189    }
190
191    /// Obtain the BER encoded representation of this certificate.
192    pub fn encode_ber(&self) -> Result<Vec<u8>, std::io::Error> {
193        let mut buffer = Vec::<u8>::new();
194        self.encode_ber_to(&mut buffer)?;
195
196        Ok(buffer)
197    }
198
199    /// Encode the certificate to PEM.
200    ///
201    /// This will write a human-readable string with `------ BEGIN CERTIFICATE -------`
202    /// armoring. This is a very common method for encoding certificates.
203    ///
204    /// The underlying binary data is DER encoded.
205    pub fn write_pem(&self, fh: &mut impl Write) -> Result<(), std::io::Error> {
206        let encoded = pem::Pem::new("CERTIFICATE", self.encode_der()?).to_string();
207
208        fh.write_all(encoded.as_bytes())
209    }
210
211    /// Encode the certificate to a PEM string.
212    pub fn encode_pem(&self) -> Result<String, std::io::Error> {
213        Ok(pem::Pem::new("CERTIFICATE", self.encode_der()?).to_string())
214    }
215
216    /// Attempt to resolve a known [KeyAlgorithm] used by the private key associated with this certificate.
217    ///
218    /// If this crate isn't aware of the OID associated with the key algorithm,
219    /// `None` is returned.
220    pub fn key_algorithm(&self) -> Option<KeyAlgorithm> {
221        KeyAlgorithm::try_from(&self.0.tbs_certificate.subject_public_key_info.algorithm).ok()
222    }
223
224    /// Obtain the OID of the private key's algorithm.
225    pub fn key_algorithm_oid(&self) -> &Oid {
226        &self
227            .0
228            .tbs_certificate
229            .subject_public_key_info
230            .algorithm
231            .algorithm
232    }
233
234    /// Obtain the [SignatureAlgorithm this certificate will use.
235    ///
236    /// Returns [None] if we failed to resolve an instance (probably because we don't
237    /// recognize the algorithm).
238    pub fn signature_algorithm(&self) -> Option<SignatureAlgorithm> {
239        SignatureAlgorithm::try_from(&self.0.tbs_certificate.signature.algorithm).ok()
240    }
241
242    /// Obtain the OID of the signature algorithm this certificate will use.
243    pub fn signature_algorithm_oid(&self) -> &Oid {
244        &self.0.tbs_certificate.signature.algorithm
245    }
246
247    /// Obtain the [SignatureAlgorithm] used to sign this certificate.
248    ///
249    /// Returns [None] if we failed to resolve an instance (probably because we
250    /// don't recognize that algorithm).
251    pub fn signature_signature_algorithm(&self) -> Option<SignatureAlgorithm> {
252        SignatureAlgorithm::try_from(&self.0.signature_algorithm).ok()
253    }
254
255    /// Obtain the OID of the signature algorithm used to sign this certificate.
256    pub fn signature_signature_algorithm_oid(&self) -> &Oid {
257        &self.0.signature_algorithm.algorithm
258    }
259
260    /// Obtain the raw data constituting this certificate's public key.
261    ///
262    /// A copy of the data is returned.
263    pub fn public_key_data(&self) -> Bytes {
264        self.0
265            .tbs_certificate
266            .subject_public_key_info
267            .subject_public_key
268            .octet_bytes()
269    }
270
271    /// Attempt to parse the public key data as [RsaPublicKey] parameters.
272    ///
273    /// Note that the raw integer value for modulus has a leading 0 byte. So its
274    /// raw length will be 1 greater than key length. e.g. an RSA 2048 key will
275    /// have `value.modulus.as_slice().len() == 257` instead of `256`.
276    pub fn rsa_public_key_data(&self) -> Result<RsaPublicKey, Error> {
277        let der = self.public_key_data();
278
279        Ok(Constructed::decode(
280            der.as_ref(),
281            Mode::Der,
282            RsaPublicKey::take_from,
283        )?)
284    }
285
286    /// Compare 2 instances, sorting them so the issuer comes before the issued.
287    ///
288    /// This function examines the [Self::issuer_name] and [Self::subject_name]
289    /// fields of 2 certificates, attempting to sort them so the issuing
290    /// certificate comes before the issued certificate.
291    ///
292    /// This function performs a strict compare of the ASN.1 [Name] data.
293    /// The assumption here is that the issuing certificate's subject [Name]
294    /// is identical to the issued's issuer [Name]. This assumption is often
295    /// true. But it likely isn't always true, so this function may not produce
296    /// reliable results.
297    pub fn compare_issuer(&self, other: &Self) -> Ordering {
298        // Self signed certificate has no ordering.
299        if self.0.tbs_certificate.subject == self.0.tbs_certificate.issuer {
300            Ordering::Equal
301            // We were issued by the other certificate. The issuer comes first.
302        } else if self.0.tbs_certificate.issuer == other.0.tbs_certificate.subject {
303            Ordering::Greater
304        } else if self.0.tbs_certificate.subject == other.0.tbs_certificate.issuer {
305            // We issued the other certificate. We come first.
306            Ordering::Less
307        } else {
308            Ordering::Equal
309        }
310    }
311
312    /// Whether the subject [Name] is also the issuer's [Name].
313    ///
314    /// This might be a way of determining if a certificate is self-signed.
315    /// But there can likely be false negatives due to differences in ASN.1
316    /// encoding of the underlying data. So we don't claim this is a test for
317    /// being self-signed.
318    pub fn subject_is_issuer(&self) -> bool {
319        self.0.tbs_certificate.subject == self.0.tbs_certificate.issuer
320    }
321
322    /// Obtain the fingerprint for this certificate given a digest algorithm.
323    pub fn fingerprint(
324        &self,
325        algorithm: DigestAlgorithm,
326    ) -> Result<aws_lc_rs::digest::Digest, std::io::Error> {
327        let raw = self.encode_der()?;
328
329        let mut h = algorithm.digester();
330        h.update(&raw);
331
332        Ok(h.finish())
333    }
334
335    /// Obtain the SHA-1 fingerprint of this certificate.
336    pub fn sha1_fingerprint(&self) -> Result<aws_lc_rs::digest::Digest, std::io::Error> {
337        self.fingerprint(DigestAlgorithm::Sha1)
338    }
339
340    /// Obtain the SHA-256 fingerprint of this certificate.
341    pub fn sha256_fingerprint(&self) -> Result<aws_lc_rs::digest::Digest, std::io::Error> {
342        self.fingerprint(DigestAlgorithm::Sha256)
343    }
344
345    /// Obtain the raw [rfc5280::TbsCertificate] for this certificate.
346    pub fn tbs_certificate(&self) -> &rfc5280::TbsCertificate {
347        &self.0.tbs_certificate
348    }
349
350    /// Obtain the certificate validity "not before" time.
351    pub fn validity_not_before(&self) -> DateTime<Utc> {
352        self.0.tbs_certificate.validity.not_before.clone().into()
353    }
354
355    /// Obtain the certificate validity "not after" time.
356    pub fn validity_not_after(&self) -> DateTime<Utc> {
357        self.0.tbs_certificate.validity.not_after.clone().into()
358    }
359
360    /// Determine whether a time is between the validity constraints in the certificate.
361    ///
362    /// i.e. check whether a certificate is "expired."
363    ///
364    /// Receives a date time to check against.
365    ///
366    /// If `None`, the current time is used. This relies on the machine's
367    /// wall clock to be accurate, of course.
368    pub fn time_constraints_valid(&self, compare_time: Option<DateTime<Utc>>) -> bool {
369        let compare_time = compare_time.unwrap_or(Utc::now());
370
371        compare_time >= self.validity_not_before() && compare_time <= self.validity_not_after()
372    }
373}
374
375impl From<rfc5280::Certificate> for X509Certificate {
376    fn from(v: rfc5280::Certificate) -> Self {
377        Self(v)
378    }
379}
380
381impl From<X509Certificate> for rfc5280::Certificate {
382    fn from(v: X509Certificate) -> Self {
383        v.0
384    }
385}
386
387impl AsRef<rfc5280::Certificate> for X509Certificate {
388    fn as_ref(&self) -> &rfc5280::Certificate {
389        &self.0
390    }
391}
392
393impl AsMut<rfc5280::Certificate> for X509Certificate {
394    fn as_mut(&mut self) -> &mut rfc5280::Certificate {
395        &mut self.0
396    }
397}
398
399impl EncodePublicKey for X509Certificate {
400    fn to_public_key_der(&self) -> spki::Result<Document> {
401        let mut data = vec![];
402
403        self.0
404            .tbs_certificate
405            .subject_public_key_info
406            .encode_ref()
407            .write_encoded(Mode::Der, &mut data)
408            .map_err(|_| spki::Error::Asn1(der::Error::new(der::ErrorKind::Failed, 0u8.into())))?;
409
410        Document::from_der(&data).map_err(spki::Error::Asn1)
411    }
412}
413
414#[derive(Clone, Eq, PartialEq)]
415enum OriginalData {
416    Ber(Vec<u8>),
417    Der(Vec<u8>),
418}
419
420impl Debug for OriginalData {
421    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
422        f.write_fmt(format_args!(
423            "{}({})",
424            match self {
425                Self::Ber(_) => "Ber",
426                Self::Der(_) => "Der",
427            },
428            match self {
429                Self::Ber(data) => hex::encode(data),
430                Self::Der(data) => hex::encode(data),
431            }
432        ))
433    }
434}
435
436/// Represents an immutable (read-only) X.509 certificate that was parsed from data.
437///
438/// This type implements [Deref] but not [DerefMut], so only functions
439/// taking a non-mutable instance are usable.
440///
441/// A copy of the certificate's raw backing data is stored, facilitating
442/// subsequent access.
443#[derive(Clone, Debug)]
444pub struct CapturedX509Certificate {
445    original: OriginalData,
446    inner: X509Certificate,
447}
448
449impl CapturedX509Certificate {
450    /// Construct an instance from DER encoded data.
451    ///
452    /// A copy of this data will be stored in the instance and is guaranteed
453    /// to be immutable for the lifetime of the instance. The original constructing
454    /// data can be retrieved later.
455    pub fn from_der(data: impl Into<Vec<u8>>) -> Result<Self, Error> {
456        let der_data = data.into();
457
458        let inner = X509Certificate::from_der(&der_data)?;
459
460        Ok(Self {
461            original: OriginalData::Der(der_data),
462            inner,
463        })
464    }
465
466    /// Construct an instance from BER encoded data.
467    ///
468    /// A copy of this data will be stored in the instance and is guaranteed
469    /// to be immutable for the lifetime of the instance, allowing it to
470    /// be retrieved later.
471    pub fn from_ber(data: impl Into<Vec<u8>>) -> Result<Self, Error> {
472        let data = data.into();
473
474        let inner = X509Certificate::from_ber(&data)?;
475
476        Ok(Self {
477            original: OriginalData::Ber(data),
478            inner,
479        })
480    }
481
482    /// Construct an instance by parsing PEM encoded ASN.1 data.
483    ///
484    /// The data is a human readable string likely containing
485    /// `--------- BEGIN CERTIFICATE ----------`.
486    pub fn from_pem(data: impl AsRef<[u8]>) -> Result<Self, Error> {
487        let data = pem::parse(data.as_ref()).map_err(Error::PemDecode)?;
488
489        Self::from_der(data.contents())
490    }
491
492    /// Construct instances by parsing PEM with potentially multiple records.
493    ///
494    /// By default, we only look for `--------- BEGIN CERTIFICATE --------`
495    /// entries and silently ignore unknown ones. If you would like to specify
496    /// an alternate set of tags (this is the value after the `BEGIN`) to search,
497    /// call [Self::from_pem_multiple_tags].
498    pub fn from_pem_multiple(data: impl AsRef<[u8]>) -> Result<Vec<Self>, Error> {
499        Self::from_pem_multiple_tags(data, &["CERTIFICATE"])
500    }
501
502    /// Construct instances by parsing PEM armored DER encoded certificates with specific PEM tags.
503    ///
504    /// This is like [Self::from_pem_multiple] except you control the filter for
505    /// which `BEGIN <tag>` values are filtered through to the DER parser.
506    pub fn from_pem_multiple_tags(
507        data: impl AsRef<[u8]>,
508        tags: &[&str],
509    ) -> Result<Vec<Self>, Error> {
510        let pem = pem::parse_many(data.as_ref()).map_err(Error::PemDecode)?;
511
512        pem.into_iter()
513            .filter(|pem| tags.contains(&pem.tag()))
514            .map(|pem| Self::from_der(pem.contents()))
515            .collect::<Result<_, _>>()
516    }
517
518    /// Obtain the DER data that was used to construct this instance.
519    ///
520    /// The data is guaranteed to not have been modified since the instance
521    /// was constructed.
522    pub fn constructed_data(&self) -> &[u8] {
523        match &self.original {
524            OriginalData::Ber(data) => data,
525            OriginalData::Der(data) => data,
526        }
527    }
528
529    /// Encode the original contents of this certificate to PEM.
530    pub fn encode_pem(&self) -> String {
531        pem::Pem::new("CERTIFICATE", self.constructed_data()).to_string()
532    }
533
534    /// Verify that another certificate, `other`, signed this certificate.
535    ///
536    /// If this is a self-signed certificate, you can pass `self` as the 2nd
537    /// argument.
538    ///
539    /// This function isn't exposed on [X509Certificate] because the exact
540    /// bytes constituting the certificate's internals need to be consulted
541    /// to verify signatures. And since this type tracks the underlying
542    /// bytes, we are guaranteed to have a pristine copy.
543    pub fn verify_signed_by_certificate(
544        &self,
545        other: impl AsRef<X509Certificate>,
546    ) -> Result<(), Error> {
547        let public_key = other
548            .as_ref()
549            .0
550            .tbs_certificate
551            .subject_public_key_info
552            .subject_public_key
553            .octet_bytes();
554        let key_algorithm = KeyAlgorithm::try_from(
555            &other
556                .as_ref()
557                .0
558                .tbs_certificate
559                .subject_public_key_info
560                .algorithm,
561        )?;
562        self.verify_signed_by_public_key_and_algorithm(public_key, key_algorithm)
563    }
564
565    /// Verify a signature over signed data purportedly signed by this certificate.
566    ///
567    /// This is a wrapper to [Self::verify_signed_data_with_algorithm()] that will derive
568    /// the verification algorithm from the public key type type and the signature algorithm
569    /// indicated in this certificate. Typically these align. However, it is possible for
570    /// a signature to be produced with a different digest algorithm from that indicated
571    /// in this certificate.
572    pub fn verify_signed_data(
573        &self,
574        signed_data: impl AsRef<[u8]>,
575        signature: impl AsRef<[u8]>,
576    ) -> Result<(), Error> {
577        let key_algorithm = KeyAlgorithm::try_from(self.key_algorithm_oid())?;
578        let signature_algorithm = SignatureAlgorithm::try_from(self.signature_algorithm_oid())?;
579        let verify_algorithm = signature_algorithm.resolve_verification_algorithm(key_algorithm)?;
580
581        self.verify_signed_data_with_algorithm(signed_data, signature, verify_algorithm)
582    }
583
584    /// Verify a signature over signed data using an explicit verification algorithm.
585    ///
586    /// This is like [Self::verify_signed_data()] except the verification algorithm to use
587    /// is passed in instead of derived from the default algorithm for the signing key's
588    /// type.
589    pub fn verify_signed_data_with_algorithm(
590        &self,
591        signed_data: impl AsRef<[u8]>,
592        signature: impl AsRef<[u8]>,
593        verify_algorithm: &'static dyn ringsig::VerificationAlgorithm,
594    ) -> Result<(), Error> {
595        let public_key = ringsig::UnparsedPublicKey::new(verify_algorithm, self.public_key_data());
596
597        public_key
598            .verify(signed_data.as_ref(), signature.as_ref())
599            .map_err(|_| Error::CertificateSignatureVerificationFailed)
600    }
601
602    /// Verifies that this certificate was cryptographically signed using raw public key data from a signing key.
603    ///
604    /// This function does the low-level work of extracting the signature and
605    /// verification details from the current certificate and figuring out
606    /// the correct combination of cryptography settings to apply to perform
607    /// signature verification.
608    ///
609    /// In many cases, an X.509 certificate is signed by another certificate. And
610    /// since the public key is embedded in the X.509 certificate, it is easier
611    /// to go through [Self::verify_signed_by_certificate] instead.
612    pub fn verify_signed_by_public_key(
613        &self,
614        public_key_data: impl AsRef<[u8]>,
615    ) -> Result<(), Error> {
616        let key_algorithm =
617            KeyAlgorithm::try_from(&self.0.tbs_certificate.subject_public_key_info.algorithm)?;
618        self.verify_signed_by_public_key_and_algorithm(public_key_data, key_algorithm)
619    }
620
621    /// Like [Self::verify_signed_by_certificate] but accepts the explicit [KeyAlgorithm] to use.
622    ///
623    /// Use this API in cases where the subject public key info algorithm is different from the
624    /// algorithm used by the signing key.
625    pub fn verify_signed_by_public_key_and_algorithm(
626        &self,
627        public_key_data: impl AsRef<[u8]>,
628        public_key_algorithm: KeyAlgorithm,
629    ) -> Result<(), Error> {
630        // Always verify against the original content, as the inner
631        // certificate could be mutated via the mutable wrapper of this
632        // type.
633        let this_cert = match &self.original {
634            OriginalData::Ber(data) => X509Certificate::from_ber(data),
635            OriginalData::Der(data) => X509Certificate::from_der(data),
636        }
637        .expect("certificate re-parse should never fail");
638
639        let signed_data = this_cert
640            .0
641            .tbs_certificate
642            .raw_data
643            .as_ref()
644            .expect("original certificate data should have persisted as part of re-parse");
645        let signature = this_cert.0.signature.octet_bytes();
646
647        let signature_algorithm = SignatureAlgorithm::try_from(&this_cert.0.signature_algorithm)?;
648
649        let verify_algorithm =
650            signature_algorithm.resolve_verification_algorithm(public_key_algorithm)?;
651
652        let public_key = ringsig::UnparsedPublicKey::new(verify_algorithm, public_key_data);
653
654        public_key
655            .verify(signed_data, &signature)
656            .map_err(|_| Error::CertificateSignatureVerificationFailed)
657    }
658
659    /// Attempt to find the issuing certificate of this one.
660    ///
661    /// Given an iterable of certificates, we find the first certificate
662    /// where we are able to verify that our signature was made by their public
663    /// key.
664    ///
665    /// This function can yield false negatives for cases where we don't
666    /// support the signature algorithm on the incoming certificates.
667    pub fn find_signing_certificate<'a>(
668        &self,
669        mut certs: impl Iterator<Item = &'a Self>,
670    ) -> Option<&'a Self> {
671        certs.find(|candidate| self.verify_signed_by_certificate(candidate).is_ok())
672    }
673
674    /// Attempt to resolve the signing chain of this certificate.
675    ///
676    /// Given an iterable of certificates, we recursively resolve the
677    /// chain of certificates that signed this one until we are no longer able
678    /// to find any more certificates in the input set.
679    ///
680    /// Like [Self::find_signing_certificate], this can yield false
681    /// negatives (read: an incomplete chain) due to run-time failures,
682    /// such as lack of support for a certificate's signature algorithm.
683    ///
684    /// As a certificate is encountered, it is removed from the set of
685    /// future candidates.
686    ///
687    /// The traversal ends when we get to an identical certificate (its
688    /// DER data is equivalent) or we couldn't find a certificate in
689    /// the remaining set that signed the last one.
690    ///
691    /// Because we need to recursively verify certificates, the incoming
692    /// iterator is buffered.
693    pub fn resolve_signing_chain<'a>(
694        &self,
695        certs: impl Iterator<Item = &'a Self>,
696    ) -> Vec<&'a Self> {
697        // The logic here is a bit wonky. As we build up the collection of certificates,
698        // we want to filter out ourself and remove duplicates. We remove duplicates by
699        // storing encountered certificates in a HashSet.
700        #[allow(clippy::mutable_key_type)]
701        let mut seen = HashSet::new();
702        let mut remaining = vec![];
703
704        for cert in certs {
705            if cert == self || seen.contains(cert) {
706                continue;
707            } else {
708                remaining.push(cert);
709                seen.insert(cert);
710            }
711        }
712
713        drop(seen);
714
715        let mut chain = vec![];
716
717        let mut last_cert = self;
718        while let Some(issuer) = last_cert.find_signing_certificate(remaining.iter().copied()) {
719            chain.push(issuer);
720            last_cert = issuer;
721
722            remaining = remaining
723                .drain(..)
724                .filter(|cert| *cert != issuer)
725                .collect::<Vec<_>>();
726        }
727
728        chain
729    }
730}
731
732impl PartialEq for CapturedX509Certificate {
733    fn eq(&self, other: &Self) -> bool {
734        self.constructed_data() == other.constructed_data()
735    }
736}
737
738impl Eq for CapturedX509Certificate {}
739
740impl Hash for CapturedX509Certificate {
741    fn hash<H: Hasher>(&self, state: &mut H) {
742        state.write(self.constructed_data());
743    }
744}
745
746impl Deref for CapturedX509Certificate {
747    type Target = X509Certificate;
748
749    fn deref(&self) -> &Self::Target {
750        &self.inner
751    }
752}
753
754impl AsRef<X509Certificate> for CapturedX509Certificate {
755    fn as_ref(&self) -> &X509Certificate {
756        &self.inner
757    }
758}
759
760impl AsRef<rfc5280::Certificate> for CapturedX509Certificate {
761    fn as_ref(&self) -> &rfc5280::Certificate {
762        self.inner.as_ref()
763    }
764}
765
766impl TryFrom<&X509Certificate> for CapturedX509Certificate {
767    type Error = Error;
768
769    fn try_from(cert: &X509Certificate) -> Result<Self, Self::Error> {
770        let mut buffer = Vec::<u8>::new();
771        cert.encode_der_to(&mut buffer)?;
772
773        Self::from_der(buffer)
774    }
775}
776
777impl TryFrom<X509Certificate> for CapturedX509Certificate {
778    type Error = Error;
779
780    fn try_from(cert: X509Certificate) -> Result<Self, Self::Error> {
781        let mut buffer = Vec::<u8>::new();
782        cert.encode_der_to(&mut buffer)?;
783
784        Self::from_der(buffer)
785    }
786}
787
788impl From<CapturedX509Certificate> for rfc5280::Certificate {
789    fn from(cert: CapturedX509Certificate) -> Self {
790        cert.inner.0
791    }
792}
793
794/// Provides a mutable wrapper to an X.509 certificate that was parsed from data.
795///
796/// This is like [CapturedX509Certificate] except it implements [DerefMut],
797/// enabling you to modify the certificate while still being able to access
798/// the raw data the certificate is backed by. However, mutations are
799/// only performed against the parsed ASN.1 data structure, not the original
800/// data it was constructed with.
801#[derive(Clone, Debug, Eq, PartialEq)]
802pub struct MutableX509Certificate(CapturedX509Certificate);
803
804impl Deref for MutableX509Certificate {
805    type Target = X509Certificate;
806
807    fn deref(&self) -> &Self::Target {
808        &self.0.inner
809    }
810}
811
812impl DerefMut for MutableX509Certificate {
813    fn deref_mut(&mut self) -> &mut Self::Target {
814        &mut self.0.inner
815    }
816}
817
818impl From<CapturedX509Certificate> for MutableX509Certificate {
819    fn from(cert: CapturedX509Certificate) -> Self {
820        Self(cert)
821    }
822}
823
824/// Whether one certificate is a subset of another certificate.
825///
826/// This returns true iff the two certificates have the same serial number
827/// and every `Name` attribute in the first certificate is present in the other.
828pub fn certificate_is_subset_of(
829    a_serial: &Integer,
830    a_name: &Name,
831    b_serial: &Integer,
832    b_name: &Name,
833) -> bool {
834    if a_serial != b_serial {
835        return false;
836    }
837
838    let Name::RdnSequence(a_sequence) = &a_name;
839    let Name::RdnSequence(b_sequence) = &b_name;
840
841    a_sequence.iter().all(|rdn| b_sequence.contains(rdn))
842}
843
844/// X.509 extension to define how a certificate can be used.
845///
846/// ```asn.1
847/// KeyUsage ::= BIT STRING {
848///   digitalSignature(0),
849///   nonRepudiation(1),
850///   keyEncipherment(2),
851///   dataEncipherment(3),
852///   keyAgreement(4),
853///   keyCertSign(5),
854///   cRLSign(6)
855/// }
856/// ```
857pub enum KeyUsage {
858    DigitalSignature,
859    NonRepudiation,
860    KeyEncipherment,
861    DataEncipherment,
862    KeyAgreement,
863    KeyCertSign,
864    CrlSign,
865}
866
867impl From<KeyUsage> for u8 {
868    fn from(ku: KeyUsage) -> Self {
869        match ku {
870            KeyUsage::DigitalSignature => 0,
871            KeyUsage::NonRepudiation => 1,
872            KeyUsage::KeyEncipherment => 2,
873            KeyUsage::DataEncipherment => 3,
874            KeyUsage::KeyAgreement => 4,
875            KeyUsage::KeyCertSign => 5,
876            KeyUsage::CrlSign => 6,
877        }
878    }
879}
880
881/// Interface for constructing new X.509 certificates.
882///
883/// This holds fields for various certificate metadata and allows you
884/// to incrementally derive a new X.509 certificate.
885///
886/// The certificate is populated with defaults:
887///
888/// * The serial number is 1.
889/// * The time validity is now until 1 hour from now.
890/// * There is no issuer. If no attempt is made to define an issuer,
891///   the subject will be copied to the issuer field and this will be
892///   a self-signed certificate.
893///
894/// This type can also be used to produce certificate signing requests. In this mode,
895/// only the subject value and additional registered attributes are meaningful.
896pub struct X509CertificateBuilder {
897    subject: Name,
898    issuer: Option<Name>,
899    extensions: rfc5280::Extensions,
900    serial_number: i64,
901    not_before: chrono::DateTime<Utc>,
902    not_after: chrono::DateTime<Utc>,
903    csr_attributes: Attributes,
904}
905
906impl Default for X509CertificateBuilder {
907    fn default() -> Self {
908        let not_before = Utc::now();
909        let not_after = not_before + Duration::hours(1);
910
911        Self {
912            subject: Name::default(),
913            issuer: None,
914            extensions: rfc5280::Extensions::default(),
915            serial_number: 1,
916            not_before,
917            not_after,
918            csr_attributes: Attributes::default(),
919        }
920    }
921}
922
923impl X509CertificateBuilder {
924    /// Deprecated. Use [Self::default()] instead.
925    #[deprecated]
926    pub fn new() -> Self {
927        Self::default()
928    }
929
930    /// Obtain a mutable reference to the subject [Name].
931    ///
932    /// The type has functions that will allow you to add attributes with ease.
933    pub fn subject(&mut self) -> &mut Name {
934        &mut self.subject
935    }
936
937    /// Obtain a mutable reference to the issuer [Name].
938    ///
939    /// If no issuer has been created yet, an empty one will be created.
940    pub fn issuer(&mut self) -> &mut Name {
941        self.issuer.get_or_insert_with(Name::default)
942    }
943
944    /// Set the serial number for the certificate.
945    pub fn serial_number(&mut self, value: i64) {
946        self.serial_number = value;
947    }
948
949    /// Obtain the raw certificate extensions.
950    pub fn extensions(&self) -> &rfc5280::Extensions {
951        &self.extensions
952    }
953
954    /// Obtain a mutable reference to raw certificate extensions.
955    pub fn extensions_mut(&mut self) -> &mut rfc5280::Extensions {
956        &mut self.extensions
957    }
958
959    /// Add an extension to the certificate with its value as pre-encoded DER data.
960    pub fn add_extension_der_data(&mut self, oid: Oid, critical: bool, data: impl AsRef<[u8]>) {
961        self.extensions.push(rfc5280::Extension {
962            id: oid,
963            critical: Some(critical),
964            value: OctetString::new(Bytes::copy_from_slice(data.as_ref())),
965        });
966    }
967
968    /// Set the expiration time in terms of [Duration] since its currently set start time.
969    pub fn validity_duration(&mut self, duration: Duration) {
970        self.not_after = self.not_before + duration;
971    }
972
973    /// Add a basic constraint extension that this isn't a CA certificate.
974    pub fn constraint_not_ca(&mut self) {
975        self.extensions.push(rfc5280::Extension {
976            id: Oid(OID_EXTENSION_BASIC_CONSTRAINTS.as_ref().into()),
977            critical: Some(true),
978            value: OctetString::new(Bytes::copy_from_slice(&[0x30, 00])),
979        });
980    }
981
982    /// Add a key usage extension.
983    pub fn key_usage(&mut self, key_usage: KeyUsage) {
984        let value: u8 = key_usage.into();
985
986        self.extensions.push(rfc5280::Extension {
987            id: Oid(OID_EXTENSION_KEY_USAGE.as_ref().into()),
988            critical: Some(true),
989            // Value is a bit string. We just encode it manually since it is easy.
990            value: OctetString::new(Bytes::copy_from_slice(&[3, 2, 7, 128 | value])),
991        });
992    }
993
994    /// Add an [Attribute] to a future certificate signing requests.
995    ///
996    /// Has no effect on regular certificate creation: only if creating certificate
997    /// signing requests.
998    pub fn add_csr_attribute(&mut self, attribute: rfc5652::Attribute) {
999        self.csr_attributes.push(attribute);
1000    }
1001
1002    /// Create a new certificate given settings using the provided key pair.
1003    pub fn create_with_key_pair(
1004        &self,
1005        key_pair: &InMemorySigningKeyPair,
1006    ) -> Result<CapturedX509Certificate, Error> {
1007        let key_pair_signature_algorithm = key_pair.signature_algorithm();
1008
1009        let issuer = if let Some(issuer) = &self.issuer {
1010            issuer
1011        } else {
1012            &self.subject
1013        };
1014
1015        let tbs_certificate = rfc5280::TbsCertificate {
1016            version: Some(rfc5280::Version::V3),
1017            serial_number: self.serial_number.into(),
1018            signature: key_pair_signature_algorithm?.into(),
1019            issuer: issuer.clone(),
1020            validity: rfc5280::Validity {
1021                not_before: Time::from(self.not_before),
1022                not_after: Time::from(self.not_after),
1023            },
1024            subject: self.subject.clone(),
1025            subject_public_key_info: rfc5280::SubjectPublicKeyInfo {
1026                algorithm: key_pair
1027                    .key_algorithm()
1028                    .expect("InMemorySigningKeyPair always has known key algorithm")
1029                    .into(),
1030                subject_public_key: BitString::new(0, key_pair.public_key_data()),
1031            },
1032            issuer_unique_id: None,
1033            subject_unique_id: None,
1034            extensions: if self.extensions.is_empty() {
1035                None
1036            } else {
1037                Some(self.extensions.clone())
1038            },
1039            raw_data: None,
1040        };
1041
1042        // Now encode the TBS certificate so we can sign it with the private key
1043        // and include its signature.
1044        let mut tbs_der = Vec::<u8>::new();
1045        tbs_certificate
1046            .encode_ref()
1047            .write_encoded(Mode::Der, &mut tbs_der)?;
1048
1049        let signature = key_pair.try_sign(&tbs_der)?;
1050        let signature_algorithm = key_pair.signature_algorithm()?;
1051
1052        let cert = rfc5280::Certificate {
1053            tbs_certificate,
1054            signature_algorithm: signature_algorithm.into(),
1055            signature: BitString::new(0, Bytes::copy_from_slice(signature.as_ref())),
1056        };
1057
1058        let cert = X509Certificate::from(cert);
1059        let cert_der = cert.encode_der()?;
1060
1061        CapturedX509Certificate::from_der(cert_der)
1062    }
1063
1064    /// Create a new certificate given settings, using a randomly generated key pair.
1065    pub fn create_with_random_keypair(
1066        &self,
1067        key_algorithm: KeyAlgorithm,
1068    ) -> Result<(CapturedX509Certificate, InMemorySigningKeyPair), Error> {
1069        let key_pair = InMemorySigningKeyPair::generate_random(key_algorithm)?;
1070        let cert = self.create_with_key_pair(&key_pair)?;
1071
1072        Ok((cert, key_pair))
1073    }
1074
1075    /// Create a new certificate signing request (CSR).
1076    ///
1077    /// The CSR is derived according to the process defined in RFC 2986 Section 3.
1078    /// Essentially, we collect metadata about the request, sign that metadata using
1079    /// a provided signing/private key, then attach the signature to form a complete
1080    /// certification request.
1081    pub fn create_certificate_signing_request(
1082        &self,
1083        signer: &dyn KeyInfoSigner,
1084    ) -> Result<rfc2986::CertificationRequest, Error> {
1085        let info = rfc2986::CertificationRequestInfo {
1086            version: rfc2986::Version::V1,
1087            subject: self.subject.clone(),
1088            subject_public_key_info: rfc5280::SubjectPublicKeyInfo {
1089                algorithm: signer
1090                    .key_algorithm()
1091                    .ok_or_else(|| {
1092                        Error::UnknownKeyAlgorithm(
1093                            "OID not available due to API limitations".into(),
1094                        )
1095                    })?
1096                    .into(),
1097                subject_public_key: BitString::new(0, signer.public_key_data()),
1098            },
1099            attributes: self.csr_attributes.clone(),
1100        };
1101
1102        // The signature is produced over the DER encoding of CertificationRequestInfo
1103        // per RFC 2986 Section 4.2.
1104        let mut info_der = vec![];
1105        info.write_encoded(Mode::Der, &mut info_der)?;
1106
1107        let signature = signer.try_sign(&info_der)?;
1108        let signature_algorithm = signer.signature_algorithm()?;
1109
1110        let request = rfc2986::CertificationRequest {
1111            certificate_request_info: info,
1112            signature_algorithm: signature_algorithm.into(),
1113            signature: BitString::new(0, signature.into()),
1114        };
1115
1116        Ok(request)
1117    }
1118}
1119
1120#[cfg(test)]
1121mod test {
1122    use {
1123        super::*,
1124        crate::{EcdsaCurve, X509CertificateError},
1125    };
1126
1127    #[test]
1128    fn builder_ed25519_default() {
1129        let builder = X509CertificateBuilder::default();
1130        builder
1131            .create_with_random_keypair(KeyAlgorithm::Ed25519)
1132            .unwrap();
1133    }
1134
1135    #[test]
1136    fn build_ecdsa_default() {
1137        for curve in EcdsaCurve::all() {
1138            let key_algorithm = KeyAlgorithm::Ecdsa(*curve);
1139
1140            let builder = X509CertificateBuilder::default();
1141            builder.create_with_random_keypair(key_algorithm).unwrap();
1142        }
1143    }
1144
1145    #[test]
1146    fn build_subject_populate() {
1147        let mut builder = X509CertificateBuilder::default();
1148        builder
1149            .subject()
1150            .append_common_name_utf8_string("My Name")
1151            .unwrap();
1152        builder
1153            .subject()
1154            .append_country_utf8_string("Wakanda")
1155            .unwrap();
1156
1157        builder
1158            .create_with_random_keypair(KeyAlgorithm::Ed25519)
1159            .unwrap();
1160    }
1161
1162    #[test]
1163    fn builder_csr_ecdsa() -> Result<(), Error> {
1164        for curve in EcdsaCurve::all() {
1165            let key_algorithm = KeyAlgorithm::Ecdsa(*curve);
1166
1167            let key = InMemorySigningKeyPair::generate_random(key_algorithm)?;
1168
1169            let builder = X509CertificateBuilder::default();
1170
1171            let csr = builder.create_certificate_signing_request(&key)?;
1172
1173            assert_eq!(
1174                csr.certificate_request_info
1175                    .subject_public_key_info
1176                    .algorithm,
1177                key_algorithm.into()
1178            );
1179        }
1180
1181        Ok(())
1182    }
1183
1184    #[test]
1185    fn ecdsa_p256_sha256_self_signed() {
1186        let der = include_bytes!("testdata/ecdsa-p256-sha256-self-signed.cer");
1187
1188        let cert = CapturedX509Certificate::from_der(der.to_vec()).unwrap();
1189        cert.verify_signed_by_certificate(&cert).unwrap();
1190
1191        cert.to_public_key_der().unwrap();
1192    }
1193
1194    #[test]
1195    fn ecdsa_p384_sha256_self_signed() {
1196        let der = include_bytes!("testdata/ecdsa-p384-sha256-self-signed.cer");
1197
1198        let cert = CapturedX509Certificate::from_der(der.to_vec()).unwrap();
1199        cert.verify_signed_by_certificate(&cert).unwrap();
1200        cert.to_public_key_der().unwrap();
1201    }
1202
1203    #[test]
1204    fn ecdsa_p512_sha256_self_signed() {
1205        let der = include_bytes!("testdata/ecdsa-p512-sha256-self-signed.cer");
1206
1207        // We can parse this. But we don't support secp512 elliptic curves because ring
1208        // doesn't support it.
1209        let cert = CapturedX509Certificate::from_der(der.to_vec()).unwrap();
1210        cert.to_public_key_der().unwrap();
1211
1212        assert!(matches!(
1213            cert.verify_signed_by_certificate(&cert),
1214            Err(Error::UnknownEllipticCurve(_))
1215        ));
1216    }
1217
1218    #[test]
1219    fn ecdsa_prime256v1_cert_validation() -> Result<(), X509CertificateError> {
1220        let root = include_bytes!("testdata/ecdsa-prime256v1-root.der");
1221        let signed = include_bytes!("testdata/ecdsa-prime256v1-signed.der");
1222
1223        let root = CapturedX509Certificate::from_der(root.as_ref())?;
1224        let signed = CapturedX509Certificate::from_der(signed.as_ref())?;
1225
1226        root.verify_signed_by_certificate(&root)?;
1227        signed.verify_signed_by_certificate(&root)?;
1228
1229        Ok(())
1230    }
1231}