summaryrefslogtreecommitdiffstats
path: root/vendor/der/src/asn1
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:42 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:42 +0000
commit837b550238aa671a591ccf282dddeab29cadb206 (patch)
tree914b6b8862bace72bd3245ca184d374b08d8a672 /vendor/der/src/asn1
parentAdding debian version 1.70.0+dfsg2-1. (diff)
downloadrustc-837b550238aa671a591ccf282dddeab29cadb206.tar.xz
rustc-837b550238aa671a591ccf282dddeab29cadb206.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/der/src/asn1')
-rw-r--r--vendor/der/src/asn1/any.rs311
-rw-r--r--vendor/der/src/asn1/bit_string.rs298
-rw-r--r--vendor/der/src/asn1/boolean.rs17
-rw-r--r--vendor/der/src/asn1/context_specific.rs4
-rw-r--r--vendor/der/src/asn1/generalized_time.rs47
-rw-r--r--vendor/der/src/asn1/ia5_string.rs154
-rw-r--r--vendor/der/src/asn1/integer.rs121
-rw-r--r--vendor/der/src/asn1/integer/bigint.rs152
-rw-r--r--vendor/der/src/asn1/integer/int.rs405
-rw-r--r--vendor/der/src/asn1/integer/uint.rs320
-rw-r--r--vendor/der/src/asn1/internal_macros.rs75
-rw-r--r--vendor/der/src/asn1/null.rs18
-rw-r--r--vendor/der/src/asn1/octet_string.rs194
-rw-r--r--vendor/der/src/asn1/oid.rs12
-rw-r--r--vendor/der/src/asn1/optional.rs4
-rw-r--r--vendor/der/src/asn1/printable_string.rs173
-rw-r--r--vendor/der/src/asn1/real.rs17
-rw-r--r--vendor/der/src/asn1/sequence.rs63
-rw-r--r--vendor/der/src/asn1/sequence_of.rs10
-rw-r--r--vendor/der/src/asn1/set_of.rs35
-rw-r--r--vendor/der/src/asn1/teletex_string.rs160
-rw-r--r--vendor/der/src/asn1/utc_time.rs52
-rw-r--r--vendor/der/src/asn1/utf8_string.rs75
-rw-r--r--vendor/der/src/asn1/videotex_string.rs59
24 files changed, 1734 insertions, 1042 deletions
diff --git a/vendor/der/src/asn1/any.rs b/vendor/der/src/asn1/any.rs
index cb65f2391..017a90908 100644
--- a/vendor/der/src/asn1/any.rs
+++ b/vendor/der/src/asn1/any.rs
@@ -1,16 +1,15 @@
//! ASN.1 `ANY` type.
+#![cfg_attr(feature = "arbitrary", allow(clippy::integer_arithmetic))]
+
use crate::{
- asn1::*, ByteSlice, Choice, Decode, DecodeValue, DerOrd, EncodeValue, Error, ErrorKind,
- FixedTag, Header, Length, Reader, Result, SliceReader, Tag, Tagged, ValueOrd, Writer,
+ BytesRef, Choice, Decode, DecodeValue, DerOrd, EncodeValue, Error, ErrorKind, Header, Length,
+ Reader, Result, SliceReader, Tag, Tagged, ValueOrd, Writer,
};
use core::cmp::Ordering;
#[cfg(feature = "alloc")]
-use alloc::vec::Vec;
-
-#[cfg(feature = "oid")]
-use crate::asn1::ObjectIdentifier;
+use crate::SliceWriter;
/// ASN.1 `ANY`: represents any explicitly tagged ASN.1 value.
///
@@ -23,30 +22,31 @@ use crate::asn1::ObjectIdentifier;
/// Nevertheless, this crate defines an `ANY` type as it remains a familiar
/// and useful concept which is still extensively used in things like
/// PKI-related RFCs.
+#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub struct AnyRef<'a> {
/// Tag representing the type of the encoded value.
tag: Tag,
/// Inner value encoded as bytes.
- value: ByteSlice<'a>,
+ value: BytesRef<'a>,
}
impl<'a> AnyRef<'a> {
/// [`AnyRef`] representation of the ASN.1 `NULL` type.
pub const NULL: Self = Self {
tag: Tag::Null,
- value: ByteSlice::EMPTY,
+ value: BytesRef::EMPTY,
};
/// Create a new [`AnyRef`] from the provided [`Tag`] and DER bytes.
pub fn new(tag: Tag, bytes: &'a [u8]) -> Result<Self> {
- let value = ByteSlice::new(bytes).map_err(|_| ErrorKind::Length { tag })?;
+ let value = BytesRef::new(bytes).map_err(|_| ErrorKind::Length { tag })?;
Ok(Self { tag, value })
}
- /// Infallible creation of an [`AnyRef`] from a [`ByteSlice`].
- pub(crate) fn from_tag_and_value(tag: Tag, value: ByteSlice<'a>) -> Self {
+ /// Infallible creation of an [`AnyRef`] from a [`BytesRef`].
+ pub(crate) fn from_tag_and_value(tag: Tag, value: BytesRef<'a>) -> Self {
Self { tag, value }
}
@@ -56,11 +56,14 @@ impl<'a> AnyRef<'a> {
}
/// Attempt to decode this [`AnyRef`] type into the inner value.
- pub fn decode_into<T>(self) -> Result<T>
+ pub fn decode_as<T>(self) -> Result<T>
where
- T: DecodeValue<'a> + FixedTag,
+ T: Choice<'a> + DecodeValue<'a>,
{
- self.tag.assert_eq(T::TAG)?;
+ if !T::can_decode(self.tag) {
+ return Err(self.tag.unexpected_error(None));
+ }
+
let header = Header {
tag: self.tag,
length: self.value.len(),
@@ -76,68 +79,6 @@ impl<'a> AnyRef<'a> {
self == Self::NULL
}
- /// Attempt to decode an ASN.1 `BIT STRING`.
- pub fn bit_string(self) -> Result<BitStringRef<'a>> {
- self.try_into()
- }
-
- /// Attempt to decode an ASN.1 `CONTEXT-SPECIFIC` field.
- pub fn context_specific<T>(self) -> Result<ContextSpecific<T>>
- where
- T: Decode<'a>,
- {
- self.try_into()
- }
-
- /// Attempt to decode an ASN.1 `GeneralizedTime`.
- pub fn generalized_time(self) -> Result<GeneralizedTime> {
- self.try_into()
- }
-
- /// Attempt to decode an ASN.1 `IA5String`.
- pub fn ia5_string(self) -> Result<Ia5StringRef<'a>> {
- self.try_into()
- }
-
- /// Attempt to decode an ASN.1 `OCTET STRING`.
- pub fn octet_string(self) -> Result<OctetStringRef<'a>> {
- self.try_into()
- }
-
- /// Attempt to decode an ASN.1 `OBJECT IDENTIFIER`.
- #[cfg(feature = "oid")]
- #[cfg_attr(docsrs, doc(cfg(feature = "oid")))]
- pub fn oid(self) -> Result<ObjectIdentifier> {
- self.try_into()
- }
-
- /// Attempt to decode an ASN.1 `OPTIONAL` value.
- pub fn optional<T>(self) -> Result<Option<T>>
- where
- T: Choice<'a> + TryFrom<Self, Error = Error>,
- {
- if T::can_decode(self.tag) {
- T::try_from(self).map(Some)
- } else {
- Ok(None)
- }
- }
-
- /// Attempt to decode an ASN.1 `PrintableString`.
- pub fn printable_string(self) -> Result<PrintableStringRef<'a>> {
- self.try_into()
- }
-
- /// Attempt to decode an ASN.1 `TeletexString`.
- pub fn teletex_string(self) -> Result<TeletexStringRef<'a>> {
- self.try_into()
- }
-
- /// Attempt to decode an ASN.1 `VideotexString`.
- pub fn videotex_string(self) -> Result<VideotexStringRef<'a>> {
- self.try_into()
- }
-
/// Attempt to decode this value an ASN.1 `SEQUENCE`, creating a new
/// nested reader and calling the provided argument with it.
pub fn sequence<F, T>(self, f: F) -> Result<T>
@@ -149,16 +90,6 @@ impl<'a> AnyRef<'a> {
let result = f(&mut reader)?;
reader.finish(result)
}
-
- /// Attempt to decode an ASN.1 `UTCTime`.
- pub fn utc_time(self) -> Result<UtcTime> {
- self.try_into()
- }
-
- /// Attempt to decode an ASN.1 `UTF8String`.
- pub fn utf8_string(self) -> Result<Utf8StringRef<'a>> {
- self.try_into()
- }
}
impl<'a> Choice<'a> for AnyRef<'a> {
@@ -170,10 +101,15 @@ impl<'a> Choice<'a> for AnyRef<'a> {
impl<'a> Decode<'a> for AnyRef<'a> {
fn decode<R: Reader<'a>>(reader: &mut R) -> Result<AnyRef<'a>> {
let header = Header::decode(reader)?;
+ Self::decode_value(reader, header)
+ }
+}
+impl<'a> DecodeValue<'a> for AnyRef<'a> {
+ fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
Ok(Self {
tag: header.tag,
- value: ByteSlice::decode_value(reader, header)?,
+ value: BytesRef::decode_value(reader, header)?,
})
}
}
@@ -183,7 +119,7 @@ impl EncodeValue for AnyRef<'_> {
Ok(self.value.len())
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
writer.write(self.value())
}
}
@@ -200,8 +136,8 @@ impl ValueOrd for AnyRef<'_> {
}
}
-impl<'a> From<AnyRef<'a>> for ByteSlice<'a> {
- fn from(any: AnyRef<'a>) -> ByteSlice<'a> {
+impl<'a> From<AnyRef<'a>> for BytesRef<'a> {
+ fn from(any: AnyRef<'a>) -> BytesRef<'a> {
any.value
}
}
@@ -214,71 +150,166 @@ impl<'a> TryFrom<&'a [u8]> for AnyRef<'a> {
}
}
-/// ASN.1 `ANY`: represents any explicitly tagged ASN.1 value.
-///
-/// This type provides the same functionality as [`AnyRef`] but owns the
-/// backing data.
#[cfg(feature = "alloc")]
-#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
-#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
-pub struct Any {
- /// Tag representing the type of the encoded value.
- tag: Tag,
-
- /// Inner value encoded as bytes.
- value: Vec<u8>,
-}
+pub use self::allocating::Any;
#[cfg(feature = "alloc")]
-impl Any {
- /// Create a new [`Any`] from the provided [`Tag`] and DER bytes.
- pub fn new(tag: Tag, bytes: impl Into<Vec<u8>>) -> Result<Self> {
- let value = bytes.into();
+mod allocating {
+ use super::*;
+ use crate::{referenced::*, BytesOwned};
+ use alloc::boxed::Box;
+
+ /// ASN.1 `ANY`: represents any explicitly tagged ASN.1 value.
+ ///
+ /// This type provides the same functionality as [`AnyRef`] but owns the
+ /// backing data.
+ #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
+ #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
+ pub struct Any {
+ /// Tag representing the type of the encoded value.
+ tag: Tag,
+
+ /// Inner value encoded as bytes.
+ value: BytesOwned,
+ }
+
+ impl Any {
+ /// Create a new [`Any`] from the provided [`Tag`] and DER bytes.
+ pub fn new(tag: Tag, bytes: impl Into<Box<[u8]>>) -> Result<Self> {
+ let value = BytesOwned::new(bytes)?;
+
+ // Ensure the tag and value are a valid `AnyRef`.
+ AnyRef::new(tag, value.as_slice())?;
+ Ok(Self { tag, value })
+ }
- // Ensure the tag and value are a valid `AnyRef`.
- AnyRef::new(tag, &value)?;
- Ok(Self { tag, value })
+ /// Allow access to value
+ pub fn value(&self) -> &[u8] {
+ self.value.as_slice()
+ }
+
+ /// Attempt to decode this [`Any`] type into the inner value.
+ pub fn decode_as<'a, T>(&'a self) -> Result<T>
+ where
+ T: Choice<'a> + DecodeValue<'a>,
+ {
+ AnyRef::from(self).decode_as()
+ }
+
+ /// Encode the provided type as an [`Any`] value.
+ pub fn encode_from<T>(msg: &T) -> Result<Self>
+ where
+ T: Tagged + EncodeValue,
+ {
+ let encoded_len = usize::try_from(msg.value_len()?)?;
+ let mut buf = vec![0u8; encoded_len];
+ let mut writer = SliceWriter::new(&mut buf);
+ msg.encode_value(&mut writer)?;
+ writer.finish()?;
+ Any::new(msg.tag(), buf)
+ }
+
+ /// Attempt to decode this value an ASN.1 `SEQUENCE`, creating a new
+ /// nested reader and calling the provided argument with it.
+ pub fn sequence<'a, F, T>(&'a self, f: F) -> Result<T>
+ where
+ F: FnOnce(&mut SliceReader<'a>) -> Result<T>,
+ {
+ AnyRef::from(self).sequence(f)
+ }
+
+ /// [`Any`] representation of the ASN.1 `NULL` type.
+ pub fn null() -> Self {
+ Self {
+ tag: Tag::Null,
+ value: BytesOwned::default(),
+ }
+ }
}
-}
-#[cfg(feature = "alloc")]
-impl Choice<'_> for Any {
- fn can_decode(_: Tag) -> bool {
- true
+ impl Choice<'_> for Any {
+ fn can_decode(_: Tag) -> bool {
+ true
+ }
}
-}
-#[cfg(feature = "alloc")]
-impl<'a> Decode<'a> for Any {
- fn decode<R: Reader<'a>>(reader: &mut R) -> Result<Self> {
- let header = Header::decode(reader)?;
- let value = reader.read_vec(header.length)?;
- Self::new(header.tag, value)
+ impl<'a> Decode<'a> for Any {
+ fn decode<R: Reader<'a>>(reader: &mut R) -> Result<Self> {
+ let header = Header::decode(reader)?;
+ Self::decode_value(reader, header)
+ }
}
-}
-#[cfg(feature = "alloc")]
-impl EncodeValue for Any {
- fn value_len(&self) -> Result<Length> {
- self.value.len().try_into()
+ impl<'a> DecodeValue<'a> for Any {
+ fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
+ let value = reader.read_vec(header.length)?;
+ Self::new(header.tag, value)
+ }
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
- writer.write(&self.value)
+ impl EncodeValue for Any {
+ fn value_len(&self) -> Result<Length> {
+ Ok(self.value.len())
+ }
+
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
+ writer.write(self.value.as_slice())
+ }
}
-}
-#[cfg(feature = "alloc")]
-impl<'a> From<&'a Any> for AnyRef<'a> {
- fn from(any: &'a Any) -> AnyRef<'a> {
- // Ensured to parse successfully in constructor
- AnyRef::new(any.tag, &any.value).expect("invalid ANY")
+ impl<'a> From<&'a Any> for AnyRef<'a> {
+ fn from(any: &'a Any) -> AnyRef<'a> {
+ // Ensured to parse successfully in constructor
+ AnyRef::new(any.tag, any.value.as_slice()).expect("invalid ANY")
+ }
}
-}
-#[cfg(feature = "alloc")]
-impl Tagged for Any {
- fn tag(&self) -> Tag {
- self.tag
+ impl Tagged for Any {
+ fn tag(&self) -> Tag {
+ self.tag
+ }
+ }
+
+ impl ValueOrd for Any {
+ fn value_cmp(&self, other: &Self) -> Result<Ordering> {
+ self.value.der_cmp(&other.value)
+ }
+ }
+
+ impl<'a, T> From<T> for Any
+ where
+ T: Into<AnyRef<'a>>,
+ {
+ fn from(input: T) -> Any {
+ let anyref: AnyRef<'a> = input.into();
+ Self {
+ tag: anyref.tag(),
+ value: BytesOwned::from(anyref.value),
+ }
+ }
+ }
+
+ impl<'a> RefToOwned<'a> for AnyRef<'a> {
+ type Owned = Any;
+ fn ref_to_owned(&self) -> Self::Owned {
+ Any {
+ tag: self.tag(),
+ value: BytesOwned::from(self.value),
+ }
+ }
+ }
+
+ impl OwnedToRef for Any {
+ type Borrowed<'a> = AnyRef<'a>;
+ fn owned_to_ref(&self) -> Self::Borrowed<'_> {
+ self.into()
+ }
+ }
+
+ impl Any {
+ /// Is this value an ASN.1 `NULL` value?
+ pub fn is_null(&self) -> bool {
+ self.owned_to_ref() == AnyRef::NULL
+ }
}
}
diff --git a/vendor/der/src/asn1/bit_string.rs b/vendor/der/src/asn1/bit_string.rs
index eed14e456..bf3371c40 100644
--- a/vendor/der/src/asn1/bit_string.rs
+++ b/vendor/der/src/asn1/bit_string.rs
@@ -1,14 +1,11 @@
//! ASN.1 `BIT STRING` support.
use crate::{
- asn1::AnyRef, ByteSlice, DecodeValue, DerOrd, EncodeValue, Error, ErrorKind, FixedTag, Header,
- Length, Reader, Result, Tag, ValueOrd, Writer,
+ BytesRef, DecodeValue, DerOrd, EncodeValue, Error, ErrorKind, FixedTag, Header, Length, Reader,
+ Result, Tag, ValueOrd, Writer,
};
use core::{cmp::Ordering, iter::FusedIterator};
-#[cfg(feature = "alloc")]
-use alloc::vec::Vec;
-
/// ASN.1 `BIT STRING` type.
///
/// This type contains a sequence of any number of bits, modeled internally as
@@ -24,7 +21,7 @@ pub struct BitStringRef<'a> {
bit_length: usize,
/// Bitstring represented as a slice of bytes.
- inner: ByteSlice<'a>,
+ inner: BytesRef<'a>,
}
impl<'a> BitStringRef<'a> {
@@ -40,7 +37,7 @@ impl<'a> BitStringRef<'a> {
return Err(Self::TAG.value_error());
}
- let inner = ByteSlice::new(bytes).map_err(|_| Self::TAG.length_error())?;
+ let inner = BytesRef::new(bytes).map_err(|_| Self::TAG.length_error())?;
let bit_length = usize::try_from(inner.len())?
.checked_mul(8)
@@ -120,6 +117,8 @@ impl<'a> BitStringRef<'a> {
}
}
+impl_any_conversions!(BitStringRef<'a>, 'a);
+
impl<'a> DecodeValue<'a> for BitStringRef<'a> {
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
let header = Header {
@@ -128,7 +127,7 @@ impl<'a> DecodeValue<'a> for BitStringRef<'a> {
};
let unused_bits = reader.read_byte()?;
- let inner = ByteSlice::decode_value(reader, header)?;
+ let inner = BytesRef::decode_value(reader, header)?;
Self::new(unused_bits, inner.as_slice())
}
}
@@ -138,7 +137,7 @@ impl EncodeValue for BitStringRef<'_> {
self.byte_len() + Length::ONE
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
writer.write_byte(self.unused_bits)?;
writer.write(self.raw_bytes())
}
@@ -159,14 +158,6 @@ impl<'a> From<&BitStringRef<'a>> for BitStringRef<'a> {
}
}
-impl<'a> TryFrom<AnyRef<'a>> for BitStringRef<'a> {
- type Error = Error;
-
- fn try_from(any: AnyRef<'a>) -> Result<BitStringRef<'a>> {
- any.decode_into()
- }
-}
-
impl<'a> TryFrom<&'a [u8]> for BitStringRef<'a> {
type Error = Error;
@@ -180,7 +171,7 @@ impl<'a> TryFrom<&&'a [u8]> for BitStringRef<'a> {
type Error = Error;
fn try_from(bytes: &&'a [u8]) -> Result<BitStringRef<'a>> {
- BitStringRef::from_bytes(*bytes)
+ BitStringRef::from_bytes(bytes)
}
}
@@ -198,141 +189,198 @@ impl<'a> FixedTag for BitStringRef<'a> {
const TAG: Tag = Tag::BitString;
}
-/// Owned form of ASN.1 `BIT STRING` type.
-///
-/// This type provides the same functionality as [`BitStringRef`] but owns the
-/// backing data.
-#[cfg(feature = "alloc")]
-#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
-#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
-pub struct BitString {
- /// Number of unused bits in the final octet.
- unused_bits: u8,
-
- /// Length of this `BIT STRING` in bits.
- bit_length: usize,
+// Implement by hand because the derive would create invalid values.
+// Use the constructor to create a valid value.
+#[cfg(feature = "arbitrary")]
+impl<'a> arbitrary::Arbitrary<'a> for BitStringRef<'a> {
+ fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
+ Self::new(
+ u.int_in_range(0..=Self::MAX_UNUSED_BITS)?,
+ BytesRef::arbitrary(u)?.as_slice(),
+ )
+ .map_err(|_| arbitrary::Error::IncorrectFormat)
+ }
- /// Bitstring represented as a slice of bytes.
- inner: Vec<u8>,
+ fn size_hint(depth: usize) -> (usize, Option<usize>) {
+ arbitrary::size_hint::and(u8::size_hint(depth), BytesRef::size_hint(depth))
+ }
}
#[cfg(feature = "alloc")]
-impl BitString {
- /// Maximum number of unused bits allowed.
- pub const MAX_UNUSED_BITS: u8 = 7;
+pub use self::allocating::BitString;
- /// Create a new ASN.1 `BIT STRING` from a byte slice.
+#[cfg(feature = "alloc")]
+mod allocating {
+ use super::*;
+ use crate::referenced::*;
+ use alloc::vec::Vec;
+
+ /// Owned form of ASN.1 `BIT STRING` type.
///
- /// Accepts an optional number of "unused bits" (0-7) which are omitted
- /// from the final octet. This number is 0 if the value is octet-aligned.
- pub fn new(unused_bits: u8, bytes: impl Into<Vec<u8>>) -> Result<Self> {
- let inner = bytes.into();
+ /// This type provides the same functionality as [`BitStringRef`] but owns the
+ /// backing data.
+ #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
+ pub struct BitString {
+ /// Number of unused bits in the final octet.
+ unused_bits: u8,
+
+ /// Length of this `BIT STRING` in bits.
+ bit_length: usize,
+
+ /// Bitstring represented as a slice of bytes.
+ inner: Vec<u8>,
+ }
+
+ impl BitString {
+ /// Maximum number of unused bits allowed.
+ pub const MAX_UNUSED_BITS: u8 = 7;
+
+ /// Create a new ASN.1 `BIT STRING` from a byte slice.
+ ///
+ /// Accepts an optional number of "unused bits" (0-7) which are omitted
+ /// from the final octet. This number is 0 if the value is octet-aligned.
+ pub fn new(unused_bits: u8, bytes: impl Into<Vec<u8>>) -> Result<Self> {
+ let inner = bytes.into();
+
+ // Ensure parameters parse successfully as a `BitStringRef`.
+ let bit_length = BitStringRef::new(unused_bits, &inner)?.bit_length;
+
+ Ok(BitString {
+ unused_bits,
+ bit_length,
+ inner,
+ })
+ }
- // Ensure parameters parse successfully as a `BitStringRef`.
- let bit_length = BitStringRef::new(unused_bits, &inner)?.bit_length;
+ /// Create a new ASN.1 `BIT STRING` from the given bytes.
+ ///
+ /// The "unused bits" are set to 0.
+ pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
+ Self::new(0, bytes)
+ }
- Ok(BitString {
- unused_bits,
- bit_length,
- inner,
- })
- }
+ /// Get the number of unused bits in the octet serialization of this
+ /// `BIT STRING`.
+ pub fn unused_bits(&self) -> u8 {
+ self.unused_bits
+ }
- /// Create a new ASN.1 `BIT STRING` from the given bytes.
- ///
- /// The "unused bits" are set to 0.
- pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
- Self::new(0, bytes)
- }
+ /// Is the number of unused bits a value other than 0?
+ pub fn has_unused_bits(&self) -> bool {
+ self.unused_bits != 0
+ }
- /// Get the number of unused bits in the octet serialization of this
- /// `BIT STRING`.
- pub fn unused_bits(&self) -> u8 {
- self.unused_bits
- }
+ /// Get the length of this `BIT STRING` in bits.
+ pub fn bit_len(&self) -> usize {
+ self.bit_length
+ }
- /// Is the number of unused bits a value other than 0?
- pub fn has_unused_bits(&self) -> bool {
- self.unused_bits != 0
- }
+ /// Is the inner byte slice empty?
+ pub fn is_empty(&self) -> bool {
+ self.inner.is_empty()
+ }
- /// Get the length of this `BIT STRING` in bits.
- pub fn bit_len(&self) -> usize {
- self.bit_length
- }
+ /// Borrow the inner byte slice.
+ ///
+ /// Returns `None` if the number of unused bits is *not* equal to zero,
+ /// i.e. if the `BIT STRING` is not octet aligned.
+ ///
+ /// Use [`BitString::raw_bytes`] to obtain access to the raw value
+ /// regardless of the presence of unused bits.
+ pub fn as_bytes(&self) -> Option<&[u8]> {
+ if self.has_unused_bits() {
+ None
+ } else {
+ Some(self.raw_bytes())
+ }
+ }
- /// Is the inner byte slice empty?
- pub fn is_empty(&self) -> bool {
- self.inner.is_empty()
- }
+ /// Borrow the raw bytes of this `BIT STRING`.
+ pub fn raw_bytes(&self) -> &[u8] {
+ self.inner.as_slice()
+ }
- /// Borrow the inner byte slice.
- ///
- /// Returns `None` if the number of unused bits is *not* equal to zero,
- /// i.e. if the `BIT STRING` is not octet aligned.
- ///
- /// Use [`BitString::raw_bytes`] to obtain access to the raw value
- /// regardless of the presence of unused bits.
- pub fn as_bytes(&self) -> Option<&[u8]> {
- if self.has_unused_bits() {
- None
- } else {
- Some(self.raw_bytes())
+ /// Iterator over the bits of this `BIT STRING`.
+ pub fn bits(&self) -> BitStringIter<'_> {
+ BitStringRef::from(self).bits()
}
}
- /// Borrow the raw bytes of this `BIT STRING`.
- pub fn raw_bytes(&self) -> &[u8] {
- self.inner.as_slice()
+ impl_any_conversions!(BitString);
+
+ impl<'a> DecodeValue<'a> for BitString {
+ fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
+ let inner_len = (header.length - Length::ONE)?;
+ let unused_bits = reader.read_byte()?;
+ let inner = reader.read_vec(inner_len)?;
+ Self::new(unused_bits, inner)
+ }
}
- /// Iterator over the bits of this `BIT STRING`.
- pub fn bits(&self) -> BitStringIter<'_> {
- BitStringRef::from(self).bits()
+ impl EncodeValue for BitString {
+ fn value_len(&self) -> Result<Length> {
+ Length::ONE + Length::try_from(self.inner.len())?
+ }
+
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
+ writer.write_byte(self.unused_bits)?;
+ writer.write(&self.inner)
+ }
}
-}
-#[cfg(feature = "alloc")]
-impl<'a> DecodeValue<'a> for BitString {
- fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
- let inner_len = (header.length - Length::ONE)?;
- let unused_bits = reader.read_byte()?;
- let inner = reader.read_vec(inner_len)?;
- Self::new(unused_bits, inner)
+ impl FixedTag for BitString {
+ const TAG: Tag = Tag::BitString;
}
-}
-#[cfg(feature = "alloc")]
-impl EncodeValue for BitString {
- fn value_len(&self) -> Result<Length> {
- Length::ONE + Length::try_from(self.inner.len())?
+ impl<'a> From<&'a BitString> for BitStringRef<'a> {
+ fn from(bit_string: &'a BitString) -> BitStringRef<'a> {
+ // Ensured to parse successfully in constructor
+ BitStringRef::new(bit_string.unused_bits, &bit_string.inner)
+ .expect("invalid BIT STRING")
+ }
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
- writer.write_byte(self.unused_bits)?;
- writer.write(&self.inner)
+ impl ValueOrd for BitString {
+ fn value_cmp(&self, other: &Self) -> Result<Ordering> {
+ match self.unused_bits.cmp(&other.unused_bits) {
+ Ordering::Equal => self.inner.der_cmp(&other.inner),
+ ordering => Ok(ordering),
+ }
+ }
}
-}
-#[cfg(feature = "alloc")]
-impl FixedTag for BitString {
- const TAG: Tag = Tag::BitString;
-}
+ // Implement by hand because the derive would create invalid values.
+ // Use the constructor to create a valid value.
+ #[cfg(feature = "arbitrary")]
+ impl<'a> arbitrary::Arbitrary<'a> for BitString {
+ fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
+ Self::new(
+ u.int_in_range(0..=Self::MAX_UNUSED_BITS)?,
+ BytesRef::arbitrary(u)?.as_slice(),
+ )
+ .map_err(|_| arbitrary::Error::IncorrectFormat)
+ }
-#[cfg(feature = "alloc")]
-impl<'a> From<&'a BitString> for BitStringRef<'a> {
- fn from(bit_string: &'a BitString) -> BitStringRef<'a> {
- // Ensured to parse successfully in constructor
- BitStringRef::new(bit_string.unused_bits, &bit_string.inner).expect("invalid BIT STRING")
+ fn size_hint(depth: usize) -> (usize, Option<usize>) {
+ arbitrary::size_hint::and(u8::size_hint(depth), BytesRef::size_hint(depth))
+ }
}
-}
-#[cfg(feature = "alloc")]
-impl ValueOrd for BitString {
- fn value_cmp(&self, other: &Self) -> Result<Ordering> {
- match self.unused_bits.cmp(&other.unused_bits) {
- Ordering::Equal => self.inner.der_cmp(&other.inner),
- ordering => Ok(ordering),
+ impl<'a> RefToOwned<'a> for BitStringRef<'a> {
+ type Owned = BitString;
+ fn ref_to_owned(&self) -> Self::Owned {
+ BitString {
+ unused_bits: self.unused_bits,
+ bit_length: self.bit_length,
+ inner: Vec::from(self.inner.as_slice()),
+ }
+ }
+ }
+
+ impl OwnedToRef for BitString {
+ type Borrowed<'a> = BitStringRef<'a>;
+ fn owned_to_ref(&self) -> Self::Borrowed<'_> {
+ self.into()
}
}
}
@@ -445,7 +493,7 @@ where
BitStringRef::new((lead % 8) as u8, buff)?.value_len()
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
let (lead, buff) = encode_flagset(self);
let buff = &buff[..buff.len() - lead / 8];
BitStringRef::new((lead % 8) as u8, buff)?.encode_value(writer)
@@ -486,7 +534,7 @@ mod tests {
assert_eq!(bits.len(), 18);
for bit in [0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1] {
- assert_eq!(bits.next().unwrap() as u8, bit)
+ assert_eq!(u8::from(bits.next().unwrap()), bit)
}
// Ensure `None` is returned on successive calls
diff --git a/vendor/der/src/asn1/boolean.rs b/vendor/der/src/asn1/boolean.rs
index e03218120..3eb0f2e68 100644
--- a/vendor/der/src/asn1/boolean.rs
+++ b/vendor/der/src/asn1/boolean.rs
@@ -1,8 +1,8 @@
//! ASN.1 `BOOLEAN` support.
use crate::{
- asn1::AnyRef, ord::OrdIsValueOrd, ByteSlice, DecodeValue, EncodeValue, Error, ErrorKind,
- FixedTag, Header, Length, Reader, Result, Tag, Writer,
+ asn1::AnyRef, ord::OrdIsValueOrd, DecodeValue, EncodeValue, Error, ErrorKind, FixedTag, Header,
+ Length, Reader, Result, Tag, Writer,
};
/// Byte used to encode `true` in ASN.1 DER. From X.690 Section 11.1:
@@ -33,7 +33,7 @@ impl EncodeValue for bool {
Ok(Length::ONE)
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
writer.write_byte(if *self { TRUE_OCTET } else { FALSE_OCTET })
}
}
@@ -44,17 +44,6 @@ impl FixedTag for bool {
impl OrdIsValueOrd for bool {}
-impl From<bool> for AnyRef<'static> {
- fn from(value: bool) -> AnyRef<'static> {
- let value = ByteSlice::from(match value {
- false => &[FALSE_OCTET],
- true => &[TRUE_OCTET],
- });
-
- AnyRef::from_tag_and_value(Tag::Boolean, value)
- }
-}
-
impl TryFrom<AnyRef<'_>> for bool {
type Error = Error;
diff --git a/vendor/der/src/asn1/context_specific.rs b/vendor/der/src/asn1/context_specific.rs
index 311b5fe74..101ddf022 100644
--- a/vendor/der/src/asn1/context_specific.rs
+++ b/vendor/der/src/asn1/context_specific.rs
@@ -145,7 +145,7 @@ where
}
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
match self.tag_mode {
TagMode::Explicit => self.value.encode(writer),
TagMode::Implicit => self.value.encode_value(writer),
@@ -239,7 +239,7 @@ where
self.encoder().value_len()
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
self.encoder().encode_value(writer)
}
}
diff --git a/vendor/der/src/asn1/generalized_time.rs b/vendor/der/src/asn1/generalized_time.rs
index 9950e368e..f7b6f180f 100644
--- a/vendor/der/src/asn1/generalized_time.rs
+++ b/vendor/der/src/asn1/generalized_time.rs
@@ -1,16 +1,18 @@
//! ASN.1 `GeneralizedTime` support.
+#![cfg_attr(feature = "arbitrary", allow(clippy::integer_arithmetic))]
use crate::{
- asn1::AnyRef,
datetime::{self, DateTime},
ord::OrdIsValueOrd,
- DecodeValue, EncodeValue, Error, ErrorKind, FixedTag, Header, Length, Reader, Result, Tag,
- Writer,
+ DecodeValue, EncodeValue, ErrorKind, FixedTag, Header, Length, Reader, Result, Tag, Writer,
};
use core::time::Duration;
#[cfg(feature = "std")]
-use std::time::SystemTime;
+use {
+ crate::{asn1::AnyRef, Error},
+ std::time::SystemTime,
+};
#[cfg(feature = "time")]
use time::PrimitiveDateTime;
@@ -26,6 +28,7 @@ use time::PrimitiveDateTime;
/// > is zero. GeneralizedTime values MUST NOT include fractional seconds.
///
/// [1]: https://tools.ietf.org/html/rfc5280#section-4.1.2.5.2
+#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub struct GeneralizedTime(DateTime);
@@ -58,7 +61,6 @@ impl GeneralizedTime {
/// Instantiate from [`SystemTime`].
#[cfg(feature = "std")]
- #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub fn from_system_time(time: SystemTime) -> Result<Self> {
DateTime::try_from(time)
.map(Into::into)
@@ -67,12 +69,13 @@ impl GeneralizedTime {
/// Convert to [`SystemTime`].
#[cfg(feature = "std")]
- #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub fn to_system_time(&self) -> SystemTime {
self.0.to_system_time()
}
}
+impl_any_conversions!(GeneralizedTime);
+
impl<'a> DecodeValue<'a> for GeneralizedTime {
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
if Self::LENGTH != usize::try_from(header.length)? {
@@ -111,7 +114,7 @@ impl EncodeValue for GeneralizedTime {
Self::LENGTH.try_into()
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
let year_hi = u8::try_from(self.0.year() / 100)?;
let year_lo = u8::try_from(self.0.year() % 100)?;
@@ -162,14 +165,6 @@ impl From<&DateTime> for GeneralizedTime {
}
}
-impl TryFrom<AnyRef<'_>> for GeneralizedTime {
- type Error = Error;
-
- fn try_from(any: AnyRef<'_>) -> Result<GeneralizedTime> {
- any.decode_into()
- }
-}
-
impl<'a> DecodeValue<'a> for DateTime {
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
Ok(GeneralizedTime::decode_value(reader, header)?.into())
@@ -181,7 +176,7 @@ impl EncodeValue for DateTime {
GeneralizedTime::from(self).value_len()
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
GeneralizedTime::from(self).encode_value(writer)
}
}
@@ -193,7 +188,6 @@ impl FixedTag for DateTime {
impl OrdIsValueOrd for DateTime {}
#[cfg(feature = "std")]
-#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl<'a> DecodeValue<'a> for SystemTime {
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
Ok(GeneralizedTime::decode_value(reader, header)?.into())
@@ -201,19 +195,17 @@ impl<'a> DecodeValue<'a> for SystemTime {
}
#[cfg(feature = "std")]
-#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl EncodeValue for SystemTime {
fn value_len(&self) -> Result<Length> {
GeneralizedTime::try_from(self)?.value_len()
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
GeneralizedTime::try_from(self)?.encode_value(writer)
}
}
#[cfg(feature = "std")]
-#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl From<GeneralizedTime> for SystemTime {
fn from(time: GeneralizedTime) -> SystemTime {
time.to_system_time()
@@ -221,7 +213,6 @@ impl From<GeneralizedTime> for SystemTime {
}
#[cfg(feature = "std")]
-#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl From<&GeneralizedTime> for SystemTime {
fn from(time: &GeneralizedTime) -> SystemTime {
time.to_system_time()
@@ -229,7 +220,6 @@ impl From<&GeneralizedTime> for SystemTime {
}
#[cfg(feature = "std")]
-#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl TryFrom<SystemTime> for GeneralizedTime {
type Error = Error;
@@ -239,7 +229,6 @@ impl TryFrom<SystemTime> for GeneralizedTime {
}
#[cfg(feature = "std")]
-#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl TryFrom<&SystemTime> for GeneralizedTime {
type Error = Error;
@@ -249,7 +238,6 @@ impl TryFrom<&SystemTime> for GeneralizedTime {
}
#[cfg(feature = "std")]
-#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl<'a> TryFrom<AnyRef<'a>> for SystemTime {
type Error = Error;
@@ -259,17 +247,14 @@ impl<'a> TryFrom<AnyRef<'a>> for SystemTime {
}
#[cfg(feature = "std")]
-#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl FixedTag for SystemTime {
const TAG: Tag = Tag::GeneralizedTime;
}
#[cfg(feature = "std")]
-#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl OrdIsValueOrd for SystemTime {}
#[cfg(feature = "time")]
-#[cfg_attr(docsrs, doc(cfg(feature = "time")))]
impl<'a> DecodeValue<'a> for PrimitiveDateTime {
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
GeneralizedTime::decode_value(reader, header)?.try_into()
@@ -277,29 +262,25 @@ impl<'a> DecodeValue<'a> for PrimitiveDateTime {
}
#[cfg(feature = "time")]
-#[cfg_attr(docsrs, doc(cfg(feature = "time")))]
impl EncodeValue for PrimitiveDateTime {
fn value_len(&self) -> Result<Length> {
GeneralizedTime::try_from(self)?.value_len()
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
GeneralizedTime::try_from(self)?.encode_value(writer)
}
}
#[cfg(feature = "time")]
-#[cfg_attr(docsrs, doc(cfg(feature = "time")))]
impl FixedTag for PrimitiveDateTime {
const TAG: Tag = Tag::GeneralizedTime;
}
#[cfg(feature = "time")]
-#[cfg_attr(docsrs, doc(cfg(feature = "time")))]
impl OrdIsValueOrd for PrimitiveDateTime {}
#[cfg(feature = "time")]
-#[cfg_attr(docsrs, doc(cfg(feature = "time")))]
impl TryFrom<PrimitiveDateTime> for GeneralizedTime {
type Error = Error;
@@ -309,7 +290,6 @@ impl TryFrom<PrimitiveDateTime> for GeneralizedTime {
}
#[cfg(feature = "time")]
-#[cfg_attr(docsrs, doc(cfg(feature = "time")))]
impl TryFrom<&PrimitiveDateTime> for GeneralizedTime {
type Error = Error;
@@ -319,7 +299,6 @@ impl TryFrom<&PrimitiveDateTime> for GeneralizedTime {
}
#[cfg(feature = "time")]
-#[cfg_attr(docsrs, doc(cfg(feature = "time")))]
impl TryFrom<GeneralizedTime> for PrimitiveDateTime {
type Error = Error;
diff --git a/vendor/der/src/asn1/ia5_string.rs b/vendor/der/src/asn1/ia5_string.rs
index 3971270a8..c3f24f01c 100644
--- a/vendor/der/src/asn1/ia5_string.rs
+++ b/vendor/der/src/asn1/ia5_string.rs
@@ -1,10 +1,26 @@
//! ASN.1 `IA5String` support.
-use crate::{
- asn1::AnyRef, ord::OrdIsValueOrd, ByteSlice, DecodeValue, EncodeValue, Error, FixedTag, Header,
- Length, Reader, Result, StrSlice, Tag, Writer,
-};
-use core::{fmt, ops::Deref, str};
+use crate::{asn1::AnyRef, FixedTag, Result, StrRef, Tag};
+use core::{fmt, ops::Deref};
+
+macro_rules! impl_ia5_string {
+ ($type: ty) => {
+ impl_ia5_string!($type,);
+ };
+ ($type: ty, $($li: lifetime)?) => {
+ impl_string_type!($type, $($li),*);
+
+ impl<$($li),*> FixedTag for $type {
+ const TAG: Tag = Tag::Ia5String;
+ }
+
+ impl<$($li),*> fmt::Debug for $type {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "Ia5String({:?})", self.as_str())
+ }
+ }
+ };
+}
/// ASN.1 `IA5String` type.
///
@@ -21,7 +37,7 @@ use core::{fmt, ops::Deref, str};
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord)]
pub struct Ia5StringRef<'a> {
/// Inner value
- inner: StrSlice<'a>,
+ inner: StrRef<'a>,
}
impl<'a> Ia5StringRef<'a> {
@@ -37,83 +53,117 @@ impl<'a> Ia5StringRef<'a> {
return Err(Self::TAG.value_error());
}
- StrSlice::from_bytes(input)
+ StrRef::from_bytes(input)
.map(|inner| Self { inner })
.map_err(|_| Self::TAG.value_error())
}
}
+impl_ia5_string!(Ia5StringRef<'a>, 'a);
+
impl<'a> Deref for Ia5StringRef<'a> {
- type Target = StrSlice<'a>;
+ type Target = StrRef<'a>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
-impl AsRef<str> for Ia5StringRef<'_> {
- fn as_ref(&self) -> &str {
- self.as_str()
+impl<'a> From<&Ia5StringRef<'a>> for Ia5StringRef<'a> {
+ fn from(value: &Ia5StringRef<'a>) -> Ia5StringRef<'a> {
+ *value
}
}
-impl AsRef<[u8]> for Ia5StringRef<'_> {
- fn as_ref(&self) -> &[u8] {
- self.as_bytes()
+impl<'a> From<Ia5StringRef<'a>> for AnyRef<'a> {
+ fn from(internationalized_string: Ia5StringRef<'a>) -> AnyRef<'a> {
+ AnyRef::from_tag_and_value(Tag::Ia5String, internationalized_string.inner.into())
}
}
-impl<'a> DecodeValue<'a> for Ia5StringRef<'a> {
- fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
- Self::new(ByteSlice::decode_value(reader, header)?.as_slice())
- }
-}
+#[cfg(feature = "alloc")]
+pub use self::allocation::Ia5String;
-impl EncodeValue for Ia5StringRef<'_> {
- fn value_len(&self) -> Result<Length> {
- self.inner.value_len()
+#[cfg(feature = "alloc")]
+mod allocation {
+ use super::Ia5StringRef;
+ use crate::{
+ asn1::AnyRef,
+ referenced::{OwnedToRef, RefToOwned},
+ FixedTag, Result, StrOwned, Tag,
+ };
+ use core::{fmt, ops::Deref};
+
+ /// ASN.1 `IA5String` type.
+ ///
+ /// Supports the [International Alphabet No. 5 (IA5)] character encoding, i.e.
+ /// the lower 128 characters of the ASCII alphabet. (Note: IA5 is now
+ /// technically known as the International Reference Alphabet or IRA as
+ /// specified in the ITU-T's T.50 recommendation).
+ ///
+ /// For UTF-8, use [`String`][`alloc::string::String`].
+ ///
+ /// [International Alphabet No. 5 (IA5)]: https://en.wikipedia.org/wiki/T.50_%28standard%29
+ #[derive(Clone, Eq, PartialEq, PartialOrd, Ord)]
+ pub struct Ia5String {
+ /// Inner value
+ inner: StrOwned,
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
- self.inner.encode_value(writer)
+ impl Ia5String {
+ /// Create a new `IA5String`.
+ pub fn new<T>(input: &T) -> Result<Self>
+ where
+ T: AsRef<[u8]> + ?Sized,
+ {
+ let input = input.as_ref();
+ Ia5StringRef::new(input)?;
+
+ StrOwned::from_bytes(input)
+ .map(|inner| Self { inner })
+ .map_err(|_| Self::TAG.value_error())
+ }
}
-}
-impl<'a> FixedTag for Ia5StringRef<'a> {
- const TAG: Tag = Tag::Ia5String;
-}
+ impl_ia5_string!(Ia5String);
-impl OrdIsValueOrd for Ia5StringRef<'_> {}
+ impl Deref for Ia5String {
+ type Target = StrOwned;
-impl<'a> From<&Ia5StringRef<'a>> for Ia5StringRef<'a> {
- fn from(value: &Ia5StringRef<'a>) -> Ia5StringRef<'a> {
- *value
+ fn deref(&self) -> &Self::Target {
+ &self.inner
+ }
}
-}
-
-impl<'a> TryFrom<AnyRef<'a>> for Ia5StringRef<'a> {
- type Error = Error;
- fn try_from(any: AnyRef<'a>) -> Result<Ia5StringRef<'a>> {
- any.decode_into()
+ impl<'a> From<Ia5StringRef<'a>> for Ia5String {
+ fn from(international_string: Ia5StringRef<'a>) -> Ia5String {
+ let inner = international_string.inner.into();
+ Self { inner }
+ }
}
-}
-impl<'a> From<Ia5StringRef<'a>> for AnyRef<'a> {
- fn from(printable_string: Ia5StringRef<'a>) -> AnyRef<'a> {
- AnyRef::from_tag_and_value(Tag::Ia5String, printable_string.inner.into())
+ impl<'a> From<&'a Ia5String> for AnyRef<'a> {
+ fn from(international_string: &'a Ia5String) -> AnyRef<'a> {
+ AnyRef::from_tag_and_value(Tag::Ia5String, (&international_string.inner).into())
+ }
}
-}
-impl<'a> fmt::Display for Ia5StringRef<'a> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str(self.as_str())
+ impl<'a> RefToOwned<'a> for Ia5StringRef<'a> {
+ type Owned = Ia5String;
+ fn ref_to_owned(&self) -> Self::Owned {
+ Ia5String {
+ inner: self.inner.ref_to_owned(),
+ }
+ }
}
-}
-impl<'a> fmt::Debug for Ia5StringRef<'a> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "Ia5String({:?})", self.as_str())
+ impl OwnedToRef for Ia5String {
+ type Borrowed<'a> = Ia5StringRef<'a>;
+ fn owned_to_ref(&self) -> Self::Borrowed<'_> {
+ Ia5StringRef {
+ inner: self.inner.owned_to_ref(),
+ }
+ }
}
}
@@ -126,7 +176,7 @@ mod tests {
#[test]
fn parse_bytes() {
let example_bytes = hex!("16 0d 74 65 73 74 31 40 72 73 61 2e 63 6f 6d");
- let printable_string = Ia5StringRef::from_der(&example_bytes).unwrap();
- assert_eq!(printable_string.as_str(), "test1@rsa.com");
+ let internationalized_string = Ia5StringRef::from_der(&example_bytes).unwrap();
+ assert_eq!(internationalized_string.as_str(), "test1@rsa.com");
}
}
diff --git a/vendor/der/src/asn1/integer.rs b/vendor/der/src/asn1/integer.rs
index 20e2f018f..a6e913d66 100644
--- a/vendor/der/src/asn1/integer.rs
+++ b/vendor/der/src/asn1/integer.rs
@@ -1,132 +1,17 @@
//! ASN.1 `INTEGER` support.
-pub(super) mod bigint;
pub(super) mod int;
pub(super) mod uint;
-use crate::{
- asn1::AnyRef, ByteSlice, DecodeValue, EncodeValue, Error, FixedTag, Header, Length, Reader,
- Result, SliceWriter, Tag, ValueOrd, Writer,
-};
use core::{cmp::Ordering, mem};
-macro_rules! impl_int_encoding {
- ($($int:ty => $uint:ty),+) => {
- $(
- impl<'a> DecodeValue<'a> for $int {
- fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
- let bytes = ByteSlice::decode_value(reader, header)?.as_slice();
+use crate::{EncodeValue, Result, SliceWriter};
- let result = if is_highest_bit_set(bytes) {
- <$uint>::from_be_bytes(int::decode_to_array(bytes)?) as $int
- } else {
- Self::from_be_bytes(uint::decode_to_array(bytes)?)
- };
-
- // Ensure we compute the same encoded length as the original any value
- if header.length != result.value_len()? {
- return Err(Self::TAG.non_canonical_error());
- }
-
- Ok(result)
- }
- }
-
- impl EncodeValue for $int {
- fn value_len(&self) -> Result<Length> {
- if *self < 0 {
- int::encoded_len(&(*self as $uint).to_be_bytes())
- } else {
- uint::encoded_len(&self.to_be_bytes())
- }
- }
-
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
- if *self < 0 {
- int::encode_bytes(writer, &(*self as $uint).to_be_bytes())
- } else {
- uint::encode_bytes(writer, &self.to_be_bytes())
- }
- }
- }
-
- impl FixedTag for $int {
- const TAG: Tag = Tag::Integer;
- }
-
- impl ValueOrd for $int {
- fn value_cmp(&self, other: &Self) -> Result<Ordering> {
- value_cmp(*self, *other)
- }
- }
-
- impl TryFrom<AnyRef<'_>> for $int {
- type Error = Error;
-
- fn try_from(any: AnyRef<'_>) -> Result<Self> {
- any.decode_into()
- }
- }
- )+
- };
-}
-
-macro_rules! impl_uint_encoding {
- ($($uint:ty),+) => {
- $(
- impl<'a> DecodeValue<'a> for $uint {
- fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
- let bytes = ByteSlice::decode_value(reader, header)?.as_slice();
- let result = Self::from_be_bytes(uint::decode_to_array(bytes)?);
-
- // Ensure we compute the same encoded length as the original any value
- if header.length != result.value_len()? {
- return Err(Self::TAG.non_canonical_error());
- }
-
- Ok(result)
- }
- }
-
- impl EncodeValue for $uint {
- fn value_len(&self) -> Result<Length> {
- uint::encoded_len(&self.to_be_bytes())
- }
-
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
- uint::encode_bytes(writer, &self.to_be_bytes())
- }
- }
-
- impl FixedTag for $uint {
- const TAG: Tag = Tag::Integer;
- }
-
- impl ValueOrd for $uint {
- fn value_cmp(&self, other: &Self) -> Result<Ordering> {
- value_cmp(*self, *other)
- }
- }
-
- impl TryFrom<AnyRef<'_>> for $uint {
- type Error = Error;
-
- fn try_from(any: AnyRef<'_>) -> Result<Self> {
- any.decode_into()
- }
- }
- )+
- };
-}
-
-impl_int_encoding!(i8 => u8, i16 => u16, i32 => u32, i64 => u64, i128 => u128);
-impl_uint_encoding!(u8, u16, u32, u64, u128);
-
-/// Is the highest bit of the first byte in the slice 1? (if present)
+/// Is the highest bit of the first byte in the slice set to `1`? (if present)
#[inline]
fn is_highest_bit_set(bytes: &[u8]) -> bool {
bytes
- .get(0)
+ .first()
.map(|byte| byte & 0b10000000 != 0)
.unwrap_or(false)
}
diff --git a/vendor/der/src/asn1/integer/bigint.rs b/vendor/der/src/asn1/integer/bigint.rs
deleted file mode 100644
index f896406a6..000000000
--- a/vendor/der/src/asn1/integer/bigint.rs
+++ /dev/null
@@ -1,152 +0,0 @@
-//! "Big" ASN.1 `INTEGER` types.
-
-use super::uint;
-use crate::{
- asn1::AnyRef, ord::OrdIsValueOrd, ByteSlice, DecodeValue, EncodeValue, Error, ErrorKind,
- FixedTag, Header, Length, Reader, Result, Tag, Writer,
-};
-
-/// "Big" unsigned ASN.1 `INTEGER` type.
-///
-/// Provides direct access to the underlying big endian bytes which comprise an
-/// unsigned integer value.
-///
-/// Intended for use cases like very large integers that are used in
-/// cryptographic applications (e.g. keys, signatures).
-#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
-pub struct UIntRef<'a> {
- /// Inner value
- inner: ByteSlice<'a>,
-}
-
-impl<'a> UIntRef<'a> {
- /// Create a new [`UIntRef`] from a byte slice.
- pub fn new(bytes: &'a [u8]) -> Result<Self> {
- let inner = ByteSlice::new(uint::strip_leading_zeroes(bytes))
- .map_err(|_| ErrorKind::Length { tag: Self::TAG })?;
-
- Ok(Self { inner })
- }
-
- /// Borrow the inner byte slice which contains the least significant bytes
- /// of a big endian integer value with all leading zeros stripped.
- pub fn as_bytes(&self) -> &'a [u8] {
- self.inner.as_slice()
- }
-
- /// Get the length of this [`UIntRef`] in bytes.
- pub fn len(&self) -> Length {
- self.inner.len()
- }
-
- /// Is the inner byte slice empty?
- pub fn is_empty(&self) -> bool {
- self.inner.is_empty()
- }
-}
-
-impl<'a> DecodeValue<'a> for UIntRef<'a> {
- fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
- let bytes = ByteSlice::decode_value(reader, header)?.as_slice();
- let result = Self::new(uint::decode_to_slice(bytes)?)?;
-
- // Ensure we compute the same encoded length as the original any value.
- if result.value_len()? != header.length {
- return Err(Self::TAG.non_canonical_error());
- }
-
- Ok(result)
- }
-}
-
-impl<'a> EncodeValue for UIntRef<'a> {
- fn value_len(&self) -> Result<Length> {
- uint::encoded_len(self.inner.as_slice())
- }
-
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
- // Add leading `0x00` byte if required
- if self.value_len()? > self.len() {
- writer.write_byte(0)?;
- }
-
- writer.write(self.as_bytes())
- }
-}
-
-impl<'a> From<&UIntRef<'a>> for UIntRef<'a> {
- fn from(value: &UIntRef<'a>) -> UIntRef<'a> {
- *value
- }
-}
-
-impl<'a> TryFrom<AnyRef<'a>> for UIntRef<'a> {
- type Error = Error;
-
- fn try_from(any: AnyRef<'a>) -> Result<UIntRef<'a>> {
- any.decode_into()
- }
-}
-
-impl<'a> FixedTag for UIntRef<'a> {
- const TAG: Tag = Tag::Integer;
-}
-
-impl<'a> OrdIsValueOrd for UIntRef<'a> {}
-
-#[cfg(test)]
-mod tests {
- use super::UIntRef;
- use crate::{
- asn1::{integer::tests::*, AnyRef},
- Decode, Encode, ErrorKind, SliceWriter, Tag,
- };
-
- #[test]
- fn decode_uint_bytes() {
- assert_eq!(&[0], UIntRef::from_der(I0_BYTES).unwrap().as_bytes());
- assert_eq!(&[127], UIntRef::from_der(I127_BYTES).unwrap().as_bytes());
- assert_eq!(&[128], UIntRef::from_der(I128_BYTES).unwrap().as_bytes());
- assert_eq!(&[255], UIntRef::from_der(I255_BYTES).unwrap().as_bytes());
-
- assert_eq!(
- &[0x01, 0x00],
- UIntRef::from_der(I256_BYTES).unwrap().as_bytes()
- );
-
- assert_eq!(
- &[0x7F, 0xFF],
- UIntRef::from_der(I32767_BYTES).unwrap().as_bytes()
- );
- }
-
- #[test]
- fn encode_uint_bytes() {
- for &example in &[
- I0_BYTES,
- I127_BYTES,
- I128_BYTES,
- I255_BYTES,
- I256_BYTES,
- I32767_BYTES,
- ] {
- let uint = UIntRef::from_der(example).unwrap();
-
- let mut buf = [0u8; 128];
- let mut encoder = SliceWriter::new(&mut buf);
- uint.encode(&mut encoder).unwrap();
-
- let result = encoder.finish().unwrap();
- assert_eq!(example, result);
- }
- }
-
- #[test]
- fn reject_oversize_without_extra_zero() {
- let err = UIntRef::try_from(AnyRef::new(Tag::Integer, &[0x81]).unwrap())
- .err()
- .unwrap();
-
- assert_eq!(err.kind(), ErrorKind::Value { tag: Tag::Integer });
- }
-}
diff --git a/vendor/der/src/asn1/integer/int.rs b/vendor/der/src/asn1/integer/int.rs
index a9fe43890..bccc5210c 100644
--- a/vendor/der/src/asn1/integer/int.rs
+++ b/vendor/der/src/asn1/integer/int.rs
@@ -1,12 +1,310 @@
-//! Support for encoding negative integers
+//! Support for encoding signed integers
-use super::is_highest_bit_set;
-use crate::{ErrorKind, Length, Result, Writer};
+use super::{is_highest_bit_set, uint, value_cmp};
+use crate::{
+ ord::OrdIsValueOrd, AnyRef, BytesRef, DecodeValue, EncodeValue, Error, ErrorKind, FixedTag,
+ Header, Length, Reader, Result, Tag, ValueOrd, Writer,
+};
+use core::cmp::Ordering;
-/// Decode an unsigned integer of the specified size.
+#[cfg(feature = "alloc")]
+pub use allocating::Int;
+
+macro_rules! impl_encoding_traits {
+ ($($int:ty => $uint:ty),+) => {
+ $(
+ impl<'a> DecodeValue<'a> for $int {
+ fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
+ let mut buf = [0u8; Self::BITS as usize / 8];
+ let max_length = u32::from(header.length) as usize;
+
+ if max_length > buf.len() {
+ return Err(Self::TAG.non_canonical_error());
+ }
+
+ let bytes = reader.read_into(&mut buf[..max_length])?;
+
+ let result = if is_highest_bit_set(bytes) {
+ <$uint>::from_be_bytes(decode_to_array(bytes)?) as $int
+ } else {
+ Self::from_be_bytes(uint::decode_to_array(bytes)?)
+ };
+
+ // Ensure we compute the same encoded length as the original any value
+ if header.length != result.value_len()? {
+ return Err(Self::TAG.non_canonical_error());
+ }
+
+ Ok(result)
+ }
+ }
+
+ impl EncodeValue for $int {
+ fn value_len(&self) -> Result<Length> {
+ if *self < 0 {
+ negative_encoded_len(&(*self as $uint).to_be_bytes())
+ } else {
+ uint::encoded_len(&self.to_be_bytes())
+ }
+ }
+
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
+ if *self < 0 {
+ encode_bytes(writer, &(*self as $uint).to_be_bytes())
+ } else {
+ uint::encode_bytes(writer, &self.to_be_bytes())
+ }
+ }
+ }
+
+ impl FixedTag for $int {
+ const TAG: Tag = Tag::Integer;
+ }
+
+ impl ValueOrd for $int {
+ fn value_cmp(&self, other: &Self) -> Result<Ordering> {
+ value_cmp(*self, *other)
+ }
+ }
+
+ impl TryFrom<AnyRef<'_>> for $int {
+ type Error = Error;
+
+ fn try_from(any: AnyRef<'_>) -> Result<Self> {
+ any.decode_as()
+ }
+ }
+ )+
+ };
+}
+
+impl_encoding_traits!(i8 => u8, i16 => u16, i32 => u32, i64 => u64, i128 => u128);
+
+/// Signed arbitrary precision ASN.1 `INTEGER` reference type.
+///
+/// Provides direct access to the underlying big endian bytes which comprise
+/// an signed integer value.
+///
+/// Intended for use cases like very large integers that are used in
+/// cryptographic applications (e.g. keys, signatures).
+#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
+pub struct IntRef<'a> {
+ /// Inner value
+ inner: BytesRef<'a>,
+}
+
+impl<'a> IntRef<'a> {
+ /// Create a new [`IntRef`] from a byte slice.
+ pub fn new(bytes: &'a [u8]) -> Result<Self> {
+ let inner = BytesRef::new(strip_leading_ones(bytes))
+ .map_err(|_| ErrorKind::Length { tag: Self::TAG })?;
+
+ Ok(Self { inner })
+ }
+
+ /// Borrow the inner byte slice which contains the least significant bytes
+ /// of a big endian integer value with all leading ones stripped.
+ pub fn as_bytes(&self) -> &'a [u8] {
+ self.inner.as_slice()
+ }
+
+ /// Get the length of this [`IntRef`] in bytes.
+ pub fn len(&self) -> Length {
+ self.inner.len()
+ }
+
+ /// Is the inner byte slice empty?
+ pub fn is_empty(&self) -> bool {
+ self.inner.is_empty()
+ }
+}
+
+impl_any_conversions!(IntRef<'a>, 'a);
+
+impl<'a> DecodeValue<'a> for IntRef<'a> {
+ fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
+ let bytes = BytesRef::decode_value(reader, header)?;
+ validate_canonical(bytes.as_slice())?;
+
+ let result = Self::new(bytes.as_slice())?;
+
+ // Ensure we compute the same encoded length as the original any value.
+ if result.value_len()? != header.length {
+ return Err(Self::TAG.non_canonical_error());
+ }
+
+ Ok(result)
+ }
+}
+
+impl<'a> EncodeValue for IntRef<'a> {
+ fn value_len(&self) -> Result<Length> {
+ // Signed integers always hold their full encoded form.
+ Ok(self.inner.len())
+ }
+
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
+ writer.write(self.as_bytes())
+ }
+}
+
+impl<'a> From<&IntRef<'a>> for IntRef<'a> {
+ fn from(value: &IntRef<'a>) -> IntRef<'a> {
+ *value
+ }
+}
+
+impl<'a> FixedTag for IntRef<'a> {
+ const TAG: Tag = Tag::Integer;
+}
+
+impl<'a> OrdIsValueOrd for IntRef<'a> {}
+
+#[cfg(feature = "alloc")]
+mod allocating {
+ use super::{strip_leading_ones, validate_canonical, IntRef};
+ use crate::{
+ asn1::Uint,
+ ord::OrdIsValueOrd,
+ referenced::{OwnedToRef, RefToOwned},
+ BytesOwned, DecodeValue, EncodeValue, ErrorKind, FixedTag, Header, Length, Reader, Result,
+ Tag, Writer,
+ };
+ use alloc::vec::Vec;
+
+ /// Signed arbitrary precision ASN.1 `INTEGER` type.
+ ///
+ /// Provides heap-allocated storage for big endian bytes which comprise an
+ /// signed integer value.
+ ///
+ /// Intended for use cases like very large integers that are used in
+ /// cryptographic applications (e.g. keys, signatures).
+ #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
+ pub struct Int {
+ /// Inner value
+ inner: BytesOwned,
+ }
+
+ impl Int {
+ /// Create a new [`Int`] from a byte slice.
+ pub fn new(bytes: &[u8]) -> Result<Self> {
+ let inner = BytesOwned::new(strip_leading_ones(bytes))
+ .map_err(|_| ErrorKind::Length { tag: Self::TAG })?;
+
+ Ok(Self { inner })
+ }
+
+ /// Borrow the inner byte slice which contains the least significant bytes
+ /// of a big endian integer value with all leading ones stripped.
+ pub fn as_bytes(&self) -> &[u8] {
+ self.inner.as_slice()
+ }
+
+ /// Get the length of this [`Int`] in bytes.
+ pub fn len(&self) -> Length {
+ self.inner.len()
+ }
+
+ /// Is the inner byte slice empty?
+ pub fn is_empty(&self) -> bool {
+ self.inner.is_empty()
+ }
+ }
+
+ impl_any_conversions!(Int);
+
+ impl<'a> DecodeValue<'a> for Int {
+ fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
+ let bytes = BytesOwned::decode_value(reader, header)?;
+ validate_canonical(bytes.as_slice())?;
+
+ let result = Self::new(bytes.as_slice())?;
+
+ // Ensure we compute the same encoded length as the original any value.
+ if result.value_len()? != header.length {
+ return Err(Self::TAG.non_canonical_error());
+ }
+
+ Ok(result)
+ }
+ }
+
+ impl EncodeValue for Int {
+ fn value_len(&self) -> Result<Length> {
+ // Signed integers always hold their full encoded form.
+ Ok(self.inner.len())
+ }
+
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
+ writer.write(self.as_bytes())
+ }
+ }
+
+ impl<'a> From<&IntRef<'a>> for Int {
+ fn from(value: &IntRef<'a>) -> Int {
+ let inner = BytesOwned::new(value.as_bytes()).expect("Invalid Int");
+ Int { inner }
+ }
+ }
+
+ impl From<Uint> for Int {
+ fn from(value: Uint) -> Self {
+ let mut inner: Vec<u8> = Vec::new();
+
+ // Add leading `0x00` byte if required
+ if value.value_len().expect("invalid Uint") > value.len() {
+ inner.push(0x00);
+ }
+
+ inner.extend_from_slice(value.as_bytes());
+ let inner = BytesOwned::new(inner).expect("invalid Uint");
+
+ Int { inner }
+ }
+ }
+
+ impl FixedTag for Int {
+ const TAG: Tag = Tag::Integer;
+ }
+
+ impl OrdIsValueOrd for Int {}
+
+ impl<'a> RefToOwned<'a> for IntRef<'a> {
+ type Owned = Int;
+ fn ref_to_owned(&self) -> Self::Owned {
+ let inner = self.inner.ref_to_owned();
+
+ Int { inner }
+ }
+ }
+
+ impl OwnedToRef for Int {
+ type Borrowed<'a> = IntRef<'a>;
+ fn owned_to_ref(&self) -> Self::Borrowed<'_> {
+ let inner = self.inner.owned_to_ref();
+
+ IntRef { inner }
+ }
+ }
+}
+
+/// Ensure `INTEGER` is canonically encoded.
+fn validate_canonical(bytes: &[u8]) -> Result<()> {
+ // The `INTEGER` type always encodes a signed value and we're decoding
+ // as signed here, so we allow a zero extension or sign extension byte,
+ // but only as permitted under DER canonicalization.
+ match bytes {
+ [] => Err(Tag::Integer.non_canonical_error()),
+ [0x00, byte, ..] if *byte < 0x80 => Err(Tag::Integer.non_canonical_error()),
+ [0xFF, byte, ..] if *byte >= 0x80 => Err(Tag::Integer.non_canonical_error()),
+ _ => Ok(()),
+ }
+}
+
+/// Decode an signed integer of the specified size.
///
/// Returns a byte array of the requested size containing a big endian integer.
-pub(super) fn decode_to_array<const N: usize>(bytes: &[u8]) -> Result<[u8; N]> {
+fn decode_to_array<const N: usize>(bytes: &[u8]) -> Result<[u8; N]> {
match N.checked_sub(bytes.len()) {
Some(offset) => {
let mut output = [0xFFu8; N];
@@ -27,21 +325,21 @@ pub(super) fn decode_to_array<const N: usize>(bytes: &[u8]) -> Result<[u8; N]> {
}
/// Encode the given big endian bytes representing an integer as ASN.1 DER.
-pub(super) fn encode_bytes<W>(writer: &mut W, bytes: &[u8]) -> Result<()>
+fn encode_bytes<W>(writer: &mut W, bytes: &[u8]) -> Result<()>
where
W: Writer + ?Sized,
{
writer.write(strip_leading_ones(bytes))
}
-/// Get the encoded length for the given unsigned integer serialized as bytes.
+/// Get the encoded length for the given **negative** integer serialized as bytes.
#[inline]
-pub(super) fn encoded_len(bytes: &[u8]) -> Result<Length> {
+fn negative_encoded_len(bytes: &[u8]) -> Result<Length> {
Length::try_from(strip_leading_ones(bytes).len())
}
/// Strip the leading all-ones bytes from the given byte slice.
-fn strip_leading_ones(mut bytes: &[u8]) -> &[u8] {
+pub(crate) fn strip_leading_ones(mut bytes: &[u8]) -> &[u8] {
while let Some((byte, rest)) = bytes.split_first() {
if *byte == 0xFF && is_highest_bit_set(rest) {
bytes = rest;
@@ -53,3 +351,92 @@ fn strip_leading_ones(mut bytes: &[u8]) -> &[u8] {
bytes
}
+
+#[cfg(test)]
+mod tests {
+ use super::{validate_canonical, IntRef};
+ use crate::{asn1::integer::tests::*, Decode, Encode, SliceWriter};
+
+ #[test]
+ fn validate_canonical_ok() {
+ assert_eq!(validate_canonical(&[0x00]), Ok(()));
+ assert_eq!(validate_canonical(&[0x01]), Ok(()));
+ assert_eq!(validate_canonical(&[0x00, 0x80]), Ok(()));
+ assert_eq!(validate_canonical(&[0xFF, 0x00]), Ok(()));
+ }
+
+ #[test]
+ fn validate_canonical_err() {
+ // Empty integers are always non-canonical.
+ assert!(validate_canonical(&[]).is_err());
+
+ // Positives with excessive zero extension are non-canonical.
+ assert!(validate_canonical(&[0x00, 0x00]).is_err());
+
+ // Negatives with excessive sign extension are non-canonical.
+ assert!(validate_canonical(&[0xFF, 0x80]).is_err());
+ }
+
+ #[test]
+ fn decode_intref() {
+ // Positive numbers decode, but have zero extensions as necessary
+ // (to distinguish them from negative representations).
+ assert_eq!(&[0], IntRef::from_der(I0_BYTES).unwrap().as_bytes());
+ assert_eq!(&[127], IntRef::from_der(I127_BYTES).unwrap().as_bytes());
+ assert_eq!(&[0, 128], IntRef::from_der(I128_BYTES).unwrap().as_bytes());
+ assert_eq!(&[0, 255], IntRef::from_der(I255_BYTES).unwrap().as_bytes());
+
+ assert_eq!(
+ &[0x01, 0x00],
+ IntRef::from_der(I256_BYTES).unwrap().as_bytes()
+ );
+
+ assert_eq!(
+ &[0x7F, 0xFF],
+ IntRef::from_der(I32767_BYTES).unwrap().as_bytes()
+ );
+
+ // Negative integers decode.
+ assert_eq!(&[128], IntRef::from_der(INEG128_BYTES).unwrap().as_bytes());
+ assert_eq!(
+ &[255, 127],
+ IntRef::from_der(INEG129_BYTES).unwrap().as_bytes()
+ );
+ assert_eq!(
+ &[128, 0],
+ IntRef::from_der(INEG32768_BYTES).unwrap().as_bytes()
+ );
+ }
+
+ #[test]
+ fn encode_intref() {
+ for &example in &[
+ I0_BYTES,
+ I127_BYTES,
+ I128_BYTES,
+ I255_BYTES,
+ I256_BYTES,
+ I32767_BYTES,
+ ] {
+ let uint = IntRef::from_der(example).unwrap();
+
+ let mut buf = [0u8; 128];
+ let mut encoder = SliceWriter::new(&mut buf);
+ uint.encode(&mut encoder).unwrap();
+
+ let result = encoder.finish().unwrap();
+ assert_eq!(example, result);
+ }
+
+ for &example in &[INEG128_BYTES, INEG129_BYTES, INEG32768_BYTES] {
+ let uint = IntRef::from_der(example).unwrap();
+
+ let mut buf = [0u8; 128];
+ let mut encoder = SliceWriter::new(&mut buf);
+ uint.encode(&mut encoder).unwrap();
+
+ let result = encoder.finish().unwrap();
+ assert_eq!(example, result);
+ }
+ }
+}
diff --git a/vendor/der/src/asn1/integer/uint.rs b/vendor/der/src/asn1/integer/uint.rs
index e45a72f2a..95c6297c2 100644
--- a/vendor/der/src/asn1/integer/uint.rs
+++ b/vendor/der/src/asn1/integer/uint.rs
@@ -1,6 +1,270 @@
//! Unsigned integer decoders/encoders.
-use crate::{Length, Result, Tag, Writer};
+use super::value_cmp;
+use crate::{
+ ord::OrdIsValueOrd, AnyRef, BytesRef, DecodeValue, EncodeValue, Error, ErrorKind, FixedTag,
+ Header, Length, Reader, Result, Tag, ValueOrd, Writer,
+};
+use core::cmp::Ordering;
+
+#[cfg(feature = "alloc")]
+pub use allocating::Uint;
+
+macro_rules! impl_encoding_traits {
+ ($($uint:ty),+) => {
+ $(
+ impl<'a> DecodeValue<'a> for $uint {
+ fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
+ // Integers always encodes as a signed value, unsigned gets a leading 0x00 that
+ // needs to be stripped off. We need to provide room for it.
+ const UNSIGNED_HEADROOM: usize = 1;
+
+ let mut buf = [0u8; (Self::BITS as usize / 8) + UNSIGNED_HEADROOM];
+ let max_length = u32::from(header.length) as usize;
+
+ if max_length > buf.len() {
+ return Err(Self::TAG.non_canonical_error());
+ }
+
+ let bytes = reader.read_into(&mut buf[..max_length])?;
+
+ let result = Self::from_be_bytes(decode_to_array(bytes)?);
+
+ // Ensure we compute the same encoded length as the original any value
+ if header.length != result.value_len()? {
+ return Err(Self::TAG.non_canonical_error());
+ }
+
+ Ok(result)
+ }
+ }
+
+ impl EncodeValue for $uint {
+ fn value_len(&self) -> Result<Length> {
+ encoded_len(&self.to_be_bytes())
+ }
+
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
+ encode_bytes(writer, &self.to_be_bytes())
+ }
+ }
+
+ impl FixedTag for $uint {
+ const TAG: Tag = Tag::Integer;
+ }
+
+ impl ValueOrd for $uint {
+ fn value_cmp(&self, other: &Self) -> Result<Ordering> {
+ value_cmp(*self, *other)
+ }
+ }
+
+ impl TryFrom<AnyRef<'_>> for $uint {
+ type Error = Error;
+
+ fn try_from(any: AnyRef<'_>) -> Result<Self> {
+ any.decode_as()
+ }
+ }
+ )+
+ };
+}
+
+impl_encoding_traits!(u8, u16, u32, u64, u128);
+
+/// Unsigned arbitrary precision ASN.1 `INTEGER` reference type.
+///
+/// Provides direct access to the underlying big endian bytes which comprise an
+/// unsigned integer value.
+///
+/// Intended for use cases like very large integers that are used in
+/// cryptographic applications (e.g. keys, signatures).
+#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
+pub struct UintRef<'a> {
+ /// Inner value
+ inner: BytesRef<'a>,
+}
+
+impl<'a> UintRef<'a> {
+ /// Create a new [`UintRef`] from a byte slice.
+ pub fn new(bytes: &'a [u8]) -> Result<Self> {
+ let inner = BytesRef::new(strip_leading_zeroes(bytes))
+ .map_err(|_| ErrorKind::Length { tag: Self::TAG })?;
+
+ Ok(Self { inner })
+ }
+
+ /// Borrow the inner byte slice which contains the least significant bytes
+ /// of a big endian integer value with all leading zeros stripped.
+ pub fn as_bytes(&self) -> &'a [u8] {
+ self.inner.as_slice()
+ }
+
+ /// Get the length of this [`UintRef`] in bytes.
+ pub fn len(&self) -> Length {
+ self.inner.len()
+ }
+
+ /// Is the inner byte slice empty?
+ pub fn is_empty(&self) -> bool {
+ self.inner.is_empty()
+ }
+}
+
+impl_any_conversions!(UintRef<'a>, 'a);
+
+impl<'a> DecodeValue<'a> for UintRef<'a> {
+ fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
+ let bytes = BytesRef::decode_value(reader, header)?.as_slice();
+ let result = Self::new(decode_to_slice(bytes)?)?;
+
+ // Ensure we compute the same encoded length as the original any value.
+ if result.value_len()? != header.length {
+ return Err(Self::TAG.non_canonical_error());
+ }
+
+ Ok(result)
+ }
+}
+
+impl<'a> EncodeValue for UintRef<'a> {
+ fn value_len(&self) -> Result<Length> {
+ encoded_len(self.inner.as_slice())
+ }
+
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
+ // Add leading `0x00` byte if required
+ if self.value_len()? > self.len() {
+ writer.write_byte(0)?;
+ }
+
+ writer.write(self.as_bytes())
+ }
+}
+
+impl<'a> From<&UintRef<'a>> for UintRef<'a> {
+ fn from(value: &UintRef<'a>) -> UintRef<'a> {
+ *value
+ }
+}
+
+impl<'a> FixedTag for UintRef<'a> {
+ const TAG: Tag = Tag::Integer;
+}
+
+impl<'a> OrdIsValueOrd for UintRef<'a> {}
+
+#[cfg(feature = "alloc")]
+mod allocating {
+ use super::{decode_to_slice, encoded_len, strip_leading_zeroes, UintRef};
+ use crate::{
+ ord::OrdIsValueOrd,
+ referenced::{OwnedToRef, RefToOwned},
+ BytesOwned, DecodeValue, EncodeValue, ErrorKind, FixedTag, Header, Length, Reader, Result,
+ Tag, Writer,
+ };
+
+ /// Unsigned arbitrary precision ASN.1 `INTEGER` type.
+ ///
+ /// Provides heap-allocated storage for big endian bytes which comprise an
+ /// unsigned integer value.
+ ///
+ /// Intended for use cases like very large integers that are used in
+ /// cryptographic applications (e.g. keys, signatures).
+ #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
+ pub struct Uint {
+ /// Inner value
+ inner: BytesOwned,
+ }
+
+ impl Uint {
+ /// Create a new [`Uint`] from a byte slice.
+ pub fn new(bytes: &[u8]) -> Result<Self> {
+ let inner = BytesOwned::new(strip_leading_zeroes(bytes))
+ .map_err(|_| ErrorKind::Length { tag: Self::TAG })?;
+
+ Ok(Self { inner })
+ }
+
+ /// Borrow the inner byte slice which contains the least significant bytes
+ /// of a big endian integer value with all leading zeros stripped.
+ pub fn as_bytes(&self) -> &[u8] {
+ self.inner.as_slice()
+ }
+
+ /// Get the length of this [`Uint`] in bytes.
+ pub fn len(&self) -> Length {
+ self.inner.len()
+ }
+
+ /// Is the inner byte slice empty?
+ pub fn is_empty(&self) -> bool {
+ self.inner.is_empty()
+ }
+ }
+
+ impl_any_conversions!(Uint);
+
+ impl<'a> DecodeValue<'a> for Uint {
+ fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
+ let bytes = BytesOwned::decode_value(reader, header)?;
+ let result = Self::new(decode_to_slice(bytes.as_slice())?)?;
+
+ // Ensure we compute the same encoded length as the original any value.
+ if result.value_len()? != header.length {
+ return Err(Self::TAG.non_canonical_error());
+ }
+
+ Ok(result)
+ }
+ }
+
+ impl EncodeValue for Uint {
+ fn value_len(&self) -> Result<Length> {
+ encoded_len(self.inner.as_slice())
+ }
+
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
+ // Add leading `0x00` byte if required
+ if self.value_len()? > self.len() {
+ writer.write_byte(0)?;
+ }
+
+ writer.write(self.as_bytes())
+ }
+ }
+
+ impl<'a> From<&UintRef<'a>> for Uint {
+ fn from(value: &UintRef<'a>) -> Uint {
+ let inner = BytesOwned::new(value.as_bytes()).expect("Invalid Uint");
+ Uint { inner }
+ }
+ }
+
+ impl FixedTag for Uint {
+ const TAG: Tag = Tag::Integer;
+ }
+
+ impl OrdIsValueOrd for Uint {}
+
+ impl<'a> RefToOwned<'a> for UintRef<'a> {
+ type Owned = Uint;
+ fn ref_to_owned(&self) -> Self::Owned {
+ let inner = self.inner.ref_to_owned();
+
+ Uint { inner }
+ }
+ }
+
+ impl OwnedToRef for Uint {
+ type Borrowed<'a> = UintRef<'a>;
+ fn owned_to_ref(&self) -> Self::Borrowed<'_> {
+ let inner = self.inner.owned_to_ref();
+
+ UintRef { inner }
+ }
+ }
+}
/// Decode an unsigned integer into a big endian byte slice with all leading
/// zeroes removed.
@@ -75,13 +339,13 @@ pub(crate) fn strip_leading_zeroes(mut bytes: &[u8]) -> &[u8] {
/// Does the given integer need a leading zero?
fn needs_leading_zero(bytes: &[u8]) -> bool {
- matches!(bytes.get(0), Some(byte) if *byte >= 0x80)
+ matches!(bytes.first(), Some(byte) if *byte >= 0x80)
}
#[cfg(test)]
mod tests {
- use super::decode_to_array;
- use crate::{ErrorKind, Tag};
+ use super::{decode_to_array, UintRef};
+ use crate::{asn1::integer::tests::*, AnyRef, Decode, Encode, ErrorKind, SliceWriter, Tag};
#[test]
fn decode_to_array_no_leading_zero() {
@@ -113,4 +377,52 @@ mod tests {
let err = decode_to_array::<1>(&[1, 2, 3]).err().unwrap();
assert_eq!(err.kind(), ErrorKind::Length { tag: Tag::Integer });
}
+
+ #[test]
+ fn decode_uintref() {
+ assert_eq!(&[0], UintRef::from_der(I0_BYTES).unwrap().as_bytes());
+ assert_eq!(&[127], UintRef::from_der(I127_BYTES).unwrap().as_bytes());
+ assert_eq!(&[128], UintRef::from_der(I128_BYTES).unwrap().as_bytes());
+ assert_eq!(&[255], UintRef::from_der(I255_BYTES).unwrap().as_bytes());
+
+ assert_eq!(
+ &[0x01, 0x00],
+ UintRef::from_der(I256_BYTES).unwrap().as_bytes()
+ );
+
+ assert_eq!(
+ &[0x7F, 0xFF],
+ UintRef::from_der(I32767_BYTES).unwrap().as_bytes()
+ );
+ }
+
+ #[test]
+ fn encode_uintref() {
+ for &example in &[
+ I0_BYTES,
+ I127_BYTES,
+ I128_BYTES,
+ I255_BYTES,
+ I256_BYTES,
+ I32767_BYTES,
+ ] {
+ let uint = UintRef::from_der(example).unwrap();
+
+ let mut buf = [0u8; 128];
+ let mut encoder = SliceWriter::new(&mut buf);
+ uint.encode(&mut encoder).unwrap();
+
+ let result = encoder.finish().unwrap();
+ assert_eq!(example, result);
+ }
+ }
+
+ #[test]
+ fn reject_oversize_without_extra_zero() {
+ let err = UintRef::try_from(AnyRef::new(Tag::Integer, &[0x81]).unwrap())
+ .err()
+ .unwrap();
+
+ assert_eq!(err.kind(), ErrorKind::Value { tag: Tag::Integer });
+ }
}
diff --git a/vendor/der/src/asn1/internal_macros.rs b/vendor/der/src/asn1/internal_macros.rs
new file mode 100644
index 000000000..10ad99d23
--- /dev/null
+++ b/vendor/der/src/asn1/internal_macros.rs
@@ -0,0 +1,75 @@
+macro_rules! impl_any_conversions {
+ ($type: ty) => {
+ impl_any_conversions!($type, );
+ };
+ ($type: ty, $($li: lifetime)?) => {
+ impl<'__der: $($li),*, $($li),*> TryFrom<$crate::AnyRef<'__der>> for $type {
+ type Error = $crate::Error;
+
+ fn try_from(any: $crate::AnyRef<'__der>) -> Result<$type> {
+ any.decode_as()
+ }
+ }
+
+ #[cfg(feature = "alloc")]
+ impl<'__der: $($li),*, $($li),*> TryFrom<&'__der $crate::Any> for $type {
+ type Error = $crate::Error;
+
+ fn try_from(any: &'__der $crate::Any) -> Result<$type> {
+ any.decode_as()
+ }
+ }
+ };
+}
+
+macro_rules! impl_string_type {
+ ($type: ty, $($li: lifetime)?) => {
+ impl_any_conversions!($type, $($li),*);
+
+ mod __impl_string {
+ use super::*;
+
+ use crate::{
+ ord::OrdIsValueOrd, BytesRef, DecodeValue, EncodeValue, Header, Length, Reader,
+ Result, Writer,
+ };
+ use core::{fmt, str};
+
+ impl<$($li),*> AsRef<str> for $type {
+ fn as_ref(&self) -> &str {
+ self.as_str()
+ }
+ }
+
+ impl<$($li),*> AsRef<[u8]> for $type {
+ fn as_ref(&self) -> &[u8] {
+ self.as_bytes()
+ }
+ }
+
+ impl<'__der: $($li),*, $($li),*> DecodeValue<'__der> for $type {
+ fn decode_value<R: Reader<'__der>>(reader: &mut R, header: Header) -> Result<Self> {
+ Self::new(BytesRef::decode_value(reader, header)?.as_slice())
+ }
+ }
+
+ impl<$($li),*> EncodeValue for $type {
+ fn value_len(&self) -> Result<Length> {
+ self.inner.value_len()
+ }
+
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
+ self.inner.encode_value(writer)
+ }
+ }
+
+ impl<$($li),*> OrdIsValueOrd for $type {}
+
+ impl<$($li),*> fmt::Display for $type {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.write_str(self.as_str())
+ }
+ }
+ }
+ };
+}
diff --git a/vendor/der/src/asn1/null.rs b/vendor/der/src/asn1/null.rs
index e87729f18..7c1e2058a 100644
--- a/vendor/der/src/asn1/null.rs
+++ b/vendor/der/src/asn1/null.rs
@@ -1,7 +1,7 @@
//! ASN.1 `NULL` support.
use crate::{
- asn1::AnyRef, ord::OrdIsValueOrd, ByteSlice, DecodeValue, EncodeValue, Error, ErrorKind,
+ asn1::AnyRef, ord::OrdIsValueOrd, BytesRef, DecodeValue, EncodeValue, Error, ErrorKind,
FixedTag, Header, Length, Reader, Result, Tag, Writer,
};
@@ -9,6 +9,8 @@ use crate::{
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub struct Null;
+impl_any_conversions!(Null);
+
impl<'a> DecodeValue<'a> for Null {
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
if header.length.is_zero() {
@@ -24,7 +26,7 @@ impl EncodeValue for Null {
Ok(Length::ZERO)
}
- fn encode_value(&self, _writer: &mut dyn Writer) -> Result<()> {
+ fn encode_value(&self, _writer: &mut impl Writer) -> Result<()> {
Ok(())
}
}
@@ -37,15 +39,7 @@ impl OrdIsValueOrd for Null {}
impl<'a> From<Null> for AnyRef<'a> {
fn from(_: Null) -> AnyRef<'a> {
- AnyRef::from_tag_and_value(Tag::Null, ByteSlice::default())
- }
-}
-
-impl TryFrom<AnyRef<'_>> for Null {
- type Error = Error;
-
- fn try_from(any: AnyRef<'_>) -> Result<Null> {
- any.decode_into()
+ AnyRef::from_tag_and_value(Tag::Null, BytesRef::default())
}
}
@@ -75,7 +69,7 @@ impl EncodeValue for () {
Ok(Length::ZERO)
}
- fn encode_value(&self, _writer: &mut dyn Writer) -> Result<()> {
+ fn encode_value(&self, _writer: &mut impl Writer) -> Result<()> {
Ok(())
}
}
diff --git a/vendor/der/src/asn1/octet_string.rs b/vendor/der/src/asn1/octet_string.rs
index 6f5b91a3d..d5eb0dd0f 100644
--- a/vendor/der/src/asn1/octet_string.rs
+++ b/vendor/der/src/asn1/octet_string.rs
@@ -1,13 +1,10 @@
//! ASN.1 `OCTET STRING` support.
use crate::{
- asn1::AnyRef, ord::OrdIsValueOrd, ByteSlice, DecodeValue, EncodeValue, Error, ErrorKind,
+ asn1::AnyRef, ord::OrdIsValueOrd, BytesRef, Decode, DecodeValue, EncodeValue, ErrorKind,
FixedTag, Header, Length, Reader, Result, Tag, Writer,
};
-#[cfg(feature = "alloc")]
-use alloc::vec::Vec;
-
/// ASN.1 `OCTET STRING` type: borrowed form.
///
/// Octet strings represent contiguous sequences of octets, a.k.a. bytes.
@@ -16,13 +13,13 @@ use alloc::vec::Vec;
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub struct OctetStringRef<'a> {
/// Inner value
- inner: ByteSlice<'a>,
+ inner: BytesRef<'a>,
}
impl<'a> OctetStringRef<'a> {
/// Create a new ASN.1 `OCTET STRING` from a byte slice.
pub fn new(slice: &'a [u8]) -> Result<Self> {
- ByteSlice::new(slice)
+ BytesRef::new(slice)
.map(|inner| Self { inner })
.map_err(|_| ErrorKind::Length { tag: Self::TAG }.into())
}
@@ -41,8 +38,15 @@ impl<'a> OctetStringRef<'a> {
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
+
+ /// Parse `T` from this `OCTET STRING`'s contents.
+ pub fn decode_into<T: Decode<'a>>(&self) -> Result<T> {
+ Decode::from_der(self.as_bytes())
+ }
}
+impl_any_conversions!(OctetStringRef<'a>, 'a);
+
impl AsRef<[u8]> for OctetStringRef<'_> {
fn as_ref(&self) -> &[u8] {
self.as_bytes()
@@ -51,7 +55,7 @@ impl AsRef<[u8]> for OctetStringRef<'_> {
impl<'a> DecodeValue<'a> for OctetStringRef<'a> {
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
- let inner = ByteSlice::decode_value(reader, header)?;
+ let inner = BytesRef::decode_value(reader, header)?;
Ok(Self { inner })
}
}
@@ -61,7 +65,7 @@ impl EncodeValue for OctetStringRef<'_> {
self.inner.value_len()
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
self.inner.encode_value(writer)
}
}
@@ -78,14 +82,6 @@ impl<'a> From<&OctetStringRef<'a>> for OctetStringRef<'a> {
}
}
-impl<'a> TryFrom<AnyRef<'a>> for OctetStringRef<'a> {
- type Error = Error;
-
- fn try_from(any: AnyRef<'a>) -> Result<OctetStringRef<'a>> {
- any.decode_into()
- }
-}
-
impl<'a> From<OctetStringRef<'a>> for AnyRef<'a> {
fn from(octet_string: OctetStringRef<'a>) -> AnyRef<'a> {
AnyRef::from_tag_and_value(Tag::OctetString, octet_string.inner)
@@ -98,85 +94,137 @@ impl<'a> From<OctetStringRef<'a>> for &'a [u8] {
}
}
-/// ASN.1 `OCTET STRING` type: owned form..
-///
-/// Octet strings represent contiguous sequences of octets, a.k.a. bytes.
-///
-/// This type provides the same functionality as [`OctetStringRef`] but owns
-/// the backing data.
#[cfg(feature = "alloc")]
-#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
-#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
-pub struct OctetString {
- /// Bitstring represented as a slice of bytes.
- inner: Vec<u8>,
-}
+pub use self::allocating::OctetString;
#[cfg(feature = "alloc")]
-impl OctetString {
- /// Create a new ASN.1 `OCTET STRING`.
- pub fn new(bytes: impl Into<Vec<u8>>) -> Result<Self> {
- let inner = bytes.into();
+mod allocating {
+ use super::*;
+ use crate::referenced::*;
+ use alloc::vec::Vec;
- // Ensure the bytes parse successfully as an `OctetStringRef`
- OctetStringRef::new(&inner)?;
+ /// ASN.1 `OCTET STRING` type: owned form..
+ ///
+ /// Octet strings represent contiguous sequences of octets, a.k.a. bytes.
+ ///
+ /// This type provides the same functionality as [`OctetStringRef`] but owns
+ /// the backing data.
+ #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
+ pub struct OctetString {
+ /// Bitstring represented as a slice of bytes.
+ inner: Vec<u8>,
+ }
- Ok(Self { inner })
+ impl OctetString {
+ /// Create a new ASN.1 `OCTET STRING`.
+ pub fn new(bytes: impl Into<Vec<u8>>) -> Result<Self> {
+ let inner = bytes.into();
+
+ // Ensure the bytes parse successfully as an `OctetStringRef`
+ OctetStringRef::new(&inner)?;
+
+ Ok(Self { inner })
+ }
+
+ /// Borrow the inner byte slice.
+ pub fn as_bytes(&self) -> &[u8] {
+ self.inner.as_slice()
+ }
+
+ /// Take ownership of the octet string.
+ pub fn into_bytes(self) -> Vec<u8> {
+ self.inner
+ }
+
+ /// Get the length of the inner byte slice.
+ pub fn len(&self) -> Length {
+ self.value_len().expect("invalid OCTET STRING length")
+ }
+
+ /// Is the inner byte slice empty?
+ pub fn is_empty(&self) -> bool {
+ self.inner.is_empty()
+ }
}
- /// Borrow the inner byte slice.
- pub fn as_bytes(&self) -> &[u8] {
- self.inner.as_slice()
+ impl_any_conversions!(OctetString);
+
+ impl AsRef<[u8]> for OctetString {
+ fn as_ref(&self) -> &[u8] {
+ self.as_bytes()
+ }
}
- /// Get the length of the inner byte slice.
- pub fn len(&self) -> Length {
- self.value_len().expect("invalid OCTET STRING length")
+ impl<'a> DecodeValue<'a> for OctetString {
+ fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
+ Self::new(reader.read_vec(header.length)?)
+ }
}
- /// Is the inner byte slice empty?
- pub fn is_empty(&self) -> bool {
- self.inner.is_empty()
+ impl EncodeValue for OctetString {
+ fn value_len(&self) -> Result<Length> {
+ self.inner.len().try_into()
+ }
+
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
+ writer.write(&self.inner)
+ }
}
-}
-#[cfg(feature = "alloc")]
-impl AsRef<[u8]> for OctetString {
- fn as_ref(&self) -> &[u8] {
- self.as_bytes()
+ impl FixedTag for OctetString {
+ const TAG: Tag = Tag::OctetString;
}
-}
-#[cfg(feature = "alloc")]
-impl<'a> DecodeValue<'a> for OctetString {
- fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
- Self::new(reader.read_vec(header.length)?)
+ impl<'a> From<&'a OctetString> for OctetStringRef<'a> {
+ fn from(octet_string: &'a OctetString) -> OctetStringRef<'a> {
+ // Ensured to parse successfully in constructor
+ OctetStringRef::new(&octet_string.inner).expect("invalid OCTET STRING")
+ }
}
-}
-#[cfg(feature = "alloc")]
-impl EncodeValue for OctetString {
- fn value_len(&self) -> Result<Length> {
- self.inner.len().try_into()
+ impl OrdIsValueOrd for OctetString {}
+
+ impl<'a> RefToOwned<'a> for OctetStringRef<'a> {
+ type Owned = OctetString;
+ fn ref_to_owned(&self) -> Self::Owned {
+ OctetString {
+ inner: Vec::from(self.inner.as_slice()),
+ }
+ }
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
- writer.write(&self.inner)
+ impl OwnedToRef for OctetString {
+ type Borrowed<'a> = OctetStringRef<'a>;
+ fn owned_to_ref(&self) -> Self::Borrowed<'_> {
+ self.into()
+ }
}
-}
-#[cfg(feature = "alloc")]
-impl FixedTag for OctetString {
- const TAG: Tag = Tag::OctetString;
-}
+ // Implement by hand because the derive would create invalid values.
+ // Use the constructor to create a valid value.
+ #[cfg(feature = "arbitrary")]
+ impl<'a> arbitrary::Arbitrary<'a> for OctetString {
+ fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
+ Self::new(Vec::arbitrary(u)?).map_err(|_| arbitrary::Error::IncorrectFormat)
+ }
-#[cfg(feature = "alloc")]
-impl<'a> From<&'a OctetString> for OctetStringRef<'a> {
- fn from(octet_string: &'a OctetString) -> OctetStringRef<'a> {
- // Ensured to parse successfully in constructor
- OctetStringRef::new(&octet_string.inner).expect("invalid OCTET STRING")
+ fn size_hint(depth: usize) -> (usize, Option<usize>) {
+ arbitrary::size_hint::and(u8::size_hint(depth), Vec::<u8>::size_hint(depth))
+ }
}
}
-#[cfg(feature = "alloc")]
-impl OrdIsValueOrd for OctetString {}
+#[cfg(test)]
+mod tests {
+ use crate::asn1::{OctetStringRef, PrintableStringRef};
+
+ #[test]
+ fn octet_string_decode_into() {
+ // PrintableString "hi"
+ let der = b"\x13\x02\x68\x69";
+ let oct = OctetStringRef::new(der).unwrap();
+
+ let res = oct.decode_into::<PrintableStringRef<'_>>().unwrap();
+ assert_eq!(AsRef::<str>::as_ref(&res), "hi");
+ }
+}
diff --git a/vendor/der/src/asn1/oid.rs b/vendor/der/src/asn1/oid.rs
index 8b287183d..3daa452b2 100644
--- a/vendor/der/src/asn1/oid.rs
+++ b/vendor/der/src/asn1/oid.rs
@@ -6,6 +6,9 @@ use crate::{
};
use const_oid::ObjectIdentifier;
+#[cfg(feature = "alloc")]
+use super::Any;
+
impl<'a> DecodeValue<'a> for ObjectIdentifier {
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
let mut buf = [0u8; ObjectIdentifier::MAX_SIZE];
@@ -24,7 +27,7 @@ impl EncodeValue for ObjectIdentifier {
Length::try_from(self.as_bytes().len())
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
writer.write(self.as_bytes())
}
}
@@ -50,6 +53,13 @@ impl<'a> From<&'a ObjectIdentifier> for AnyRef<'a> {
}
}
+#[cfg(feature = "alloc")]
+impl From<ObjectIdentifier> for Any {
+ fn from(oid: ObjectIdentifier) -> Any {
+ AnyRef::from(&oid).into()
+ }
+}
+
impl TryFrom<AnyRef<'_>> for ObjectIdentifier {
type Error = Error;
diff --git a/vendor/der/src/asn1/optional.rs b/vendor/der/src/asn1/optional.rs
index a9b923ccc..ecda4f8ec 100644
--- a/vendor/der/src/asn1/optional.rs
+++ b/vendor/der/src/asn1/optional.rs
@@ -41,7 +41,7 @@ where
(&self).encoded_len()
}
- fn encode(&self, writer: &mut dyn Writer) -> Result<()> {
+ fn encode(&self, writer: &mut impl Writer) -> Result<()> {
(&self).encode(writer)
}
}
@@ -57,7 +57,7 @@ where
}
}
- fn encode(&self, encoder: &mut dyn Writer) -> Result<()> {
+ fn encode(&self, encoder: &mut impl Writer) -> Result<()> {
match self {
Some(encodable) => encodable.encode(encoder),
None => Ok(()),
diff --git a/vendor/der/src/asn1/printable_string.rs b/vendor/der/src/asn1/printable_string.rs
index d48f90f09..651c5ba23 100644
--- a/vendor/der/src/asn1/printable_string.rs
+++ b/vendor/der/src/asn1/printable_string.rs
@@ -1,10 +1,26 @@
//! ASN.1 `PrintableString` support.
-use crate::{
- asn1::AnyRef, ord::OrdIsValueOrd, ByteSlice, DecodeValue, EncodeValue, Error, FixedTag, Header,
- Length, Reader, Result, StrSlice, Tag, Writer,
-};
-use core::{fmt, ops::Deref, str};
+use crate::{asn1::AnyRef, FixedTag, Result, StrRef, Tag};
+use core::{fmt, ops::Deref};
+
+macro_rules! impl_printable_string {
+ ($type: ty) => {
+ impl_printable_string!($type,);
+ };
+ ($type: ty, $($li: lifetime)?) => {
+ impl_string_type!($type, $($li),*);
+
+ impl<$($li),*> FixedTag for $type {
+ const TAG: Tag = Tag::PrintableString;
+ }
+
+ impl<$($li),*> fmt::Debug for $type {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "PrintableString({:?})", self.as_str())
+ }
+ }
+ };
+}
/// ASN.1 `PrintableString` type.
///
@@ -38,7 +54,7 @@ use core::{fmt, ops::Deref, str};
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord)]
pub struct PrintableStringRef<'a> {
/// Inner value
- inner: StrSlice<'a>,
+ inner: StrRef<'a>,
}
impl<'a> PrintableStringRef<'a> {
@@ -71,83 +87,138 @@ impl<'a> PrintableStringRef<'a> {
}
}
- StrSlice::from_bytes(input)
+ StrRef::from_bytes(input)
.map(|inner| Self { inner })
.map_err(|_| Self::TAG.value_error())
}
}
+impl_printable_string!(PrintableStringRef<'a>, 'a);
+
impl<'a> Deref for PrintableStringRef<'a> {
- type Target = StrSlice<'a>;
+ type Target = StrRef<'a>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
-
-impl AsRef<str> for PrintableStringRef<'_> {
- fn as_ref(&self) -> &str {
- self.as_str()
+impl<'a> From<&PrintableStringRef<'a>> for PrintableStringRef<'a> {
+ fn from(value: &PrintableStringRef<'a>) -> PrintableStringRef<'a> {
+ *value
}
}
-impl AsRef<[u8]> for PrintableStringRef<'_> {
- fn as_ref(&self) -> &[u8] {
- self.as_bytes()
+impl<'a> From<PrintableStringRef<'a>> for AnyRef<'a> {
+ fn from(printable_string: PrintableStringRef<'a>) -> AnyRef<'a> {
+ AnyRef::from_tag_and_value(Tag::PrintableString, printable_string.inner.into())
}
}
-impl<'a> DecodeValue<'a> for PrintableStringRef<'a> {
- fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
- Self::new(ByteSlice::decode_value(reader, header)?.as_slice())
- }
-}
+#[cfg(feature = "alloc")]
+pub use self::allocation::PrintableString;
-impl<'a> EncodeValue for PrintableStringRef<'a> {
- fn value_len(&self) -> Result<Length> {
- self.inner.value_len()
+#[cfg(feature = "alloc")]
+mod allocation {
+ use super::PrintableStringRef;
+
+ use crate::{
+ asn1::AnyRef,
+ referenced::{OwnedToRef, RefToOwned},
+ BytesRef, FixedTag, Result, StrOwned, Tag,
+ };
+ use core::{fmt, ops::Deref};
+
+ /// ASN.1 `PrintableString` type.
+ ///
+ /// Supports a subset the ASCII character set (described below).
+ ///
+ /// For UTF-8, use [`Utf8StringRef`][`crate::asn1::Utf8StringRef`] instead.
+ /// For the full ASCII character set, use
+ /// [`Ia5StringRef`][`crate::asn1::Ia5StringRef`].
+ ///
+ /// # Supported characters
+ ///
+ /// The following ASCII characters/ranges are supported:
+ ///
+ /// - `A..Z`
+ /// - `a..z`
+ /// - `0..9`
+ /// - "` `" (i.e. space)
+ /// - `\`
+ /// - `(`
+ /// - `)`
+ /// - `+`
+ /// - `,`
+ /// - `-`
+ /// - `.`
+ /// - `/`
+ /// - `:`
+ /// - `=`
+ /// - `?`
+ #[derive(Clone, Eq, PartialEq, PartialOrd, Ord)]
+ pub struct PrintableString {
+ /// Inner value
+ inner: StrOwned,
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
- self.inner.encode_value(writer)
+ impl PrintableString {
+ /// Create a new ASN.1 `PrintableString`.
+ pub fn new<T>(input: &T) -> Result<Self>
+ where
+ T: AsRef<[u8]> + ?Sized,
+ {
+ let input = input.as_ref();
+ PrintableStringRef::new(input)?;
+
+ StrOwned::from_bytes(input)
+ .map(|inner| Self { inner })
+ .map_err(|_| Self::TAG.value_error())
+ }
}
-}
-impl FixedTag for PrintableStringRef<'_> {
- const TAG: Tag = Tag::PrintableString;
-}
+ impl_printable_string!(PrintableString);
-impl OrdIsValueOrd for PrintableStringRef<'_> {}
+ impl Deref for PrintableString {
+ type Target = StrOwned;
-impl<'a> From<&PrintableStringRef<'a>> for PrintableStringRef<'a> {
- fn from(value: &PrintableStringRef<'a>) -> PrintableStringRef<'a> {
- *value
+ fn deref(&self) -> &Self::Target {
+ &self.inner
+ }
}
-}
-
-impl<'a> TryFrom<AnyRef<'a>> for PrintableStringRef<'a> {
- type Error = Error;
- fn try_from(any: AnyRef<'a>) -> Result<PrintableStringRef<'a>> {
- any.decode_into()
+ impl<'a> From<PrintableStringRef<'a>> for PrintableString {
+ fn from(value: PrintableStringRef<'a>) -> PrintableString {
+ let inner =
+ StrOwned::from_bytes(value.inner.as_bytes()).expect("Invalid PrintableString");
+ Self { inner }
+ }
}
-}
-impl<'a> From<PrintableStringRef<'a>> for AnyRef<'a> {
- fn from(printable_string: PrintableStringRef<'a>) -> AnyRef<'a> {
- AnyRef::from_tag_and_value(Tag::PrintableString, printable_string.inner.into())
+ impl<'a> From<&'a PrintableString> for AnyRef<'a> {
+ fn from(printable_string: &'a PrintableString) -> AnyRef<'a> {
+ AnyRef::from_tag_and_value(
+ Tag::PrintableString,
+ BytesRef::new(printable_string.inner.as_bytes()).expect("Invalid PrintableString"),
+ )
+ }
}
-}
-impl<'a> fmt::Display for PrintableStringRef<'a> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str(self.as_str())
+ impl<'a> RefToOwned<'a> for PrintableStringRef<'a> {
+ type Owned = PrintableString;
+ fn ref_to_owned(&self) -> Self::Owned {
+ PrintableString {
+ inner: self.inner.ref_to_owned(),
+ }
+ }
}
-}
-impl<'a> fmt::Debug for PrintableStringRef<'a> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "PrintableString({:?})", self.as_str())
+ impl OwnedToRef for PrintableString {
+ type Borrowed<'a> = PrintableStringRef<'a>;
+ fn owned_to_ref(&self) -> Self::Borrowed<'_> {
+ PrintableStringRef {
+ inner: self.inner.owned_to_ref(),
+ }
+ }
}
}
diff --git a/vendor/der/src/asn1/real.rs b/vendor/der/src/asn1/real.rs
index f872d2d0b..b9f2e67f5 100644
--- a/vendor/der/src/asn1/real.rs
+++ b/vendor/der/src/asn1/real.rs
@@ -8,22 +8,21 @@
)]
use crate::{
- str_slice::StrSlice, ByteSlice, DecodeValue, EncodeValue, FixedTag, Header, Length, Reader,
- Result, Tag, Writer,
+ BytesRef, DecodeValue, EncodeValue, FixedTag, Header, Length, Reader, Result, StrRef, Tag,
+ Writer,
};
use super::integer::uint::strip_leading_zeroes;
-#[cfg_attr(docsrs, doc(cfg(feature = "real")))]
impl<'a> DecodeValue<'a> for f64 {
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
- let bytes = ByteSlice::decode_value(reader, header)?.as_slice();
+ let bytes = BytesRef::decode_value(reader, header)?.as_slice();
if header.length == Length::ZERO {
Ok(0.0)
} else if is_nth_bit_one::<7>(bytes) {
// Binary encoding from section 8.5.7 applies
- let sign: u64 = if is_nth_bit_one::<6>(bytes) { 1 } else { 0 };
+ let sign: u64 = u64::from(is_nth_bit_one::<6>(bytes));
// Section 8.5.7.2: Check the base -- the DER specs say that only base 2 should be supported in DER
let base = mnth_bits_to_u8::<5, 4>(bytes);
@@ -74,7 +73,7 @@ impl<'a> DecodeValue<'a> for f64 {
_ => Err(Tag::Real.value_error()),
}
} else {
- let astr = StrSlice::from_bytes(&bytes[1..])?;
+ let astr = StrRef::from_bytes(&bytes[1..])?;
match astr.inner.parse::<f64>() {
Ok(val) => Ok(val),
// Real related error: encoding not supported or malformed
@@ -84,7 +83,6 @@ impl<'a> DecodeValue<'a> for f64 {
}
}
-#[cfg_attr(docsrs, doc(cfg(feature = "real")))]
impl EncodeValue for f64 {
fn value_len(&self) -> Result<Length> {
if self.is_sign_positive() && (*self) < f64::MIN_POSITIVE {
@@ -120,7 +118,7 @@ impl EncodeValue for f64 {
}
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
// Check if special value
// Encode zero first, if it's zero
// Special value from section 8.5.9 if non zero
@@ -194,7 +192,6 @@ impl EncodeValue for f64 {
}
}
-#[cfg_attr(docsrs, doc(cfg(feature = "real")))]
impl FixedTag for f64 {
const TAG: Tag = Tag::Real;
}
@@ -204,7 +201,7 @@ impl FixedTag for f64 {
pub(crate) fn is_nth_bit_one<const N: usize>(bytes: &[u8]) -> bool {
if N < 8 {
bytes
- .get(0)
+ .first()
.map(|byte| byte & (1 << N) != 0)
.unwrap_or(false)
} else {
diff --git a/vendor/der/src/asn1/sequence.rs b/vendor/der/src/asn1/sequence.rs
index d2f6bc5d1..ad4a5d52e 100644
--- a/vendor/der/src/asn1/sequence.rs
+++ b/vendor/der/src/asn1/sequence.rs
@@ -2,69 +2,40 @@
//! `SEQUENCE`s to Rust structs.
use crate::{
- ByteSlice, Decode, DecodeValue, Encode, EncodeValue, FixedTag, Header, Length, Reader, Result,
- Tag, Writer,
+ BytesRef, DecodeValue, EncodeValue, FixedTag, Header, Length, Reader, Result, Tag, Writer,
};
-/// ASN.1 `SEQUENCE` trait.
-///
-/// Types which impl this trait receive blanket impls for the [`Decode`],
-/// [`Encode`], and [`FixedTag`] traits.
-pub trait Sequence<'a>: Decode<'a> {
- /// Call the provided function with a slice of [`Encode`] trait objects
- /// representing the fields of this `SEQUENCE`.
- ///
- /// This method uses a callback because structs with fields which aren't
- /// directly [`Encode`] may need to construct temporary values from
- /// their fields prior to encoding.
- fn fields<F, T>(&self, f: F) -> Result<T>
- where
- F: FnOnce(&[&dyn Encode]) -> Result<T>;
-}
-
-impl<'a, M> EncodeValue for M
-where
- M: Sequence<'a>,
-{
- fn value_len(&self) -> Result<Length> {
- self.fields(|fields| {
- fields
- .iter()
- .try_fold(Length::ZERO, |acc, field| acc + field.encoded_len()?)
- })
- }
+#[cfg(feature = "alloc")]
+use alloc::boxed::Box;
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
- self.fields(|fields| {
- for &field in fields {
- field.encode(writer)?;
- }
-
- Ok(())
- })
- }
-}
+/// Marker trait for ASN.1 `SEQUENCE`s.
+///
+/// This is mainly used for custom derive.
+pub trait Sequence<'a>: DecodeValue<'a> + EncodeValue {}
-impl<'a, M> FixedTag for M
+impl<'a, S> FixedTag for S
where
- M: Sequence<'a>,
+ S: Sequence<'a>,
{
const TAG: Tag = Tag::Sequence;
}
+#[cfg(feature = "alloc")]
+impl<'a, T> Sequence<'a> for Box<T> where T: Sequence<'a> {}
+
/// The [`SequenceRef`] type provides raw access to the octets which comprise a
/// DER-encoded `SEQUENCE`.
///
/// This is a zero-copy reference type which borrows from the input data.
pub struct SequenceRef<'a> {
/// Body of the `SEQUENCE`.
- body: ByteSlice<'a>,
+ body: BytesRef<'a>,
}
impl<'a> DecodeValue<'a> for SequenceRef<'a> {
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
Ok(Self {
- body: ByteSlice::decode_value(reader, header)?,
+ body: BytesRef::decode_value(reader, header)?,
})
}
}
@@ -74,11 +45,9 @@ impl EncodeValue for SequenceRef<'_> {
Ok(self.body.len())
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
self.body.encode_value(writer)
}
}
-impl<'a> FixedTag for SequenceRef<'a> {
- const TAG: Tag = Tag::Sequence;
-}
+impl<'a> Sequence<'a> for SequenceRef<'a> {}
diff --git a/vendor/der/src/asn1/sequence_of.rs b/vendor/der/src/asn1/sequence_of.rs
index 6334d7197..42c2a9ca8 100644
--- a/vendor/der/src/asn1/sequence_of.rs
+++ b/vendor/der/src/asn1/sequence_of.rs
@@ -88,7 +88,7 @@ where
.fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
for elem in self.iter() {
elem.encode(writer)?;
}
@@ -155,7 +155,7 @@ where
.fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
for elem in self {
elem.encode(writer)?;
}
@@ -178,7 +178,6 @@ where
}
#[cfg(feature = "alloc")]
-#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<'a, T> DecodeValue<'a> for Vec<T>
where
T: Decode<'a>,
@@ -197,7 +196,6 @@ where
}
#[cfg(feature = "alloc")]
-#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<T> EncodeValue for Vec<T>
where
T: Encode,
@@ -207,7 +205,7 @@ where
.fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
for elem in self {
elem.encode(writer)?;
}
@@ -217,13 +215,11 @@ where
}
#[cfg(feature = "alloc")]
-#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<T> FixedTag for Vec<T> {
const TAG: Tag = Tag::Sequence;
}
#[cfg(feature = "alloc")]
-#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<T> ValueOrd for Vec<T>
where
T: DerOrd,
diff --git a/vendor/der/src/asn1/set_of.rs b/vendor/der/src/asn1/set_of.rs
index b8c4b0da4..e8f20e9c3 100644
--- a/vendor/der/src/asn1/set_of.rs
+++ b/vendor/der/src/asn1/set_of.rs
@@ -119,7 +119,7 @@ where
.fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
for elem in self.iter() {
elem.encode(writer)?;
}
@@ -185,7 +185,6 @@ impl<'a, T> ExactSizeIterator for SetOfIter<'a, T> {}
/// This type implements an append-only `SET OF` type which is heap-backed
/// and depends on `alloc` support.
#[cfg(feature = "alloc")]
-#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub struct SetOfVec<T>
where
@@ -195,7 +194,6 @@ where
}
#[cfg(feature = "alloc")]
-#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<T: DerOrd> Default for SetOfVec<T> {
fn default() -> Self {
Self {
@@ -205,7 +203,6 @@ impl<T: DerOrd> Default for SetOfVec<T> {
}
#[cfg(feature = "alloc")]
-#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<T> SetOfVec<T>
where
T: DerOrd,
@@ -265,7 +262,6 @@ where
}
#[cfg(feature = "alloc")]
-#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<T> AsRef<[T]> for SetOfVec<T>
where
T: DerOrd,
@@ -276,7 +272,6 @@ where
}
#[cfg(feature = "alloc")]
-#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<'a, T> DecodeValue<'a> for SetOfVec<T>
where
T: Decode<'a> + DerOrd,
@@ -297,7 +292,6 @@ where
}
#[cfg(feature = "alloc")]
-#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<'a, T> EncodeValue for SetOfVec<T>
where
T: 'a + Decode<'a> + Encode + DerOrd,
@@ -307,7 +301,7 @@ where
.fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
for elem in self.iter() {
elem.encode(writer)?;
}
@@ -317,7 +311,6 @@ where
}
#[cfg(feature = "alloc")]
-#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<T> FixedTag for SetOfVec<T>
where
T: DerOrd,
@@ -326,7 +319,6 @@ where
}
#[cfg(feature = "alloc")]
-#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<T> From<SetOfVec<T>> for Vec<T>
where
T: DerOrd,
@@ -337,7 +329,6 @@ where
}
#[cfg(feature = "alloc")]
-#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<T> TryFrom<Vec<T>> for SetOfVec<T>
where
T: DerOrd,
@@ -352,7 +343,6 @@ where
}
#[cfg(feature = "alloc")]
-#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<T, const N: usize> TryFrom<[T; N]> for SetOfVec<T>
where
T: DerOrd,
@@ -365,7 +355,6 @@ where
}
#[cfg(feature = "alloc")]
-#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<T> ValueOrd for SetOfVec<T>
where
T: DerOrd,
@@ -375,6 +364,26 @@ where
}
}
+// Implement by hand because the derive would create invalid values.
+// Use the conversion from Vec to create a valid value.
+#[cfg(feature = "arbitrary")]
+impl<'a, T> arbitrary::Arbitrary<'a> for SetOfVec<T>
+where
+ T: DerOrd + arbitrary::Arbitrary<'a>,
+{
+ fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
+ Self::try_from(
+ u.arbitrary_iter()?
+ .collect::<std::result::Result<Vec<_>, _>>()?,
+ )
+ .map_err(|_| arbitrary::Error::IncorrectFormat)
+ }
+
+ fn size_hint(_depth: usize) -> (usize, Option<usize>) {
+ (0, None)
+ }
+}
+
/// Sort a mut slice according to its [`DerOrd`], returning any errors which
/// might occur during the comparison.
///
diff --git a/vendor/der/src/asn1/teletex_string.rs b/vendor/der/src/asn1/teletex_string.rs
index 7d6621d2d..cedf727db 100644
--- a/vendor/der/src/asn1/teletex_string.rs
+++ b/vendor/der/src/asn1/teletex_string.rs
@@ -1,10 +1,26 @@
//! ASN.1 `TeletexString` support.
+//!
+use crate::{asn1::AnyRef, FixedTag, Result, StrRef, Tag};
+use core::{fmt, ops::Deref};
+
+macro_rules! impl_teletex_string {
+ ($type: ty) => {
+ impl_teletex_string!($type,);
+ };
+ ($type: ty, $($li: lifetime)?) => {
+ impl_string_type!($type, $($li),*);
+
+ impl<$($li),*> FixedTag for $type {
+ const TAG: Tag = Tag::TeletexString;
+ }
-use crate::{
- asn1::AnyRef, ord::OrdIsValueOrd, ByteSlice, DecodeValue, EncodeValue, Error, FixedTag, Header,
- Length, Reader, Result, StrSlice, Tag, Writer,
-};
-use core::{fmt, ops::Deref, str};
+ impl<$($li),*> fmt::Debug for $type {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "TeletexString({:?})", self.as_str())
+ }
+ }
+ };
+}
/// ASN.1 `TeletexString` type.
///
@@ -25,7 +41,7 @@ use core::{fmt, ops::Deref, str};
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord)]
pub struct TeletexStringRef<'a> {
/// Inner value
- inner: StrSlice<'a>,
+ inner: StrRef<'a>,
}
impl<'a> TeletexStringRef<'a> {
@@ -41,83 +57,127 @@ impl<'a> TeletexStringRef<'a> {
return Err(Self::TAG.value_error());
}
- StrSlice::from_bytes(input)
+ StrRef::from_bytes(input)
.map(|inner| Self { inner })
.map_err(|_| Self::TAG.value_error())
}
}
+impl_teletex_string!(TeletexStringRef<'a>, 'a);
+
impl<'a> Deref for TeletexStringRef<'a> {
- type Target = StrSlice<'a>;
+ type Target = StrRef<'a>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
-impl AsRef<str> for TeletexStringRef<'_> {
- fn as_ref(&self) -> &str {
- self.as_str()
+impl<'a> From<&TeletexStringRef<'a>> for TeletexStringRef<'a> {
+ fn from(value: &TeletexStringRef<'a>) -> TeletexStringRef<'a> {
+ *value
}
}
-impl AsRef<[u8]> for TeletexStringRef<'_> {
- fn as_ref(&self) -> &[u8] {
- self.as_bytes()
+impl<'a> From<TeletexStringRef<'a>> for AnyRef<'a> {
+ fn from(teletex_string: TeletexStringRef<'a>) -> AnyRef<'a> {
+ AnyRef::from_tag_and_value(Tag::TeletexString, teletex_string.inner.into())
}
}
-impl<'a> DecodeValue<'a> for TeletexStringRef<'a> {
- fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
- Self::new(ByteSlice::decode_value(reader, header)?.as_slice())
- }
-}
+#[cfg(feature = "alloc")]
+pub use self::allocation::TeletexString;
-impl<'a> EncodeValue for TeletexStringRef<'a> {
- fn value_len(&self) -> Result<Length> {
- self.inner.value_len()
- }
+#[cfg(feature = "alloc")]
+mod allocation {
+ use super::TeletexStringRef;
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
- self.inner.encode_value(writer)
+ use crate::{
+ asn1::AnyRef,
+ referenced::{OwnedToRef, RefToOwned},
+ BytesRef, FixedTag, Result, StrOwned, Tag,
+ };
+ use core::{fmt, ops::Deref};
+
+ /// ASN.1 `TeletexString` type.
+ ///
+ /// Supports a subset the ASCII character set (described below).
+ ///
+ /// For UTF-8, use [`Utf8StringRef`][`crate::asn1::Utf8StringRef`] instead.
+ /// For the full ASCII character set, use
+ /// [`Ia5StringRef`][`crate::asn1::Ia5StringRef`].
+ ///
+ /// # Supported characters
+ ///
+ /// The standard defines a complex character set allowed in this type. However, quoting the ASN.1
+ /// mailing list, "a sizable volume of software in the world treats TeletexString (T61String) as a
+ /// simple 8-bit string with mostly Windows Latin 1 (superset of iso-8859-1) encoding".
+ ///
+ #[derive(Clone, Eq, PartialEq, PartialOrd, Ord)]
+ pub struct TeletexString {
+ /// Inner value
+ inner: StrOwned,
}
-}
-impl FixedTag for TeletexStringRef<'_> {
- const TAG: Tag = Tag::TeletexString;
-}
+ impl TeletexString {
+ /// Create a new ASN.1 `TeletexString`.
+ pub fn new<T>(input: &T) -> Result<Self>
+ where
+ T: AsRef<[u8]> + ?Sized,
+ {
+ let input = input.as_ref();
-impl OrdIsValueOrd for TeletexStringRef<'_> {}
+ TeletexStringRef::new(input)?;
-impl<'a> From<&TeletexStringRef<'a>> for TeletexStringRef<'a> {
- fn from(value: &TeletexStringRef<'a>) -> TeletexStringRef<'a> {
- *value
+ StrOwned::from_bytes(input)
+ .map(|inner| Self { inner })
+ .map_err(|_| Self::TAG.value_error())
+ }
}
-}
-impl<'a> TryFrom<AnyRef<'a>> for TeletexStringRef<'a> {
- type Error = Error;
+ impl_teletex_string!(TeletexString);
- fn try_from(any: AnyRef<'a>) -> Result<TeletexStringRef<'a>> {
- any.decode_into()
+ impl Deref for TeletexString {
+ type Target = StrOwned;
+
+ fn deref(&self) -> &Self::Target {
+ &self.inner
+ }
}
-}
-impl<'a> From<TeletexStringRef<'a>> for AnyRef<'a> {
- fn from(teletex_string: TeletexStringRef<'a>) -> AnyRef<'a> {
- AnyRef::from_tag_and_value(Tag::TeletexString, teletex_string.inner.into())
+ impl<'a> From<TeletexStringRef<'a>> for TeletexString {
+ fn from(value: TeletexStringRef<'a>) -> TeletexString {
+ let inner =
+ StrOwned::from_bytes(value.inner.as_bytes()).expect("Invalid TeletexString");
+ Self { inner }
+ }
}
-}
-impl<'a> fmt::Display for TeletexStringRef<'a> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str(self.as_str())
+ impl<'a> From<&'a TeletexString> for AnyRef<'a> {
+ fn from(teletex_string: &'a TeletexString) -> AnyRef<'a> {
+ AnyRef::from_tag_and_value(
+ Tag::TeletexString,
+ BytesRef::new(teletex_string.inner.as_bytes()).expect("Invalid TeletexString"),
+ )
+ }
}
-}
-impl<'a> fmt::Debug for TeletexStringRef<'a> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "TeletexString({:?})", self.as_str())
+ impl<'a> RefToOwned<'a> for TeletexStringRef<'a> {
+ type Owned = TeletexString;
+ fn ref_to_owned(&self) -> Self::Owned {
+ TeletexString {
+ inner: self.inner.ref_to_owned(),
+ }
+ }
+ }
+
+ impl OwnedToRef for TeletexString {
+ type Borrowed<'a> = TeletexStringRef<'a>;
+ fn owned_to_ref(&self) -> Self::Borrowed<'_> {
+ TeletexStringRef {
+ inner: self.inner.owned_to_ref(),
+ }
+ }
}
}
diff --git a/vendor/der/src/asn1/utc_time.rs b/vendor/der/src/asn1/utc_time.rs
index 7c2381155..0c10e3aff 100644
--- a/vendor/der/src/asn1/utc_time.rs
+++ b/vendor/der/src/asn1/utc_time.rs
@@ -1,7 +1,6 @@
//! ASN.1 `UTCTime` support.
use crate::{
- asn1::AnyRef,
datetime::{self, DateTime},
ord::OrdIsValueOrd,
DecodeValue, EncodeValue, Error, ErrorKind, FixedTag, Header, Length, Reader, Result, Tag,
@@ -12,9 +11,6 @@ use core::time::Duration;
#[cfg(feature = "std")]
use std::time::SystemTime;
-/// Maximum year that can be represented as a `UTCTime`.
-pub const MAX_YEAR: u16 = 2049;
-
/// ASN.1 `UTCTime` type.
///
/// This type implements the validity requirements specified in
@@ -37,9 +33,12 @@ impl UtcTime {
/// Length of an RFC 5280-flavored ASN.1 DER-encoded [`UtcTime`].
pub const LENGTH: usize = 13;
+ /// Maximum year that can be represented as a `UTCTime`.
+ pub const MAX_YEAR: u16 = 2049;
+
/// Create a [`UtcTime`] from a [`DateTime`].
pub fn from_date_time(datetime: DateTime) -> Result<Self> {
- if datetime.year() <= MAX_YEAR {
+ if datetime.year() <= UtcTime::MAX_YEAR {
Ok(Self(datetime))
} else {
Err(Self::TAG.value_error())
@@ -64,7 +63,6 @@ impl UtcTime {
/// Instantiate from [`SystemTime`].
#[cfg(feature = "std")]
- #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub fn from_system_time(time: SystemTime) -> Result<Self> {
DateTime::try_from(time)
.map_err(|_| Self::TAG.value_error())?
@@ -73,12 +71,13 @@ impl UtcTime {
/// Convert to [`SystemTime`].
#[cfg(feature = "std")]
- #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub fn to_system_time(&self) -> SystemTime {
self.0.to_system_time()
}
}
+impl_any_conversions!(UtcTime);
+
impl<'a> DecodeValue<'a> for UtcTime {
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
if Self::LENGTH != usize::try_from(header.length)? {
@@ -120,7 +119,7 @@ impl EncodeValue for UtcTime {
Self::LENGTH.try_into()
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
let year = match self.0.year() {
y @ 1950..=1999 => y.checked_sub(1900),
y @ 2000..=2049 => y.checked_sub(2000),
@@ -180,18 +179,43 @@ impl TryFrom<&DateTime> for UtcTime {
}
#[cfg(feature = "std")]
-#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl From<UtcTime> for SystemTime {
fn from(utc_time: UtcTime) -> SystemTime {
utc_time.to_system_time()
}
}
-impl TryFrom<AnyRef<'_>> for UtcTime {
- type Error = Error;
-
- fn try_from(any: AnyRef<'_>) -> Result<UtcTime> {
- any.decode_into()
+// Implement by hand because the derive would create invalid values.
+// Use the conversion from DateTime to create a valid value.
+// The DateTime type has a way bigger range of valid years than UtcTime,
+// so the DateTime year is mapped into a valid range to throw away less inputs.
+#[cfg(feature = "arbitrary")]
+impl<'a> arbitrary::Arbitrary<'a> for UtcTime {
+ fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
+ const MIN_YEAR: u16 = 1970;
+ const VALID_YEAR_COUNT: u16 = UtcTime::MAX_YEAR - MIN_YEAR + 1;
+ const AVERAGE_SECONDS_IN_YEAR: u64 = 31_556_952;
+
+ let datetime = DateTime::arbitrary(u)?;
+ let year = datetime.year();
+ let duration = datetime.unix_duration();
+
+ // Clamp the year into a valid range to not throw away too much input
+ let valid_year = (year.saturating_sub(MIN_YEAR))
+ .rem_euclid(VALID_YEAR_COUNT)
+ .saturating_add(MIN_YEAR);
+ let year_to_remove = year.saturating_sub(valid_year);
+ let valid_duration = duration
+ - Duration::from_secs(
+ u64::from(year_to_remove).saturating_mul(AVERAGE_SECONDS_IN_YEAR),
+ );
+
+ Self::from_date_time(DateTime::from_unix_duration(valid_duration).expect("supported range"))
+ .map_err(|_| arbitrary::Error::IncorrectFormat)
+ }
+
+ fn size_hint(depth: usize) -> (usize, Option<usize>) {
+ DateTime::size_hint(depth)
}
}
diff --git a/vendor/der/src/asn1/utf8_string.rs b/vendor/der/src/asn1/utf8_string.rs
index 1a0641172..6018750a0 100644
--- a/vendor/der/src/asn1/utf8_string.rs
+++ b/vendor/der/src/asn1/utf8_string.rs
@@ -1,13 +1,16 @@
//! ASN.1 `UTF8String` support.
use crate::{
- asn1::AnyRef, ord::OrdIsValueOrd, ByteSlice, DecodeValue, EncodeValue, Error, FixedTag, Header,
- Length, Reader, Result, StrSlice, Tag, Writer,
+ asn1::AnyRef, ord::OrdIsValueOrd, EncodeValue, Error, FixedTag, Length, Result, StrRef, Tag,
+ Writer,
};
use core::{fmt, ops::Deref, str};
#[cfg(feature = "alloc")]
-use alloc::{borrow::ToOwned, string::String};
+use {
+ crate::{DecodeValue, Header, Reader},
+ alloc::{borrow::ToOwned, string::String},
+};
/// ASN.1 `UTF8String` type.
///
@@ -26,7 +29,7 @@ use alloc::{borrow::ToOwned, string::String};
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord)]
pub struct Utf8StringRef<'a> {
/// Inner value
- inner: StrSlice<'a>,
+ inner: StrRef<'a>,
}
impl<'a> Utf8StringRef<'a> {
@@ -35,75 +38,33 @@ impl<'a> Utf8StringRef<'a> {
where
T: AsRef<[u8]> + ?Sized,
{
- StrSlice::from_bytes(input.as_ref()).map(|inner| Self { inner })
+ StrRef::from_bytes(input.as_ref()).map(|inner| Self { inner })
}
}
+impl_string_type!(Utf8StringRef<'a>, 'a);
+
impl<'a> Deref for Utf8StringRef<'a> {
- type Target = StrSlice<'a>;
+ type Target = StrRef<'a>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
-impl AsRef<str> for Utf8StringRef<'_> {
- fn as_ref(&self) -> &str {
- self.as_str()
- }
-}
-
-impl AsRef<[u8]> for Utf8StringRef<'_> {
- fn as_ref(&self) -> &[u8] {
- self.as_bytes()
- }
-}
-
-impl<'a> DecodeValue<'a> for Utf8StringRef<'a> {
- fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
- Self::new(ByteSlice::decode_value(reader, header)?.as_slice())
- }
-}
-
-impl EncodeValue for Utf8StringRef<'_> {
- fn value_len(&self) -> Result<Length> {
- self.inner.value_len()
- }
-
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
- self.inner.encode_value(writer)
- }
-}
-
impl FixedTag for Utf8StringRef<'_> {
const TAG: Tag = Tag::Utf8String;
}
-impl OrdIsValueOrd for Utf8StringRef<'_> {}
-
impl<'a> From<&Utf8StringRef<'a>> for Utf8StringRef<'a> {
fn from(value: &Utf8StringRef<'a>) -> Utf8StringRef<'a> {
*value
}
}
-impl<'a> TryFrom<AnyRef<'a>> for Utf8StringRef<'a> {
- type Error = Error;
-
- fn try_from(any: AnyRef<'a>) -> Result<Utf8StringRef<'a>> {
- any.decode_into()
- }
-}
-
impl<'a> From<Utf8StringRef<'a>> for AnyRef<'a> {
- fn from(printable_string: Utf8StringRef<'a>) -> AnyRef<'a> {
- AnyRef::from_tag_and_value(Tag::Utf8String, printable_string.inner.into())
- }
-}
-
-impl<'a> fmt::Display for Utf8StringRef<'a> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str(self.as_str())
+ fn from(utf_string: Utf8StringRef<'a>) -> AnyRef<'a> {
+ AnyRef::from_tag_and_value(Tag::Utf8String, utf_string.inner.into())
}
}
@@ -126,7 +87,7 @@ impl EncodeValue for str {
Utf8StringRef::new(self)?.value_len()
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
Utf8StringRef::new(self)?.encode_value(writer)
}
}
@@ -138,7 +99,6 @@ impl FixedTag for str {
impl OrdIsValueOrd for str {}
#[cfg(feature = "alloc")]
-#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<'a> From<Utf8StringRef<'a>> for String {
fn from(s: Utf8StringRef<'a>) -> String {
s.as_str().to_owned()
@@ -146,7 +106,6 @@ impl<'a> From<Utf8StringRef<'a>> for String {
}
#[cfg(feature = "alloc")]
-#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<'a> TryFrom<AnyRef<'a>> for String {
type Error = Error;
@@ -156,7 +115,6 @@ impl<'a> TryFrom<AnyRef<'a>> for String {
}
#[cfg(feature = "alloc")]
-#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<'a> DecodeValue<'a> for String {
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
Ok(String::from_utf8(reader.read_vec(header.length)?)?)
@@ -164,25 +122,22 @@ impl<'a> DecodeValue<'a> for String {
}
#[cfg(feature = "alloc")]
-#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl EncodeValue for String {
fn value_len(&self) -> Result<Length> {
Utf8StringRef::new(self)?.value_len()
}
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
+ fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
Utf8StringRef::new(self)?.encode_value(writer)
}
}
#[cfg(feature = "alloc")]
-#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl FixedTag for String {
const TAG: Tag = Tag::Utf8String;
}
#[cfg(feature = "alloc")]
-#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl OrdIsValueOrd for String {}
#[cfg(test)]
diff --git a/vendor/der/src/asn1/videotex_string.rs b/vendor/der/src/asn1/videotex_string.rs
index b758a22e6..55b1a49cf 100644
--- a/vendor/der/src/asn1/videotex_string.rs
+++ b/vendor/der/src/asn1/videotex_string.rs
@@ -1,10 +1,7 @@
//! ASN.1 `VideotexString` support.
-use crate::{
- asn1::AnyRef, ord::OrdIsValueOrd, ByteSlice, DecodeValue, EncodeValue, Error, FixedTag, Header,
- Length, Reader, Result, StrSlice, Tag, Writer,
-};
-use core::{fmt, ops::Deref, str};
+use crate::{asn1::AnyRef, FixedTag, Result, StrRef, Tag};
+use core::{fmt, ops::Deref};
/// ASN.1 `VideotexString` type.
///
@@ -23,7 +20,7 @@ use core::{fmt, ops::Deref, str};
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord)]
pub struct VideotexStringRef<'a> {
/// Inner value
- inner: StrSlice<'a>,
+ inner: StrRef<'a>,
}
impl<'a> VideotexStringRef<'a> {
@@ -40,68 +37,32 @@ impl<'a> VideotexStringRef<'a> {
return Err(Self::TAG.value_error());
}
- StrSlice::from_bytes(input)
+ StrRef::from_bytes(input)
.map(|inner| Self { inner })
.map_err(|_| Self::TAG.value_error())
}
}
+impl_string_type!(VideotexStringRef<'a>, 'a);
+
impl<'a> Deref for VideotexStringRef<'a> {
- type Target = StrSlice<'a>;
+ type Target = StrRef<'a>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
-impl AsRef<str> for VideotexStringRef<'_> {
- fn as_ref(&self) -> &str {
- self.as_str()
- }
-}
-
-impl AsRef<[u8]> for VideotexStringRef<'_> {
- fn as_ref(&self) -> &[u8] {
- self.as_bytes()
- }
-}
-
-impl<'a> DecodeValue<'a> for VideotexStringRef<'a> {
- fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
- Self::new(ByteSlice::decode_value(reader, header)?.as_slice())
- }
-}
-
-impl<'a> EncodeValue for VideotexStringRef<'a> {
- fn value_len(&self) -> Result<Length> {
- self.inner.value_len()
- }
-
- fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
- self.inner.encode_value(writer)
- }
-}
-
impl FixedTag for VideotexStringRef<'_> {
const TAG: Tag = Tag::VideotexString;
}
-impl OrdIsValueOrd for VideotexStringRef<'_> {}
-
impl<'a> From<&VideotexStringRef<'a>> for VideotexStringRef<'a> {
fn from(value: &VideotexStringRef<'a>) -> VideotexStringRef<'a> {
*value
}
}
-impl<'a> TryFrom<AnyRef<'a>> for VideotexStringRef<'a> {
- type Error = Error;
-
- fn try_from(any: AnyRef<'a>) -> Result<VideotexStringRef<'a>> {
- any.decode_into()
- }
-}
-
impl<'a> From<VideotexStringRef<'a>> for AnyRef<'a> {
fn from(printable_string: VideotexStringRef<'a>) -> AnyRef<'a> {
AnyRef::from_tag_and_value(Tag::VideotexString, printable_string.inner.into())
@@ -114,12 +75,6 @@ impl<'a> From<VideotexStringRef<'a>> for &'a [u8] {
}
}
-impl<'a> fmt::Display for VideotexStringRef<'a> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str(self.as_str())
- }
-}
-
impl<'a> fmt::Debug for VideotexStringRef<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "VideotexString({:?})", self.as_str())