rustls_pki_types/
lib.rs

1//! This crate provides types for representing X.509 certificates, keys and other types as
2//! commonly used in the rustls ecosystem. It is intended to be used by crates that need to work
3//! with such X.509 types, such as [rustls](https://crates.io/crates/rustls),
4//! [rustls-webpki](https://crates.io/crates/rustls-webpki),
5//! [rustls-pemfile](https://crates.io/crates/rustls-pemfile), and others.
6//!
7//! Some of these crates used to define their own trivial wrappers around DER-encoded bytes.
8//! However, in order to avoid inconvenient dependency edges, these were all disconnected. By
9//! using a common low-level crate of types with long-term stable API, we hope to avoid the
10//! downsides of unnecessary dependency edges while providing good interoperability between crates.
11//!
12//! ## DER and PEM
13//!
14//! Many of the types defined in this crate represent DER-encoded data. DER is a binary encoding of
15//! the ASN.1 format commonly used in web PKI specifications. It is a binary encoding, so it is
16//! relatively compact when stored in memory. However, as a binary format, it is not very easy to
17//! work with for humans and in contexts where binary data is inconvenient. For this reason,
18//! many tools and protocols use a ASCII-based encoding of DER, called PEM. In addition to the
19//! base64-encoded DER, PEM objects are delimited by header and footer lines which indicate the type
20//! of object contained in the PEM blob.
21//!
22//! Types here can be created from:
23//!
24//! - DER using (for example) [`PrivatePkcs8KeyDer::from()`].
25//! - PEM using (for example) [`pem::PemObject::from_pem_slice()`].
26//!
27//! The [`pem::PemObject`] trait contains the full selection of ways to construct
28//! these types from PEM encodings.  That includes ways to open and read from a file,
29//! from a slice, or from an `std::io` stream.
30//!
31//! There is also a lower-level API that allows a given PEM file to be fully consumed
32//! in one pass, even if it contains different data types: see the implementation of
33//! the [`pem::PemObject`] trait on the `(pem::SectionKind, Vec<u8>)` tuple.
34//!
35//! ## Creating new certificates and keys
36//!
37//! This crate does not provide any functionality for creating new certificates or keys. However,
38//! the [rcgen](https://docs.rs/rcgen) crate can be used to create new certificates and keys.
39//!
40//! ## Cloning private keys
41//!
42//! This crate intentionally **does not** implement `Clone` on private key types in
43//! order to minimize the exposure of private key data in memory.
44//!
45//! If you want to extend the lifetime of a `PrivateKeyDer<'_>`, consider [`PrivateKeyDer::clone_key()`].
46//! Alternatively  since these types are immutable, consider wrapping the `PrivateKeyDer<'_>` in a [`Rc`]
47//! or an [`Arc`].
48//!
49//! [`Rc`]: https://doc.rust-lang.org/std/rc/struct.Rc.html
50//! [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html
51//! [`PrivateKeyDer::clone_key()`]: https://docs.rs/rustls-pki-types/latest/rustls_pki_types/enum.PrivateKeyDer.html#method.clone_key
52//!
53//! ## Target `wasm32-unknown-unknown` with the `web` feature
54//!
55//! [`std::time::SystemTime`](https://doc.rust-lang.org/std/time/struct.SystemTime.html)
56//! is unavailable in `wasm32-unknown-unknown` targets, so calls to
57//! [`UnixTime::now()`](https://docs.rs/rustls-pki-types/latest/rustls_pki_types/struct.UnixTime.html#method.now),
58//! otherwise enabled by the [`std`](https://docs.rs/crate/rustls-pki-types/latest/features#std) feature,
59//! require building instead with the [`web`](https://docs.rs/crate/rustls-pki-types/latest/features#web)
60//! feature. It gets time by calling [`Date.now()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now)
61//! in the browser.
62
63#![cfg_attr(not(feature = "std"), no_std)]
64#![warn(unreachable_pub, clippy::use_self)]
65#![deny(missing_docs)]
66#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
67
68#[cfg(feature = "alloc")]
69extern crate alloc;
70
71#[cfg(feature = "alloc")]
72use alloc::vec::Vec;
73use core::fmt;
74use core::ops::Deref;
75use core::time::Duration;
76#[cfg(feature = "alloc")]
77use pem::{PemObject, PemObjectFilter, SectionKind};
78#[cfg(all(
79    feature = "std",
80    not(all(target_family = "wasm", target_os = "unknown"))
81))]
82use std::time::SystemTime;
83#[cfg(all(target_family = "wasm", target_os = "unknown", feature = "web"))]
84use web_time::SystemTime;
85
86pub mod alg_id;
87mod base64;
88mod server_name;
89
90/// Low-level PEM decoding APIs.
91///
92/// These APIs allow decoding PEM format in an iterator, which means you
93/// can load multiple different types of PEM section from a file in a single
94/// pass.
95#[cfg(feature = "alloc")]
96pub mod pem;
97
98pub use alg_id::AlgorithmIdentifier;
99pub use server_name::{
100    AddrParseError, DnsName, InvalidDnsNameError, IpAddr, Ipv4Addr, Ipv6Addr, ServerName,
101};
102
103/// A DER-encoded X.509 private key, in one of several formats
104///
105/// See variant inner types for more detailed information.
106///
107/// This can load several types of PEM-encoded private key, and then reveal
108/// which types were found:
109///
110/// ```rust
111/// # #[cfg(all(feature = "alloc", feature = "std"))] {
112/// use rustls_pki_types::{PrivateKeyDer, pem::PemObject};
113///
114/// // load from a PEM file
115/// let pkcs8 = PrivateKeyDer::from_pem_file("tests/data/nistp256key.pkcs8.pem").unwrap();
116/// let pkcs1 = PrivateKeyDer::from_pem_file("tests/data/rsa1024.pkcs1.pem").unwrap();
117/// let sec1 = PrivateKeyDer::from_pem_file("tests/data/nistp256key.pem").unwrap();
118/// assert!(matches!(pkcs8, PrivateKeyDer::Pkcs8(_)));
119/// assert!(matches!(pkcs1, PrivateKeyDer::Pkcs1(_)));
120/// assert!(matches!(sec1, PrivateKeyDer::Sec1(_)));
121/// # }
122/// ```
123#[non_exhaustive]
124#[derive(Debug, PartialEq, Eq)]
125pub enum PrivateKeyDer<'a> {
126    /// An RSA private key
127    Pkcs1(PrivatePkcs1KeyDer<'a>),
128    /// A Sec1 private key
129    Sec1(PrivateSec1KeyDer<'a>),
130    /// A PKCS#8 private key
131    Pkcs8(PrivatePkcs8KeyDer<'a>),
132}
133
134#[cfg(feature = "alloc")]
135impl zeroize::Zeroize for PrivateKeyDer<'static> {
136    fn zeroize(&mut self) {
137        match self {
138            Self::Pkcs1(key) => key.zeroize(),
139            Self::Sec1(key) => key.zeroize(),
140            Self::Pkcs8(key) => key.zeroize(),
141        }
142    }
143}
144
145impl PrivateKeyDer<'_> {
146    /// Clone the private key to a `'static` value
147    #[cfg(feature = "alloc")]
148    pub fn clone_key(&self) -> PrivateKeyDer<'static> {
149        use PrivateKeyDer::*;
150        match self {
151            Pkcs1(key) => Pkcs1(key.clone_key()),
152            Sec1(key) => Sec1(key.clone_key()),
153            Pkcs8(key) => Pkcs8(key.clone_key()),
154        }
155    }
156
157    /// Yield the DER-encoded bytes of the private key
158    pub fn secret_der(&self) -> &[u8] {
159        match self {
160            PrivateKeyDer::Pkcs1(key) => key.secret_pkcs1_der(),
161            PrivateKeyDer::Sec1(key) => key.secret_sec1_der(),
162            PrivateKeyDer::Pkcs8(key) => key.secret_pkcs8_der(),
163        }
164    }
165}
166
167#[cfg(feature = "alloc")]
168impl PemObject for PrivateKeyDer<'static> {
169    fn from_pem(kind: SectionKind, value: Vec<u8>) -> Option<Self> {
170        match kind {
171            SectionKind::RsaPrivateKey => Some(Self::Pkcs1(value.into())),
172            SectionKind::EcPrivateKey => Some(Self::Sec1(value.into())),
173            SectionKind::PrivateKey => Some(Self::Pkcs8(value.into())),
174            _ => None,
175        }
176    }
177}
178
179impl<'a> From<PrivatePkcs1KeyDer<'a>> for PrivateKeyDer<'a> {
180    fn from(key: PrivatePkcs1KeyDer<'a>) -> Self {
181        Self::Pkcs1(key)
182    }
183}
184
185impl<'a> From<PrivateSec1KeyDer<'a>> for PrivateKeyDer<'a> {
186    fn from(key: PrivateSec1KeyDer<'a>) -> Self {
187        Self::Sec1(key)
188    }
189}
190
191impl<'a> From<PrivatePkcs8KeyDer<'a>> for PrivateKeyDer<'a> {
192    fn from(key: PrivatePkcs8KeyDer<'a>) -> Self {
193        Self::Pkcs8(key)
194    }
195}
196
197impl<'a> TryFrom<&'a [u8]> for PrivateKeyDer<'a> {
198    type Error = &'static str;
199
200    fn try_from(key: &'a [u8]) -> Result<Self, Self::Error> {
201        const SHORT_FORM_LEN_MAX: u8 = 128;
202        const TAG_SEQUENCE: u8 = 0x30;
203        const TAG_INTEGER: u8 = 0x02;
204
205        // We expect all key formats to begin with a SEQUENCE, which requires at least 2 bytes
206        // in the short length encoding.
207        if key.first() != Some(&TAG_SEQUENCE) || key.len() < 2 {
208            return Err(INVALID_KEY_DER_ERR);
209        }
210
211        // The length of the SEQUENCE is encoded in the second byte. We must skip this many bytes.
212        let skip_len = match key[1] >= SHORT_FORM_LEN_MAX {
213            // 1 byte for SEQUENCE tag, 1 byte for short-form len
214            false => 2,
215            // 1 byte for SEQUENCE tag, 1 byte for start of len, remaining bytes encoded
216            // in key[1].
217            true => 2 + (key[1] - SHORT_FORM_LEN_MAX) as usize,
218        };
219        let key_bytes = key.get(skip_len..).ok_or(INVALID_KEY_DER_ERR)?;
220
221        // PKCS#8 (https://www.rfc-editor.org/rfc/rfc5208) describes the PrivateKeyInfo
222        // structure as:
223        //   PrivateKeyInfo ::= SEQUENCE {
224        //      version Version,
225        //      privateKeyAlgorithm AlgorithmIdentifier {{PrivateKeyAlgorithms}},
226        //      privateKey PrivateKey,
227        //      attributes [0] Attributes OPTIONAL
228        //   }
229        // PKCS#5 (https://www.rfc-editor.org/rfc/rfc8018) describes the AlgorithmIdentifier
230        // as a SEQUENCE.
231        //
232        // Therefore, we consider the outer SEQUENCE, a version number, and the start of
233        // an AlgorithmIdentifier to be enough to identify a PKCS#8 key. If it were PKCS#1 or SEC1
234        // the version would not be followed by a SEQUENCE.
235        if matches!(key_bytes, [TAG_INTEGER, 0x01, _, TAG_SEQUENCE, ..]) {
236            return Ok(Self::Pkcs8(key.into()));
237        }
238
239        // PKCS#1 (https://www.rfc-editor.org/rfc/rfc8017) describes the RSAPrivateKey structure
240        // as:
241        //  RSAPrivateKey ::= SEQUENCE {
242        //              version           Version,
243        //              modulus           INTEGER,  -- n
244        //              publicExponent    INTEGER,  -- e
245        //              privateExponent   INTEGER,  -- d
246        //              prime1            INTEGER,  -- p
247        //              prime2            INTEGER,  -- q
248        //              exponent1         INTEGER,  -- d mod (p-1)
249        //              exponent2         INTEGER,  -- d mod (q-1)
250        //              coefficient       INTEGER,  -- (inverse of q) mod p
251        //              otherPrimeInfos   OtherPrimeInfos OPTIONAL
252        //          }
253        //
254        // Therefore, we consider the outer SEQUENCE and a Version of 0 to be enough to identify
255        // a PKCS#1 key. If it were PKCS#8, the version would be followed by a SEQUENCE. If it
256        // were SEC1, the VERSION would have been 1.
257        if key_bytes.starts_with(&[TAG_INTEGER, 0x01, 0x00]) {
258            return Ok(Self::Pkcs1(key.into()));
259        }
260
261        // SEC1 (https://www.rfc-editor.org/rfc/rfc5915) describes the ECPrivateKey structure as:
262        //   ECPrivateKey ::= SEQUENCE {
263        //      version        INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
264        //      privateKey     OCTET STRING,
265        //      parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
266        //      publicKey  [1] BIT STRING OPTIONAL
267        //   }
268        //
269        // Therefore, we consider the outer SEQUENCE and an INTEGER of 1 to be enough to
270        // identify a SEC1 key. If it were PKCS#8 or PKCS#1, the version would have been 0.
271        if key_bytes.starts_with(&[TAG_INTEGER, 0x01, 0x01]) {
272            return Ok(Self::Sec1(key.into()));
273        }
274
275        Err(INVALID_KEY_DER_ERR)
276    }
277}
278
279static INVALID_KEY_DER_ERR: &str = "unknown or invalid key format";
280
281#[cfg(feature = "alloc")]
282impl TryFrom<Vec<u8>> for PrivateKeyDer<'_> {
283    type Error = &'static str;
284
285    fn try_from(key: Vec<u8>) -> Result<Self, Self::Error> {
286        Ok(match PrivateKeyDer::try_from(&key[..])? {
287            PrivateKeyDer::Pkcs1(_) => Self::Pkcs1(key.into()),
288            PrivateKeyDer::Sec1(_) => Self::Sec1(key.into()),
289            PrivateKeyDer::Pkcs8(_) => Self::Pkcs8(key.into()),
290        })
291    }
292}
293
294/// A DER-encoded plaintext RSA private key; as specified in PKCS#1/RFC 3447
295///
296/// RSA private keys are identified in PEM context as `RSA PRIVATE KEY` and when stored in a
297/// file usually use a `.pem` or `.key` extension.
298///
299/// ```rust
300/// # #[cfg(all(feature = "alloc", feature = "std"))] {
301/// use rustls_pki_types::{PrivatePkcs1KeyDer, pem::PemObject};
302///
303/// // load from a PEM file
304/// PrivatePkcs1KeyDer::from_pem_file("tests/data/rsa1024.pkcs1.pem").unwrap();
305///
306/// // or from a PEM byte slice...
307/// # let byte_slice = include_bytes!("../tests/data/rsa1024.pkcs1.pem");
308/// PrivatePkcs1KeyDer::from_pem_slice(byte_slice).unwrap();
309/// # }
310/// ```
311#[derive(PartialEq, Eq)]
312pub struct PrivatePkcs1KeyDer<'a>(Der<'a>);
313
314impl PrivatePkcs1KeyDer<'_> {
315    /// Clone the private key to a `'static` value
316    #[cfg(feature = "alloc")]
317    pub fn clone_key(&self) -> PrivatePkcs1KeyDer<'static> {
318        PrivatePkcs1KeyDer::from(self.0.as_ref().to_vec())
319    }
320
321    /// Yield the DER-encoded bytes of the private key
322    pub fn secret_pkcs1_der(&self) -> &[u8] {
323        self.0.as_ref()
324    }
325}
326
327#[cfg(feature = "alloc")]
328impl zeroize::Zeroize for PrivatePkcs1KeyDer<'static> {
329    fn zeroize(&mut self) {
330        self.0.0.zeroize()
331    }
332}
333
334#[cfg(feature = "alloc")]
335impl PemObjectFilter for PrivatePkcs1KeyDer<'static> {
336    const KIND: SectionKind = SectionKind::RsaPrivateKey;
337}
338
339impl<'a> From<&'a [u8]> for PrivatePkcs1KeyDer<'a> {
340    fn from(slice: &'a [u8]) -> Self {
341        Self(Der(BytesInner::Borrowed(slice)))
342    }
343}
344
345#[cfg(feature = "alloc")]
346impl From<Vec<u8>> for PrivatePkcs1KeyDer<'_> {
347    fn from(vec: Vec<u8>) -> Self {
348        Self(Der(BytesInner::Owned(vec)))
349    }
350}
351
352impl fmt::Debug for PrivatePkcs1KeyDer<'_> {
353    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
354        f.debug_tuple("PrivatePkcs1KeyDer")
355            .field(&"[secret key elided]")
356            .finish()
357    }
358}
359
360/// A Sec1-encoded plaintext private key; as specified in RFC 5915
361///
362/// Sec1 private keys are identified in PEM context as `EC PRIVATE KEY` and when stored in a
363/// file usually use a `.pem` or `.key` extension. For more on PEM files, refer to the crate
364/// documentation.
365///
366/// ```rust
367/// # #[cfg(all(feature = "alloc", feature = "std"))] {
368/// use rustls_pki_types::{PrivateSec1KeyDer, pem::PemObject};
369///
370/// // load from a PEM file
371/// PrivateSec1KeyDer::from_pem_file("tests/data/nistp256key.pem").unwrap();
372///
373/// // or from a PEM byte slice...
374/// # let byte_slice = include_bytes!("../tests/data/nistp256key.pem");
375/// PrivateSec1KeyDer::from_pem_slice(byte_slice).unwrap();
376/// # }
377/// ```
378#[derive(PartialEq, Eq)]
379pub struct PrivateSec1KeyDer<'a>(Der<'a>);
380
381impl PrivateSec1KeyDer<'_> {
382    /// Clone the private key to a `'static` value
383    #[cfg(feature = "alloc")]
384    pub fn clone_key(&self) -> PrivateSec1KeyDer<'static> {
385        PrivateSec1KeyDer::from(self.0.as_ref().to_vec())
386    }
387
388    /// Yield the DER-encoded bytes of the private key
389    pub fn secret_sec1_der(&self) -> &[u8] {
390        self.0.as_ref()
391    }
392}
393
394#[cfg(feature = "alloc")]
395impl zeroize::Zeroize for PrivateSec1KeyDer<'static> {
396    fn zeroize(&mut self) {
397        self.0.0.zeroize()
398    }
399}
400
401#[cfg(feature = "alloc")]
402impl PemObjectFilter for PrivateSec1KeyDer<'static> {
403    const KIND: SectionKind = SectionKind::EcPrivateKey;
404}
405
406impl<'a> From<&'a [u8]> for PrivateSec1KeyDer<'a> {
407    fn from(slice: &'a [u8]) -> Self {
408        Self(Der(BytesInner::Borrowed(slice)))
409    }
410}
411
412#[cfg(feature = "alloc")]
413impl From<Vec<u8>> for PrivateSec1KeyDer<'_> {
414    fn from(vec: Vec<u8>) -> Self {
415        Self(Der(BytesInner::Owned(vec)))
416    }
417}
418
419impl fmt::Debug for PrivateSec1KeyDer<'_> {
420    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
421        f.debug_tuple("PrivateSec1KeyDer")
422            .field(&"[secret key elided]")
423            .finish()
424    }
425}
426
427/// A DER-encoded plaintext private key; as specified in PKCS#8/RFC 5958
428///
429/// PKCS#8 private keys are identified in PEM context as `PRIVATE KEY` and when stored in a
430/// file usually use a `.pem` or `.key` extension. For more on PEM files, refer to the crate
431/// documentation.
432///
433/// ```rust
434/// # #[cfg(all(feature = "alloc", feature = "std"))] {
435/// use rustls_pki_types::{PrivatePkcs8KeyDer, pem::PemObject};
436///
437/// // load from a PEM file
438/// PrivatePkcs8KeyDer::from_pem_file("tests/data/nistp256key.pkcs8.pem").unwrap();
439/// PrivatePkcs8KeyDer::from_pem_file("tests/data/rsa1024.pkcs8.pem").unwrap();
440///
441/// // or from a PEM byte slice...
442/// # let byte_slice = include_bytes!("../tests/data/nistp256key.pkcs8.pem");
443/// PrivatePkcs8KeyDer::from_pem_slice(byte_slice).unwrap();
444/// # }
445/// ```
446#[derive(PartialEq, Eq)]
447pub struct PrivatePkcs8KeyDer<'a>(Der<'a>);
448
449impl PrivatePkcs8KeyDer<'_> {
450    /// Clone the private key to a `'static` value
451    #[cfg(feature = "alloc")]
452    pub fn clone_key(&self) -> PrivatePkcs8KeyDer<'static> {
453        PrivatePkcs8KeyDer::from(self.0.as_ref().to_vec())
454    }
455
456    /// Yield the DER-encoded bytes of the private key
457    pub fn secret_pkcs8_der(&self) -> &[u8] {
458        self.0.as_ref()
459    }
460}
461
462#[cfg(feature = "alloc")]
463impl zeroize::Zeroize for PrivatePkcs8KeyDer<'static> {
464    fn zeroize(&mut self) {
465        self.0.0.zeroize()
466    }
467}
468
469#[cfg(feature = "alloc")]
470impl PemObjectFilter for PrivatePkcs8KeyDer<'static> {
471    const KIND: SectionKind = SectionKind::PrivateKey;
472}
473
474impl<'a> From<&'a [u8]> for PrivatePkcs8KeyDer<'a> {
475    fn from(slice: &'a [u8]) -> Self {
476        Self(Der(BytesInner::Borrowed(slice)))
477    }
478}
479
480#[cfg(feature = "alloc")]
481impl From<Vec<u8>> for PrivatePkcs8KeyDer<'_> {
482    fn from(vec: Vec<u8>) -> Self {
483        Self(Der(BytesInner::Owned(vec)))
484    }
485}
486
487impl fmt::Debug for PrivatePkcs8KeyDer<'_> {
488    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
489        f.debug_tuple("PrivatePkcs8KeyDer")
490            .field(&"[secret key elided]")
491            .finish()
492    }
493}
494
495/// A trust anchor (a.k.a. root CA)
496///
497/// Traditionally, certificate verification libraries have represented trust anchors as full X.509
498/// root certificates. However, those certificates contain a lot more data than is needed for
499/// verifying certificates. The [`TrustAnchor`] representation allows an application to store
500/// just the essential elements of trust anchors.
501///
502/// The most common way to get one of these is to call [`rustls_webpki::anchor_from_trusted_cert()`].
503///
504/// [`rustls_webpki::anchor_from_trusted_cert()`]: https://docs.rs/rustls-webpki/latest/webpki/fn.anchor_from_trusted_cert.html
505#[derive(Clone, Debug, PartialEq, Eq)]
506pub struct TrustAnchor<'a> {
507    /// Value of the `subject` field of the trust anchor
508    pub subject: Der<'a>,
509    /// Value of the `subjectPublicKeyInfo` field of the trust anchor
510    pub subject_public_key_info: Der<'a>,
511    /// Value of DER-encoded `NameConstraints`, containing name constraints to the trust anchor, if any
512    pub name_constraints: Option<Der<'a>>,
513}
514
515impl TrustAnchor<'_> {
516    /// Yield a `'static` lifetime of the `TrustAnchor` by allocating owned `Der` variants
517    #[cfg(feature = "alloc")]
518    pub fn to_owned(&self) -> TrustAnchor<'static> {
519        #[cfg(not(feature = "std"))]
520        use alloc::borrow::ToOwned;
521        TrustAnchor {
522            subject: self.subject.as_ref().to_owned().into(),
523            subject_public_key_info: self.subject_public_key_info.as_ref().to_owned().into(),
524            name_constraints: self
525                .name_constraints
526                .as_ref()
527                .map(|nc| nc.as_ref().to_owned().into()),
528        }
529    }
530}
531
532/// A Certificate Revocation List; as specified in RFC 5280
533///
534/// Certificate revocation lists are identified in PEM context as `X509 CRL` and when stored in a
535/// file usually use a `.crl` extension. For more on PEM files, refer to the crate documentation.
536///
537/// ```rust
538/// # #[cfg(all(feature = "alloc", feature = "std"))] {
539/// use rustls_pki_types::{CertificateRevocationListDer, pem::PemObject};
540///
541/// // load several from a PEM file
542/// let crls: Vec<_> = CertificateRevocationListDer::pem_file_iter("tests/data/crl.pem")
543///     .unwrap()
544///     .collect();
545/// assert!(crls.len() >= 1);
546///
547/// // or one from a PEM byte slice...
548/// # let byte_slice = include_bytes!("../tests/data/crl.pem");
549/// CertificateRevocationListDer::from_pem_slice(byte_slice).unwrap();
550///
551/// // or several from a PEM byte slice
552/// let crls: Vec<_> = CertificateRevocationListDer::pem_slice_iter(byte_slice)
553///     .collect();
554/// assert!(crls.len() >= 1);
555/// # }
556/// ```
557
558#[derive(Clone, Debug, PartialEq, Eq)]
559pub struct CertificateRevocationListDer<'a>(Der<'a>);
560
561#[cfg(feature = "alloc")]
562impl PemObjectFilter for CertificateRevocationListDer<'static> {
563    const KIND: SectionKind = SectionKind::Crl;
564}
565
566impl AsRef<[u8]> for CertificateRevocationListDer<'_> {
567    fn as_ref(&self) -> &[u8] {
568        self.0.as_ref()
569    }
570}
571
572impl Deref for CertificateRevocationListDer<'_> {
573    type Target = [u8];
574
575    fn deref(&self) -> &Self::Target {
576        self.as_ref()
577    }
578}
579
580impl<'a> From<&'a [u8]> for CertificateRevocationListDer<'a> {
581    fn from(slice: &'a [u8]) -> Self {
582        Self(Der::from(slice))
583    }
584}
585
586#[cfg(feature = "alloc")]
587impl From<Vec<u8>> for CertificateRevocationListDer<'_> {
588    fn from(vec: Vec<u8>) -> Self {
589        Self(Der::from(vec))
590    }
591}
592
593/// A Certificate Signing Request; as specified in RFC 2986
594///
595/// Certificate signing requests are identified in PEM context as `CERTIFICATE REQUEST` and when stored in a
596/// file usually use a `.csr` extension. For more on PEM files, refer to the crate documentation.
597///
598/// ```rust
599/// # #[cfg(all(feature = "alloc", feature = "std"))] {
600/// use rustls_pki_types::{CertificateSigningRequestDer, pem::PemObject};
601///
602/// // load from a PEM file
603/// CertificateSigningRequestDer::from_pem_file("tests/data/csr.pem").unwrap();
604///
605/// // or from a PEM byte slice...
606/// # let byte_slice = include_bytes!("../tests/data/csr.pem");
607/// CertificateSigningRequestDer::from_pem_slice(byte_slice).unwrap();
608/// # }
609/// ```
610#[derive(Clone, Debug, PartialEq, Eq)]
611pub struct CertificateSigningRequestDer<'a>(Der<'a>);
612
613#[cfg(feature = "alloc")]
614impl PemObjectFilter for CertificateSigningRequestDer<'static> {
615    const KIND: SectionKind = SectionKind::Csr;
616}
617
618impl AsRef<[u8]> for CertificateSigningRequestDer<'_> {
619    fn as_ref(&self) -> &[u8] {
620        self.0.as_ref()
621    }
622}
623
624impl Deref for CertificateSigningRequestDer<'_> {
625    type Target = [u8];
626
627    fn deref(&self) -> &Self::Target {
628        self.as_ref()
629    }
630}
631
632impl<'a> From<&'a [u8]> for CertificateSigningRequestDer<'a> {
633    fn from(slice: &'a [u8]) -> Self {
634        Self(Der::from(slice))
635    }
636}
637
638#[cfg(feature = "alloc")]
639impl From<Vec<u8>> for CertificateSigningRequestDer<'_> {
640    fn from(vec: Vec<u8>) -> Self {
641        Self(Der::from(vec))
642    }
643}
644
645/// A DER-encoded X.509 certificate; as specified in RFC 5280
646///
647/// Certificates are identified in PEM context as `CERTIFICATE` and when stored in a
648/// file usually use a `.pem`, `.cer` or `.crt` extension. For more on PEM files, refer to the
649/// crate documentation.
650///
651/// ```rust
652/// # #[cfg(all(feature = "alloc", feature = "std"))] {
653/// use rustls_pki_types::{CertificateDer, pem::PemObject};
654///
655/// // load several from a PEM file
656/// let certs: Vec<_> = CertificateDer::pem_file_iter("tests/data/certificate.chain.pem")
657///     .unwrap()
658///     .collect();
659/// assert_eq!(certs.len(), 3);
660///
661/// // or one from a PEM byte slice...
662/// # let byte_slice = include_bytes!("../tests/data/certificate.chain.pem");
663/// CertificateDer::from_pem_slice(byte_slice).unwrap();
664///
665/// // or several from a PEM byte slice
666/// let certs: Vec<_> = CertificateDer::pem_slice_iter(byte_slice)
667///     .collect();
668/// assert_eq!(certs.len(), 3);
669/// # }
670/// ```
671#[derive(Clone, Debug, PartialEq, Eq)]
672pub struct CertificateDer<'a>(Der<'a>);
673
674impl<'a> CertificateDer<'a> {
675    /// A const constructor to create a `CertificateDer` from a slice of DER.
676    pub const fn from_slice(bytes: &'a [u8]) -> Self {
677        Self(Der::from_slice(bytes))
678    }
679}
680
681#[cfg(feature = "alloc")]
682impl PemObjectFilter for CertificateDer<'static> {
683    const KIND: SectionKind = SectionKind::Certificate;
684}
685
686impl AsRef<[u8]> for CertificateDer<'_> {
687    fn as_ref(&self) -> &[u8] {
688        self.0.as_ref()
689    }
690}
691
692impl Deref for CertificateDer<'_> {
693    type Target = [u8];
694
695    fn deref(&self) -> &Self::Target {
696        self.as_ref()
697    }
698}
699
700impl<'a> From<&'a [u8]> for CertificateDer<'a> {
701    fn from(slice: &'a [u8]) -> Self {
702        Self(Der::from(slice))
703    }
704}
705
706#[cfg(feature = "alloc")]
707impl From<Vec<u8>> for CertificateDer<'_> {
708    fn from(vec: Vec<u8>) -> Self {
709        Self(Der::from(vec))
710    }
711}
712
713impl CertificateDer<'_> {
714    /// Converts this certificate into its owned variant, unfreezing borrowed content (if any)
715    #[cfg(feature = "alloc")]
716    pub fn into_owned(self) -> CertificateDer<'static> {
717        CertificateDer(Der(self.0.0.into_owned()))
718    }
719}
720
721/// A DER-encoded SubjectPublicKeyInfo (SPKI), as specified in RFC 5280.
722#[deprecated(since = "1.7.0", note = "Prefer `SubjectPublicKeyInfoDer` instead")]
723pub type SubjectPublicKeyInfo<'a> = SubjectPublicKeyInfoDer<'a>;
724
725/// A DER-encoded SubjectPublicKeyInfo (SPKI), as specified in RFC 5280.
726///
727/// Public keys are identified in PEM context as a `PUBLIC KEY`.
728///
729/// ```rust
730/// # #[cfg(all(feature = "alloc", feature = "std"))] {
731/// use rustls_pki_types::{SubjectPublicKeyInfoDer, pem::PemObject};
732///
733/// // load from a PEM file
734/// SubjectPublicKeyInfoDer::from_pem_file("tests/data/spki.pem").unwrap();
735///
736/// // or from a PEM byte slice...
737/// # let byte_slice = include_bytes!("../tests/data/spki.pem");
738/// SubjectPublicKeyInfoDer::from_pem_slice(byte_slice).unwrap();
739/// # }
740/// ```
741#[derive(Clone, Debug, PartialEq, Eq)]
742pub struct SubjectPublicKeyInfoDer<'a>(Der<'a>);
743
744#[cfg(feature = "alloc")]
745impl PemObjectFilter for SubjectPublicKeyInfoDer<'static> {
746    const KIND: SectionKind = SectionKind::PublicKey;
747}
748
749impl AsRef<[u8]> for SubjectPublicKeyInfoDer<'_> {
750    fn as_ref(&self) -> &[u8] {
751        self.0.as_ref()
752    }
753}
754
755impl Deref for SubjectPublicKeyInfoDer<'_> {
756    type Target = [u8];
757
758    fn deref(&self) -> &Self::Target {
759        self.as_ref()
760    }
761}
762
763impl<'a> From<&'a [u8]> for SubjectPublicKeyInfoDer<'a> {
764    fn from(slice: &'a [u8]) -> Self {
765        Self(Der::from(slice))
766    }
767}
768
769#[cfg(feature = "alloc")]
770impl From<Vec<u8>> for SubjectPublicKeyInfoDer<'_> {
771    fn from(vec: Vec<u8>) -> Self {
772        Self(Der::from(vec))
773    }
774}
775
776impl SubjectPublicKeyInfoDer<'_> {
777    /// Converts this SubjectPublicKeyInfo into its owned variant, unfreezing borrowed content (if any)
778    #[cfg(feature = "alloc")]
779    pub fn into_owned(self) -> SubjectPublicKeyInfoDer<'static> {
780        SubjectPublicKeyInfoDer(Der(self.0.0.into_owned()))
781    }
782}
783
784/// A TLS-encoded Encrypted Client Hello (ECH) configuration list (`ECHConfigList`); as specified in
785/// [draft-ietf-tls-esni-18 ยง4](https://datatracker.ietf.org/doc/html/draft-ietf-tls-esni-18#section-4)
786#[derive(Clone, Eq, PartialEq)]
787pub struct EchConfigListBytes<'a>(BytesInner<'a>);
788
789impl EchConfigListBytes<'_> {
790    /// Converts this config into its owned variant, unfreezing borrowed content (if any)
791    #[cfg(feature = "alloc")]
792    pub fn into_owned(self) -> EchConfigListBytes<'static> {
793        EchConfigListBytes(self.0.into_owned())
794    }
795}
796
797#[cfg(feature = "alloc")]
798impl EchConfigListBytes<'static> {
799    /// Convert an iterator over PEM items into an `EchConfigListBytes` and private key.
800    ///
801    /// This handles the "ECHConfig file" format specified in
802    /// <https://www.ietf.org/archive/id/draft-farrell-tls-pemesni-05.html#name-echconfig-file>
803    ///
804    /// Use it like:
805    ///
806    /// ```rust
807    /// # #[cfg(all(feature = "alloc", feature = "std"))] {
808    /// # use rustls_pki_types::{EchConfigListBytes, pem::PemObject};
809    /// let (config, key) = EchConfigListBytes::config_and_key_from_iter(
810    ///     PemObject::pem_file_iter("tests/data/ech.pem").unwrap()
811    /// ).unwrap();
812    /// # }
813    /// ```
814    pub fn config_and_key_from_iter(
815        iter: impl Iterator<Item = Result<(SectionKind, Vec<u8>), pem::Error>>,
816    ) -> Result<(Self, PrivatePkcs8KeyDer<'static>), pem::Error> {
817        let mut key = None;
818        let mut config = None;
819
820        for item in iter {
821            let (kind, data) = item?;
822            match kind {
823                SectionKind::PrivateKey => {
824                    key = PrivatePkcs8KeyDer::from_pem(kind, data);
825                }
826                SectionKind::EchConfigList => {
827                    config = Self::from_pem(kind, data);
828                }
829                _ => continue,
830            };
831
832            if let (Some(_key), Some(_config)) = (&key, &config) {
833                return Ok((config.take().unwrap(), key.take().unwrap()));
834            }
835        }
836
837        Err(pem::Error::NoItemsFound)
838    }
839}
840
841#[cfg(feature = "alloc")]
842impl PemObjectFilter for EchConfigListBytes<'static> {
843    const KIND: SectionKind = SectionKind::EchConfigList;
844}
845
846impl fmt::Debug for EchConfigListBytes<'_> {
847    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
848        hex(f, self.as_ref())
849    }
850}
851
852impl AsRef<[u8]> for EchConfigListBytes<'_> {
853    fn as_ref(&self) -> &[u8] {
854        self.0.as_ref()
855    }
856}
857
858impl Deref for EchConfigListBytes<'_> {
859    type Target = [u8];
860
861    fn deref(&self) -> &Self::Target {
862        self.as_ref()
863    }
864}
865
866impl<'a> From<&'a [u8]> for EchConfigListBytes<'a> {
867    fn from(slice: &'a [u8]) -> Self {
868        Self(BytesInner::Borrowed(slice))
869    }
870}
871
872#[cfg(feature = "alloc")]
873impl From<Vec<u8>> for EchConfigListBytes<'_> {
874    fn from(vec: Vec<u8>) -> Self {
875        Self(BytesInner::Owned(vec))
876    }
877}
878
879/// An abstract signature verification algorithm.
880///
881/// One of these is needed per supported pair of public key type (identified
882/// with `public_key_alg_id()`) and `signatureAlgorithm` (identified with
883/// `signature_alg_id()`).  Note that both of these `AlgorithmIdentifier`s include
884/// the parameters encoding, so separate `SignatureVerificationAlgorithm`s are needed
885/// for each possible public key or signature parameters.
886///
887/// Debug implementations should list the public key algorithm identifier and
888/// signature algorithm identifier in human friendly form (i.e. not encoded bytes),
889/// along with the name of the implementing library (to distinguish different
890/// implementations of the same algorithms).
891pub trait SignatureVerificationAlgorithm: Send + Sync + fmt::Debug {
892    /// Verify a signature.
893    ///
894    /// `public_key` is the `subjectPublicKey` value from a `SubjectPublicKeyInfo` encoding
895    /// and is untrusted.  The key's `subjectPublicKeyInfo` matches the [`AlgorithmIdentifier`]
896    /// returned by `public_key_alg_id()`.
897    ///
898    /// `message` is the data over which the signature was allegedly computed.
899    /// It is not hashed; implementations of this trait function must do hashing
900    /// if that is required by the algorithm they implement.
901    ///
902    /// `signature` is the signature allegedly over `message`.
903    ///
904    /// Return `Ok(())` only if `signature` is a valid signature on `message`.
905    ///
906    /// Return `Err(InvalidSignature)` if the signature is invalid, including if the `public_key`
907    /// encoding is invalid.  There is no need or opportunity to produce errors
908    /// that are more specific than this.
909    fn verify_signature(
910        &self,
911        public_key: &[u8],
912        message: &[u8],
913        signature: &[u8],
914    ) -> Result<(), InvalidSignature>;
915
916    /// Return the `AlgorithmIdentifier` that must equal a public key's
917    /// `subjectPublicKeyInfo` value for this `SignatureVerificationAlgorithm`
918    /// to be used for signature verification.
919    fn public_key_alg_id(&self) -> AlgorithmIdentifier;
920
921    /// Return the `AlgorithmIdentifier` that must equal the `signatureAlgorithm` value
922    /// on the data to be verified for this `SignatureVerificationAlgorithm` to be used
923    /// for signature verification.
924    fn signature_alg_id(&self) -> AlgorithmIdentifier;
925
926    /// Return `true` if this is backed by a FIPS-approved implementation.
927    fn fips(&self) -> bool {
928        false
929    }
930}
931
932/// A detail-less error when a signature is not valid.
933#[derive(Debug, Copy, Clone)]
934pub struct InvalidSignature;
935
936/// A timestamp, tracking the number of non-leap seconds since the Unix epoch.
937///
938/// The Unix epoch is defined January 1, 1970 00:00:00 UTC.
939#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
940pub struct UnixTime(u64);
941
942impl UnixTime {
943    /// The current time, as a `UnixTime`
944    #[cfg(any(
945        all(
946            feature = "std",
947            not(all(target_family = "wasm", target_os = "unknown"))
948        ),
949        all(target_family = "wasm", target_os = "unknown", feature = "web")
950    ))]
951    pub fn now() -> Self {
952        Self::since_unix_epoch(
953            SystemTime::now()
954                .duration_since(SystemTime::UNIX_EPOCH)
955                .unwrap(), // Safe: this code did not exist before 1970.
956        )
957    }
958
959    /// Convert a `Duration` since the start of 1970 to a `UnixTime`
960    ///
961    /// The `duration` must be relative to the Unix epoch.
962    pub fn since_unix_epoch(duration: Duration) -> Self {
963        Self(duration.as_secs())
964    }
965
966    /// Number of seconds since the Unix epoch
967    pub fn as_secs(&self) -> u64 {
968        self.0
969    }
970}
971
972/// DER-encoded data, either owned or borrowed
973///
974/// This wrapper type is used to represent DER-encoded data in a way that is agnostic to whether
975/// the data is owned (by a `Vec<u8>`) or borrowed (by a `&[u8]`). Support for the owned
976/// variant is only available when the `alloc` feature is enabled.
977#[derive(Clone, Eq, PartialEq)]
978pub struct Der<'a>(BytesInner<'a>);
979
980impl<'a> Der<'a> {
981    /// A const constructor to create a `Der` from a borrowed slice
982    pub const fn from_slice(der: &'a [u8]) -> Self {
983        Self(BytesInner::Borrowed(der))
984    }
985}
986
987impl AsRef<[u8]> for Der<'_> {
988    fn as_ref(&self) -> &[u8] {
989        self.0.as_ref()
990    }
991}
992
993impl Deref for Der<'_> {
994    type Target = [u8];
995
996    fn deref(&self) -> &Self::Target {
997        self.as_ref()
998    }
999}
1000
1001impl<'a> From<&'a [u8]> for Der<'a> {
1002    fn from(slice: &'a [u8]) -> Self {
1003        Self(BytesInner::Borrowed(slice))
1004    }
1005}
1006
1007#[cfg(feature = "alloc")]
1008impl From<Vec<u8>> for Der<'static> {
1009    fn from(vec: Vec<u8>) -> Self {
1010        Self(BytesInner::Owned(vec))
1011    }
1012}
1013
1014impl fmt::Debug for Der<'_> {
1015    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1016        hex(f, self.as_ref())
1017    }
1018}
1019
1020#[derive(Debug, Clone)]
1021enum BytesInner<'a> {
1022    #[cfg(feature = "alloc")]
1023    Owned(Vec<u8>),
1024    Borrowed(&'a [u8]),
1025}
1026
1027#[cfg(feature = "alloc")]
1028impl BytesInner<'_> {
1029    fn into_owned(self) -> BytesInner<'static> {
1030        BytesInner::Owned(match self {
1031            Self::Owned(vec) => vec,
1032            Self::Borrowed(slice) => slice.to_vec(),
1033        })
1034    }
1035}
1036
1037#[cfg(feature = "alloc")]
1038impl zeroize::Zeroize for BytesInner<'static> {
1039    fn zeroize(&mut self) {
1040        match self {
1041            BytesInner::Owned(vec) => vec.zeroize(),
1042            BytesInner::Borrowed(_) => (),
1043        }
1044    }
1045}
1046
1047impl AsRef<[u8]> for BytesInner<'_> {
1048    fn as_ref(&self) -> &[u8] {
1049        match &self {
1050            #[cfg(feature = "alloc")]
1051            BytesInner::Owned(vec) => vec.as_ref(),
1052            BytesInner::Borrowed(slice) => slice,
1053        }
1054    }
1055}
1056
1057impl PartialEq for BytesInner<'_> {
1058    fn eq(&self, other: &Self) -> bool {
1059        self.as_ref() == other.as_ref()
1060    }
1061}
1062
1063impl Eq for BytesInner<'_> {}
1064
1065// Format an iterator of u8 into a hex string
1066fn hex<'a>(f: &mut fmt::Formatter<'_>, payload: impl IntoIterator<Item = &'a u8>) -> fmt::Result {
1067    for (i, b) in payload.into_iter().enumerate() {
1068        if i == 0 {
1069            write!(f, "0x")?;
1070        }
1071        write!(f, "{:02x}", b)?;
1072    }
1073    Ok(())
1074}
1075
1076#[cfg(all(test, feature = "std"))]
1077mod tests {
1078    use super::*;
1079
1080    #[test]
1081    fn der_debug() {
1082        let der = Der::from_slice(&[0x01, 0x02, 0x03]);
1083        assert_eq!(format!("{:?}", der), "0x010203");
1084    }
1085
1086    #[test]
1087    fn alg_id_debug() {
1088        let alg_id = AlgorithmIdentifier::from_slice(&[0x01, 0x02, 0x03]);
1089        assert_eq!(format!("{:?}", alg_id), "0x010203");
1090    }
1091
1092    #[test]
1093    fn bytes_inner_equality() {
1094        let owned_a = BytesInner::Owned(vec![1, 2, 3]);
1095        let owned_b = BytesInner::Owned(vec![4, 5]);
1096        let borrowed_a = BytesInner::Borrowed(&[1, 2, 3]);
1097        let borrowed_b = BytesInner::Borrowed(&[99]);
1098
1099        // Self-equality.
1100        assert_eq!(owned_a, owned_a);
1101        assert_eq!(owned_b, owned_b);
1102        assert_eq!(borrowed_a, borrowed_a);
1103        assert_eq!(borrowed_b, borrowed_b);
1104
1105        // Borrowed vs Owned equality
1106        assert_eq!(owned_a, borrowed_a);
1107        assert_eq!(borrowed_a, owned_a);
1108
1109        // Owned inequality
1110        assert_ne!(owned_a, owned_b);
1111        assert_ne!(owned_b, owned_a);
1112
1113        // Borrowed inequality
1114        assert_ne!(borrowed_a, borrowed_b);
1115        assert_ne!(borrowed_b, borrowed_a);
1116
1117        // Borrowed vs Owned inequality
1118        assert_ne!(owned_a, borrowed_b);
1119        assert_ne!(borrowed_b, owned_a);
1120    }
1121}