1 //! ASN.1 `BOOLEAN` support.
2 
3 use crate::{
4     asn1::AnyRef, ord::OrdIsValueOrd, DecodeValue, EncodeValue, Error, ErrorKind, FixedTag, Header,
5     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.
12 const TRUE_OCTET: u8 = 0b11111111;
13 
14 /// Byte used to encode `false` in ASN.1 DER.
15 const FALSE_OCTET: u8 = 0b00000000;
16 
17 impl<'a> DecodeValue<'a> for bool {
decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self>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 
31 impl EncodeValue for bool {
value_len(&self) -> Result<Length>32     fn value_len(&self) -> Result<Length> {
33         Ok(Length::ONE)
34     }
35 
encode_value(&self, writer: &mut impl Writer) -> Result<()>36     fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
37         writer.write_byte(if *self { TRUE_OCTET } else { FALSE_OCTET })
38     }
39 }
40 
41 impl FixedTag for bool {
42     const TAG: Tag = Tag::Boolean;
43 }
44 
45 impl OrdIsValueOrd for bool {}
46 
47 impl TryFrom<AnyRef<'_>> for bool {
48     type Error = Error;
49 
try_from(any: AnyRef<'_>) -> Result<bool>50     fn try_from(any: AnyRef<'_>) -> Result<bool> {
51         any.try_into()
52     }
53 }
54 
55 #[cfg(test)]
56 mod tests {
57     use crate::{Decode, Encode};
58 
59     #[test]
decode()60     fn decode() {
61         assert_eq!(true, bool::from_der(&[0x01, 0x01, 0xFF]).unwrap());
62         assert_eq!(false, bool::from_der(&[0x01, 0x01, 0x00]).unwrap());
63     }
64 
65     #[test]
encode()66     fn encode() {
67         let mut buffer = [0u8; 3];
68         assert_eq!(
69             &[0x01, 0x01, 0xFF],
70             true.encode_to_slice(&mut buffer).unwrap()
71         );
72         assert_eq!(
73             &[0x01, 0x01, 0x00],
74             false.encode_to_slice(&mut buffer).unwrap()
75         );
76     }
77 
78     #[test]
reject_non_canonical()79     fn reject_non_canonical() {
80         assert!(bool::from_der(&[0x01, 0x01, 0x01]).is_err());
81     }
82 }
83