Skip to content

Commit ca58360

Browse files
committed
Use ASN.1 string types for subject alternative names
1 parent 551c1ee commit ca58360

File tree

9 files changed

+51
-47
lines changed

9 files changed

+51
-47
lines changed

rcgen/examples/sign-leaf-with-ca.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ fn main() {
1717
}
1818

1919
fn new_ca() -> Certificate {
20-
let mut params = CertificateParams::new(Vec::default());
20+
let mut params =
21+
CertificateParams::new(Vec::default()).expect("empty subject alt name can't produce error");
2122
let (yesterday, tomorrow) = validity_period();
2223
params.is_ca = IsCa::Ca(BasicConstraints::Unconstrained);
2324
params.distinguished_name.push(
@@ -40,7 +41,7 @@ fn new_ca() -> Certificate {
4041

4142
fn new_end_entity() -> Certificate {
4243
let name = "entity.other.host";
43-
let mut params = CertificateParams::new(vec![name.into()]);
44+
let mut params = CertificateParams::new(vec![name.into()]).expect("we know the name is valid");
4445
let (yesterday, tomorrow) = validity_period();
4546
params.distinguished_name.push(DnType::CommonName, name);
4647
params.use_authority_key_identifier_extension = true;

rcgen/examples/simple.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
1515
.distinguished_name
1616
.push(DnType::CommonName, "Master Cert");
1717
params.subject_alt_names = vec![
18-
SanType::DnsName("crabs.crabs".to_string()),
19-
SanType::DnsName("localhost".to_string()),
18+
SanType::DnsName("crabs.crabs".try_into()?),
19+
SanType::DnsName("localhost".try_into()?),
2020
];
2121

2222
let key_pair = KeyPair::generate()?;

rcgen/src/lib.rs

+19-15
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ pub fn generate_simple_self_signed(
119119
) -> Result<CertifiedKey, Error> {
120120
let key_pair = KeyPair::generate()?;
121121
let cert =
122-
Certificate::generate_self_signed(CertificateParams::new(subject_alt_names), &key_pair)?;
122+
Certificate::generate_self_signed(CertificateParams::new(subject_alt_names)?, &key_pair)?;
123123
Ok(CertifiedKey { cert, key_pair })
124124
}
125125

@@ -152,9 +152,9 @@ const ENCODE_CONFIG: pem::EncodeConfig = {
152152
/// The type of subject alt name
153153
pub enum SanType {
154154
/// Also known as E-Mail address
155-
Rfc822Name(String),
156-
DnsName(String),
157-
URI(String),
155+
Rfc822Name(Ia5String),
156+
DnsName(Ia5String),
157+
URI(Ia5String),
158158
IpAddress(IpAddr),
159159
}
160160

@@ -174,10 +174,12 @@ impl SanType {
174174
fn try_from_general(name: &x509_parser::extensions::GeneralName<'_>) -> Result<Self, Error> {
175175
Ok(match name {
176176
x509_parser::extensions::GeneralName::RFC822Name(name) => {
177-
SanType::Rfc822Name((*name).into())
177+
SanType::Rfc822Name((*name).try_into()?)
178178
},
179-
x509_parser::extensions::GeneralName::DNSName(name) => SanType::DnsName((*name).into()),
180-
x509_parser::extensions::GeneralName::URI(name) => SanType::URI((*name).into()),
179+
x509_parser::extensions::GeneralName::DNSName(name) => {
180+
SanType::DnsName((*name).try_into()?)
181+
},
182+
x509_parser::extensions::GeneralName::URI(name) => SanType::URI((*name).try_into()?),
181183
x509_parser::extensions::GeneralName::IPAddress(octets) => {
182184
SanType::IpAddress(ip_addr_from_octets(octets)?)
183185
},
@@ -582,19 +584,21 @@ impl Default for CertificateParams {
582584

583585
impl CertificateParams {
584586
/// Generate certificate parameters with reasonable defaults
585-
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> {
586588
let subject_alt_names = subject_alt_names
587589
.into()
588590
.into_iter()
589-
.map(|s| match s.parse() {
590-
Ok(ip) => SanType::IpAddress(ip),
591-
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+
})
592596
})
593-
.collect::<Vec<_>>();
594-
CertificateParams {
597+
.collect::<Result<Vec<_>, _>>()?;
598+
Ok(CertificateParams {
595599
subject_alt_names,
596600
..Default::default()
597-
}
601+
})
598602
}
599603

600604
/// Parses an existing ca certificate from the ASCII PEM format.
@@ -854,7 +858,7 @@ impl CertificateParams {
854858
|writer| match san {
855859
SanType::Rfc822Name(name)
856860
| SanType::DnsName(name)
857-
| SanType::URI(name) => writer.write_ia5_string(name),
861+
| SanType::URI(name) => writer.write_ia5_string(name.as_str()),
858862
SanType::IpAddress(IpAddr::V4(addr)) => {
859863
writer.write_bytes(&addr.octets())
860864
},

rcgen/tests/botan.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ fn test_botan_separate_ca() {
122122
params.is_ca = IsCa::Ca(BasicConstraints::Unconstrained);
123123
let ca_cert = Certificate::generate_self_signed(params, &ca_key).unwrap();
124124

125-
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]);
125+
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]).unwrap();
126126
params
127127
.distinguished_name
128128
.push(DnType::OrganizationName, "Crab widgits SE");
@@ -150,7 +150,7 @@ fn test_botan_imported_ca() {
150150
let imported_ca_cert =
151151
Certificate::generate_self_signed(imported_ca_cert_params, &ca_key).unwrap();
152152

153-
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]);
153+
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]).unwrap();
154154
params
155155
.distinguished_name
156156
.push(DnType::OrganizationName, "Crab widgits SE");
@@ -182,7 +182,7 @@ fn test_botan_imported_ca_with_printable_string() {
182182
let imported_ca_cert =
183183
Certificate::generate_self_signed(imported_ca_cert_params, &imported_ca_key).unwrap();
184184

185-
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]);
185+
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]).unwrap();
186186
params
187187
.distinguished_name
188188
.push(DnType::OrganizationName, "Crab widgits SE");

rcgen/tests/openssl.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ fn test_openssl_separate_ca() {
295295
let ca_cert = Certificate::generate_self_signed(params, &ca_key).unwrap();
296296
let ca_cert_pem = ca_cert.pem();
297297

298-
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]);
298+
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]).unwrap();
299299
params
300300
.distinguished_name
301301
.push(DnType::OrganizationName, "Crab widgits SE");
@@ -319,7 +319,7 @@ fn test_openssl_separate_ca_with_printable_string() {
319319
params.is_ca = IsCa::Ca(BasicConstraints::Unconstrained);
320320
let ca_cert = Certificate::generate_self_signed(params, &ca_key).unwrap();
321321

322-
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]);
322+
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]).unwrap();
323323
params
324324
.distinguished_name
325325
.push(DnType::OrganizationName, "Crab widgits SE");
@@ -340,7 +340,7 @@ fn test_openssl_separate_ca_with_other_signing_alg() {
340340
let ca_key = KeyPair::generate_for(&rcgen::PKCS_ECDSA_P256_SHA256).unwrap();
341341
let ca_cert = Certificate::generate_self_signed(params, &ca_key).unwrap();
342342

343-
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]);
343+
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]).unwrap();
344344
params
345345
.distinguished_name
346346
.push(DnType::OrganizationName, "Crab widgits SE");
@@ -370,7 +370,7 @@ fn test_openssl_separate_ca_name_constraints() {
370370
});
371371
let ca_cert = Certificate::generate_self_signed(params, &ca_key).unwrap();
372372

