der/asn1/
boolean.rs

1//! ASN.1 `BOOLEAN` support.
2
3use crate::{
4    asn1::AnyRef, ord::OrdIsValueOrd, ByteSlice, DecodeValue, EncodeValue, Error, ErrorKind,
5    FixedTag, Header, Length, Reader, Result, Tag, Writer,
6};
7
8/// Byte used to encode `true` in ASN.1 DER. From X.690 Section 11.1:
9///
10/// > If the encoding represents the boolean value TRUE, its single contents
11/// > octet shall have all eight bits set to one.
12const TRUE_OCTET: u8 = 0b11111111;
13
14/// Byte used to encode `false` in ASN.1 DER.
15const FALSE_OCTET: u8 = 0b00000000;
16
17impl<'a> DecodeValue<'a> for bool {
18    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
19        if header.length != Length::ONE {
20            return Err(reader.error(ErrorKind::Length { tag: Self::TAG }));
21        }
22
23        match reader.read_byte()? {
24            FALSE_OCTET => Ok(false),
25            TRUE_OCTET => Ok(true),
26            _ => Err(Self::TAG.non_canonical_error()),
27        }
28    }
29}
30
31impl EncodeValue for bool {
32    fn value_len(&self) -> Result<Length> {
33        Ok(Length::ONE)
34    }
35
36    fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
37        writer.write_byte(if *self { TRUE_OCTET } else { FALSE_OCTET })
38    }
39}
40
41impl FixedTag for bool {
42    const TAG: Tag = Tag::Boolean;
43}
44
45impl OrdIsValueOrd for bool {}
46
47impl From<bool> for AnyRef<'static> {
48    fn from(value: bool) -> AnyRef<'static> {
49        let value = ByteSlice::from(match value {
50            false => &[FALSE_OCTET],
51            true => &[TRUE_OCTET],
52        });
53
54        AnyRef::from_tag_and_value(Tag::Boolean, value)
55    }
56}
57
58impl TryFrom<AnyRef<'_>> for bool {
59    type Error = Error;
60
61    fn try_from(any: AnyRef<'_>) -> Result<bool> {
62        any.try_into()
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use crate::{Decode, Encode};
69
70    #[test]
71    fn decode() {
72        assert_eq!(true, bool::from_der(&[0x01, 0x01, 0xFF]).unwrap());
73        assert_eq!(false, bool::from_der(&[0x01, 0x01, 0x00]).unwrap());
74    }
75
76    #[test]
77    fn encode() {
78        let mut buffer = [0u8; 3];
79        assert_eq!(
80            &[0x01, 0x01, 0xFF],
81            true.encode_to_slice(&mut buffer).unwrap()
82        );
83        assert_eq!(
84            &[0x01, 0x01, 0x00],
85            false.encode_to_slice(&mut buffer).unwrap()
86        );
87    }
88
89    #[test]
90    fn reject_non_canonical() {
91        assert!(bool::from_der(&[0x01, 0x01, 0x01]).is_err());
92    }
93}