18
18
//! ```
19
19
use std:: fmt:: Write ;
20
20
21
+ use crate :: asn1:: Asn1Object ;
21
22
use crate :: error:: ErrorStack ;
22
23
use crate :: nid:: Nid ;
23
- use crate :: x509:: { X509Extension , X509v3Context } ;
24
+ use crate :: x509:: { GeneralName , Stack , X509Extension , X509v3Context } ;
25
+ use foreign_types:: ForeignType ;
24
26
25
27
/// An extension which indicates whether a certificate is a CA certificate.
26
28
pub struct BasicConstraints {
@@ -222,18 +224,7 @@ impl KeyUsage {
222
224
/// for which the certificate public key can be used for.
223
225
pub struct ExtendedKeyUsage {
224
226
critical : bool ,
225
- server_auth : bool ,
226
- client_auth : bool ,
227
- code_signing : bool ,
228
- email_protection : bool ,
229
- time_stamping : bool ,
230
- ms_code_ind : bool ,
231
- ms_code_com : bool ,
232
- ms_ctl_sign : bool ,
233
- ms_sgc : bool ,
234
- ms_efs : bool ,
235
- ns_sgc : bool ,
236
- other : Vec < String > ,
227
+ items : Vec < String > ,
237
228
}
238
229
239
230
impl Default for ExtendedKeyUsage {
@@ -247,18 +238,7 @@ impl ExtendedKeyUsage {
247
238
pub fn new ( ) -> ExtendedKeyUsage {
248
239
ExtendedKeyUsage {
249
240
critical : false ,
250
- server_auth : false ,
251
- client_auth : false ,
252
- code_signing : false ,
253
- email_protection : false ,
254
- time_stamping : false ,
255
- ms_code_ind : false ,
256
- ms_code_com : false ,
257
- ms_ctl_sign : false ,
258
- ms_sgc : false ,
259
- ms_efs : false ,
260
- ns_sgc : false ,
261
- other : vec ! [ ] ,
241
+ items : vec ! [ ] ,
262
242
}
263
243
}
264
244
@@ -270,101 +250,74 @@ impl ExtendedKeyUsage {
270
250
271
251
/// Sets the `serverAuth` flag to `true`.
272
252
pub fn server_auth ( & mut self ) -> & mut ExtendedKeyUsage {
273
- self . server_auth = true ;
274
- self
253
+ self . other ( "serverAuth" )
275
254
}
276
255
277
256
/// Sets the `clientAuth` flag to `true`.
278
257
pub fn client_auth ( & mut self ) -> & mut ExtendedKeyUsage {
279
- self . client_auth = true ;
280
- self
258
+ self . other ( "clientAuth" )
281
259
}
282
260
283
261
/// Sets the `codeSigning` flag to `true`.
284
262
pub fn code_signing ( & mut self ) -> & mut ExtendedKeyUsage {
285
- self . code_signing = true ;
286
- self
263
+ self . other ( "codeSigning" )
287
264
}
288
265
289
266
/// Sets the `emailProtection` flag to `true`.
290
267
pub fn email_protection ( & mut self ) -> & mut ExtendedKeyUsage {
291
- self . email_protection = true ;
292
- self
268
+ self . other ( "emailProtection" )
293
269
}
294
270
295
271
/// Sets the `timeStamping` flag to `true`.
296
272
pub fn time_stamping ( & mut self ) -> & mut ExtendedKeyUsage {
297
- self . time_stamping = true ;
298
- self
273
+ self . other ( "timeStamping" )
299
274
}
300
275
301
276
/// Sets the `msCodeInd` flag to `true`.
302
277
pub fn ms_code_ind ( & mut self ) -> & mut ExtendedKeyUsage {
303
- self . ms_code_ind = true ;
304
- self
278
+ self . other ( "msCodeInd" )
305
279
}
306
280
307
281
/// Sets the `msCodeCom` flag to `true`.
308
282
pub fn ms_code_com ( & mut self ) -> & mut ExtendedKeyUsage {
309
- self . ms_code_com = true ;
310
- self
283
+ self . other ( "msCodeCom" )
311
284
}
312
285
313
286
/// Sets the `msCTLSign` flag to `true`.
314
287
pub fn ms_ctl_sign ( & mut self ) -> & mut ExtendedKeyUsage {
315
- self . ms_ctl_sign = true ;
316
- self
288
+ self . other ( "msCTLSign" )
317
289
}
318
290
319
291
/// Sets the `msSGC` flag to `true`.
320
292
pub fn ms_sgc ( & mut self ) -> & mut ExtendedKeyUsage {
321
- self . ms_sgc = true ;
322
- self
293
+ self . other ( "msSGC" )
323
294
}
324
295
325
296
/// Sets the `msEFS` flag to `true`.
326
297
pub fn ms_efs ( & mut self ) -> & mut ExtendedKeyUsage {
327
- self . ms_efs = true ;
328
- self
298
+ self . other ( "msEFS" )
329
299
}
330
300
331
301
/// Sets the `nsSGC` flag to `true`.
332
302
pub fn ns_sgc ( & mut self ) -> & mut ExtendedKeyUsage {
333
- self . ns_sgc = true ;
334
- self
303
+ self . other ( "nsSGC" )
335
304
}
336
305
337
306
/// Sets a flag not already defined.
338
307
pub fn other ( & mut self , other : & str ) -> & mut ExtendedKeyUsage {
339
- self . other . push ( other. to_owned ( ) ) ;
308
+ self . items . push ( other. to_string ( ) ) ;
340
309
self
341
310
}
342
311
343
312
/// Return the `ExtendedKeyUsage` extension as an `X509Extension`.
344
313
pub fn build ( & self ) -> Result < X509Extension , ErrorStack > {
345
- let mut value = String :: new ( ) ;
346
- let mut first = true ;
347
- append ( & mut value, & mut first, self . critical , "critical" ) ;
348
- append ( & mut value, & mut first, self . server_auth , "serverAuth" ) ;
349
- append ( & mut value, & mut first, self . client_auth , "clientAuth" ) ;
350
- append ( & mut value, & mut first, self . code_signing , "codeSigning" ) ;
351
- append (
352
- & mut value,
353
- & mut first,
354
- self . email_protection ,
355
- "emailProtection" ,
356
- ) ;
357
- append ( & mut value, & mut first, self . time_stamping , "timeStamping" ) ;
358
- append ( & mut value, & mut first, self . ms_code_ind , "msCodeInd" ) ;
359
- append ( & mut value, & mut first, self . ms_code_com , "msCodeCom" ) ;
360
- append ( & mut value, & mut first, self . ms_ctl_sign , "msCTLSign" ) ;
361
- append ( & mut value, & mut first, self . ms_sgc , "msSGC" ) ;
362
- append ( & mut value, & mut first, self . ms_efs , "msEFS" ) ;
363
- append ( & mut value, & mut first, self . ns_sgc , "nsSGC" ) ;
364
- for other in & self . other {
365
- append ( & mut value, & mut first, true , other) ;
314
+ let mut stack = Stack :: new ( ) ?;
315
+ for item in & self . items {
316
+ stack. push ( Asn1Object :: from_str ( item) ?) ?;
317
+ }
318
+ unsafe {
319
+ X509Extension :: new_internal ( Nid :: EXT_KEY_USAGE , self . critical , stack. as_ptr ( ) . cast ( ) )
366
320
}
367
- X509Extension :: new_nid ( None , None , Nid :: EXT_KEY_USAGE , & value)
368
321
}
369
322
}
370
323
@@ -463,11 +416,19 @@ impl AuthorityKeyIdentifier {
463
416
}
464
417
}
465
418
419
+ enum RustGeneralName {
420
+ Dns ( String ) ,
421
+ Email ( String ) ,
422
+ Uri ( String ) ,
423
+ Ip ( String ) ,
424
+ Rid ( String ) ,
425
+ }
426
+
466
427
/// An extension that allows additional identities to be bound to the subject
467
428
/// of the certificate.
468
429
pub struct SubjectAlternativeName {
469
430
critical : bool ,
470
- names : Vec < String > ,
431
+ items : Vec < RustGeneralName > ,
471
432
}
472
433
473
434
impl Default for SubjectAlternativeName {
@@ -481,7 +442,7 @@ impl SubjectAlternativeName {
481
442
pub fn new ( ) -> SubjectAlternativeName {
482
443
SubjectAlternativeName {
483
444
critical : false ,
484
- names : vec ! [ ] ,
445
+ items : vec ! [ ] ,
485
446
}
486
447
}
487
448
@@ -493,55 +454,73 @@ impl SubjectAlternativeName {
493
454
494
455
/// Sets the `email` flag.
495
456
pub fn email ( & mut self , email : & str ) -> & mut SubjectAlternativeName {
496
- self . names . push ( format ! ( " email:{}" , email ) ) ;
457
+ self . items . push ( RustGeneralName :: Email ( email. to_string ( ) ) ) ;
497
458
self
498
459
}
499
460
500
461
/// Sets the `uri` flag.
501
462
pub fn uri ( & mut self , uri : & str ) -> & mut SubjectAlternativeName {
502
- self . names . push ( format ! ( "URI:{}" , uri) ) ;
463
+ self . items . push ( RustGeneralName :: Uri ( uri. to_string ( ) ) ) ;
503
464
self
504
465
}
505
466
506
467
/// Sets the `dns` flag.
507
468
pub fn dns ( & mut self , dns : & str ) -> & mut SubjectAlternativeName {
508
- self . names . push ( format ! ( "DNS:{}" , dns) ) ;
469
+ self . items . push ( RustGeneralName :: Dns ( dns. to_string ( ) ) ) ;
509
470
self
510
471
}
511
472
512
473
/// Sets the `rid` flag.
513
474
pub fn rid ( & mut self , rid : & str ) -> & mut SubjectAlternativeName {
514
- self . names . push ( format ! ( "RID:{}" , rid) ) ;
475
+ self . items . push ( RustGeneralName :: Rid ( rid. to_string ( ) ) ) ;
515
476
self
516
477
}
517
478
518
479
/// Sets the `ip` flag.
519
480
pub fn ip ( & mut self , ip : & str ) -> & mut SubjectAlternativeName {
520
- self . names . push ( format ! ( "IP:{}" , ip ) ) ;
481
+ self . items . push ( RustGeneralName :: Ip ( ip . to_string ( ) ) ) ;
521
482
self
522
483
}
523
484
524
485
/// Sets the `dirName` flag.
525
- pub fn dir_name ( & mut self , dir_name : & str ) -> & mut SubjectAlternativeName {
526
- self . names . push ( format ! ( "dirName:{}" , dir_name) ) ;
527
- self
486
+ ///
487
+ /// Not currently actually supported, always panics.
488
+ #[ deprecated = "dir_name is deprecated and always panics. Please file a bug if you have a use case for this." ]
489
+ pub fn dir_name ( & mut self , _dir_name : & str ) -> & mut SubjectAlternativeName {
490
+ unimplemented ! (
491
+ "This has not yet been adapted for the new internals. File a bug if you need this."
492
+ ) ;
528
493
}
529
494
530
495
/// Sets the `otherName` flag.
531
- pub fn other_name ( & mut self , other_name : & str ) -> & mut SubjectAlternativeName {
532
- self . names . push ( format ! ( "otherName:{}" , other_name) ) ;
533
- self
496
+ ///
497
+ /// Not currently actually supported, always panics.
498
+ #[ deprecated = "other_name is deprecated and always panics. Please file a bug if you have a use case for this." ]
499
+ pub fn other_name ( & mut self , _other_name : & str ) -> & mut SubjectAlternativeName {
500
+ unimplemented ! (
501
+ "This has not yet been adapted for the new internals. File a bug if you need this."
502
+ ) ;
534
503
}
535
504
536
505
/// Return a `SubjectAlternativeName` extension as an `X509Extension`.
537
- pub fn build ( & self , ctx : & X509v3Context < ' _ > ) -> Result < X509Extension , ErrorStack > {
538
- let mut value = String :: new ( ) ;
539
- let mut first = true ;
540
- append ( & mut value, & mut first, self . critical , "critical" ) ;
541
- for name in & self . names {
542
- append ( & mut value, & mut first, true , name) ;
506
+ pub fn build ( & self , _ctx : & X509v3Context < ' _ > ) -> Result < X509Extension , ErrorStack > {
507
+ let mut stack = Stack :: new ( ) ?;
508
+ for item in & self . items {
509
+ let gn = match item {
510
+ RustGeneralName :: Dns ( s) => GeneralName :: new_dns ( s. as_bytes ( ) ) ?,
511
+ RustGeneralName :: Email ( s) => GeneralName :: new_email ( s. as_bytes ( ) ) ?,
512
+ RustGeneralName :: Uri ( s) => GeneralName :: new_uri ( s. as_bytes ( ) ) ?,
513
+ RustGeneralName :: Ip ( s) => {
514
+ GeneralName :: new_ip ( s. parse ( ) . map_err ( |_| ErrorStack :: get ( ) ) ?) ?
515
+ }
516
+ RustGeneralName :: Rid ( s) => GeneralName :: new_rid ( Asn1Object :: from_str ( s) ?) ?,
517
+ } ;
518
+ stack. push ( gn) ?;
519
+ }
520
+
521
+ unsafe {
522
+ X509Extension :: new_internal ( Nid :: SUBJECT_ALT_NAME , self . critical , stack. as_ptr ( ) . cast ( ) )
543
523
}
544
- X509Extension :: new_nid ( None , Some ( ctx) , Nid :: SUBJECT_ALT_NAME , & value)
545
524
}
546
525
}
547
526
0 commit comments