1
1
//! X509 Certificate builder
2
2
3
- use alloc:: vec:: Vec ;
3
+ use alloc:: vec;
4
4
use der:: asn1:: { BitString , OctetString } ;
5
5
use sha1:: { Digest , Sha1 } ;
6
6
use spki:: { AlgorithmIdentifierOwned , SubjectPublicKeyInfoOwned } ;
@@ -81,12 +81,13 @@ impl Profile {
81
81
& self ,
82
82
spk : & SubjectPublicKeyInfoOwned ,
83
83
issuer_spk : & SubjectPublicKeyInfoOwned ,
84
- ) -> Result < Vec < Extension > > {
85
- let mut extensions: Vec < Extension > = Vec :: new ( ) ;
84
+ tbs : & TbsCertificate ,
85
+ ) -> Result < vec:: Vec < Extension > > {
86
+ let mut extensions: vec:: Vec < Extension > = vec:: Vec :: new ( ) ;
86
87
87
88
extensions. push ( {
88
89
let result = Sha1 :: digest ( spk. subject_public_key . raw_bytes ( ) ) ;
89
- SubjectKeyIdentifier ( OctetString :: new ( result. to_vec ( ) ) ?) . to_extension ( ) ?
90
+ SubjectKeyIdentifier ( OctetString :: new ( result. to_vec ( ) ) ?) . to_extension ( tbs ) ?
90
91
} ) ;
91
92
92
93
// Build Authority Key Identifier
@@ -103,7 +104,7 @@ impl Profile {
103
104
authority_cert_issuer : None ,
104
105
authority_cert_serial_number : None ,
105
106
}
106
- . to_extension ( ) ?,
107
+ . to_extension ( tbs ) ?,
107
108
) ;
108
109
}
109
110
}
@@ -114,20 +115,20 @@ impl Profile {
114
115
ca : true ,
115
116
path_len_constraint : None ,
116
117
}
117
- . to_extension ( ) ?,
118
+ . to_extension ( tbs ) ?,
118
119
Profile :: SubCA {
119
120
path_len_constraint,
120
121
..
121
122
} => BasicConstraints {
122
123
ca : true ,
123
124
path_len_constraint : * path_len_constraint,
124
125
}
125
- . to_extension ( ) ?,
126
+ . to_extension ( tbs ) ?,
126
127
Profile :: Leaf { .. } => BasicConstraints {
127
128
ca : false ,
128
129
path_len_constraint : None ,
129
130
}
130
- . to_extension ( ) ?,
131
+ . to_extension ( tbs ) ?,
131
132
} ) ;
132
133
133
134
// Build Key Usage extension
@@ -137,7 +138,7 @@ impl Profile {
137
138
KeyUsage (
138
139
KeyUsages :: DigitalSignature | KeyUsages :: KeyCertSign | KeyUsages :: CRLSign ,
139
140
)
140
- . to_extension ( ) ?,
141
+ . to_extension ( tbs ) ?,
141
142
) ;
142
143
}
143
144
Profile :: Leaf { .. } => {
@@ -230,18 +231,7 @@ impl From<CertificateVersion> for Version {
230
231
/// .expect("Create certificate");
231
232
/// ```
232
233
pub struct CertificateBuilder < ' s , S : Signer > {
233
- version : Version ,
234
- serial_number : SerialNumber ,
235
- signature_alg : AlgorithmIdentifierOwned ,
236
- issuer : Name ,
237
- validity : Validity ,
238
- subject : Name ,
239
- subject_public_key_info : SubjectPublicKeyInfoOwned ,
240
- issuer_unique_id : Option < BitString > ,
241
- subject_unique_id : Option < BitString > ,
242
-
243
- extensions : Vec < Extension > ,
244
-
234
+ tbs : TbsCertificate ,
245
235
signer : & ' s S ,
246
236
}
247
237
@@ -264,63 +254,59 @@ impl<'s, S: Signer> CertificateBuilder<'s, S> {
264
254
validity. not_before . rfc5280_adjust_utc_time ( ) ?;
265
255
validity. not_after . rfc5280_adjust_utc_time ( ) ?;
266
256
267
- let ( version, ( issuer_unique_id, subject_unique_id) , extensions) = match version {
268
- CertificateVersion :: V1 => ( Version :: V1 , ( None , None ) , Vec :: new ( ) ) ,
269
- CertificateVersion :: V2 ( uids) => ( Version :: V2 , uids. get_unique_ids ( ) , Vec :: new ( ) ) ,
270
- CertificateVersion :: V3 ( uids) => (
271
- Version :: V3 ,
272
- uids. get_unique_ids ( ) ,
273
- profile. build_extensions ( & subject_public_key_info, & signer_pub) ?,
274
- ) ,
257
+ let ( version, ( issuer_unique_id, subject_unique_id) ) = match version {
258
+ CertificateVersion :: V1 => ( Version :: V1 , ( None , None ) ) ,
259
+ CertificateVersion :: V2 ( uids) => ( Version :: V2 , uids. get_unique_ids ( ) ) ,
260
+ CertificateVersion :: V3 ( uids) => ( Version :: V3 , uids. get_unique_ids ( ) ) ,
275
261
} ;
276
262
277
- Ok ( Self {
263
+ let mut tbs = TbsCertificate {
278
264
version,
279
- issuer_unique_id,
280
- subject_unique_id,
281
265
serial_number,
266
+ signature : signature_alg,
282
267
issuer,
283
- subject,
284
268
validity,
269
+ subject,
285
270
subject_public_key_info,
286
- signature_alg,
287
- extensions,
288
- signer,
289
- } )
271
+ issuer_unique_id,
272
+ subject_unique_id,
273
+ extensions : None ,
274
+ } ;
275
+
276
+ if tbs. version == Version :: V3 {
277
+ let extensions =
278
+ profile. build_extensions ( & tbs. subject_public_key_info , & signer_pub, & tbs) ?;
279
+ if !extensions. is_empty ( ) {
280
+ tbs. extensions = Some ( extensions) ;
281
+ }
282
+ }
283
+
284
+ Ok ( Self { tbs, signer } )
290
285
}
291
286
292
287
/// Add an extension to this certificate
293
288
pub fn add_extension < E : AsExtension > ( & mut self , extension : & E ) -> Result < ( ) > {
294
- self . extensions . push ( extension. to_extension ( ) ?) ;
289
+ if self . tbs . version == Version :: V3 {
290
+ let ext = extension. to_extension ( & self . tbs ) ?;
291
+
292
+ if let Some ( extensions) = self . tbs . extensions . as_mut ( ) {
293
+ extensions. push ( ext) ;
294
+ } else {
295
+ let extensions = vec ! [ ext] ;
296
+ self . tbs . extensions = Some ( extensions) ;
297
+ }
298
+ }
299
+
295
300
Ok ( ( ) )
296
301
}
297
302
298
303
/// Run the certificate through the signer and build the end certificate.
299
304
pub fn build ( & mut self ) -> Result < Certificate > {
300
- let extensions = if self . version == Version :: V3 {
301
- Some ( self . extensions . clone ( ) )
302
- } else {
303
- None
304
- } ;
305
-
306
- let tbs_certificate = TbsCertificate {
307
- version : self . version ,
308
- serial_number : self . serial_number . clone ( ) ,
309
- signature : self . signature_alg . clone ( ) ,
310
- issuer : self . issuer . clone ( ) ,
311
- validity : self . validity ,
312
- subject : self . subject . clone ( ) ,
313
- subject_public_key_info : self . subject_public_key_info . clone ( ) ,
314
- issuer_unique_id : self . issuer_unique_id . clone ( ) ,
315
- subject_unique_id : self . subject_unique_id . clone ( ) ,
316
- extensions,
317
- } ;
318
-
319
- let signature = BitString :: from_bytes ( & self . signer . sign ( & tbs_certificate) ) ?;
305
+ let signature = BitString :: from_bytes ( & self . signer . sign ( & self . tbs ) ) ?;
320
306
321
307
let cert = Certificate {
322
- tbs_certificate,
323
- signature_algorithm : self . signature_alg . clone ( ) ,
308
+ tbs_certificate : self . tbs . clone ( ) ,
309
+ signature_algorithm : self . tbs . signature . clone ( ) ,
324
310
signature,
325
311
} ;
326
312
@@ -346,5 +332,5 @@ pub trait Signer {
346
332
fn public_key ( & self ) -> SubjectPublicKeyInfoOwned ;
347
333
348
334
/// The sign method should return the signature of the payload.
349
- fn sign ( & self , input : & TbsCertificate ) -> Vec < u8 > ;
335
+ fn sign ( & self , input : & TbsCertificate ) -> vec :: Vec < u8 > ;
350
336
}
0 commit comments