@@ -165,38 +165,8 @@ impl CertificateParams {
165
165
. derive ( key. subject_public_key_info ( ) )
166
166
}
167
167
168
- /// Parses an existing ca certificate from the ASCII PEM format.
169
- ///
170
- /// See [`from_ca_cert_der`](Self::from_ca_cert_der) for more details.
171
- #[ cfg( all( feature = "pem" , feature = "x509-parser" ) ) ]
172
- pub fn from_ca_cert_pem ( pem_str : & str ) -> Result < Self , Error > {
173
- let certificate = pem:: parse ( pem_str) . map_err ( |_| Error :: CouldNotParseCertificate ) ?;
174
- Self :: from_ca_cert_der ( & certificate. contents ( ) . into ( ) )
175
- }
176
-
177
- /// Parses an existing ca certificate from the DER format.
178
- ///
179
- /// This function is only of use if you have an existing CA certificate
180
- /// you would like to use to sign a certificate generated by `rcgen`.
181
- /// By providing the constructed [`CertificateParams`] and the [`SigningKey`]
182
- /// associated with your existing `ca_cert` you can use [`CertificateParams::signed_by()`]
183
- /// or [`crate::CertificateSigningRequestParams::signed_by()`] to issue new certificates
184
- /// using the CA cert.
185
- ///
186
- /// In general this function only extracts the information needed for signing.
187
- /// Other attributes of the [`Certificate`] may be left as defaults.
188
- ///
189
- /// This function assumes the provided certificate is a CA. It will not check
190
- /// for the presence of the `BasicConstraints` extension, or perform any other
191
- /// validation.
192
- ///
193
- /// [`rustls_pemfile::certs()`] is often used to obtain a [`CertificateDer`] from PEM input.
194
- /// If you already have a byte slice containing DER, it can trivially be converted into
195
- /// [`CertificateDer`] using the [`Into`] trait.
196
- ///
197
- /// [`rustls_pemfile::certs()`]: https://docs.rs/rustls-pemfile/latest/rustls_pemfile/fn.certs.html
198
- #[ cfg( feature = "x509-parser" ) ]
199
- pub fn from_ca_cert_der ( ca_cert : & CertificateDer < ' _ > ) -> Result < Self , Error > {
168
+ #[ cfg( all( test, feature = "x509-parser" ) ) ]
169
+ pub ( crate ) fn from_ca_cert_der ( ca_cert : & CertificateDer < ' _ > ) -> Result < Self , Error > {
200
170
let ( _remainder, x509) = x509_parser:: parse_x509_certificate ( ca_cert)
201
171
. map_err ( |_| Error :: CouldNotParseCertificate ) ?;
202
172
@@ -801,7 +771,7 @@ pub enum ExtendedKeyUsagePurpose {
801
771
}
802
772
803
773
impl ExtendedKeyUsagePurpose {
804
- #[ cfg( feature = "x509-parser" ) ]
774
+ #[ cfg( all ( test , feature = "x509-parser" ) ) ]
805
775
fn from_x509 ( x509 : & x509_parser:: certificate:: X509Certificate < ' _ > ) -> Result < Vec < Self > , Error > {
806
776
let extended_key_usage = x509
807
777
. extended_key_usage ( )
@@ -866,7 +836,7 @@ pub struct NameConstraints {
866
836
}
867
837
868
838
impl NameConstraints {
869
- #[ cfg( feature = "x509-parser" ) ]
839
+ #[ cfg( all ( test , feature = "x509-parser" ) ) ]
870
840
fn from_x509 (
871
841
x509 : & x509_parser:: certificate:: X509Certificate < ' _ > ,
872
842
) -> Result < Option < Self > , Error > {
@@ -919,7 +889,7 @@ pub enum GeneralSubtree {
919
889
}
920
890
921
891
impl GeneralSubtree {
922
- #[ cfg( feature = "x509-parser" ) ]
892
+ #[ cfg( all ( test , feature = "x509-parser" ) ) ]
923
893
fn from_x509 (
924
894
subtrees : & [ x509_parser:: extensions:: GeneralSubtree < ' _ > ] ,
925
895
) -> Result < Vec < Self > , Error > {
@@ -1091,7 +1061,7 @@ pub enum IsCa {
1091
1061
}
1092
1062
1093
1063
impl IsCa {
1094
- #[ cfg( feature = "x509-parser" ) ]
1064
+ #[ cfg( all ( test , feature = "x509-parser" ) ) ]
1095
1065
fn from_x509 ( x509 : & x509_parser:: certificate:: X509Certificate < ' _ > ) -> Result < Self , Error > {
1096
1066
use x509_parser:: extensions:: BasicConstraints as B ;
1097
1067
@@ -1133,11 +1103,16 @@ pub enum BasicConstraints {
1133
1103
1134
1104
#[ cfg( test) ]
1135
1105
mod tests {
1106
+ #[ cfg( feature = "x509-parser" ) ]
1107
+ use std:: net:: Ipv4Addr ;
1108
+
1136
1109
#[ cfg( feature = "x509-parser" ) ]
1137
1110
use pki_types:: pem:: PemObject ;
1138
1111
1139
1112
#[ cfg( feature = "pem" ) ]
1140
1113
use super :: * ;
1114
+ #[ cfg( feature = "x509-parser" ) ]
1115
+ use crate :: DnValue ;
1141
1116
#[ cfg( feature = "crypto" ) ]
1142
1117
use crate :: KeyPair ;
1143
1118
@@ -1293,7 +1268,84 @@ mod tests {
1293
1268
}
1294
1269
}
1295
1270
1296
- #[ cfg( all( feature = "x509-parser" ) ) ]
1271
+ #[ cfg( feature = "x509-parser" ) ]
1272
+ #[ test]
1273
+ fn parse_other_name_alt_name ( ) {
1274
+ // Create and serialize a certificate with an alternative name containing an "OtherName".
1275
+ let mut params = CertificateParams :: default ( ) ;
1276
+ let other_name = SanType :: OtherName ( ( vec ! [ 1 , 2 , 3 , 4 ] , "Foo" . into ( ) ) ) ;
1277
+ params. subject_alt_names . push ( other_name. clone ( ) ) ;
1278
+ let key_pair = KeyPair :: generate ( ) . unwrap ( ) ;
1279
+ let cert = params. self_signed ( & key_pair) . unwrap ( ) ;
1280
+
1281
+ // We should be able to parse the certificate with x509-parser.
1282
+ assert ! ( x509_parser:: parse_x509_certificate( cert. der( ) ) . is_ok( ) ) ;
1283
+
1284
+ // We should be able to reconstitute params from the DER using x509-parser.
1285
+ let params_from_cert = CertificateParams :: from_ca_cert_der ( cert. der ( ) ) . unwrap ( ) ;
1286
+
1287
+ // We should find the expected distinguished name in the reconstituted params.
1288
+ let expected_alt_names = & [ & other_name] ;
1289
+ let subject_alt_names = params_from_cert
1290
+ . subject_alt_names
1291
+ . iter ( )
1292
+ . collect :: < Vec < _ > > ( ) ;
1293
+ assert_eq ! ( subject_alt_names, expected_alt_names) ;
1294
+ }
1295
+
1296
+ #[ cfg( feature = "x509-parser" ) ]
1297
+ #[ test]
1298
+ fn parse_ia5string_subject ( ) {
1299
+ // Create and serialize a certificate with a subject containing an IA5String email address.
1300
+ let email_address_dn_type = DnType :: CustomDnType ( vec ! [ 1 , 2 , 840 , 113549 , 1 , 9 , 1 ] ) ; // id-emailAddress
1301
+ let email_address_dn_value =
DnValue :: Ia5String ( "[email protected] " . try_into ( ) . unwrap ( ) ) ;
1302
+ let mut params = CertificateParams :: new ( vec ! [ "crabs" . to_owned( ) ] ) . unwrap ( ) ;
1303
+ params. distinguished_name = DistinguishedName :: new ( ) ;
1304
+ params. distinguished_name . push (
1305
+ email_address_dn_type. clone ( ) ,
1306
+ email_address_dn_value. clone ( ) ,
1307
+ ) ;
1308
+ let key_pair = KeyPair :: generate ( ) . unwrap ( ) ;
1309
+ let cert = params. self_signed ( & key_pair) . unwrap ( ) ;
1310
+
1311
+ // We should be able to parse the certificate with x509-parser.
1312
+ assert ! ( x509_parser:: parse_x509_certificate( cert. der( ) ) . is_ok( ) ) ;
1313
+
1314
+ // We should be able to reconstitute params from the DER using x509-parser.
1315
+ let params_from_cert = CertificateParams :: from_ca_cert_der ( cert. der ( ) ) . unwrap ( ) ;
1316
+
1317
+ // We should find the expected distinguished name in the reconstituted params.
1318
+ let expected_names = & [ ( & email_address_dn_type, & email_address_dn_value) ] ;
1319
+ let names = params_from_cert
1320
+ . distinguished_name
1321
+ . iter ( )
1322
+ . collect :: < Vec < ( _ , _ ) > > ( ) ;
1323
+ assert_eq ! ( names, expected_names) ;
1324
+ }
1325
+
1326
+ #[ cfg( feature = "x509-parser" ) ]
1327
+ #[ test]
1328
+ fn converts_from_ip ( ) {
1329
+ let ip = Ipv4Addr :: new ( 2 , 4 , 6 , 8 ) ;
1330
+ let ip_san = SanType :: IpAddress ( IpAddr :: V4 ( ip) ) ;
1331
+
1332
+ let mut params = CertificateParams :: new ( vec ! [ "crabs" . to_owned( ) ] ) . unwrap ( ) ;
1333
+ let ca_key = KeyPair :: generate ( ) . unwrap ( ) ;
1334
+
1335
+ // Add the SAN we want to test the parsing for
1336
+ params. subject_alt_names . push ( ip_san. clone ( ) ) ;
1337
+
1338
+ // Because we're using a function for CA certificates
1339
+ params. is_ca = IsCa :: Ca ( BasicConstraints :: Unconstrained ) ;
1340
+
1341
+ // Serialize our cert that has our chosen san, so we can testing parsing/deserializing it.
1342
+ let cert = params. self_signed ( & ca_key) . unwrap ( ) ;
1343
+
1344
+ let actual = CertificateParams :: from_ca_cert_der ( cert. der ( ) ) . unwrap ( ) ;
1345
+ assert ! ( actual. subject_alt_names. contains( & ip_san) ) ;
1346
+ }
1347
+
1348
+ #[ cfg( feature = "x509-parser" ) ]
1297
1349
mod test_key_identifier_from_ca {
1298
1350
use super :: * ;
1299
1351
0 commit comments