1use crate::error::{Error, ErrorCode, Located, Result};
4use crate::extension::{self, Extension};
5use structured_asn1::memory::{Memory, OwnedVec};
6use structured_asn1::{BitString, Oid};
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 #[must_use]
136 pub fn purposes(&self) -> &[Oid<'a>] {
137 &self.purposes
138 }
139
140 pub fn has(&self, purpose: Oid<'_>, execution: &Memory) -> Result<bool> {
147 for candidate in &self.purposes {
148 let work = 1 + candidate.as_bytes().len().max(purpose.as_bytes().len()) as u64;
149 execution
150 .charge_work(work)
151 .map_err(|reason| Error::resource(reason, "extensions.extKeyUsage", self.at))?;
152 if *candidate == purpose {
153 return Ok(true);
154 }
155 }
156 Ok(false)
157 }
158
159 pub fn read(extension: &Extension<'a>, execution: &Memory) -> Result<Self> {
161 const FIELD: &str = "extensions.extKeyUsage";
162 let fail = |code| Error::new(code, FIELD, extension.span().start);
163
164 let mut inside = extension::sequence(extension, FIELD, execution)?;
165 let mut purposes = inside.memory().vector();
166 let mut seen = inside.memory().map::<Oid<'a>, ()>();
167 while !inside.is_empty() {
168 let purpose = inside.read_oid().field(FIELD)?;
169 if seen
176 .try_insert(purpose, ())
177 .map_err(|reason| Error::resource(reason, FIELD, inside.offset()))?
178 .is_none()
179 {
180 purposes
181 .try_push(purpose)
182 .map_err(|reason| Error::resource(reason, FIELD, inside.offset()))?;
183 }
184 }
185 if purposes.is_empty() {
186 return Err(fail(ErrorCode::EmptySequence));
187 }
188
189 Ok(Self {
190 purposes,
191 at: extension.span().start,
192 })
193 }
194}
195
196#[cfg(test)]
197mod tests;