1use yasna::{ASN1Error, ASN1ErrorKind, ASN1Result, BERReader, DERWriter, BERDecodable, Tag};
8use {DerWrite, FromDer};
9use types::*;
10use bit_vec::BitVec;
11use oid;
12
13pub type DerCertificationRequest =
16 CertificationRequest<CertificationRequestInfo<'static, DerSequence<'static>>,
17 DerSequence<'static>,
18 BitVec>;
19
20#[derive(Clone, Debug, Eq, PartialEq, Hash)]
21pub struct CertificationRequest<I = CertificationRequestInfo<'static, DerSequence<'static>>,
22 A: SignatureAlgorithm = DerSequence<'static>,
23 S = BitVec> {
24 pub reqinfo: I,
25 pub sigalg: A,
26 pub sig: S,
27}
28
29impl<I: DerWrite, A: SignatureAlgorithm + DerWrite, S: DerWrite> DerWrite for CertificationRequest<I, A, S> {
30 fn write(&self, writer: DERWriter) {
31 writer.write_sequence(|writer| {
32 self.reqinfo.write(writer.next());
33 self.sigalg.write(writer.next());
34 self.sig.write(writer.next());
35 });
36 }
37}
38
39impl<I: BERDecodable, A: SignatureAlgorithm + BERDecodable, S: BERDecodable> BERDecodable for CertificationRequest<I, A, S> {
40 fn decode_ber<'a, 'b>(reader: BERReader<'a, 'b>) -> ASN1Result<Self> {
41 reader.read_sequence(|r| {
42 let reqinfo = I::decode_ber(r.next())?;
43 let sigalg = A::decode_ber(r.next())?;
44 let sig = S::decode_ber(r.next())?;
45
46 Ok(CertificationRequest { reqinfo, sigalg, sig })
47 })
48 }
49}
50
51impl<'a, K, A: SignatureAlgorithm, S> CertificationRequest<CertificationRequestInfo<'a, K>, A, S> {
52 pub fn has_attribute(&self, oid: &ObjectIdentifier) -> bool {
53 self.reqinfo.attributes.iter().any(|a| a.oid == *oid)
54 }
55
56 pub fn get_attribute<T: FromDer + HasOid>(&self) -> Option<Vec<T>> {
57 let oid = T::oid();
58
59 let mut iter = self.reqinfo.attributes.iter().filter(|a| a.oid == *oid);
60
61 match (iter.next(), iter.next()) {
65 (Some(attr), None) => {
66 attr.value
67 .iter()
68 .map(|v| T::from_der(v))
69 .collect::<ASN1Result<Vec<T>>>()
70 .ok()
71 }
72 _ => None,
73 }
74 }
75
76 pub fn get_singular_attribute<T: FromDer + HasOid>(&self) -> Option<T> {
77 match self.get_attribute() {
78 None => None,
79 Some(mut values) => {
80 if values.len() != 1 {
81 return None;
83 } else {
84 Some(values.pop().unwrap())
85 }
86 }
87 }
88 }
89}
90
91#[derive(Clone, Debug, Eq, PartialEq, Hash)]
92pub struct CertificationRequestInfo<'e, K> {
93 pub subject: Name,
95 pub spki: K,
96 pub attributes: Vec<Attribute<'e>>,
97}
98
99const CERTIFICATION_REQUEST_INFO_V1: u8 = 0;
100
101impl<'e, K: DerWrite> DerWrite for CertificationRequestInfo<'e, K> {
102 fn write(&self, writer: DERWriter) {
103 writer.write_sequence(|writer| {
104 CERTIFICATION_REQUEST_INFO_V1.write(writer.next());
105 self.subject.write(writer.next());
106 self.spki.write(writer.next());
107 writer.next().write_tagged_implicit(Tag::context(0), |w| {
108 w.write_set(|w| for attr in &self.attributes {
109 attr.write(w.next());
110 })
111 });
112 });
113 }
114}
115
116impl<'a, K: BERDecodable> BERDecodable for CertificationRequestInfo<'a, K> {
117 fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
118 reader.read_sequence(|r| {
119 let version = r.next().read_u8()?;
120 if version != CERTIFICATION_REQUEST_INFO_V1 {
121 return Err(ASN1Error::new(ASN1ErrorKind::Invalid));
122 }
123 let subject = Name::decode_ber(r.next())?;
124 let spki = K::decode_ber(r.next())?;
125 let attributes = r.next().read_tagged_implicit(Tag::context(0), |r| {
126 let mut attributes = Vec::<Attribute<'static>>::new();
127 r.read_set_of(|r| {
128 attributes.push(Attribute::decode_ber(r)?);
129 Ok(())
130 })?;
131 Ok(attributes)
132 })?;
133
134 Ok(CertificationRequestInfo { subject, spki, attributes })
135 })
136 }
137}
138
139#[derive(Clone, Debug, Eq, PartialEq, Hash)]
140pub struct ExtensionRequest {
141 pub extensions: Extensions,
142}
143
144impl HasOid for ExtensionRequest {
145 fn oid() -> &'static ObjectIdentifier {
146 &oid::extensionRequest
147 }
148}
149
150impl DerWrite for ExtensionRequest {
151 fn write(&self, writer: DERWriter) {
152 self.extensions.write(writer)
153 }
154}
155
156impl BERDecodable for ExtensionRequest {
157 fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
158 Ok(ExtensionRequest { extensions: Extensions::decode_ber(reader)? })
159 }
160}
161
162impl ExtensionRequest {
163 pub fn get_requested_extension<T: FromDer + HasOid>(&self) -> Option<T> {
164 self.extensions.get_extension::<T>()
165 }
166}
167
168#[cfg(test)]
169mod tests {
170 use super::*;
171 use crate::test::test_encode_decode;
172
173 #[test]
174 fn extension_request() {
175 let extension_request = ExtensionRequest {
176 extensions: Extensions(vec![
177 Extension {
178 oid: oid::basicConstraints.clone(),
179 critical: true,
180 value: vec![0x30, 0x00],
181 },
182 Extension {
183 oid: oid::keyUsage.clone(),
184 critical: true,
185 value: vec![0x03, 0x03, 0x07, 0x80, 0x00],
186 },
187 ])
188 };
189
190 let der = &[
191 0x30, 0x1f, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d,
192 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00,
193 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
194 0x01, 0xff, 0x04, 0x05, 0x03, 0x03, 0x07, 0x80,
195 0x00];
196
197 test_encode_decode(&extension_request, der);
198 }
199}