1use crate::error::{Error, ErrorCode, Located, Result};
4use crate::extension::{self, Extension};
5use structured_asn1::memory::{Memory, OwnedVec, Work};
6use structured_asn1::{BitString, Element, Oid, Reader, Tag, universal};
7
8#[derive(Debug, Clone, Copy)]
10pub struct KeyUsage<'a> {
11 bits: BitString<'a>,
12}
13
14impl<'a> KeyUsage<'a> {
15 #[must_use]
17 pub fn digital_signature(self) -> bool {
18 self.bits.bit(0)
19 }
20
21 #[must_use]
24 pub fn content_commitment(self) -> bool {
25 self.bits.bit(1)
26 }
27
28 #[must_use]
30 pub fn key_encipherment(self) -> bool {
31 self.bits.bit(2)
32 }
33
34 #[must_use]
36 pub fn data_encipherment(self) -> bool {
37 self.bits.bit(3)
38 }
39
40 #[must_use]
42 pub fn key_agreement(self) -> bool {
43 self.bits.bit(4)
44 }
45
46 #[must_use]
49 pub fn key_cert_sign(self) -> bool {
50 self.bits.bit(5)
51 }
52
53 #[must_use]
55 pub fn crl_sign(self) -> bool {
56 self.bits.bit(6)
57 }
58
59 #[must_use]
61 pub fn encipher_only(self) -> bool {
62 self.bits.bit(7)
63 }
64
65 #[must_use]
67 pub fn decipher_only(self) -> bool {
68 self.bits.bit(8)
69 }
70
71 #[must_use]
74 pub fn bits(self) -> BitString<'a> {
75 self.bits
76 }
77
78 pub fn read(extension: &Extension<'a>, execution: &Memory) -> Result<Self> {
80 const FIELD: &str = "extensions.keyUsage";
81 let fail = |code| Error::new(code, FIELD, extension.span().start);
82
83 let mut reader = extension.reader(execution).field(FIELD)?;
84 let bits = reader.read_bit_string().field(FIELD)?;
85 if !reader.is_empty() {
86 return Err(fail(ErrorCode::TrailingData));
87 }
88
89 reader.charge(bits.as_bytes().len() as u64).field(FIELD)?;
93
94 if bits.as_bytes().iter().all(|byte| *byte == 0) {
98 return Err(fail(ErrorCode::MalformedValue));
99 }
100
101 if reader.encoding().is_der() {
106 let length = bits.len();
107 if !bits.bit(length - 1) {
108 return Err(fail(ErrorCode::MalformedValue));
109 }
110 if length > 9 {
111 return Err(fail(ErrorCode::MalformedValue));
112 }
113 }
114
115 let usage = Self { bits };
116 if (usage.encipher_only() || usage.decipher_only()) && !usage.key_agreement() {
120 return Err(fail(ErrorCode::MalformedValue));
121 }
122 Ok(usage)
123 }
124}
125
126#[derive(Debug)]
128pub struct ExtendedKeyUsage<'a> {
129 purposes: OwnedVec<Oid<'a>>,
130 at: u64,
131}
132
133impl<'a> ExtendedKeyUsage<'a> {
134 pub fn read_value(parent: &Reader<'a>, value: &Element<'a>) -> Result<Self> {
144 const FIELD: &str = "extensions.extKeyUsage";
145 let fail = |code| Error::new(code, FIELD, value.span().start);
146 if value.tag() != Tag::constructed(universal::SEQUENCE) {
147 return Err(fail(ErrorCode::Encoding(
148 structured_asn1::ErrorCode::UnexpectedTag,
149 )));
150 }
151 Self::read_members(
152 parent.enter(value).field(FIELD)?,
153 parent.memory(),
154 value.span().start,
155 )
156 }
157
158 fn read_members(mut inside: Reader<'a>, execution: &Memory, at: u64) -> Result<Self> {
159 const FIELD: &str = "extensions.extKeyUsage";
160 let work = inside.execution_in(execution);
161 let mut purposes = work.vector();
162 let mut seen = work.map::<Oid<'a>, ()>();
163 while !inside.is_empty() {
168 let purpose = inside.read_oid().field(FIELD)?;
169 if seen
170 .try_insert(purpose, ())
171 .map_err(|reason| Error::resource(reason, FIELD, inside.offset()))?
172 .is_none()
173 {
174 purposes
175 .try_push(purpose)
176 .map_err(|reason| Error::resource(reason, FIELD, inside.offset()))?;
177 }
178 }
179 if purposes.is_empty() {
180 return Err(Error::new(ErrorCode::EmptySequence, FIELD, at));
181 }
182 Ok(Self {
183 purposes: purposes.into_owned(),
184 at,
185 })
186 }
187
188 #[must_use]
190 pub fn purposes(&self) -> &[Oid<'a>] {
191 &self.purposes
192 }
193
194 pub fn has(&self, purpose: Oid<'_>, execution: &Memory) -> Result<bool> {
201 for candidate in &self.purposes {
202 let work = 1 + candidate.as_bytes().len().max(purpose.as_bytes().len()) as u64;
203 execution
204 .charge_work(work)
205 .map_err(|reason| Error::resource(reason, "extensions.extKeyUsage", self.at))?;
206 if *candidate == purpose {
207 return Ok(true);
208 }
209 }
210 Ok(false)
211 }
212
213 pub fn read(extension: &Extension<'a>, execution: &Memory) -> Result<Self> {
215 Self::read_members(
216 extension::sequence(extension, "extensions.extKeyUsage", execution)?,
217 execution,
218 extension.span().start,
219 )
220 }
221
222 pub fn read_in<'work>(
224 extension: &Extension<'a>,
225 query: &Reader<'work>,
226 ) -> Result<ExtendedKeyUsage<'work>>
227 where
228 'a: 'work,
229 {
230 let reader = extension.reader_in(query).field("extensions.extKeyUsage")?;
231 let inside =
232 extension::sequence_reader(reader, "extensions.extKeyUsage", extension.span().start)?;
233 ExtendedKeyUsage::read_members(inside, query.memory(), extension.span().start)
234 }
235}
236
237#[cfg(test)]
238mod tests;