1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use crate::{asn1::Any, Encodable, Encoder, Error, Header, Length, Result, Tag, Tagged};
use core::convert::TryFrom;
const TRUE_OCTET: u8 = 0b11111111;
const FALSE_OCTET: u8 = 0b00000000;
impl TryFrom<Any<'_>> for bool {
type Error = Error;
fn try_from(any: Any<'_>) -> Result<bool> {
let tag = any.tag().assert_eq(Tag::Boolean)?;
match any.as_bytes() {
[FALSE_OCTET] => Ok(false),
[TRUE_OCTET] => Ok(true),
_ => Err(tag.non_canonical_error()),
}
}
}
impl Encodable for bool {
fn encoded_len(&self) -> Result<Length> {
Length::ONE.for_tlv()
}
fn encode(&self, encoder: &mut Encoder<'_>) -> Result<()> {
Header::new(Self::TAG, Length::ONE)?.encode(encoder)?;
let byte = if *self { TRUE_OCTET } else { FALSE_OCTET };
encoder.byte(byte)
}
}
impl Tagged for bool {
const TAG: Tag = Tag::Boolean;
}
#[cfg(test)]
mod tests {
use crate::{Decodable, Encodable};
#[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());
}
}