webpki/
webpki.rs

1// Copyright 2015 Brian Smith.
2//
3// Permission to use, copy, modify, and/or distribute this software for any
4// purpose with or without fee is hereby granted, provided that the above
5// copyright notice and this permission notice appear in all copies.
6//
7// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
8// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
10// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15//! webpki: Web PKI X.509 Certificate Validation.
16//!
17//! See `EndEntityCert`'s documentation for a description of the certificate
18//! processing steps necessary for a TLS connection.
19
20#![doc(html_root_url = "https://briansmith.org/rustdoc/")]
21#![cfg_attr(not(feature = "std"), no_std)]
22#![allow(missing_debug_implementations)]
23// `#[derive(...)]` uses `#[allow(unused_qualifications)]` internally.
24#![deny(unused_qualifications)]
25#![forbid(
26    anonymous_parameters,
27    box_pointers,
28    missing_copy_implementations,
29    missing_docs,
30    trivial_casts,
31    trivial_numeric_casts,
32    unsafe_code,
33    unstable_features,
34    unused_extern_crates,
35    unused_import_braces,
36    unused_results,
37    variant_size_differences,
38    warnings
39)]
40
41#[cfg(all(test, not(feature = "std")))]
42#[macro_use]
43extern crate std;
44
45#[macro_use]
46mod der;
47
48mod calendar;
49mod cert;
50mod error;
51mod name;
52mod signed_data;
53mod time;
54
55#[cfg(feature = "trust_anchor_util")]
56pub mod trust_anchor_util;
57
58mod verify_cert;
59
60pub use error::Error;
61pub use name::{DNSNameRef, InvalidDNSNameError};
62
63#[cfg(feature = "std")]
64pub use name::DNSName;
65
66pub use signed_data::{
67    SignatureAlgorithm, ECDSA_P256_SHA256, ECDSA_P256_SHA384, ECDSA_P384_SHA256, ECDSA_P384_SHA384,
68    ED25519, RSA_PKCS1_2048_8192_SHA256, RSA_PKCS1_2048_8192_SHA384, RSA_PKCS1_2048_8192_SHA512,
69    RSA_PKCS1_3072_8192_SHA384, RSA_PSS_2048_8192_SHA256_LEGACY_KEY,
70    RSA_PSS_2048_8192_SHA384_LEGACY_KEY, RSA_PSS_2048_8192_SHA512_LEGACY_KEY,
71};
72
73pub use time::Time;
74
75/// An end-entity certificate.
76///
77/// Server certificate processing in a TLS connection consists of several
78/// steps. All of these steps are necessary:
79///
80/// * `EndEntityCert.verify_is_valid_tls_server_cert`: Verify that the server's
81///   certificate is currently valid *for use by a TLS server*.
82/// * `EndEntityCert.verify_is_valid_for_dns_name`: Verify that the server's
83///   certificate is valid for the host that is being connected to.
84/// * `EndEntityCert.verify_signature`: Verify that the signature of server's
85///   `ServerKeyExchange` message is valid for the server's certificate.
86///
87/// Client certificate processing in a TLS connection consists of analogous
88/// steps. All of these steps are necessary:
89///
90/// * `EndEntityCert.verify_is_valid_tls_client_cert`: Verify that the client's
91///   certificate is currently valid *for use by a TLS client*.
92/// * `EndEntityCert.verify_is_valid_for_dns_name` or
93///   `EndEntityCert.verify_is_valid_for_at_least_one_dns_name`: Verify that the
94///   client's certificate is valid for the identity or identities used to
95///   identify the client. (Currently client authentication only works when the
96///   client is identified by one or more DNS hostnames.)
97/// * `EndEntityCert.verify_signature`: Verify that the client's signature in
98///   its `CertificateVerify` message is valid using the public key from the
99///   client's certificate.
100///
101/// Although it would be less error-prone to combine all these steps into a
102/// single function call, some significant optimizations are possible if the
103/// three steps are processed separately (in parallel). It does not matter much
104/// which order the steps are done in, but **all of these steps must completed
105/// before application data is sent and before received application data is
106/// processed**. `EndEntityCert::from` is an inexpensive operation and is
107/// deterministic, so if these tasks are done in multiple threads, it is
108/// probably best to just call `EndEntityCert::from` multiple times (before each
109/// operation) for the same DER-encoded ASN.1 certificate bytes.
110pub struct EndEntityCert<'a> {
111    inner: cert::Cert<'a>,
112}
113
114impl<'a> EndEntityCert<'a> {
115    /// Parse the ASN.1 DER-encoded X.509 encoding of the certificate
116    /// `cert_der`.
117    pub fn from(cert_der: &'a [u8]) -> Result<Self, Error> {
118        Ok(Self {
119            inner: cert::parse_cert(
120                untrusted::Input::from(cert_der),
121                cert::EndEntityOrCA::EndEntity,
122            )?,
123        })
124    }
125
126    /// Verifies that the end-entity certificate is valid for use by a TLS
127    /// server.
128    ///
129    /// `supported_sig_algs` is the list of signature algorithms that are
130    /// trusted for use in certificate signatures; the end-entity certificate's
131    /// public key is not validated against this list. `trust_anchors` is the
132    /// list of root CAs to trust. `intermediate_certs` is the sequence of
133    /// intermediate certificates that the server sent in the TLS handshake.
134    /// `time` is the time for which the validation is effective (usually the
135    /// current time).
136    pub fn verify_is_valid_tls_server_cert(
137        &self, supported_sig_algs: &[&SignatureAlgorithm],
138        &TLSServerTrustAnchors(trust_anchors): &TLSServerTrustAnchors,
139        intermediate_certs: &[&[u8]], time: Time,
140    ) -> Result<(), Error> {
141        verify_cert::build_chain(
142            verify_cert::EKU_SERVER_AUTH,
143            supported_sig_algs,
144            trust_anchors,
145            intermediate_certs,
146            &self.inner,
147            time,
148            0,
149        )
150    }
151
152    /// Verifies that the end-entity certificate is valid for use by a TLS
153    /// client.
154    ///
155    /// If the certificate is not valid for any of the given names then this
156    /// fails with `Error::CertNotValidForName`.
157    ///
158    /// `supported_sig_algs` is the list of signature algorithms that are
159    /// trusted for use in certificate signatures; the end-entity certificate's
160    /// public key is not validated against this list. `trust_anchors` is the
161    /// list of root CAs to trust. `intermediate_certs` is the sequence of
162    /// intermediate certificates that the client sent in the TLS handshake.
163    /// `cert` is the purported end-entity certificate of the client. `time` is
164    /// the time for which the validation is effective (usually the current
165    /// time).
166    pub fn verify_is_valid_tls_client_cert(
167        &self, supported_sig_algs: &[&SignatureAlgorithm],
168        &TLSClientTrustAnchors(trust_anchors): &TLSClientTrustAnchors,
169        intermediate_certs: &[&[u8]], time: Time,
170    ) -> Result<(), Error> {
171        verify_cert::build_chain(
172            verify_cert::EKU_CLIENT_AUTH,
173            supported_sig_algs,
174            trust_anchors,
175            intermediate_certs,
176            &self.inner,
177            time,
178            0,
179        )
180    }
181
182    /// Verifies that the certificate is valid for the given DNS host name.
183    pub fn verify_is_valid_for_dns_name(&self, dns_name: DNSNameRef) -> Result<(), Error> {
184        name::verify_cert_dns_name(&self, dns_name)
185    }
186
187    /// Verifies that the certificate is valid for at least one of the given DNS
188    /// host names.
189    ///
190    /// If the certificate is not valid for any of the given names then this
191    /// fails with `Error::CertNotValidForName`. Otherwise the DNS names for
192    /// which the certificate is valid are returned.
193    ///
194    /// Requires the `std` default feature; i.e. this isn't available in
195    /// `#![no_std]` configurations.
196    #[cfg(feature = "std")]
197    pub fn verify_is_valid_for_at_least_one_dns_name<'names, Names>(
198        &self, dns_names: Names,
199    ) -> Result<Vec<DNSNameRef<'names>>, Error>
200    where
201        Names: Iterator<Item = DNSNameRef<'names>>,
202    {
203        let result: Vec<DNSNameRef<'names>> = dns_names
204            .filter(|n| self.verify_is_valid_for_dns_name(*n).is_ok())
205            .collect();
206        if result.is_empty() {
207            return Err(Error::CertNotValidForName);
208        }
209        Ok(result)
210    }
211
212    /// Verifies the signature `signature` of message `msg` using the
213    /// certificate's public key.
214    ///
215    /// `signature_alg` is the algorithm to use to
216    /// verify the signature; the certificate's public key is verified to be
217    /// compatible with this algorithm.
218    ///
219    /// For TLS 1.2, `signature` corresponds to TLS's
220    /// `DigitallySigned.signature` and `signature_alg` corresponds to TLS's
221    /// `DigitallySigned.algorithm` of TLS type `SignatureAndHashAlgorithm`. In
222    /// TLS 1.2 a single `SignatureAndHashAlgorithm` may map to multiple
223    /// `SignatureAlgorithm`s. For example, a TLS 1.2
224    /// `ignatureAndHashAlgorithm` of (ECDSA, SHA-256) may map to any or all
225    /// of {`ECDSA_P256_SHA256`, `ECDSA_P384_SHA256`}, depending on how the TLS
226    /// implementation is configured.
227    ///
228    /// For current TLS 1.3 drafts, `signature_alg` corresponds to TLS's
229    /// `algorithm` fields of type `SignatureScheme`. There is (currently) a
230    /// one-to-one correspondence between TLS 1.3's `SignatureScheme` and
231    /// `SignatureAlgorithm`.
232    pub fn verify_signature(
233        &self, signature_alg: &SignatureAlgorithm, msg: &[u8], signature: &[u8],
234    ) -> Result<(), Error> {
235        signed_data::verify_signature(
236            signature_alg,
237            self.inner.spki.value(),
238            untrusted::Input::from(msg),
239            untrusted::Input::from(signature),
240        )
241    }
242}
243
244/// A trust anchor (a.k.a. root CA).
245///
246/// Traditionally, certificate verification libraries have represented trust
247/// anchors as full X.509 root certificates. However, those certificates
248/// contain a lot more data than is needed for verifying certificates. The
249/// `TrustAnchor` representation allows an application to store just the
250/// essential elements of trust anchors. The `webpki::trust_anchor_util` module
251/// provides functions for converting X.509 certificates to to the minimized
252/// `TrustAnchor` representation, either at runtime or in a build script.
253#[derive(Debug)]
254pub struct TrustAnchor<'a> {
255    /// The value of the `subject` field of the trust anchor.
256    pub subject: &'a [u8],
257
258    /// The value of the `subjectPublicKeyInfo` field of the trust anchor.
259    pub spki: &'a [u8],
260
261    /// The value of a DER-encoded NameConstraints, containing name
262    /// constraints to apply to the trust anchor, if any.
263    pub name_constraints: Option<&'a [u8]>,
264}
265
266/// Trust anchors which may be used for authenticating servers.
267#[derive(Debug)]
268pub struct TLSServerTrustAnchors<'a>(pub &'a [TrustAnchor<'a>]);
269
270/// Trust anchors which may be used for authenticating clients.
271#[derive(Debug)]
272pub struct TLSClientTrustAnchors<'a>(pub &'a [TrustAnchor<'a>]);