structured_pkix/
identifier.rs1use crate::error::{Error, ErrorCode, Located, Result};
10use crate::extension::{self, Extension};
11use crate::general_name::{self, GeneralName};
12use structured_asn1::memory::{Memory, OwnedVec};
13use structured_asn1::{Element, Integer, Tag, universal};
14
15#[derive(Debug, Clone, Copy)]
17pub struct SubjectKeyIdentifier<'a> {
18 bytes: &'a [u8],
19}
20
21impl<'a> SubjectKeyIdentifier<'a> {
22 #[must_use]
26 pub fn as_bytes(self) -> &'a [u8] {
27 self.bytes
28 }
29
30 pub fn read(extension: &Extension<'a>, execution: &Memory) -> Result<Self> {
32 const FIELD: &str = "extensions.subjectKeyIdentifier";
33 let fail = |code| Error::new(code, FIELD, extension.span().start);
34
35 let mut reader = extension.reader(execution).field(FIELD)?;
36 let element = reader
37 .next_element()
38 .field(FIELD)?
39 .ok_or_else(|| fail(ErrorCode::MissingField))?;
40 if element.tag() != Tag::primitive(universal::OCTET_STRING) {
41 return Err(fail(ErrorCode::Encoding(
42 structured_asn1::ErrorCode::UnexpectedTag,
43 )));
44 }
45 if !reader.is_empty() {
46 return Err(fail(ErrorCode::TrailingData));
47 }
48
49 Ok(Self {
50 bytes: element.contents(),
51 })
52 }
53}
54
55#[derive(Debug)]
57pub struct AuthorityKeyIdentifier<'a> {
58 key_id: Option<&'a [u8]>,
59 issuer: OwnedVec<GeneralName<'a>>,
60 serial: Option<Integer<'a>>,
61}
62
63impl<'a> AuthorityKeyIdentifier<'a> {
64 #[must_use]
66 pub fn key_id(&self) -> Option<&'a [u8]> {
67 self.key_id
68 }
69
70 #[must_use]
73 pub fn issuer(&self) -> &[GeneralName<'a>] {
74 &self.issuer
75 }
76
77 #[must_use]
80 pub fn serial(&self) -> Option<Integer<'a>> {
81 self.serial
82 }
83
84 pub fn read(extension: &Extension<'a>, execution: &Memory) -> Result<Self> {
86 const FIELD: &str = "extensions.authorityKeyIdentifier";
87 let fail = |code| Error::new(code, FIELD, extension.span().start);
88
89 let mut inside = extension::sequence(extension, FIELD, execution)?;
90 let mut identifier = Self {
91 key_id: None,
92 issuer: inside.memory().vector(),
93 serial: None,
94 };
95
96 let mut last_number = None;
99 while let Some(field) = inside.next_element().field(FIELD)? {
100 let tag = extension::context_of(field.tag());
101 match tag {
102 Some((0, false)) if last_number.is_none() => {
103 identifier.key_id = Some(field.contents());
104 }
105 Some((1, true)) if last_number < Some(1) => {
106 identifier.issuer = general_name::read_all(&inside, &field, FIELD)?;
107 }
108 Some((2, false)) if last_number < Some(2) => {
109 identifier.serial = Some(inside.integer(&field).field(FIELD)?);
110 }
111 _ => return Err(at(FIELD, ErrorCode::UnexpectedField, &field)),
112 }
113 last_number = tag.map(|(number, _)| number);
114 }
115
116 if identifier.issuer.is_empty() != identifier.serial.is_none() {
120 return Err(fail(ErrorCode::MalformedValue));
121 }
122
123 if !identifier.issuer.is_empty()
128 && !identifier
129 .issuer
130 .iter()
131 .any(|name| matches!(name, general_name::GeneralName::Directory(_)))
132 {
133 return Err(fail(ErrorCode::MalformedValue));
134 }
135
136 if identifier.key_id.is_none() && identifier.serial.is_none() {
140 return Err(fail(ErrorCode::MalformedValue));
141 }
142
143 Ok(identifier)
144 }
145}
146
147fn at(field: &'static str, code: ErrorCode, element: &Element<'_>) -> Error {
148 Error::new(code, field, element.span().start)
149}
150
151#[cfg(test)]
152mod tests;