x509_certificate/
rfc5652.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5//! ASN.1 types defined in RFC 5652.
6//!
7//! Only the types referenced by X.509 certificates are defined here.
8//! For the higher-level CMS types, see the `cryptographic-message-syntax`
9//! crate.
10
11use {
12    bcder::{
13        decode::{Constructed, DecodeError, Source},
14        encode::{self, PrimitiveContent, Values},
15        Captured, Mode, Oid,
16    },
17    std::{
18        fmt::{Debug, Formatter},
19        io::Write,
20        ops::{Deref, DerefMut},
21    },
22};
23
24/// A single attribute.
25///
26/// ```ASN.1
27/// Attribute ::= SEQUENCE {
28///   attrType OBJECT IDENTIFIER,
29///   attrValues SET OF AttributeValue }
30/// ```
31#[derive(Clone, Eq, PartialEq)]
32pub struct Attribute {
33    pub typ: Oid,
34    pub values: Vec<AttributeValue>,
35}
36
37impl Debug for Attribute {
38    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
39        let mut s = f.debug_struct("Attribute");
40        s.field("type", &format_args!("{}", self.typ));
41        s.field("values", &self.values);
42        s.finish()
43    }
44}
45
46impl Attribute {
47    pub fn take_opt_from<S: Source>(
48        cons: &mut Constructed<S>,
49    ) -> Result<Option<Self>, DecodeError<S::Error>> {
50        cons.take_opt_sequence(|cons| {
51            let typ = Oid::take_from(cons)?;
52
53            let values = cons.take_set(|cons| {
54                let mut values = Vec::new();
55
56                while let Some(value) = AttributeValue::take_opt_from(cons)? {
57                    values.push(value);
58                }
59
60                Ok(values)
61            })?;
62
63            Ok(Self { typ, values })
64        })
65    }
66
67    pub fn encode_ref(&self) -> impl Values + '_ {
68        encode::sequence((self.typ.encode_ref(), encode::set(&self.values)))
69    }
70
71    pub fn encode(self) -> impl Values {
72        encode::sequence((self.typ.encode(), encode::set(self.values)))
73    }
74}
75
76#[derive(Clone)]
77pub struct AttributeValue(Captured);
78
79impl Debug for AttributeValue {
80    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
81        f.write_fmt(format_args!(
82            "{}",
83            hex::encode(self.0.clone().into_bytes().as_ref())
84        ))
85    }
86}
87
88impl AttributeValue {
89    /// Construct a new instance from captured data.
90    pub fn new(captured: Captured) -> Self {
91        Self(captured)
92    }
93
94    pub fn take_opt_from<S: Source>(
95        cons: &mut Constructed<S>,
96    ) -> Result<Option<Self>, DecodeError<S::Error>> {
97        let captured = cons.capture_all()?;
98
99        if captured.is_empty() {
100            Ok(None)
101        } else {
102            Ok(Some(Self(captured)))
103        }
104    }
105}
106
107impl Values for AttributeValue {
108    fn encoded_len(&self, mode: Mode) -> usize {
109        self.0.encoded_len(mode)
110    }
111
112    fn write_encoded<W: Write>(&self, mode: Mode, target: &mut W) -> Result<(), std::io::Error> {
113        self.0.write_encoded(mode, target)
114    }
115}
116
117impl Deref for AttributeValue {
118    type Target = Captured;
119
120    fn deref(&self) -> &Self::Target {
121        &self.0
122    }
123}
124
125impl DerefMut for AttributeValue {
126    fn deref_mut(&mut self) -> &mut Self::Target {
127        &mut self.0
128    }
129}
130
131impl PartialEq for AttributeValue {
132    fn eq(&self, other: &Self) -> bool {
133        self.0.as_slice() == other.0.as_slice()
134    }
135}
136
137impl Eq for AttributeValue {}