Skip to main content

structured_pkix/
usage.rs

1//! What a key may be used for.
2
3use crate::error::{Error, ErrorCode, Located, Result};
4use crate::extension::{self, Extension};
5use structured_asn1::memory::{Memory, OwnedVec};
6use structured_asn1::{BitString, Oid};
7
8/// The purposes a key may be used for, as the bits the certificate set.
9#[derive(Debug, Clone, Copy)]
10pub struct KeyUsage<'a> {
11    bits: BitString<'a>,
12}
13
14impl<'a> KeyUsage<'a> {
15    /// Signing data.
16    #[must_use]
17    pub fn digital_signature(self) -> bool {
18        self.bits.bit(0)
19    }
20
21    /// Signing in a way the signer is not meant to be able to deny later,
22    /// which is the bit a signature under the Regulation rests on.
23    #[must_use]
24    pub fn content_commitment(self) -> bool {
25        self.bits.bit(1)
26    }
27
28    /// Enciphering a key.
29    #[must_use]
30    pub fn key_encipherment(self) -> bool {
31        self.bits.bit(2)
32    }
33
34    /// Enciphering data directly.
35    #[must_use]
36    pub fn data_encipherment(self) -> bool {
37        self.bits.bit(3)
38    }
39
40    /// Agreeing a key.
41    #[must_use]
42    pub fn key_agreement(self) -> bool {
43        self.bits.bit(4)
44    }
45
46    /// Signing certificates, which is what makes a certification authority
47    /// one.
48    #[must_use]
49    pub fn key_cert_sign(self) -> bool {
50        self.bits.bit(5)
51    }
52
53    /// Signing revocation lists.
54    #[must_use]
55    pub fn crl_sign(self) -> bool {
56        self.bits.bit(6)
57    }
58
59    /// Enciphering only, which means something only alongside key agreement.
60    #[must_use]
61    pub fn encipher_only(self) -> bool {
62        self.bits.bit(7)
63    }
64
65    /// Deciphering only, on the same terms.
66    #[must_use]
67    pub fn decipher_only(self) -> bool {
68        self.bits.bit(8)
69    }
70
71    /// The bits as they were written, for a report that has to say what a
72    /// certificate carries rather than what it means.
73    #[must_use]
74    pub fn bits(self) -> BitString<'a> {
75        self.bits
76    }
77
78    /// Reads the value of a key usage extension.
79    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        // The zero walk below touches every content byte, so it is charged
90        // to the shared work budget first: a caller bounding work must see
91        // an oversized string's scan on the same meter the reads use.
92        reader.charge(bits.as_bytes().len() as u64).field(FIELD)?;
93
94        // A key usage with no bit set forbids every use while claiming to
95        // permit one, and the schema asks for at least one. Written as a
96        // string of zero bits or as zero bytes, it says the same nothing.
97        if bits.as_bytes().iter().all(|byte| *byte == 0) {
98            return Err(fail(ErrorCode::MalformedValue));
99        }
100
101        // DER trims a named bit list to its last set bit, so trailing zero
102        // bits are a second spelling of a shorter value; and a set bit past
103        // decipherOnly is a bit this schema gives no name. BER carries no
104        // trimming rule, and past-the-end bits there read as unset.
105        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        // The meaning of encipherOnly and decipherOnly is undefined in the
117        // absence of the keyAgreement bit (RFC 5280 4.2.1.3): a bit with no
118        // defined meaning cannot be read as permitting anything.
119        if (usage.encipher_only() || usage.decipher_only()) && !usage.key_agreement() {
120            return Err(fail(ErrorCode::MalformedValue));
121        }
122        Ok(usage)
123    }
124}
125
126/// Further purposes, named by identifier rather than by bit.
127#[derive(Debug)]
128pub struct ExtendedKeyUsage<'a> {
129    purposes: OwnedVec<Oid<'a>>,
130    at: u64,
131}
132
133impl<'a> ExtendedKeyUsage<'a> {
134    /// The purposes, in the order the certificate holds them.
135    #[must_use]
136    pub fn purposes(&self) -> &[Oid<'a>] {
137        &self.purposes
138    }
139
140    /// Whether one purpose is among them.
141    ///
142    /// The identifier that stands for any purpose is not treated as matching
143    /// everything here: whether it does is a policy question, and answering it
144    /// in the parser would hide the difference between a certificate that
145    /// names a purpose and one that names none.
146    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    /// Reads the value of an extended key usage extension.
160    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            // The list is a SEQUENCE OF with no uniqueness constraint, and
170            // a repeated purpose permits exactly what one occurrence does:
171            // refusing it would block a valid certificate, so the repeat is
172            // folded away and the list holds each purpose once. A set
173            // rather than a scan, so a long list costs the work its size
174            // says and not its square.
175            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;