der/asn1/
oid.rs

1//! ASN.1 `OBJECT IDENTIFIER`
2
3use crate::{
4    asn1::Any, ByteSlice, DecodeValue, Decoder, EncodeValue, Encoder, Error, FixedTag, Length,
5    OrdIsValueOrd, Result, Tag, Tagged,
6};
7use const_oid::ObjectIdentifier;
8
9impl DecodeValue<'_> for ObjectIdentifier {
10    fn decode_value(decoder: &mut Decoder<'_>, length: Length) -> Result<Self> {
11        let bytes = ByteSlice::decode_value(decoder, length)?.as_bytes();
12        Ok(Self::from_bytes(bytes)?)
13    }
14}
15
16impl EncodeValue for ObjectIdentifier {
17    fn value_len(&self) -> Result<Length> {
18        Length::try_from(self.as_bytes().len())
19    }
20
21    fn encode_value(&self, encoder: &mut Encoder<'_>) -> Result<()> {
22        encoder.bytes(self.as_bytes())
23    }
24}
25
26impl FixedTag for ObjectIdentifier {
27    const TAG: Tag = Tag::ObjectIdentifier;
28}
29
30impl OrdIsValueOrd for ObjectIdentifier {}
31
32impl<'a> From<&'a ObjectIdentifier> for Any<'a> {
33    fn from(oid: &'a ObjectIdentifier) -> Any<'a> {
34        // Note: ensuring an infallible conversion is possible relies on the
35        // invariant that `const_oid::MAX_LEN <= Length::max()`.
36        //
37        // The `length()` test below ensures this is the case.
38        let value = oid
39            .as_bytes()
40            .try_into()
41            .expect("OID length invariant violated");
42
43        Any::from_tag_and_value(Tag::ObjectIdentifier, value)
44    }
45}
46
47impl TryFrom<Any<'_>> for ObjectIdentifier {
48    type Error = Error;
49
50    fn try_from(any: Any<'_>) -> Result<ObjectIdentifier> {
51        any.tag().assert_eq(Tag::ObjectIdentifier)?;
52        Ok(ObjectIdentifier::from_bytes(any.value())?)
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::ObjectIdentifier;
59    use crate::{Decodable, Encodable, Length};
60
61    const EXAMPLE_OID: ObjectIdentifier = ObjectIdentifier::new("1.2.840.113549");
62    const EXAMPLE_OID_BYTES: &[u8; 8] = &[0x06, 0x06, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d];
63
64    #[test]
65    fn decode() {
66        let oid = ObjectIdentifier::from_der(EXAMPLE_OID_BYTES).unwrap();
67        assert_eq!(EXAMPLE_OID, oid);
68    }
69
70    #[test]
71    fn encode() {
72        let mut buffer = [0u8; 8];
73        assert_eq!(
74            EXAMPLE_OID_BYTES,
75            EXAMPLE_OID.encode_to_slice(&mut buffer).unwrap()
76        );
77    }
78
79    #[test]
80    fn length() {
81        // Ensure an infallible `From` conversion to `Any` will never panic
82        assert!(ObjectIdentifier::MAX_SIZE <= Length::MAX.try_into().unwrap());
83    }
84}