373-
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]);
373+
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]).unwrap();
374374
params
375375
.distinguished_name
376376
.push(DnType::OrganizationName, "Crab widgits SE");

rcgen/tests/util.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ YPTHy8SWRA2sMII3ArhHJ8A=
6868

6969
pub fn default_params() -> (CertificateParams, KeyPair) {
7070
let mut params =
71-
CertificateParams::new(vec!["crabs.crabs".to_string(), "localhost".to_string()]);
71+
CertificateParams::new(vec!["crabs.crabs".to_string(), "localhost".to_string()]).unwrap();
7272
params
7373
.distinguished_name
7474
.push(DnType::OrganizationName, "Crab widgits SE");

rcgen/tests/webpki.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ fn test_webpki_separate_ca() {
267267
params.is_ca = IsCa::Ca(BasicConstraints::Unconstrained);
268268
let ca_cert = Certificate::generate_self_signed(params, &ca_key).unwrap();
269269

270-
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]);
270+
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]).unwrap();
271271
params
272272
.distinguished_name
273273
.push(DnType::OrganizationName, "Crab widgits SE");
@@ -295,7 +295,7 @@ fn test_webpki_separate_ca_with_other_signing_alg() {
295295
let ca_key = KeyPair::generate_for(&rcgen::PKCS_ECDSA_P256_SHA256).unwrap();
296296
let ca_cert = Certificate::generate_self_signed(params, &ca_key).unwrap();
297297

298-
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]);
298+
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]).unwrap();
299299
params
300300
.distinguished_name
301301
.push(DnType::OrganizationName, "Crab widgits SE");
@@ -422,7 +422,7 @@ fn test_webpki_imported_ca() {
422422
let imported_ca_cert =
423423
Certificate::generate_self_signed(imported_ca_cert_params, &ca_key).unwrap();
424424

425-
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]);
425+
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]).unwrap();
426426
params
427427
.distinguished_name
428428
.push(DnType::OrganizationName, "Crab widgits SE");
@@ -460,7 +460,7 @@ fn test_webpki_imported_ca_with_printable_string() {
460460
let imported_ca_cert =
461461
Certificate::generate_self_signed(imported_ca_cert_params, &ca_key).unwrap();
462462

463-
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]);
463+
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]).unwrap();
464464
params
465465
.distinguished_name
466466
.push(DnType::OrganizationName, "Crab widgits SE");
@@ -484,7 +484,7 @@ fn test_webpki_imported_ca_with_printable_string() {
484484
#[cfg(feature = "x509-parser")]
485485
#[test]
486486
fn test_certificate_from_csr() {
487-
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]);
487+
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]).unwrap();
488488
params
489489
.distinguished_name
490490
.push(DnType::OrganizationName, "Crab widgits SE");

