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]
43 extern crate std;
44 
45 #[macro_use]
46 mod der;
47 
48 mod calendar;
49 mod cert;
50 mod error;
51 mod name;
52 mod signed_data;
53 mod time;
54 
55 #[cfg(feature = "trust_anchor_util")]
56 pub mod trust_anchor_util;
57 
58 mod verify_cert;
59 
60 pub use error::Error;
61 pub use name::{DNSNameRef, InvalidDNSNameError};
62 
63 #[cfg(feature = "std")]
64 pub use name::DNSName;
65 
66 pub 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 
73 pub 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.
110 pub struct EndEntityCert<'a> {
111     inner: cert::Cert<'a>,
112 }
113 
114 impl<'a> EndEntityCert<'a> {
115     /// Parse the ASN.1 DER-encoded X.509 encoding of the certificate
116     /// `cert_der`.
from(cert_der: &'a [u8]) -> Result<Self, Error>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).
verify_is_valid_tls_server_cert( &self, supported_sig_algs: &[&SignatureAlgorithm], &TLSServerTrustAnchors(trust_anchors): &TLSServerTrustAnchors, intermediate_certs: &[&[u8]], time: Time, ) -> Result<(), Error>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).
verify_is_valid_tls_client_cert( &self, supported_sig_algs: &[&SignatureAlgorithm], &TLSClientTrustAnchors(trust_anchors): &TLSClientTrustAnchors, intermediate_certs: &[&[u8]], time: Time, ) -> Result<(), Error>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.
verify_is_valid_for_dns_name(&self, dns_name: DNSNameRef) -> Result<(), Error>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")]
verify_is_valid_for_at_least_one_dns_name<'names, Names>( &self, dns_names: Names, ) -> Result<Vec<DNSNameRef<'names>>, Error> where Names: Iterator<Item = DNSNameRef<'names>>,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`.
verify_signature( &self, signature_alg: &SignatureAlgorithm, msg: &[u8], signature: &[u8], ) -> Result<(), Error>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)]
254 pub 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)]
268 pub struct TLSServerTrustAnchors<'a>(pub &'a [TrustAnchor<'a>]);
269 
270 /// Trust anchors which may be used for authenticating clients.
271 #[derive(Debug)]
272 pub struct TLSClientTrustAnchors<'a>(pub &'a [TrustAnchor<'a>]);
273