summaryrefslogtreecommitdiffstats
path: root/vendor/der/src/asn1/bit_string.rs
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/bit_string.rs
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/bit_string.rs')
-rw-r--r--vendor/der/src/asn1/bit_string.rs298
1 files changed, 173 insertions, 125 deletions
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