diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:41:41 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:41:41 +0000 |
commit | 10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 (patch) | |
tree | bdffd5d80c26cf4a7a518281a204be1ace85b4c1 /vendor/der/src/asn1/boolean.rs | |
parent | Releasing progress-linux version 1.70.0+dfsg1-9~progress7.99u1. (diff) | |
download | rustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.tar.xz rustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.zip |
Merging upstream version 1.70.0+dfsg2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/der/src/asn1/boolean.rs')
-rw-r--r-- | vendor/der/src/asn1/boolean.rs | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/vendor/der/src/asn1/boolean.rs b/vendor/der/src/asn1/boolean.rs new file mode 100644 index 000000000..e03218120 --- /dev/null +++ b/vendor/der/src/asn1/boolean.rs @@ -0,0 +1,93 @@ +//! ASN.1 `BOOLEAN` support. + +use crate::{ + asn1::AnyRef, ord::OrdIsValueOrd, ByteSlice, 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: +/// +/// > If the encoding represents the boolean value TRUE, its single contents +/// > octet shall have all eight bits set to one. +const TRUE_OCTET: u8 = 0b11111111; + +/// Byte used to encode `false` in ASN.1 DER. +const FALSE_OCTET: u8 = 0b00000000; + +impl<'a> DecodeValue<'a> for bool { + fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> { + if header.length != Length::ONE { + return Err(reader.error(ErrorKind::Length { tag: Self::TAG })); + } + + match reader.read_byte()? { + FALSE_OCTET => Ok(false), + TRUE_OCTET => Ok(true), + _ => Err(Self::TAG.non_canonical_error()), + } + } +} + +impl EncodeValue for bool { + fn value_len(&self) -> Result<Length> { + Ok(Length::ONE) + } + + fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> { + writer.write_byte(if *self { TRUE_OCTET } else { FALSE_OCTET }) + } +} + +impl FixedTag for bool { + const TAG: Tag = Tag::Boolean; +} + +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; + + fn try_from(any: AnyRef<'_>) -> Result<bool> { + any.try_into() + } +} + +#[cfg(test)] +mod tests { + use crate::{Decode, Encode}; + + #[test] + fn decode() { + assert_eq!(true, bool::from_der(&[0x01, 0x01, 0xFF]).unwrap()); + assert_eq!(false, bool::from_der(&[0x01, 0x01, 0x00]).unwrap()); + } + + #[test] + fn encode() { + let mut buffer = [0u8; 3]; + assert_eq!( + &[0x01, 0x01, 0xFF], + true.encode_to_slice(&mut buffer).unwrap() + ); + assert_eq!( + &[0x01, 0x01, 0x00], + false.encode_to_slice(&mut buffer).unwrap() + ); + } + + #[test] + fn reject_non_canonical() { + assert!(bool::from_der(&[0x01, 0x01, 0x01]).is_err()); + } +} |