@@ -56,12 +56,13 @@ pub use crate::crl::{
56
56
CrlIssuingDistributionPoint , CrlScope , RevocationReason , RevokedCertParams ,
57
57
} ;
58
58
pub use crate :: csr:: { CertificateSigningRequestParams , PublicKey } ;
59
- pub use crate :: error:: Error ;
59
+ pub use crate :: error:: { Error , InvalidAsn1String } ;
60
60
use crate :: key_pair:: PublicKeyData ;
61
61
pub use crate :: key_pair:: { KeyPair , RemoteKeyPair } ;
62
62
use crate :: oid:: * ;
63
63
pub use crate :: sign_algo:: algo:: * ;
64
64
pub use crate :: sign_algo:: SignatureAlgorithm ;
65
+ pub use crate :: string_types:: * ;
65
66
66
67
/// Type-alias for the old name of [`Error`].
67
68
#[ deprecated(
@@ -118,7 +119,7 @@ pub fn generate_simple_self_signed(
118
119
) -> Result < CertifiedKey , Error > {
119
120
let key_pair = KeyPair :: generate ( ) ?;
120
121
let cert =
121
- Certificate :: generate_self_signed ( CertificateParams :: new ( subject_alt_names) , & key_pair) ?;
122
+ Certificate :: generate_self_signed ( CertificateParams :: new ( subject_alt_names) ? , & key_pair) ?;
122
123
Ok ( CertifiedKey { cert, key_pair } )
123
124
}
124
125
@@ -131,6 +132,7 @@ mod key_pair;
131
132
mod oid;
132
133
mod ring_like;
133
134
mod sign_algo;
135
+ mod string_types;
134
136
135
137
// Example certs usable as reference:
136
138
// Uses ECDSA: https://crt.sh/?asn1=607203242
@@ -150,9 +152,9 @@ const ENCODE_CONFIG: pem::EncodeConfig = {
150
152
/// The type of subject alt name
151
153
pub enum SanType {
152
154
/// Also known as E-Mail address
153
- Rfc822Name ( String ) ,
154
- DnsName ( String ) ,
155
- URI ( String ) ,
155
+ Rfc822Name ( Ia5String ) ,
156
+ DnsName ( Ia5String ) ,
157
+ URI ( Ia5String ) ,
156
158
IpAddress ( IpAddr ) ,
157
159
}
158
160
@@ -172,10 +174,12 @@ impl SanType {
172
174
fn try_from_general ( name : & x509_parser:: extensions:: GeneralName < ' _ > ) -> Result < Self , Error > {
173
175
Ok ( match name {
174
176
x509_parser:: extensions:: GeneralName :: RFC822Name ( name) => {
175
- SanType :: Rfc822Name ( ( * name) . into ( ) )
177
+ SanType :: Rfc822Name ( ( * name) . try_into ( ) ?)
178
+ } ,
179
+ x509_parser:: extensions:: GeneralName :: DNSName ( name) => {
180
+ SanType :: DnsName ( ( * name) . try_into ( ) ?)
176
181
} ,
177
- x509_parser:: extensions:: GeneralName :: DNSName ( name) => SanType :: DnsName ( ( * name) . into ( ) ) ,
178
- x509_parser:: extensions:: GeneralName :: URI ( name) => SanType :: URI ( ( * name) . into ( ) ) ,
182
+ x509_parser:: extensions:: GeneralName :: URI ( name) => SanType :: URI ( ( * name) . try_into ( ) ?) ,
179
183
x509_parser:: extensions:: GeneralName :: IPAddress ( octets) => {
180
184
SanType :: IpAddress ( ip_addr_from_octets ( octets) ?)
181
185
} ,
@@ -376,15 +380,15 @@ impl DnType {
376
380
#[ non_exhaustive]
377
381
pub enum DnValue {
378
382
/// A string encoded using UCS-2
379
- BmpString ( Vec < u8 > ) ,
383
+ BmpString ( BmpString ) ,
380
384
/// An ASCII string.
381
- Ia5String ( String ) ,
385
+ Ia5String ( Ia5String ) ,
382
386
/// An ASCII string containing only A-Z, a-z, 0-9, '()+,-./:=? and `<SPACE>`
383
- PrintableString ( String ) ,
387
+ PrintableString ( PrintableString ) ,
384
388
/// A string of characters from the T.61 character set
385
- TeletexString ( Vec < u8 > ) ,
389
+ TeletexString ( TeletexString ) ,
386
390
/// A string encoded using UTF-32
387
- UniversalString ( Vec < u8 > ) ,
391
+ UniversalString ( UniversalString ) ,
388
392
/// A string encoded using UTF-8
389
393
Utf8String ( String ) ,
390
394
}
@@ -444,9 +448,9 @@ impl DistinguishedName {
444
448
/// # use rcgen::{DistinguishedName, DnType, DnValue};
445
449
/// let mut dn = DistinguishedName::new();
446
450
/// dn.push(DnType::OrganizationName, "Crab widgits SE");
447
- /// dn.push(DnType::CommonName, DnValue::PrintableString("Master Cert".to_string ()));
451
+ /// dn.push(DnType::CommonName, DnValue::PrintableString("Master Cert".try_into().unwrap ()));
448
452
/// assert_eq!(dn.get(&DnType::OrganizationName), Some(&DnValue::Utf8String("Crab widgits SE".to_string())));
449
- /// assert_eq!(dn.get(&DnType::CommonName), Some(&DnValue::PrintableString("Master Cert".to_string ())));
453
+ /// assert_eq!(dn.get(&DnType::CommonName), Some(&DnValue::PrintableString("Master Cert".try_into().unwrap ())));
450
454
/// ```
451
455
pub fn push ( & mut self , ty : DnType , s : impl Into < DnValue > ) {
452
456
if !self . entries . contains_key ( & ty) {
@@ -490,11 +494,13 @@ impl DistinguishedName {
490
494
let try_str =
491
495
|data| std:: str:: from_utf8 ( data) . map_err ( |_| Error :: CouldNotParseCertificate ) ;
492
496
let dn_value = match attr. attr_value ( ) . header . tag ( ) {
493
- Tag :: BmpString => DnValue :: BmpString ( data. into ( ) ) ,
494
- Tag :: Ia5String => DnValue :: Ia5String ( try_str ( data) ?. to_owned ( ) ) ,
495
- Tag :: PrintableString => DnValue :: PrintableString ( try_str ( data) ?. to_owned ( ) ) ,
496
- Tag :: T61String => DnValue :: TeletexString ( data. into ( ) ) ,
497
- Tag :: UniversalString => DnValue :: UniversalString ( data. into ( ) ) ,
497
+ Tag :: BmpString => DnValue :: BmpString ( BmpString :: from_utf16be ( data. to_vec ( ) ) ?) ,
498
+ Tag :: Ia5String => DnValue :: Ia5String ( try_str ( data) ?. try_into ( ) ?) ,
499
+ Tag :: PrintableString => DnValue :: PrintableString ( try_str ( data) ?. try_into ( ) ?) ,
500
+ Tag :: T61String => DnValue :: TeletexString ( try_str ( data) ?. try_into ( ) ?) ,
501
+ Tag :: UniversalString => {
502
+ DnValue :: UniversalString ( UniversalString :: from_utf32be ( data. to_vec ( ) ) ?)
503
+ } ,
498
504
Tag :: Utf8String => DnValue :: Utf8String ( try_str ( data) ?. to_owned ( ) ) ,
499
505
_ => return Err ( Error :: CouldNotParseCertificate ) ,
500
506
} ;
@@ -578,19 +584,21 @@ impl Default for CertificateParams {
578
584
579
585
impl CertificateParams {
580
586
/// Generate certificate parameters with reasonable defaults
581
- pub fn new ( subject_alt_names : impl Into < Vec < String > > ) -> Self {
587
+ pub fn new ( subject_alt_names : impl Into < Vec < String > > ) -> Result < Self , Error > {
582
588
let subject_alt_names = subject_alt_names
583
589
. into ( )
584
590
. into_iter ( )
585
- . map ( |s| match s. parse ( ) {
586
- Ok ( ip) => SanType :: IpAddress ( ip) ,
587
- Err ( _) => SanType :: DnsName ( s) ,
591
+ . map ( |s| {
592
+ Ok ( match IpAddr :: from_str ( & s) {
593
+ Ok ( ip) => SanType :: IpAddress ( ip) ,
594
+ Err ( _) => SanType :: DnsName ( s. try_into ( ) ?) ,
595
+ } )
588
596
} )
589
- . collect :: < Vec < _ > > ( ) ;
590
- CertificateParams {
597
+ . collect :: < Result < Vec < _ > , _ > > ( ) ? ;
598
+ Ok ( CertificateParams {
591
599
subject_alt_names,
592
600
..Default :: default ( )
593
- }
601
+ } )
594
602
}
595
603
596
604
/// Parses an existing ca certificate from the ASCII PEM format.
@@ -850,7 +858,7 @@ impl CertificateParams {
850
858
|writer| match san {
851
859
SanType :: Rfc822Name ( name)
852
860
| SanType :: DnsName ( name)
853
- | SanType :: URI ( name) => writer. write_ia5_string ( name) ,
861
+ | SanType :: URI ( name) => writer. write_ia5_string ( name. as_str ( ) ) ,
854
862
SanType :: IpAddress ( IpAddr :: V4 ( addr) ) => {
855
863
writer. write_bytes ( & addr. octets ( ) )
856
864
} ,
@@ -1450,18 +1458,24 @@ fn write_distinguished_name(writer: DERWriter, dn: &DistinguishedName) {
1450
1458
match content {
1451
1459
DnValue :: BmpString ( s) => writer
1452
1460
. next ( )
1453
- . write_tagged_implicit ( TAG_BMPSTRING , |writer| writer. write_bytes ( s) ) ,
1454
- DnValue :: Ia5String ( s) => writer. next ( ) . write_ia5_string ( s) ,
1455
- DnValue :: PrintableString ( s) => writer. next ( ) . write_printable_string ( s) ,
1461
+ . write_tagged_implicit ( TAG_BMPSTRING , |writer| {
1462
+ writer. write_bytes ( s. as_bytes ( ) )
1463
+ } ) ,
1464
+
1465
+ DnValue :: Ia5String ( s) => writer. next ( ) . write_ia5_string ( s. as_str ( ) ) ,
1466
+
1467
+ DnValue :: PrintableString ( s) => {
1468
+ writer. next ( ) . write_printable_string ( s. as_str ( ) )
1469
+ } ,
1456
1470
DnValue :: TeletexString ( s) => writer
1457
1471
. next ( )
1458
1472
. write_tagged_implicit ( TAG_TELETEXSTRING , |writer| {
1459
- writer. write_bytes ( s)
1473
+ writer. write_bytes ( s. as_bytes ( ) )
1460
1474
} ) ,
1461
1475
DnValue :: UniversalString ( s) => writer
1462
1476
. next ( )
1463
1477
. write_tagged_implicit ( TAG_UNIVERSALSTRING , |writer| {
1464
- writer. write_bytes ( s)
1478
+ writer. write_bytes ( s. as_bytes ( ) )
1465
1479
} ) ,
1466
1480
DnValue :: Utf8String ( s) => writer. next ( ) . write_utf8_string ( s) ,
1467
1481
}
0 commit comments