rustls-cert-gen/src/cert.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -403,13 +403,13 @@ mod tests {
403403
.build()
404404
.unwrap();
405405
let name = "unexpected.oomyoo.xyz";
406-
let names = vec![SanType::DnsName(name.into())];
406+
let names = vec![SanType::DnsName(name.try_into().unwrap())];
407407
let params = CertificateParams::default();
408408
let cert = EndEntityBuilder::new(params, KeyPairAlgorithm::default())
409409
.subject_alternative_names(names);
410410
assert_eq!(
411411
cert.params.subject_alt_names,
412-
vec![rcgen::SanType::DnsName(name.into())]
412+
vec![rcgen::SanType::DnsName(name.try_into().unwrap())]
413413
);
414414
}
415415
#[test]

rustls-cert-gen/src/main.rs

+12-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use bpaf::Bpaf;
2-
use rcgen::SanType;
3-
use std::{net::IpAddr, path::PathBuf};
2+
use rcgen::{Error, SanType};
3+
use std::{net::IpAddr, path::PathBuf, str::FromStr};
44

55
mod cert;
66
use cert::{key_pair_algorithm, CertificateBuilder, KeyPairAlgorithm};
@@ -67,7 +67,7 @@ struct Options {
6767
#[bpaf(long, fallback("root-ca".into()), display_fallback)]
6868
pub ca_file_name: String,
6969
/// Subject Alt Name (apply multiple times for multiple names/Ips)
70-
#[bpaf(many, long, argument::<String>("san"), map(parse_sans))]
70+
#[bpaf(many, long, argument::<String>("san"), parse(parse_sans))]
7171
pub san: Vec<SanType>,
7272
/// Common Name (Currently only used for end-entity)
7373
#[bpaf(long, fallback("Tls End-Entity Certificate".into()), display_fallback)]
@@ -82,15 +82,14 @@ struct Options {
8282

8383
/// Parse cli input into SanType. Try first `IpAddr`, if that fails
8484
/// declare it to be a DnsName.
85-
fn parse_sans(hosts: Vec<String>) -> Vec<SanType> {
85+
fn parse_sans(hosts: Vec<String>) -> Result<Vec<SanType>, Error> {
8686
hosts
8787
.into_iter()
88-
.map(|host| {
89-
if let Ok(ip) = host.parse::<IpAddr>() {
90-
SanType::IpAddress(ip)
91-
} else {
92-
SanType::DnsName(host)
93-
}
88+
.map(|s| {
89+
Ok(match IpAddr::from_str(&s) {
90+
Ok(ip) => SanType::IpAddress(ip),
91+
Err(_) => SanType::DnsName(s.try_into()?),
92+
})
9493
})
9594
.collect()
9695
}
@@ -110,9 +109,9 @@ mod tests {
110109
.into_iter()
111110
.map(Into::into)
112111
.collect();
113-
let sans: Vec<SanType> = parse_sans(hosts);
114-
assert_eq!(SanType::DnsName("my.host.com".into()), sans[0]);
115-
assert_eq!(SanType::DnsName("localhost".into()), sans[1]);
112+
let sans: Vec<SanType> = parse_sans(hosts).unwrap();
113+
assert_eq!(SanType::DnsName("my.host.com".try_into().unwrap()), sans[0]);
114+
assert_eq!(SanType::DnsName("localhost".try_into().unwrap()), sans[1]);
116115
assert_eq!(
117116
SanType::IpAddress("185.199.108.153".parse().unwrap()),
118117
sans[2]

0 commit comments

Comments
 (0)