@@ -20,7 +20,8 @@ use std::fmt::Write;
20
20
21
21
use crate :: error:: ErrorStack ;
22
22
use crate :: nid:: Nid ;
23
- use crate :: x509:: { X509Extension , X509v3Context } ;
23
+ use crate :: x509:: { Asn1Object , GeneralName , Stack , X509Extension , X509v3Context } ;
24
+ use foreign_types:: ForeignType ;
24
25
25
26
/// An extension which indicates whether a certificate is a CA certificate.
26
27
pub struct BasicConstraints {
@@ -463,11 +464,19 @@ impl AuthorityKeyIdentifier {
463
464
}
464
465
}
465
466
467
+ enum RustGeneralName {
468
+ Dns ( String ) ,
469
+ Email ( String ) ,
470
+ Uri ( String ) ,
471
+ Ip ( String ) ,
472
+ Rid ( String ) ,
473
+ }
474
+
466
475
/// An extension that allows additional identities to be bound to the subject
467
476
/// of the certificate.
468
477
pub struct SubjectAlternativeName {
469
478
critical : bool ,
470
- names : Vec < String > ,
479
+ items : Vec < RustGeneralName > ,
471
480
}
472
481
473
482
impl Default for SubjectAlternativeName {
@@ -481,7 +490,7 @@ impl SubjectAlternativeName {
481
490
pub fn new ( ) -> SubjectAlternativeName {
482
491
SubjectAlternativeName {
483
492
critical : false ,
484
- names : vec ! [ ] ,
493
+ items : vec ! [ ] ,
485
494
}
486
495
}
487
496
@@ -493,55 +502,73 @@ impl SubjectAlternativeName {
493
502
494
503
/// Sets the `email` flag.
495
504
pub fn email ( & mut self , email : & str ) -> & mut SubjectAlternativeName {
496
- self . names . push ( format ! ( " email:{}" , email ) ) ;
505
+ self . items . push ( RustGeneralName :: Email ( email. to_string ( ) ) ) ;
497
506
self
498
507
}
499
508
500
509
/// Sets the `uri` flag.
501
510
pub fn uri ( & mut self , uri : & str ) -> & mut SubjectAlternativeName {
502
- self . names . push ( format ! ( "URI:{}" , uri) ) ;
511
+ self . items . push ( RustGeneralName :: Uri ( uri. to_string ( ) ) ) ;
503
512
self
504
513
}
505
514
506
515
/// Sets the `dns` flag.
507
516
pub fn dns ( & mut self , dns : & str ) -> & mut SubjectAlternativeName {
508
- self . names . push ( format ! ( "DNS:{}" , dns) ) ;
517
+ self . items . push ( RustGeneralName :: Dns ( dns. to_string ( ) ) ) ;
509
518
self
510
519
}
511
520
512
521
/// Sets the `rid` flag.
513
522
pub fn rid ( & mut self , rid : & str ) -> & mut SubjectAlternativeName {
514
- self . names . push ( format ! ( "RID:{}" , rid) ) ;
523
+ self . items . push ( RustGeneralName :: Rid ( rid. to_string ( ) ) ) ;
515
524
self
516
525
}
517
526
518
527
/// Sets the `ip` flag.
519
528
pub fn ip ( & mut self , ip : & str ) -> & mut SubjectAlternativeName {
520
- self . names . push ( format ! ( "IP:{}" , ip ) ) ;
529
+ self . items . push ( RustGeneralName :: Ip ( ip . to_string ( ) ) ) ;
521
530
self
522
531
}
523
532
524
533
/// 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
534
+ ///
535
+ /// Not currently actually supported, always panics.
536
+ #[ deprecated = "dir_name is deprecated and always panics. Please file a bug if you have a use case for this." ]
537
+ pub fn dir_name ( & mut self , _dir_name : & str ) -> & mut SubjectAlternativeName {
538
+ unimplemented ! (
539
+ "This has not yet been adapted for the new internals. File a bug if you need this."
540
+ ) ;
528
541
}
529
542
530
543
/// 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
544
+ ///
545
+ /// Not currently actually supported, always panics.
546
+ #[ deprecated = "other_name is deprecated and always panics. Please file a bug if you have a use case for this." ]
547
+ pub fn other_name ( & mut self , _other_name : & str ) -> & mut SubjectAlternativeName {
548
+ unimplemented ! (
549
+ "This has not yet been adapted for the new internals. File a bug if you need this."
550
+ ) ;
534
551
}
535
552
536
553
/// 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) ;
554
+ pub fn build ( & self , _ctx : & X509v3Context < ' _ > ) -> Result < X509Extension , ErrorStack > {
555
+ let mut stack = Stack :: new ( ) ?;
556
+ for item in & self . items {
557
+ let gn = match item {
558
+ RustGeneralName :: Dns ( s) => GeneralName :: new_dns ( s. as_bytes ( ) ) ?,
559
+ RustGeneralName :: Email ( s) => GeneralName :: new_email ( s. as_bytes ( ) ) ?,
560
+ RustGeneralName :: Uri ( s) => GeneralName :: new_uri ( s. as_bytes ( ) ) ?,
561
+ RustGeneralName :: Ip ( s) => {
562
+ GeneralName :: new_ip ( s. parse ( ) . map_err ( |_| ErrorStack :: get ( ) ) ?) ?
563
+ }
564
+ RustGeneralName :: Rid ( s) => GeneralName :: new_rid ( Asn1Object :: from_str ( s) ?) ?,
565
+ } ;
566
+ stack. push ( gn) ?;
567
+ }
568
+
569
+ unsafe {
570
+ X509Extension :: new_internal ( Nid :: SUBJECT_ALT_NAME , self . critical , stack. as_ptr ( ) . cast ( ) )
543
571
}
544
- X509Extension :: new_nid ( None , Some ( ctx) , Nid :: SUBJECT_ALT_NAME , & value)
545
572
}
546
573
}
547
574
0 commit comments