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