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