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        algorithm::DigestAlgorithm, asn1time::Time, rfc2986, rfc3280::Name, rfc5280, rfc5652,
10        rfc5958::Attributes, rfc8017::RsaPublicKey, signing::Sign, InMemorySigningKeyPair,
11        KeyAlgorithm, KeyInfoSigner, SignatureAlgorithm, X509CertificateError as Error,
12    },
13    bcder::{
14        decode::Constructed,
15        encode::Values,
16        int::Integer,
17        string::{BitString, OctetString},
18        ConstOid, Mode, Oid,
19    },
20    bytes::Bytes,
21    chrono::{DateTime, Duration, Utc},
22    der::{Decode, Document},
23    ring::signature as ringsig,
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<ring::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<ring::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<ring::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
555        self.verify_signed_by_public_key(public_key)
556    }
557
558    /// Verify a signature over signed data purportedly signed by this certificate.
559    ///
560    /// This is a wrapper to [Self::verify_signed_data_with_algorithm()] that will derive
561    /// the verification algorithm from the public key type type and the signature algorithm
562    /// indicated in this certificate. Typically these align. However, it is possible for
563    /// a signature to be produced with a different digest algorithm from that indicated
564    /// in this certificate.
565    pub fn verify_signed_data(
566        &self,
567        signed_data: impl AsRef<[u8]>,
568        signature: impl AsRef<[u8]>,
569    ) -> Result<(), Error> {
570        let key_algorithm = KeyAlgorithm::try_from(self.key_algorithm_oid())?;
571        let signature_algorithm = SignatureAlgorithm::try_from(self.signature_algorithm_oid())?;
572        let verify_algorithm = signature_algorithm.resolve_verification_algorithm(key_algorithm)?;
573
574        self.verify_signed_data_with_algorithm(signed_data, signature, verify_algorithm)
575    }
576
577    /// Verify a signature over signed data using an explicit verification algorithm.
578    ///
579    /// This is like [Self::verify_signed_data()] except the verification algorithm to use
580    /// is passed in instead of derived from the default algorithm for the signing key's
581    /// type.
582    pub fn verify_signed_data_with_algorithm(
583        &self,
584        signed_data: impl AsRef<[u8]>,
585        signature: impl AsRef<[u8]>,
586        verify_algorithm: &'static dyn ringsig::VerificationAlgorithm,
587    ) -> Result<(), Error> {
588        let public_key = ringsig::UnparsedPublicKey::new(verify_algorithm, self.public_key_data());
589
590        public_key
591            .verify(signed_data.as_ref(), signature.as_ref())
592            .map_err(|_| Error::CertificateSignatureVerificationFailed)
593    }
594
595    /// Verifies that this certificate was cryptographically signed using raw public key data from a signing key.
596    ///
597    /// This function does the low-level work of extracting the signature and
598    /// verification details from the current certificate and figuring out
599    /// the correct combination of cryptography settings to apply to perform
600    /// signature verification.
601    ///
602    /// In many cases, an X.509 certificate is signed by another certificate. And
603    /// since the public key is embedded in the X.509 certificate, it is easier
604    /// to go through [Self::verify_signed_by_certificate] instead.
605    pub fn verify_signed_by_public_key(
606        &self,
607        public_key_data: impl AsRef<[u8]>,
608    ) -> Result<(), Error> {
609        // Always verify against the original content, as the inner
610        // certificate could be mutated via the mutable wrapper of this
611        // type.
612        let this_cert = match &self.original {
613            OriginalData::Ber(data) => X509Certificate::from_ber(data),
614            OriginalData::Der(data) => X509Certificate::from_der(data),
615        }
616        .expect("certificate re-parse should never fail");
617
618        let signed_data = this_cert
619            .0
620            .tbs_certificate
621            .raw_data
622            .as_ref()
623            .expect("original certificate data should have persisted as part of re-parse");
624        let signature = this_cert.0.signature.octet_bytes();
625
626        let key_algorithm = KeyAlgorithm::try_from(
627            &this_cert
628                .0
629                .tbs_certificate
630                .subject_public_key_info
631                .algorithm,
632        )?;
633        let signature_algorithm = SignatureAlgorithm::try_from(&this_cert.0.signature_algorithm)?;
634
635        let verify_algorithm = signature_algorithm.resolve_verification_algorithm(key_algorithm)?;
636
637        let public_key = ringsig::UnparsedPublicKey::new(verify_algorithm, public_key_data);
638
639        public_key
640            .verify(signed_data, &signature)
641            .map_err(|_| Error::CertificateSignatureVerificationFailed)
642    }
643
644    /// Attempt to find the issuing certificate of this one.
645    ///
646    /// Given an iterable of certificates, we find the first certificate
647    /// where we are able to verify that our signature was made by their public
648    /// key.
649    ///
650    /// This function can yield false negatives for cases where we don't
651    /// support the signature algorithm on the incoming certificates.
652    pub fn find_signing_certificate<'a>(
653        &self,
654        mut certs: impl Iterator<Item = &'a Self>,
655    ) -> Option<&'a Self> {
656        certs.find(|candidate| self.verify_signed_by_certificate(candidate).is_ok())
657    }
658
659    /// Attempt to resolve the signing chain of this certificate.
660    ///
661    /// Given an iterable of certificates, we recursively resolve the
662    /// chain of certificates that signed this one until we are no longer able
663    /// to find any more certificates in the input set.
664    ///
665    /// Like [Self::find_signing_certificate], this can yield false
666    /// negatives (read: an incomplete chain) due to run-time failures,
667    /// such as lack of support for a certificate's signature algorithm.
668    ///
669    /// As a certificate is encountered, it is removed from the set of
670    /// future candidates.
671    ///
672    /// The traversal ends when we get to an identical certificate (its
673    /// DER data is equivalent) or we couldn't find a certificate in
674    /// the remaining set that signed the last one.
675    ///
676    /// Because we need to recursively verify certificates, the incoming
677    /// iterator is buffered.
678    pub fn resolve_signing_chain<'a>(
679        &self,
680        certs: impl Iterator<Item = &'a Self>,
681    ) -> Vec<&'a Self> {
682        // The logic here is a bit wonky. As we build up the collection of certificates,
683        // we want to filter out ourself and remove duplicates. We remove duplicates by
684        // storing encountered certificates in a HashSet.
685        #[allow(clippy::mutable_key_type)]
686        let mut seen = HashSet::new();
687        let mut remaining = vec![];
688
689        for cert in certs {
690            if cert == self || seen.contains(cert) {
691                continue;
692            } else {
693                remaining.push(cert);
694                seen.insert(cert);
695            }
696        }
697
698        drop(seen);
699
700        let mut chain = vec![];
701
702        let mut last_cert = self;
703        while let Some(issuer) = last_cert.find_signing_certificate(remaining.iter().copied()) {
704            chain.push(issuer);
705            last_cert = issuer;
706
707            remaining = remaining
708                .drain(..)
709                .filter(|cert| *cert != issuer)
710                .collect::<Vec<_>>();
711        }
712
713        chain
714    }
715}
716
717impl PartialEq for CapturedX509Certificate {
718    fn eq(&self, other: &Self) -> bool {
719        self.constructed_data() == other.constructed_data()
720    }
721}
722
723impl Eq for CapturedX509Certificate {}
724
725impl Hash for CapturedX509Certificate {
726    fn hash<H: Hasher>(&self, state: &mut H) {
727        state.write(self.constructed_data());
728    }
729}
730
731impl Deref for CapturedX509Certificate {
732    type Target = X509Certificate;
733
734    fn deref(&self) -> &Self::Target {
735        &self.inner
736    }
737}
738
739impl AsRef<X509Certificate> for CapturedX509Certificate {
740    fn as_ref(&self) -> &X509Certificate {
741        &self.inner
742    }
743}
744
745impl AsRef<rfc5280::Certificate> for CapturedX509Certificate {
746    fn as_ref(&self) -> &rfc5280::Certificate {
747        self.inner.as_ref()
748    }
749}
750
751impl TryFrom<&X509Certificate> for CapturedX509Certificate {
752    type Error = Error;
753
754    fn try_from(cert: &X509Certificate) -> Result<Self, Self::Error> {
755        let mut buffer = Vec::<u8>::new();
756        cert.encode_der_to(&mut buffer)?;
757
758        Self::from_der(buffer)
759    }
760}
761
762impl TryFrom<X509Certificate> for CapturedX509Certificate {
763    type Error = Error;
764
765    fn try_from(cert: X509Certificate) -> Result<Self, Self::Error> {
766        let mut buffer = Vec::<u8>::new();
767        cert.encode_der_to(&mut buffer)?;
768
769        Self::from_der(buffer)
770    }
771}
772
773impl From<CapturedX509Certificate> for rfc5280::Certificate {
774    fn from(cert: CapturedX509Certificate) -> Self {
775        cert.inner.0
776    }
777}
778
779/// Provides a mutable wrapper to an X.509 certificate that was parsed from data.
780///
781/// This is like [CapturedX509Certificate] except it implements [DerefMut],
782/// enabling you to modify the certificate while still being able to access
783/// the raw data the certificate is backed by. However, mutations are
784/// only performed against the parsed ASN.1 data structure, not the original
785/// data it was constructed with.
786#[derive(Clone, Debug, Eq, PartialEq)]
787pub struct MutableX509Certificate(CapturedX509Certificate);
788
789impl Deref for MutableX509Certificate {
790    type Target = X509Certificate;
791
792    fn deref(&self) -> &Self::Target {
793        &self.0.inner
794    }
795}
796
797impl DerefMut for MutableX509Certificate {
798    fn deref_mut(&mut self) -> &mut Self::Target {
799        &mut self.0.inner
800    }
801}
802
803impl From<CapturedX509Certificate> for MutableX509Certificate {
804    fn from(cert: CapturedX509Certificate) -> Self {
805        Self(cert)
806    }
807}
808
809/// Whether one certificate is a subset of another certificate.
810///
811/// This returns true iff the two certificates have the same serial number
812/// and every `Name` attribute in the first certificate is present in the other.
813pub fn certificate_is_subset_of(
814    a_serial: &Integer,
815    a_name: &Name,
816    b_serial: &Integer,
817    b_name: &Name,
818) -> bool {
819    if a_serial != b_serial {
820        return false;
821    }
822
823    let Name::RdnSequence(a_sequence) = &a_name;
824    let Name::RdnSequence(b_sequence) = &b_name;
825
826    a_sequence.iter().all(|rdn| b_sequence.contains(rdn))
827}
828
829/// X.509 extension to define how a certificate can be used.
830///
831/// ```asn.1
832/// KeyUsage ::= BIT STRING {
833///   digitalSignature(0),
834///   nonRepudiation(1),
835///   keyEncipherment(2),
836///   dataEncipherment(3),
837///   keyAgreement(4),
838///   keyCertSign(5),
839///   cRLSign(6)
840/// }
841/// ```
842pub enum KeyUsage {
843    DigitalSignature,
844    NonRepudiation,
845    KeyEncipherment,
846    DataEncipherment,
847    KeyAgreement,
848    KeyCertSign,
849    CrlSign,
850}
851
852impl From<KeyUsage> for u8 {
853    fn from(ku: KeyUsage) -> Self {
854        match ku {
855            KeyUsage::DigitalSignature => 0,
856            KeyUsage::NonRepudiation => 1,
857            KeyUsage::KeyEncipherment => 2,
858            KeyUsage::DataEncipherment => 3,
859            KeyUsage::KeyAgreement => 4,
860            KeyUsage::KeyCertSign => 5,
861            KeyUsage::CrlSign => 6,
862        }
863    }
864}
865
866/// Interface for constructing new X.509 certificates.
867///
868/// This holds fields for various certificate metadata and allows you
869/// to incrementally derive a new X.509 certificate.
870///
871/// The certificate is populated with defaults:
872///
873/// * The serial number is 1.
874/// * The time validity is now until 1 hour from now.
875/// * There is no issuer. If no attempt is made to define an issuer,
876///   the subject will be copied to the issuer field and this will be
877///   a self-signed certificate.
878///
879/// This type can also be used to produce certificate signing requests. In this mode,
880/// only the subject value and additional registered attributes are meaningful.
881pub struct X509CertificateBuilder {
882    subject: Name,
883    issuer: Option<Name>,
884    extensions: rfc5280::Extensions,
885    serial_number: i64,
886    not_before: chrono::DateTime<Utc>,
887    not_after: chrono::DateTime<Utc>,
888    csr_attributes: Attributes,
889}
890
891impl Default for X509CertificateBuilder {
892    fn default() -> Self {
893        let not_before = Utc::now();
894        let not_after = not_before + Duration::hours(1);
895
896        Self {
897            subject: Name::default(),
898            issuer: None,
899            extensions: rfc5280::Extensions::default(),
900            serial_number: 1,
901            not_before,
902            not_after,
903            csr_attributes: Attributes::default(),
904        }
905    }
906}
907
908impl X509CertificateBuilder {
909    /// Deprecated. Use [Self::default()] instead.
910    #[deprecated]
911    pub fn new() -> Self {
912        Self::default()
913    }
914
915    /// Obtain a mutable reference to the subject [Name].
916    ///
917    /// The type has functions that will allow you to add attributes with ease.
918    pub fn subject(&mut self) -> &mut Name {
919        &mut self.subject
920    }
921
922    /// Obtain a mutable reference to the issuer [Name].
923    ///
924    /// If no issuer has been created yet, an empty one will be created.
925    pub fn issuer(&mut self) -> &mut Name {
926        self.issuer.get_or_insert_with(Name::default)
927    }
928
929    /// Set the serial number for the certificate.
930    pub fn serial_number(&mut self, value: i64) {
931        self.serial_number = value;
932    }
933
934    /// Obtain the raw certificate extensions.
935    pub fn extensions(&self) -> &rfc5280::Extensions {
936        &self.extensions
937    }
938
939    /// Obtain a mutable reference to raw certificate extensions.
940    pub fn extensions_mut(&mut self) -> &mut rfc5280::Extensions {
941        &mut self.extensions
942    }
943
944    /// Add an extension to the certificate with its value as pre-encoded DER data.
945    pub fn add_extension_der_data(&mut self, oid: Oid, critical: bool, data: impl AsRef<[u8]>) {
946        self.extensions.push(rfc5280::Extension {
947            id: oid,
948            critical: Some(critical),
949            value: OctetString::new(Bytes::copy_from_slice(data.as_ref())),
950        });
951    }
952
953    /// Set the expiration time in terms of [Duration] since its currently set start time.
954    pub fn validity_duration(&mut self, duration: Duration) {
955        self.not_after = self.not_before + duration;
956    }
957
958    /// Add a basic constraint extension that this isn't a CA certificate.
959    pub fn constraint_not_ca(&mut self) {
960        self.extensions.push(rfc5280::Extension {
961            id: Oid(OID_EXTENSION_BASIC_CONSTRAINTS.as_ref().into()),
962            critical: Some(true),
963            value: OctetString::new(Bytes::copy_from_slice(&[0x30, 00])),
964        });
965    }
966
967    /// Add a key usage extension.
968    pub fn key_usage(&mut self, key_usage: KeyUsage) {
969        let value: u8 = key_usage.into();
970
971        self.extensions.push(rfc5280::Extension {
972            id: Oid(OID_EXTENSION_KEY_USAGE.as_ref().into()),
973            critical: Some(true),
974            // Value is a bit string. We just encode it manually since it is easy.
975            value: OctetString::new(Bytes::copy_from_slice(&[3, 2, 7, 128 | value])),
976        });
977    }
978
979    /// Add an [Attribute] to a future certificate signing requests.
980    ///
981    /// Has no effect on regular certificate creation: only if creating certificate
982    /// signing requests.
983    pub fn add_csr_attribute(&mut self, attribute: rfc5652::Attribute) {
984        self.csr_attributes.push(attribute);
985    }
986
987    /// Create a new certificate given settings using the provided key pair.
988    pub fn create_with_key_pair(
989        &self,
990        key_pair: &InMemorySigningKeyPair,
991    ) -> Result<CapturedX509Certificate, Error> {
992        let key_pair_signature_algorithm = key_pair.signature_algorithm();
993
994        let issuer = if let Some(issuer) = &self.issuer {
995            issuer
996        } else {
997            &self.subject
998        };
999
1000        let tbs_certificate = rfc5280::TbsCertificate {
1001            version: Some(rfc5280::Version::V3),
1002            serial_number: self.serial_number.into(),
1003            signature: key_pair_signature_algorithm?.into(),
1004            issuer: issuer.clone(),
1005            validity: rfc5280::Validity {
1006                not_before: Time::from(self.not_before),
1007                not_after: Time::from(self.not_after),
1008            },
1009            subject: self.subject.clone(),
1010            subject_public_key_info: rfc5280::SubjectPublicKeyInfo {
1011                algorithm: key_pair
1012                    .key_algorithm()
1013                    .expect("InMemorySigningKeyPair always has known key algorithm")
1014                    .into(),
1015                subject_public_key: BitString::new(0, key_pair.public_key_data()),
1016            },
1017            issuer_unique_id: None,
1018            subject_unique_id: None,
1019            extensions: if self.extensions.is_empty() {
1020                None
1021            } else {
1022                Some(self.extensions.clone())
1023            },
1024            raw_data: None,
1025        };
1026
1027        // Now encode the TBS certificate so we can sign it with the private key
1028        // and include its signature.
1029        let mut tbs_der = Vec::<u8>::new();
1030        tbs_certificate
1031            .encode_ref()
1032            .write_encoded(Mode::Der, &mut tbs_der)?;
1033
1034        let signature = key_pair.try_sign(&tbs_der)?;
1035        let signature_algorithm = key_pair.signature_algorithm()?;
1036
1037        let cert = rfc5280::Certificate {
1038            tbs_certificate,
1039            signature_algorithm: signature_algorithm.into(),
1040            signature: BitString::new(0, Bytes::copy_from_slice(signature.as_ref())),
1041        };
1042
1043        let cert = X509Certificate::from(cert);
1044        let cert_der = cert.encode_der()?;
1045
1046        CapturedX509Certificate::from_der(cert_der)
1047    }
1048
1049    /// Create a new certificate given settings, using a randomly generated key pair.
1050    pub fn create_with_random_keypair(
1051        &self,
1052        key_algorithm: KeyAlgorithm,
1053    ) -> Result<(CapturedX509Certificate, InMemorySigningKeyPair), Error> {
1054        let key_pair = InMemorySigningKeyPair::generate_random(key_algorithm)?;
1055        let cert = self.create_with_key_pair(&key_pair)?;
1056
1057        Ok((cert, key_pair))
1058    }
1059
1060    /// Create a new certificate signing request (CSR).
1061    ///
1062    /// The CSR is derived according to the process defined in RFC 2986 Section 3.
1063    /// Essentially, we collect metadata about the request, sign that metadata using
1064    /// a provided signing/private key, then attach the signature to form a complete
1065    /// certification request.
1066    pub fn create_certificate_signing_request(
1067        &self,
1068        signer: &dyn KeyInfoSigner,
1069    ) -> Result<rfc2986::CertificationRequest, Error> {
1070        let info = rfc2986::CertificationRequestInfo {
1071            version: rfc2986::Version::V1,
1072            subject: self.subject.clone(),
1073            subject_public_key_info: rfc5280::SubjectPublicKeyInfo {
1074                algorithm: signer
1075                    .key_algorithm()
1076                    .ok_or_else(|| {
1077                        Error::UnknownKeyAlgorithm(
1078                            "OID not available due to API limitations".into(),
1079                        )
1080                    })?
1081                    .into(),
1082                subject_public_key: BitString::new(0, signer.public_key_data()),
1083            },
1084            attributes: self.csr_attributes.clone(),
1085        };
1086
1087        // The signature is produced over the DER encoding of CertificationRequestInfo
1088        // per RFC 2986 Section 4.2.
1089        let mut info_der = vec![];
1090        info.write_encoded(Mode::Der, &mut info_der)?;
1091
1092        let signature = signer.try_sign(&info_der)?;
1093        let signature_algorithm = signer.signature_algorithm()?;
1094
1095        let request = rfc2986::CertificationRequest {
1096            certificate_request_info: info,
1097            signature_algorithm: signature_algorithm.into(),
1098            signature: BitString::new(0, signature.into()),
1099        };
1100
1101        Ok(request)
1102    }
1103}
1104
1105#[cfg(test)]
1106mod test {
1107    use {
1108        super::*,
1109        crate::{EcdsaCurve, X509CertificateError},
1110    };
1111
1112    #[test]
1113    fn builder_ed25519_default() {
1114        let builder = X509CertificateBuilder::default();
1115        builder
1116            .create_with_random_keypair(KeyAlgorithm::Ed25519)
1117            .unwrap();
1118    }
1119
1120    #[test]
1121    fn build_ecdsa_default() {
1122        for curve in EcdsaCurve::all() {
1123            let key_algorithm = KeyAlgorithm::Ecdsa(*curve);
1124
1125            let builder = X509CertificateBuilder::default();
1126            builder.create_with_random_keypair(key_algorithm).unwrap();
1127        }
1128    }
1129
1130    #[test]
1131    fn build_subject_populate() {
1132        let mut builder = X509CertificateBuilder::default();
1133        builder
1134            .subject()
1135            .append_common_name_utf8_string("My Name")
1136            .unwrap();
1137        builder
1138            .subject()
1139            .append_country_utf8_string("Wakanda")
1140            .unwrap();
1141
1142        builder
1143            .create_with_random_keypair(KeyAlgorithm::Ed25519)
1144            .unwrap();
1145    }
1146
1147    #[test]
1148    fn builder_csr_ecdsa() -> Result<(), Error> {
1149        for curve in EcdsaCurve::all() {
1150            let key_algorithm = KeyAlgorithm::Ecdsa(*curve);
1151
1152            let key = InMemorySigningKeyPair::generate_random(key_algorithm)?;
1153
1154            let builder = X509CertificateBuilder::default();
1155
1156            let csr = builder.create_certificate_signing_request(&key)?;
1157
1158            assert_eq!(
1159                csr.certificate_request_info
1160                    .subject_public_key_info
1161                    .algorithm,
1162                key_algorithm.into()
1163            );
1164        }
1165
1166        Ok(())
1167    }
1168
1169    #[test]
1170    fn ecdsa_p256_sha256_self_signed() {
1171        let der = include_bytes!("testdata/ecdsa-p256-sha256-self-signed.cer");
1172
1173        let cert = CapturedX509Certificate::from_der(der.to_vec()).unwrap();
1174        cert.verify_signed_by_certificate(&cert).unwrap();
1175
1176        cert.to_public_key_der().unwrap();
1177    }
1178
1179    #[test]
1180    fn ecdsa_p384_sha256_self_signed() {
1181        let der = include_bytes!("testdata/ecdsa-p384-sha256-self-signed.cer");
1182
1183        let cert = CapturedX509Certificate::from_der(der.to_vec()).unwrap();
1184        cert.verify_signed_by_certificate(&cert).unwrap();
1185        cert.to_public_key_der().unwrap();
1186    }
1187
1188    #[test]
1189    fn ecdsa_p512_sha256_self_signed() {
1190        let der = include_bytes!("testdata/ecdsa-p512-sha256-self-signed.cer");
1191
1192        // We can parse this. But we don't support secp512 elliptic curves because ring
1193        // doesn't support it.
1194        let cert = CapturedX509Certificate::from_der(der.to_vec()).unwrap();
1195        cert.to_public_key_der().unwrap();
1196
1197        assert!(matches!(
1198            cert.verify_signed_by_certificate(&cert),
1199            Err(Error::UnknownEllipticCurve(_))
1200        ));
1201    }
1202
1203    #[test]
1204    fn ecdsa_prime256v1_cert_validation() -> Result<(), X509CertificateError> {
1205        let root = include_bytes!("testdata/ecdsa-prime256v1-root.der");
1206        let signed = include_bytes!("testdata/ecdsa-prime256v1-signed.der");
1207
1208        let root = CapturedX509Certificate::from_der(root.as_ref())?;
1209        let signed = CapturedX509Certificate::from_der(signed.as_ref())?;
1210
1211        root.verify_signed_by_certificate(&root)?;
1212        signed.verify_signed_by_certificate(&root)?;
1213
1214        Ok(())
1215    }
1216}