der/asn1/
boolean.rs

1//! ASN.1 `BOOLEAN` support.
2
3use crate::{
4    asn1::Any, ByteSlice, DecodeValue, Decoder, EncodeValue, Encoder, Error, ErrorKind, FixedTag,
5    Length, OrdIsValueOrd, Result, Tag,
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(decoder: &mut Decoder<'a>, length: Length) -> Result<Self> {
19        if length != Length::ONE {
20            return Err(decoder.error(ErrorKind::Length { tag: Self::TAG }));
21        }
22
23        match decoder.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, encoder: &mut Encoder<'_>) -> Result<()> {
37        encoder.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 Any<'static> {
48    fn from(value: bool) -> Any<'static> {
49        let value = ByteSlice::from(match value {
50            false => &[FALSE_OCTET],
51            true => &[TRUE_OCTET],
52        });
53
54        Any::from_tag_and_value(Tag::Boolean, value)
55    }
56}
57
58impl TryFrom<Any<'_>> for bool {
59    type Error = Error;
60
61    fn try_from(any: Any<'_>) -> Result<bool> {
62        any.try_into()
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use crate::{Decodable, Encodable};
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}