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 pub(crate) raw: &'a [u8],
25}
26
27impl<'a> X509CertificationRequest<'a> {
28 pub fn as_raw(&self) -> &'a [u8] {
34 self.raw
35 }
36
37 pub fn requested_extensions(&self) -> Option<impl Iterator<Item = &ParsedExtension<'_>>> {
38 self.certification_request_info
39 .iter_attributes()
40 .find_map(|attr| {
41 if let ParsedCriAttribute::ExtensionRequest(requested) = &attr.parsed_attribute {
42 Some(requested.extensions.iter().map(|ext| &ext.parsed_extension))
43 } else {
44 None
45 }
46 })
47 }
48
49 #[cfg(feature = "verify")]
54 pub fn verify_signature(&self) -> Result<(), X509Error> {
55 let spki = &self.certification_request_info.subject_pki;
56 verify_signature(
57 spki,
58 &self.signature_algorithm,
59 &self.signature_value,
60 self.certification_request_info.raw,
61 )
62 }
63}
64
65impl<'a> AsRef<[u8]> for X509CertificationRequest<'a> {
66 fn as_ref(&self) -> &[u8] {
67 self.as_raw()
68 }
69}
70
71impl<'a> FromDer<'a, X509Error> for X509CertificationRequest<'a> {
79 fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
80 let start_i = i;
81 let (rem, mut req) = parse_der_sequence_defined_g(|i, _| {
82 let (i, certification_request_info) = X509CertificationRequestInfo::from_der(i)?;
83 let (i, signature_algorithm) = AlgorithmIdentifier::from_der(i)?;
84 let (i, signature_value) = parse_signature_value(i)?;
85 let cert = X509CertificationRequest {
86 certification_request_info,
87 signature_algorithm,
88 signature_value,
89 raw: &[],
90 };
91 Ok((i, cert))
92 })(i)?;
93 let len = start_i.offset(rem);
94 req.raw = &start_i[..len];
95 Ok((rem, req))
96 }
97}
98
99#[derive(Debug, PartialEq)]
117pub struct X509CertificationRequestInfo<'a> {
118 pub version: X509Version,
119 pub subject: X509Name<'a>,
120 pub subject_pki: SubjectPublicKeyInfo<'a>,
121 attributes: Vec<X509CriAttribute<'a>>,
122 pub raw: &'a [u8],
123}
124
125impl X509CertificationRequestInfo<'_> {
126 #[inline]
128 pub fn attributes(&self) -> &[X509CriAttribute<'_>] {
129 &self.attributes
130 }
131
132 #[inline]
134 pub fn iter_attributes(&self) -> impl Iterator<Item = &X509CriAttribute<'_>> {
135 self.attributes.iter()
136 }
137
138 pub fn find_attribute(&self, oid: &Oid) -> Option<&X509CriAttribute<'_>> {
142 self.attributes.iter().find(|&ext| ext.oid == *oid)
143 }
144
145 pub fn attributes_map(&self) -> Result<HashMap<Oid<'_>, &X509CriAttribute<'_>>, X509Error> {
149 self.attributes
150 .iter()
151 .try_fold(HashMap::new(), |mut m, ext| {
152 if m.contains_key(&ext.oid) {
153 return Err(X509Error::DuplicateAttributes);
154 }
155 m.insert(ext.oid.clone(), ext);
156 Ok(m)
157 })
158 }
159}
160
161impl<'a> FromDer<'a, X509Error> for X509CertificationRequestInfo<'a> {
170 fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
171 let start_i = i;
172 parse_der_sequence_defined_g(move |i, _| {
173 let (i, version) = X509Version::from_der(i)?;
174 let (i, subject) = X509Name::from_der(i)?;
175 let (i, subject_pki) = SubjectPublicKeyInfo::from_der(i)?;
176 let (i, attributes) = parse_cri_attributes(i)?;
177 let len = start_i.offset(i);
178 let tbs = X509CertificationRequestInfo {
179 version,
180 subject,
181 subject_pki,
182 attributes,
183 raw: &start_i[..len],
184 };
185 Ok((i, tbs))
186 })(i)
187 }
188}