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 that are necessary for GitHub
Actions to work correctly now.

The exact commands I used were:

```
git checkout \
    6c334a2cf5 \
    -- \
    Cargo.toml \
    LICENSE \
    README.md \
    src \
    tests \
    third-party
git rm src/trust_anchor_util.rs
```

Commit 6c334a2cf5 was the commit from
which 0.22.0 was released. It is confusing because the commit
immediately prior, 0b7cbf2d32, has
commit message "0.22.0". It appears that I merged the "0.22.0"
commit, expecting to `cargo publish` from that commit, but then
`cargo publish` failed. Then I added
6c334a2cf5 to fix `cargo publish`
and did the `cargo publish` from that commit. That's why I added
the `package` CI step at that time, to prevent this confusing
situation from happening again.

`trust_anchor_utils.rs` was not in 0.22.0; the `git checkout` didn't
delete it, so I had to do it separately.

I left the tests added subsequent to 0.22.0 in `tests/` (e.g.
`name_tests.rs`) since those tests pass with the 0.22.0 sources too.

Unfortunately, this requires disabling a bunch of Clippy lints, to
avoid modifying the contents from 0.22.0.

(I know it is confusing. It took me a while to figure it out myself
today.)
This commit is contained in:
Brian Smith 2023-08-29 18:13:07 -07:00
parent 8330c72930
commit 0cd0b31beb
18 changed files with 131 additions and 130 deletions

View File

@ -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",
@ -42,7 +42,6 @@ include = [
"src/signed_data.rs",
"src/time.rs",
"src/trust_anchor.rs",
"src/trust_anchor_util.rs",
"src/verify_cert.rs",
"src/lib.rs",
@ -68,19 +67,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

View File

@ -22,16 +22,20 @@ cargo clippy \
--target-dir=target/clippy \
--all-features --all-targets \
-- \
--deny missing_docs \
--deny warnings \
\
--deny clippy::as_conversions \
\
--allow clippy::clone_on_copy \
--allow clippy::explicit_auto_deref \
--allow clippy::len_without_is_empty \
--allow clippy::needless_borrow \
--allow clippy::new_without_default \
--allow clippy::octal_escapes \
--allow clippy::redundant_closure \
--allow clippy::single_match \
--allow clippy::single_match_else \
--allow clippy::type_complexity \
--allow clippy::upper_case_acronyms \
--allow clippy::useless_asref \
$NULL

View File

@ -67,7 +67,7 @@ fn days_before_year_since_unix_epoch(year: u64) -> Result<u64, Error> {
// 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);

View File

@ -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<Cert<'a>, 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);

View File

@ -23,7 +23,7 @@ pub fn expect_tag_and_get_value<'a>(
input: &mut untrusted::Reader<'a>,
tag: Tag,
) -> Result<untrusted::Input<'a>, 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<Value<'a>, 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<Val
pub fn read_tag_and_get_value<'a>(
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<untrusted::Input<'a>, 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<bool, Error> {
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<Positive<'a>, 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<u8, Error> {
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<time::Time, Error> {
@ -120,11 +120,11 @@ pub fn time_choice(input: &mut untrusted::Reader) -> Result<time::Time, Error> {
fn read_digit(inner: &mut untrusted::Reader) -> Result<u64, Error> {
const DIGIT: core::ops::RangeInclusive<u8> = 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<u64, Error> {
@ -132,12 +132,12 @@ pub fn time_choice(input: &mut untrusted::Reader) -> Result<time::Time, Error> {
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<time::Time, Error> {
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)

View File

@ -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<Self, Error> {
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<Vec<DnsNameRef<'names>>, Error>
where
Names: Iterator<Item = DnsNameRef<'names>>,
{
let result: Vec<DnsNameRef<'names>> = 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.
///

View File

@ -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,

View File

@ -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>;

View File

@ -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())
}
}

View File

@ -28,10 +28,10 @@ pub(super) fn presented_id_matches_constraint(
constraint: untrusted::Input,
) -> Result<bool, Error> {
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))

View File

@ -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<GeneralName<'b>, 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<GeneralName<'a>
| UNIFORM_RESOURCE_IDENTIFIER_TAG
| REGISTERED_ID_TAG => GeneralName::Unsupported(tag & !(CONTEXT_SPECIFIC | CONSTRUCTED)),
_ => return Err(Error::BadDER),
_ => return Err(Error::BadDer),
};
Ok(name)
}

View File

@ -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<SubjectPublicKeyInfo, Error> {
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()

View File

@ -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<Self, ring::error::Unspecified> {
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<std::time::SystemTime> 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<std::time::SystemTime> 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<std::time::SystemTime> 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)
}
}

View File

@ -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<Cert<'a>> for TrustAnchor<'a> {
/// Parses a v1 certificate directly into a TrustAnchor.
fn parse_cert_v1(cert_der: untrusted::Input) -> Result<TrustAnchor, Error> {
// 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)?;

View File

@ -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, Error> {
TrustAnchor::try_from_cert_der(cert_der)
}

View File

@ -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)
})?;

View File

@ -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]

View File

@ -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);