From ccf88cd3f5a1010fda90023006d6acc7eb3a3123 Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Tue, 29 Aug 2023 18:13:07 -0700 Subject: [PATCH] Revert main branch crate contents to the 0.22.0 release contents. Reset the crate contents (sources, tests, etc.) to what they were at that commit, while retaining the newer CI configuration. The changes since the 0.22.0 release were primarily intended to accomplish two goals: * Fix and improve the GitHub Actions configuration. * Prepare a 0.21.5 release that was backward compatible with 0.21.4 but which also contained the improvements that were in 0.22.0. 0.21.5 was never released and will not be released. Therefore all of the noise to facilitate the 0.21.5 release can just be deleted, as long as we leave the CI changes. The exact commands I used were: ``` git checkout \ 0b7cbf2d327d7665d9d06072bf46b2e7ca05f065 \ -- \ Cargo.toml \ LICENSE \ README.md \ src \ tests \ third-party git rm src/trust_anchor_util.rs ``` (Commit 0b7cbf2d327d7665d9d06072bf46b2e7ca05f065 was the commit from which 0.22.0 was released. `trust_anchor_utils.rs` was not in 0.22.0 and the `git checkout` didn't delete it.) I left `tests/name_tests.rs` that wasn't in 0.22.0 since those tests were actually intended to test API changes from 0.22.0. --- Cargo.toml | 17 ++++---------- src/calendar.rs | 2 +- src/cert.rs | 12 +++++----- src/der.rs | 32 ++++++++++++------------- src/end_entity.rs | 50 +++++++++++++++++++++++++++++----------- src/error.rs | 6 ++--- src/lib.rs | 28 ++++++++++++++++------ src/name/dns_name.rs | 2 +- src/name/ip_address.rs | 6 ++--- src/name/verify.rs | 12 +++++----- src/signed_data.rs | 22 +++++++++--------- src/time.rs | 15 +++--------- src/trust_anchor.rs | 12 +++++----- src/trust_anchor_util.rs | 23 ------------------ src/verify_cert.rs | 16 ++++++------- tests/dns_name_tests.rs | 4 ++-- tests/integration.rs | 4 ++-- 17 files changed, 128 insertions(+), 135 deletions(-) delete mode 100644 src/trust_anchor_util.rs diff --git a/Cargo.toml b/Cargo.toml index 4be84684..42bc7bba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ license-file = "LICENSE" name = "webpki" readme = "README.md" repository = "https://github.com/briansmith/webpki" -version = "0.21.4" +version = "0.22.0" include = [ "Cargo.toml", @@ -33,18 +33,13 @@ include = [ "src/calendar.rs", "src/cert.rs", "src/der.rs", - "src/end_entity.rs", - "src/error.rs", "src/name.rs", - "src/name/dns_name.rs", - "src/name/ip_address.rs", - "src/name/verify.rs", + "src/error.rs", "src/signed_data.rs", "src/time.rs", - "src/trust_anchor.rs", "src/trust_anchor_util.rs", "src/verify_cert.rs", - "src/lib.rs", + "src/webpki.rs", "src/data/**/*", @@ -68,19 +63,15 @@ all-features = true name = "webpki" [features] -# TODO: In the next release, make this non-default. -default = ["std"] alloc = ["ring/alloc"] std = ["alloc"] -# TODO: In the next release, remove this. -trust_anchor_util = ["std"] [dependencies] ring = { version = "0.16.19", default-features = false } untrusted = "0.7.1" [dev-dependencies] -base64 = "0.13" +base64 = "0.9.1" [profile.bench] opt-level = 3 diff --git a/src/calendar.rs b/src/calendar.rs index 0abe938b..f1d2c444 100644 --- a/src/calendar.rs +++ b/src/calendar.rs @@ -67,7 +67,7 @@ fn days_before_year_since_unix_epoch(year: u64) -> Result { // Unix epoch. It is likely that other software won't deal well with // certificates that have dates before the epoch. if year < 1970 { - return Err(Error::BadDERTime); + return Err(Error::BadDerTime); } let days_before_year_ad = days_before_year_ad(year); debug_assert!(days_before_year_ad >= DAYS_BEFORE_UNIX_EPOCH_AD); diff --git a/src/cert.rs b/src/cert.rs index 75e022a1..7c76f2e1 100644 --- a/src/cert.rs +++ b/src/cert.rs @@ -49,16 +49,16 @@ pub(crate) fn parse_cert_internal<'a>( ee_or_ca: EndEntityOrCa<'a>, serial_number: fn(input: &mut untrusted::Reader<'_>) -> Result<(), Error>, ) -> Result, Error> { - let (tbs, signed_data) = cert_der.read_all(Error::BadDER, |cert_der| { + let (tbs, signed_data) = cert_der.read_all(Error::BadDer, |cert_der| { der::nested( cert_der, der::Tag::Sequence, - Error::BadDER, + Error::BadDer, signed_data::parse_signed_data, ) })?; - tbs.read_all(Error::BadDER, |tbs| { + tbs.read_all(Error::BadDer, |tbs| { version3(tbs)?; serial_number(tbs)?; @@ -110,7 +110,7 @@ pub(crate) fn parse_cert_internal<'a>( tagged, der::Tag::Sequence, der::Tag::Sequence, - Error::BadDER, + Error::BadDer, |extension| { let extn_id = der::expect_tag_and_get_value(extension, der::Tag::OID)?; let critical = der::optional_boolean(extension)?; @@ -154,7 +154,7 @@ pub fn certificate_serial_number(input: &mut untrusted::Reader) -> Result<(), Er let value = der::positive_integer(input)?; if value.big_endian_without_leading_zero().len() > 20 { - return Err(Error::BadDER); + return Err(Error::BadDer); } Ok(()) } @@ -215,7 +215,7 @@ fn remember_extension<'a>( } None => { // All the extensions that we care about are wrapped in a SEQUENCE. - let sequence_value = value.read_all(Error::BadDER, |value| { + let sequence_value = value.read_all(Error::BadDer, |value| { der::expect_tag_and_get_value(value, der::Tag::Sequence) })?; *out = Some(sequence_value); diff --git a/src/der.rs b/src/der.rs index c4cad81b..43d0847d 100644 --- a/src/der.rs +++ b/src/der.rs @@ -23,7 +23,7 @@ pub fn expect_tag_and_get_value<'a>( input: &mut untrusted::Reader<'a>, tag: Tag, ) -> Result, Error> { - ring::io::der::expect_tag_and_get_value(input, tag).map_err(|_| Error::BadDER) + ring::io::der::expect_tag_and_get_value(input, tag).map_err(|_| Error::BadDer) } pub struct Value<'a> { @@ -39,7 +39,7 @@ impl<'a> Value<'a> { pub fn expect_tag<'a>(input: &mut untrusted::Reader<'a>, tag: Tag) -> Result, Error> { let (actual_tag, value) = read_tag_and_get_value(input)?; if usize::from(tag) != usize::from(actual_tag) { - return Err(Error::BadDER); + return Err(Error::BadDer); } Ok(Value { value }) @@ -49,7 +49,7 @@ pub fn expect_tag<'a>(input: &mut untrusted::Reader<'a>, tag: Tag) -> Result( input: &mut untrusted::Reader<'a>, ) -> Result<(u8, untrusted::Input<'a>), Error> { - ring::io::der::read_tag_and_get_value(input).map_err(|_| Error::BadDER) + ring::io::der::read_tag_and_get_value(input).map_err(|_| Error::BadDer) } // TODO: investigate taking decoder as a reference to reduce generated code @@ -78,10 +78,10 @@ where pub fn bit_string_with_no_unused_bits<'a>( input: &mut untrusted::Reader<'a>, ) -> Result, Error> { - nested(input, Tag::BitString, Error::BadDER, |value| { - let unused_bits_at_end = value.read_byte().map_err(|_| Error::BadDER)?; + nested(input, Tag::BitString, Error::BadDer, |value| { + let unused_bits_at_end = value.read_byte().map_err(|_| Error::BadDer)?; if unused_bits_at_end != 0 { - return Err(Error::BadDER); + return Err(Error::BadDer); } Ok(value.read_bytes_to_end()) }) @@ -93,21 +93,21 @@ pub fn optional_boolean(input: &mut untrusted::Reader) -> Result { if !input.peek(Tag::Boolean.into()) { return Ok(false); } - nested(input, Tag::Boolean, Error::BadDER, |input| { + nested(input, Tag::Boolean, Error::BadDer, |input| { match input.read_byte() { Ok(0xff) => Ok(true), Ok(0x00) => Ok(false), - _ => Err(Error::BadDER), + _ => Err(Error::BadDer), } }) } pub fn positive_integer<'a>(input: &'a mut untrusted::Reader) -> Result, Error> { - ring::io::der::positive_integer(input).map_err(|_| Error::BadDER) + ring::io::der::positive_integer(input).map_err(|_| Error::BadDer) } pub fn small_nonnegative_integer(input: &mut untrusted::Reader) -> Result { - ring::io::der::small_nonnegative_integer(input).map_err(|_| Error::BadDER) + ring::io::der::small_nonnegative_integer(input).map_err(|_| Error::BadDer) } pub fn time_choice(input: &mut untrusted::Reader) -> Result { @@ -120,11 +120,11 @@ pub fn time_choice(input: &mut untrusted::Reader) -> Result { fn read_digit(inner: &mut untrusted::Reader) -> Result { const DIGIT: core::ops::RangeInclusive = b'0'..=b'9'; - let b = inner.read_byte().map_err(|_| Error::BadDERTime)?; + let b = inner.read_byte().map_err(|_| Error::BadDerTime)?; if DIGIT.contains(&b) { return Ok(u64::from(b - DIGIT.start())); } - Err(Error::BadDERTime) + Err(Error::BadDerTime) } fn read_two_digits(inner: &mut untrusted::Reader, min: u64, max: u64) -> Result { @@ -132,12 +132,12 @@ pub fn time_choice(input: &mut untrusted::Reader) -> Result { let lo = read_digit(inner)?; let value = (hi * 10) + lo; if value < min || value > max { - return Err(Error::BadDERTime); + return Err(Error::BadDerTime); } Ok(value) } - nested(input, expected_tag, Error::BadDER, |value| { + nested(input, expected_tag, Error::BadDer, |value| { let (year_hi, year_lo) = if is_utc_time { let lo = read_two_digits(value, 0, 99)?; let hi = if lo >= 50 { 19 } else { 20 }; @@ -156,9 +156,9 @@ pub fn time_choice(input: &mut untrusted::Reader) -> Result { let minutes = read_two_digits(value, 0, 59)?; let seconds = read_two_digits(value, 0, 59)?; - let time_zone = value.read_byte().map_err(|_| Error::BadDERTime)?; + let time_zone = value.read_byte().map_err(|_| Error::BadDerTime)?; if time_zone != b'Z' { - return Err(Error::BadDERTime); + return Err(Error::BadDerTime); } calendar::time_from_ymdhms_utc(year, month, day_of_month, hours, minutes, seconds) diff --git a/src/end_entity.rs b/src/end_entity.rs index 1161c305..8c0650a9 100644 --- a/src/end_entity.rs +++ b/src/end_entity.rs @@ -13,10 +13,12 @@ // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. use crate::{ - cert, name, signed_data, verify_cert, DnsNameRef, Error, SignatureAlgorithm, - TLSClientTrustAnchors, TLSServerTrustAnchors, Time, + cert, name, signed_data, verify_cert, DnsNameRef, Error, SignatureAlgorithm, Time, + TlsClientTrustAnchors, TlsServerTrustAnchors, }; -use core::convert::TryFrom; + +#[cfg(feature = "alloc")] +use alloc::vec::Vec; /// An end-entity certificate. /// @@ -57,7 +59,7 @@ pub struct EndEntityCert<'a> { inner: cert::Cert<'a>, } -impl<'a> TryFrom<&'a [u8]> for EndEntityCert<'a> { +impl<'a> core::convert::TryFrom<&'a [u8]> for EndEntityCert<'a> { type Error = Error; /// Parse the ASN.1 DER-encoded X.509 encoding of the certificate @@ -73,12 +75,6 @@ impl<'a> TryFrom<&'a [u8]> for EndEntityCert<'a> { } impl<'a> EndEntityCert<'a> { - /// Deprecated. Use `TryFrom::try_from`. - #[deprecated(note = "Use TryFrom::try_from")] - pub fn from(cert_der: &'a [u8]) -> Result { - TryFrom::try_from(cert_der) - } - pub(super) fn inner(&self) -> &cert::Cert { &self.inner } @@ -96,7 +92,7 @@ impl<'a> EndEntityCert<'a> { pub fn verify_is_valid_tls_server_cert( &self, supported_sig_algs: &[&SignatureAlgorithm], - &TLSServerTrustAnchors(trust_anchors): &TLSServerTrustAnchors, + &TlsServerTrustAnchors(trust_anchors): &TlsServerTrustAnchors, intermediate_certs: &[&[u8]], time: Time, ) -> Result<(), Error> { @@ -128,7 +124,7 @@ impl<'a> EndEntityCert<'a> { pub fn verify_is_valid_tls_client_cert( &self, supported_sig_algs: &[&SignatureAlgorithm], - &TLSClientTrustAnchors(trust_anchors): &TLSClientTrustAnchors, + &TlsClientTrustAnchors(trust_anchors): &TlsClientTrustAnchors, intermediate_certs: &[&[u8]], time: Time, ) -> Result<(), Error> { @@ -145,7 +141,33 @@ impl<'a> EndEntityCert<'a> { /// Verifies that the certificate is valid for the given DNS host name. pub fn verify_is_valid_for_dns_name(&self, dns_name: DnsNameRef) -> Result<(), Error> { - name::verify_cert_dns_name(self, dns_name) + name::verify_cert_dns_name(&self, dns_name) + } + + /// Verifies that the certificate is valid for at least one of the given DNS + /// host names. + /// + /// If the certificate is not valid for any of the given names then this + /// fails with `Error::CertNotValidForName`. Otherwise the DNS names for + /// which the certificate is valid are returned. + /// + /// Requires the `alloc` default feature; i.e. this isn't available in + /// `#![no_std]` configurations. + #[cfg(feature = "alloc")] + pub fn verify_is_valid_for_at_least_one_dns_name<'names, Names>( + &self, + dns_names: Names, + ) -> Result>, Error> + where + Names: Iterator>, + { + let result: Vec> = dns_names + .filter(|n| self.verify_is_valid_for_dns_name(*n).is_ok()) + .collect(); + if result.is_empty() { + return Err(Error::CertNotValidForName); + } + Ok(result) } /// Verifies the signature `signature` of message `msg` using the @@ -160,7 +182,7 @@ impl<'a> EndEntityCert<'a> { /// `DigitallySigned.algorithm` of TLS type `SignatureAndHashAlgorithm`. In /// TLS 1.2 a single `SignatureAndHashAlgorithm` may map to multiple /// `SignatureAlgorithm`s. For example, a TLS 1.2 - /// `SignatureAndHashAlgorithm` of (ECDSA, SHA-256) may map to any or all + /// `ignatureAndHashAlgorithm` of (ECDSA, SHA-256) may map to any or all /// of {`ECDSA_P256_SHA256`, `ECDSA_P384_SHA256`}, depending on how the TLS /// implementation is configured. /// diff --git a/src/error.rs b/src/error.rs index ae11bbc9..deeb9a83 100644 --- a/src/error.rs +++ b/src/error.rs @@ -18,12 +18,10 @@ use core::fmt; #[derive(Clone, Copy, Debug, PartialEq)] pub enum Error { /// The encoding of some ASN.1 DER-encoded item is invalid. - // TODO: Rename to `BadDer` in the next release. - BadDER, + BadDer, /// The encoding of an ASN.1 DER-encoded time is invalid. - // TODO: Rename to `BadDerTime` in the next release. - BadDERTime, + BadDerTime, /// A CA certificate is being used as an end-entity certificate. CaUsedAsEndEntity, diff --git a/src/lib.rs b/src/lib.rs index a70afe25..ce9e71a5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,6 +26,17 @@ #![doc(html_root_url = "https://briansmith.org/rustdoc/")] #![cfg_attr(not(feature = "std"), no_std)] +#![allow( + clippy::doc_markdown, + clippy::if_not_else, + clippy::inline_always, + clippy::items_after_statements, + clippy::missing_errors_doc, + clippy::module_name_repetitions, + clippy::single_match, + clippy::single_match_else +)] +#![deny(clippy::as_conversions)] #[cfg(any(test, feature = "alloc"))] #[cfg_attr(test, macro_use)] @@ -42,7 +53,6 @@ mod name; mod signed_data; mod time; mod trust_anchor; -pub mod trust_anchor_util; mod verify_cert; @@ -55,7 +65,7 @@ pub use { ECDSA_P384_SHA384, ED25519, }, time::Time, - trust_anchor::{TLSClientTrustAnchors, TLSServerTrustAnchors, TrustAnchor}, + trust_anchor::{TlsClientTrustAnchors, TlsServerTrustAnchors, TrustAnchor}, }; #[cfg(feature = "alloc")] @@ -69,14 +79,18 @@ pub use { }; #[cfg(feature = "alloc")] -#[allow(missing_docs, unknown_lints, clippy::upper_case_acronyms)] +#[allow(unknown_lints, clippy::upper_case_acronyms)] #[deprecated(note = "Use DnsName")] pub type DNSName = DnsName; #[deprecated(note = "use DnsNameRef")] -#[allow(missing_docs, unknown_lints, clippy::upper_case_acronyms)] +#[allow(unknown_lints, clippy::upper_case_acronyms)] pub type DNSNameRef<'a> = DnsNameRef<'a>; -#[deprecated(note = "use InvalidDnsNameError")] -#[allow(missing_docs, unknown_lints, clippy::upper_case_acronyms)] -pub type InvalidDNSNameError = InvalidDnsNameError; +#[deprecated(note = "use TlsServerTrustAnchors")] +#[allow(unknown_lints, clippy::upper_case_acronyms)] +pub type TLSServerTrustAnchors<'a> = TlsServerTrustAnchors<'a>; + +#[deprecated(note = "use TlsClientTrustAnchors")] +#[allow(unknown_lints, clippy::upper_case_acronyms)] +pub type TLSClientTrustAnchors<'a> = TlsClientTrustAnchors<'a>; diff --git a/src/name/dns_name.rs b/src/name/dns_name.rs index e4f18f20..e40e703f 100644 --- a/src/name/dns_name.rs +++ b/src/name/dns_name.rs @@ -125,7 +125,7 @@ impl<'a> DnsNameRef<'a> { pub fn to_owned(&self) -> DnsName { // DnsNameRef is already guaranteed to be valid ASCII, which is a // subset of UTF-8. - let s: &str = (*self).into(); + let s: &str = self.clone().into(); DnsName(s.to_ascii_lowercase()) } } diff --git a/src/name/ip_address.rs b/src/name/ip_address.rs index 1eedf169..fac53625 100644 --- a/src/name/ip_address.rs +++ b/src/name/ip_address.rs @@ -28,10 +28,10 @@ pub(super) fn presented_id_matches_constraint( constraint: untrusted::Input, ) -> Result { if name.len() != 4 && name.len() != 16 { - return Err(Error::BadDER); + return Err(Error::BadDer); } if constraint.len() != 8 && constraint.len() != 32 { - return Err(Error::BadDER); + return Err(Error::BadDer); } // an IPv4 address never matches an IPv6 constraint, and vice versa. @@ -39,7 +39,7 @@ pub(super) fn presented_id_matches_constraint( return Ok(false); } - let (constraint_address, constraint_mask) = constraint.read_all(Error::BadDER, |value| { + let (constraint_address, constraint_mask) = constraint.read_all(Error::BadDer, |value| { let address = value.read_bytes(constraint.len() / 2).unwrap(); let mask = value.read_bytes(constraint.len() / 2).unwrap(); Ok((address, mask)) diff --git a/src/name/verify.rs b/src/name/verify.rs index 749a9ea6..6082c19e 100644 --- a/src/name/verify.rs +++ b/src/name/verify.rs @@ -26,7 +26,7 @@ pub fn verify_cert_dns_name( dns_name: DnsNameRef, ) -> Result<(), Error> { let cert = cert.inner(); - let dns_name = untrusted::Input::from(dns_name.as_ref()); + let dns_name = untrusted::Input::from(dns_name.as_ref().as_ref()); iterate_names( cert.subject, cert.subject_alt_name, @@ -40,7 +40,7 @@ pub fn verify_cert_dns_name( } Some(false) => (), None => { - return NameIteration::Stop(Err(Error::BadDER)); + return NameIteration::Stop(Err(Error::BadDer)); } } } @@ -70,7 +70,7 @@ pub fn check_name_constraints( if !inner.peek(subtrees_tag.into()) { return Ok(None); } - let subtrees = der::nested(inner, subtrees_tag, Error::BadDER, |tagged| { + let subtrees = der::nested(inner, subtrees_tag, Error::BadDer, |tagged| { der::expect_tag_and_get_value(tagged, der::Tag::Sequence) })?; Ok(Some(subtrees)) @@ -152,7 +152,7 @@ fn check_presented_id_conforms_to_constraints_in_subtree( input: &mut untrusted::Reader<'b>, ) -> Result, Error> { let general_subtree = der::expect_tag_and_get_value(input, der::Tag::Sequence)?; - general_subtree.read_all(Error::BadDER, general_name) + general_subtree.read_all(Error::BadDer, |subtree| general_name(subtree)) } let base = match general_subtree(&mut constraints) { @@ -164,7 +164,7 @@ fn check_presented_id_conforms_to_constraints_in_subtree( let matches = match (name, base) { (GeneralName::DnsName(name), GeneralName::DnsName(base)) => { - dns_name::presented_id_matches_constraint(name, base).ok_or(Error::BadDER) + dns_name::presented_id_matches_constraint(name, base).ok_or(Error::BadDer) } (GeneralName::DirectoryName(name), GeneralName::DirectoryName(base)) => Ok( @@ -322,7 +322,7 @@ fn general_name<'a>(input: &mut untrusted::Reader<'a>) -> Result | UNIFORM_RESOURCE_IDENTIFIER_TAG | REGISTERED_ID_TAG => GeneralName::Unsupported(tag & !(CONTEXT_SPECIFIC | CONSTRUCTED)), - _ => return Err(Error::BadDER), + _ => return Err(Error::BadDer), }; Ok(name) } diff --git a/src/signed_data.rs b/src/signed_data.rs index fce767b8..834f9076 100644 --- a/src/signed_data.rs +++ b/src/signed_data.rs @@ -175,7 +175,7 @@ struct SubjectPublicKeyInfo<'a> { // `PublicKeyAlgorithm` for the `SignatureAlgorithm` that is matched when // parsing the signature. fn parse_spki_value(input: untrusted::Input) -> Result { - input.read_all(Error::BadDER, |input| { + input.read_all(Error::BadDer, |input| { let algorithm_id_value = der::expect_tag_and_get_value(input, der::Tag::Sequence)?; let key_value = der::bit_string_with_no_unused_bits(input)?; Ok(SubjectPublicKeyInfo { @@ -402,7 +402,7 @@ mod tests { let tsd = parse_test_signed_data(file_contents); let spki_value = untrusted::Input::from(&tsd.spki); let spki_value = spki_value - .read_all(Error::BadDER, |input| { + .read_all(Error::BadDer, |input| { der::expect_tag_and_get_value(input, der::Tag::Sequence) }) .unwrap(); @@ -415,14 +415,14 @@ mod tests { let algorithm = untrusted::Input::from(&tsd.algorithm); let algorithm = algorithm - .read_all(Error::BadDER, |input| { + .read_all(Error::BadDer, |input| { der::expect_tag_and_get_value(input, der::Tag::Sequence) }) .unwrap(); let signature = untrusted::Input::from(&tsd.signature); let signature = signature - .read_all(Error::BadDER, |input| { + .read_all(Error::BadDer, |input| { der::bit_string_with_no_unused_bits(input) }) .unwrap(); @@ -461,7 +461,7 @@ mod tests { let signature = untrusted::Input::from(&tsd.signature); assert_eq!( Err(expected_error), - signature.read_all(Error::BadDER, |input| { + signature.read_all(Error::BadDer, |input| { der::bit_string_with_no_unused_bits(input) }) ); @@ -482,7 +482,7 @@ mod tests { let spki = untrusted::Input::from(&tsd.spki); assert_eq!( Err(expected_error), - spki.read_all(Error::BadDER, |input| { + spki.read_all(Error::BadDer, |input| { der::expect_tag_and_get_value(input, der::Tag::Sequence) }) ); @@ -518,7 +518,7 @@ mod tests { test_verify_signed_data_signature_outer!( test_ecdsa_prime256v1_sha512_unused_bits_signature, "ecdsa-prime256v1-sha512-unused-bits-signature.pem", - Error::BadDER + Error::BadDer ); // XXX: We should have a variant of this test with a SHA-256 digest that gives // `Error::UnsupportedSignatureAlgorithmForPublicKey`. @@ -571,12 +571,12 @@ mod tests { test_parse_spki_bad_outer!( test_rsa_pkcs1_sha1_bad_key_der_length, "rsa-pkcs1-sha1-bad-key-der-length.pem", - Error::BadDER + Error::BadDer ); test_parse_spki_bad_outer!( test_rsa_pkcs1_sha1_bad_key_der_null, "rsa-pkcs1-sha1-bad-key-der-null.pem", - Error::BadDER + Error::BadDer ); test_verify_signed_data!( test_rsa_pkcs1_sha1_key_params_absent, @@ -610,7 +610,7 @@ mod tests { test_parse_spki_bad_outer!( test_rsa_pkcs1_sha256_key_encoded_ber, "rsa-pkcs1-sha256-key-encoded-ber.pem", - Error::BadDER + Error::BadDer ); test_verify_signed_data!( test_rsa_pkcs1_sha256_spki_non_null_params, @@ -755,7 +755,7 @@ mod tests { if line == end_section { break; } - base64.push_str(line); + base64.push_str(&line); } base64::decode(&base64).unwrap() diff --git a/src/time.rs b/src/time.rs index 4fa0daaf..0457cae7 100644 --- a/src/time.rs +++ b/src/time.rs @@ -23,13 +23,6 @@ pub struct Time(u64); impl Time { - /// Deprecated. Use `TryFrom::try_from`. - #[cfg(feature = "std")] - // Soft deprecation. #[deprecated(note = "Use TryFrom::try_from")] - pub fn try_from(time: std::time::SystemTime) -> Result { - core::convert::TryFrom::try_from(time) - } - /// Create a `webpki::Time` from a unix timestamp. /// /// It is usually better to use the less error-prone @@ -44,8 +37,7 @@ impl Time { #[cfg(feature = "std")] impl core::convert::TryFrom for Time { - // TODO: In the next release, make this `std::time::SystemTimeError`. - type Error = ring::error::Unspecified; + type Error = std::time::SystemTimeError; /// Create a `webpki::Time` from a `std::time::SystemTime`. /// @@ -58,9 +50,9 @@ impl core::convert::TryFrom for Time { /// # extern crate webpki; /// # /// #![cfg(feature = "std")] - /// use std::{convert::TryFrom, time::SystemTime}; + /// use std::{convert::TryFrom, time::{SystemTime, SystemTimeError}}; /// - /// # fn foo() -> Result<(), ring::error::Unspecified> { + /// # fn foo() -> Result<(), SystemTimeError> { /// let time = webpki::Time::try_from(SystemTime::now())?; /// # Ok(()) /// # } @@ -69,6 +61,5 @@ impl core::convert::TryFrom for Time { value .duration_since(std::time::UNIX_EPOCH) .map(|d| Self::from_seconds_since_unix_epoch(d.as_secs())) - .map_err(|_| ring::error::Unspecified) } } diff --git a/src/trust_anchor.rs b/src/trust_anchor.rs index 1e926b55..0ac2806e 100644 --- a/src/trust_anchor.rs +++ b/src/trust_anchor.rs @@ -28,11 +28,11 @@ pub struct TrustAnchor<'a> { /// Trust anchors which may be used for authenticating servers. #[derive(Debug)] -pub struct TLSServerTrustAnchors<'a>(pub &'a [TrustAnchor<'a>]); +pub struct TlsServerTrustAnchors<'a>(pub &'a [TrustAnchor<'a>]); /// Trust anchors which may be used for authenticating clients. #[derive(Debug)] -pub struct TLSClientTrustAnchors<'a>(pub &'a [TrustAnchor<'a>]); +pub struct TlsClientTrustAnchors<'a>(pub &'a [TrustAnchor<'a>]); impl<'a> TrustAnchor<'a> { /// Interprets the given DER-encoded certificate as a `TrustAnchor`. The @@ -57,7 +57,7 @@ impl<'a> TrustAnchor<'a> { possibly_invalid_certificate_serial_number, ) { Ok(cert) => Ok(Self::from(cert)), - Err(Error::UnsupportedCertVersion) => parse_cert_v1(cert_der).or(Err(Error::BadDER)), + Err(Error::UnsupportedCertVersion) => parse_cert_v1(cert_der).or(Err(Error::BadDer)), Err(err) => Err(err), } } @@ -86,9 +86,9 @@ impl<'a> From> for TrustAnchor<'a> { /// Parses a v1 certificate directly into a TrustAnchor. fn parse_cert_v1(cert_der: untrusted::Input) -> Result { // X.509 Certificate: https://tools.ietf.org/html/rfc5280#section-4.1. - cert_der.read_all(Error::BadDER, |cert_der| { - der::nested(cert_der, der::Tag::Sequence, Error::BadDER, |cert_der| { - let anchor = der::nested(cert_der, der::Tag::Sequence, Error::BadDER, |tbs| { + cert_der.read_all(Error::BadDer, |cert_der| { + der::nested(cert_der, der::Tag::Sequence, Error::BadDer, |cert_der| { + let anchor = der::nested(cert_der, der::Tag::Sequence, Error::BadDer, |tbs| { // The version number field does not appear in v1 certificates. certificate_serial_number(tbs)?; diff --git a/src/trust_anchor_util.rs b/src/trust_anchor_util.rs deleted file mode 100644 index 9453947d..00000000 --- a/src/trust_anchor_util.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2015-2021 Brian Smith. -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -//! Deprecated. Use `TrustAnchor`. - -use crate::{Error, TrustAnchor}; - -/// Deprecated. Use TrustAnchor::try_from_cert_der. -#[deprecated(note = "Use TrustAnchor::try_from_cert_der")] -pub fn cert_der_as_trust_anchor(cert_der: &[u8]) -> Result { - TrustAnchor::try_from_cert_der(cert_der) -} diff --git a/src/verify_cert.rs b/src/verify_cert.rs index 8a6bed91..c68e6cf2 100644 --- a/src/verify_cert.rs +++ b/src/verify_cert.rs @@ -61,8 +61,8 @@ pub fn build_chain( let name_constraints = trust_anchor.name_constraints.map(untrusted::Input::from); - untrusted::read_all_optional(name_constraints, Error::BadDER, |value| { - name::check_name_constraints(value, cert) + untrusted::read_all_optional(name_constraints, Error::BadDer, |value| { + name::check_name_constraints(value, &cert) })?; let trust_anchor_spki = untrusted::Input::from(trust_anchor.spki); @@ -83,7 +83,7 @@ pub fn build_chain( loop_while_non_fatal_error(intermediate_certs, |cert_der| { let potential_issuer = - cert::parse_cert(untrusted::Input::from(*cert_der), EndEntityOrCa::Ca(cert))?; + cert::parse_cert(untrusted::Input::from(*cert_der), EndEntityOrCa::Ca(&cert))?; if potential_issuer.subject != cert.issuer { return Err(Error::UnknownIssuer); @@ -107,8 +107,8 @@ pub fn build_chain( } } - untrusted::read_all_optional(potential_issuer.name_constraints, Error::BadDER, |value| { - name::check_name_constraints(value, cert) + untrusted::read_all_optional(potential_issuer.name_constraints, Error::BadDer, |value| { + name::check_name_constraints(value, &cert) })?; let next_sub_ca_count = match used_as_ca { @@ -170,11 +170,11 @@ fn check_issuer_independent_properties( // KeyUsage extension. cert.validity - .read_all(Error::BadDER, |value| check_validity(value, time))?; - untrusted::read_all_optional(cert.basic_constraints, Error::BadDER, |value| { + .read_all(Error::BadDer, |value| check_validity(value, time))?; + untrusted::read_all_optional(cert.basic_constraints, Error::BadDer, |value| { check_basic_constraints(value, used_as_ca, sub_ca_count) })?; - untrusted::read_all_optional(cert.eku, Error::BadDER, |value| { + untrusted::read_all_optional(cert.eku, Error::BadDer, |value| { check_eku(value, required_eku_if_present) })?; diff --git a/tests/dns_name_tests.rs b/tests/dns_name_tests.rs index 0e519999..b3a3adc4 100644 --- a/tests/dns_name_tests.rs +++ b/tests/dns_name_tests.rs @@ -250,7 +250,7 @@ static IP_ADDRESS_DNS_VALIDITY: &[(&[u8], bool)] = &[ (b"1.2.3.4\n", false), // Nulls not allowed (b"\0", false), - (b"\x001.2.3.4", false), + (b"\01.2.3.4", false), (b"1.2.3.4\0", false), (b"1.2.3.4\0.5", false), // Range @@ -389,7 +389,7 @@ static IP_ADDRESS_DNS_VALIDITY: &[(&[u8], bool)] = &[ (b"::1\0:2", false), (b"::1\0", false), (b"::1.2.3.4\0", false), - (b"::1.2\x002.3.4", false), + (b"::1.2\02.3.4", false), ]; #[test] diff --git a/tests/integration.rs b/tests/integration.rs index 34270272..598641d3 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -41,7 +41,7 @@ pub fn netflix() { let ca = include_bytes!("netflix/ca.der"); let anchors = vec![webpki::TrustAnchor::try_from_cert_der(ca).unwrap()]; - let anchors = webpki::TLSServerTrustAnchors(&anchors); + let anchors = webpki::TlsServerTrustAnchors(&anchors); #[allow(clippy::unreadable_literal)] // TODO: Make this clear. let time = webpki::Time::from_seconds_since_unix_epoch(1492441716); @@ -59,7 +59,7 @@ pub fn ed25519() { let ca = include_bytes!("ed25519/ca.der"); let anchors = vec![webpki::TrustAnchor::try_from_cert_der(ca).unwrap()]; - let anchors = webpki::TLSServerTrustAnchors(&anchors); + let anchors = webpki::TlsServerTrustAnchors(&anchors); #[allow(clippy::unreadable_literal)] // TODO: Make this clear. let time = webpki::Time::from_seconds_since_unix_epoch(1547363522);