x509_cert/request/
builder.rs1use alloc::vec;
2
3use der::{Encode, asn1::BitString};
4use signature::Keypair;
5use spki::{
6 AlgorithmIdentifier, DynSignatureAlgorithmIdentifier, EncodePublicKey, SubjectPublicKeyInfo,
7};
8
9use crate::{
10 builder::{Builder, Error, NULL_OID, Result},
11 ext::ToExtension,
12 name::Name,
13 request::{CertReq, CertReqInfo, ExtensionReq, attributes::AsAttribute},
14};
15
16pub struct RequestBuilder {
46 info: CertReqInfo,
47 extension_req: ExtensionReq,
48}
49
50impl RequestBuilder {
51 pub fn new(subject: Name) -> Result<Self> {
53 let version = Default::default();
54
55 let algorithm = AlgorithmIdentifier {
56 oid: NULL_OID,
57 parameters: None,
58 };
59 let public_key = SubjectPublicKeyInfo {
60 algorithm,
61 subject_public_key: BitString::from_bytes(&[]).expect("unable to parse empty object"),
62 };
63
64 let attributes = Default::default();
65 let extension_req = Default::default();
66
67 Ok(Self {
68 info: CertReqInfo {
69 version,
70 subject,
71 public_key,
72 attributes,
73 },
74 extension_req,
75 })
76 }
77
78 pub fn add_extension<E: ToExtension>(
84 &mut self,
85 extension: E,
86 ) -> core::result::Result<(), E::Error> {
87 let ext = extension.to_extension(&self.info.subject, &self.extension_req.0)?;
88
89 self.extension_req.0.push(ext);
90
91 Ok(())
92 }
93
94 pub fn add_attribute<A: AsAttribute>(&mut self, attribute: &A) -> Result<()> {
96 let attr = attribute.to_attribute()?;
97
98 self.info.attributes.insert(attr)?;
99 Ok(())
100 }
101}
102
103impl Builder for RequestBuilder {
104 type Output = CertReq;
105
106 fn finalize<S>(&mut self, signer: &S) -> Result<vec::Vec<u8>>
107 where
108 S: Keypair + DynSignatureAlgorithmIdentifier,
109 S::VerifyingKey: EncodePublicKey,
110 {
111 let verifying_key = signer.verifying_key();
112 let public_key = SubjectPublicKeyInfo::from_key(&verifying_key)?;
113 self.info.public_key = public_key;
114
115 self.info
116 .attributes
117 .insert(self.extension_req.clone().try_into()?)?;
118
119 self.info.to_der().map_err(Error::from)
120 }
121
122 fn assemble<S>(self, signature: BitString, signer: &S) -> Result<Self::Output>
123 where
124 S: Keypair + DynSignatureAlgorithmIdentifier,
125 S::VerifyingKey: EncodePublicKey,
126 {
127 let algorithm = signer.signature_algorithm_identifier()?;
128
129 Ok(CertReq {
130 info: self.info,
131 algorithm,
132 signature,
133 })
134 }
135}