x509_parser/
certification_request.rs1use crate::cri_attributes::*;
2use crate::error::{X509Error, X509Result};
3use crate::extensions::*;
4use crate::x509::{
5 parse_signature_value, AlgorithmIdentifier, SubjectPublicKeyInfo, X509Name, X509Version,
6};
7
8#[cfg(feature = "verify")]
9use crate::verify::verify_signature;
10use asn1_rs::{BitString, FromDer};
11use der_parser::der::*;
12use der_parser::oid::Oid;
13use der_parser::*;
14use nom::Offset;
15use std::collections::HashMap;
16
17#[derive(Debug, PartialEq)]
19pub struct X509CertificationRequest<'a> {
20 pub certification_request_info: X509CertificationRequestInfo<'a>,
21 pub signature_algorithm: AlgorithmIdentifier<'a>,
22 pub signature_value: BitString<'a>,
23}
24
25impl<'a> X509CertificationRequest<'a> {
26 pub fn requested_extensions(&self) -> Option<impl Iterator<Item = &ParsedExtension>> {
27 self.certification_request_info
28 .iter_attributes()
29 .find_map(|attr| {
30 if let ParsedCriAttribute::ExtensionRequest(requested) = &attr.parsed_attribute {
31 Some(requested.extensions.iter().map(|ext| &ext.parsed_extension))
32 } else {
33 None
34 }
35 })
36 }
37
38 #[cfg(feature = "verify")]
43 pub fn verify_signature(&self) -> Result<(), X509Error> {
44 let spki = &self.certification_request_info.subject_pki;
45 verify_signature(
46 spki,
47 &self.signature_algorithm,
48 &self.signature_value,
49 self.certification_request_info.raw,
50 )
51 }
52}
53
54impl<'a> FromDer<'a, X509Error> for X509CertificationRequest<'a> {
62 fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
63 parse_der_sequence_defined_g(|i, _| {
64 let (i, certification_request_info) = X509CertificationRequestInfo::from_der(i)?;
65 let (i, signature_algorithm) = AlgorithmIdentifier::from_der(i)?;
66 let (i, signature_value) = parse_signature_value(i)?;
67 let cert = X509CertificationRequest {
68 certification_request_info,
69 signature_algorithm,
70 signature_value,
71 };
72 Ok((i, cert))
73 })(i)
74 }
75}
76
77#[derive(Debug, PartialEq)]
95pub struct X509CertificationRequestInfo<'a> {
96 pub version: X509Version,
97 pub subject: X509Name<'a>,
98 pub subject_pki: SubjectPublicKeyInfo<'a>,
99 attributes: Vec<X509CriAttribute<'a>>,
100 pub raw: &'a [u8],
101}
102
103impl<'a> X509CertificationRequestInfo<'a> {
104 #[inline]
106 pub fn attributes(&self) -> &[X509CriAttribute] {
107 &self.attributes
108 }
109
110 #[inline]
112 pub fn iter_attributes(&self) -> impl Iterator<Item = &X509CriAttribute> {
113 self.attributes.iter()
114 }
115
116 pub fn find_attribute(&self, oid: &Oid) -> Option<&X509CriAttribute> {
120 self.attributes.iter().find(|&ext| ext.oid == *oid)
121 }
122
123 pub fn attributes_map(&self) -> Result<HashMap<Oid, &X509CriAttribute>, X509Error> {
127 self.attributes
128 .iter()
129 .try_fold(HashMap::new(), |mut m, ext| {
130 if m.contains_key(&ext.oid) {
131 return Err(X509Error::DuplicateAttributes);
132 }
133 m.insert(ext.oid.clone(), ext);
134 Ok(m)
135 })
136 }
137}
138
139impl<'a> FromDer<'a, X509Error> for X509CertificationRequestInfo<'a> {
148 fn from_der(i: &'a [u8]) -> X509Result<Self> {
149 let start_i = i;
150 parse_der_sequence_defined_g(move |i, _| {
151 let (i, version) = X509Version::from_der(i)?;
152 let (i, subject) = X509Name::from_der(i)?;
153 let (i, subject_pki) = SubjectPublicKeyInfo::from_der(i)?;
154 let (i, attributes) = parse_cri_attributes(i)?;
155 let len = start_i.offset(i);
156 let tbs = X509CertificationRequestInfo {
157 version,
158 subject,
159 subject_pki,
160 attributes,
161 raw: &start_i[..len],
162 };
163 Ok((i, tbs))
164 })(i)
165 }
166}