1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use crate::{
error::{X509Error, X509Result},
extensions::X509Extension,
};
use asn1_rs::{Error, FromDer, Header, Oid, Sequence, Tag};
use nom::Err;
use oid_registry::*;
use std::collections::HashMap;
#[derive(Clone, Debug, PartialEq)]
pub struct X509CriAttribute<'a> {
pub oid: Oid<'a>,
pub value: &'a [u8],
pub(crate) parsed_attribute: ParsedCriAttribute<'a>,
}
impl<'a> FromDer<'a, X509Error> for X509CriAttribute<'a> {
fn from_der(i: &'a [u8]) -> X509Result<X509CriAttribute> {
Sequence::from_ber_and_then(i, |i| {
let (i, oid) = Oid::from_der(i)?;
let value_start = i;
let (i, hdr) = Header::from_der(i)?;
if hdr.tag() != Tag::Set {
return Err(Err::Error(Error::BerTypeError));
};
let (i, parsed_attribute) = crate::cri_attributes::parser::parse_attribute(i, &oid)
.map_err(|_| Err::Error(Error::BerValueError))?;
let ext = X509CriAttribute {
oid,
value: &value_start[..value_start.len() - i.len()],
parsed_attribute,
};
Ok((i, ext))
})
.map_err(|_| X509Error::InvalidAttributes.into())
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct ExtensionRequest<'a> {
pub extensions: Vec<X509Extension<'a>>,
}
impl<'a> FromDer<'a, X509Error> for ExtensionRequest<'a> {
fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
parser::parse_extension_request(i).map_err(Err::convert)
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum ParsedCriAttribute<'a> {
ExtensionRequest(ExtensionRequest<'a>),
UnsupportedAttribute,
}
pub(crate) mod parser {
use crate::cri_attributes::*;
use lazy_static::lazy_static;
use nom::combinator::map;
type AttrParser = fn(&[u8]) -> X509Result<ParsedCriAttribute>;
lazy_static! {
static ref ATTRIBUTE_PARSERS: HashMap<Oid<'static>, AttrParser> = {
macro_rules! add {
($m:ident, $oid:ident, $p:ident) => {
$m.insert($oid, $p as AttrParser);
};
}
let mut m = HashMap::new();
add!(m, OID_PKCS9_EXTENSION_REQUEST, parse_extension_request_ext);
m
};
}
pub(crate) fn parse_attribute<'a>(
i: &'a [u8],
oid: &Oid,
) -> X509Result<'a, ParsedCriAttribute<'a>> {
if let Some(parser) = ATTRIBUTE_PARSERS.get(oid) {
parser(i)
} else {
Ok((i, ParsedCriAttribute::UnsupportedAttribute))
}
}
pub(super) fn parse_extension_request(i: &[u8]) -> X509Result<ExtensionRequest> {
crate::extensions::parse_extension_sequence(i)
.map(|(i, extensions)| (i, ExtensionRequest { extensions }))
}
fn parse_extension_request_ext(i: &[u8]) -> X509Result<ParsedCriAttribute> {
map(
parse_extension_request,
ParsedCriAttribute::ExtensionRequest,
)(i)
}
}
pub(crate) fn parse_cri_attributes(i: &[u8]) -> X509Result<Vec<X509CriAttribute>> {
let (i, hdr) = Header::from_der(i).map_err(|_| Err::Error(X509Error::InvalidAttributes))?;
if i.is_empty() {
return Ok((i, Vec::new()));
}
let constructed = if hdr.constructed() { 1 } else { 0 };
(0..constructed)
.into_iter()
.try_fold((i, Vec::new()), |(i, mut attrs), _| {
let (rem, attr) = X509CriAttribute::from_der(i)?;
attrs.push(attr);
Ok((rem, attrs))
})
}