Skip to content

Commit 89e13be

Browse files
committed
Create Certificates via methods on CertificateParams
1 parent bfa6663 commit 89e13be

File tree

12 files changed

+141
-144
lines changed

12 files changed

+141
-144
lines changed

rcgen/examples/rsa-irc-openssl.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
fn main() -> Result<(), Box<dyn std::error::Error>> {
2-
use rcgen::{date_time_ymd, Certificate, CertificateParams, DistinguishedName};
2+
use rcgen::{date_time_ymd, CertificateParams, DistinguishedName};
33
use std::fmt::Write;
44
use std::fs;
55

@@ -12,7 +12,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
1212
let key_pair_pem = String::from_utf8(pkey.private_key_to_pem_pkcs8()?)?;
1313
let key_pair = rcgen::KeyPair::from_pem(&key_pair_pem)?;
1414

15-
let cert = Certificate::generate_self_signed(params, &key_pair)?;
15+
let cert = params.self_signed(&key_pair)?;
1616
let pem_serialized = cert.pem();
1717
let pem = pem::parse(&pem_serialized)?;
1818
let der_serialized = pem.contents();

rcgen/examples/rsa-irc.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
33
use rsa::pkcs8::EncodePrivateKey;
44
use rsa::RsaPrivateKey;
55

6-
use rcgen::{date_time_ymd, Certificate, CertificateParams, DistinguishedName};
6+
use rcgen::{date_time_ymd, CertificateParams, DistinguishedName};
77
use std::fmt::Write;
88
use std::fs;
99

@@ -18,7 +18,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
1818
let private_key_der = private_key.to_pkcs8_der()?;
1919
let key_pair = rcgen::KeyPair::try_from(private_key_der.as_bytes()).unwrap();
2020

21-
let cert = Certificate::generate_self_signed(params, &key_pair)?;
21+
let cert = params.self_signed(&key_pair)?;
2222
let pem_serialized = cert.pem();
2323
let pem = pem::parse(&pem_serialized)?;
2424
let der_serialized = pem.contents();

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ fn new_ca() -> Certificate {
3636
params.not_after = tomorrow;
3737

3838
let key_pair = KeyPair::generate().unwrap();
39-
Certificate::generate_self_signed(params, &key_pair).unwrap()
39+
params.self_signed(&key_pair).unwrap()
4040
}
4141

4242
fn new_end_entity() -> Certificate {
@@ -53,7 +53,7 @@ fn new_end_entity() -> Certificate {
5353
params.not_after = tomorrow;
5454

5555
let key_pair = KeyPair::generate().unwrap();
56-
Certificate::generate_self_signed(params, &key_pair).unwrap()
56+
params.self_signed(&key_pair).unwrap()
5757
}
5858

5959
fn validity_period() -> (OffsetDateTime, OffsetDateTime) {

rcgen/examples/simple.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
use rcgen::{
2-
date_time_ymd, Certificate, CertificateParams, DistinguishedName, DnType, KeyPair, SanType,
3-
};
1+
use rcgen::{date_time_ymd, CertificateParams, DistinguishedName, DnType, KeyPair, SanType};
42
use std::fs;
53

64
fn main() -> Result<(), Box<dyn std::error::Error>> {
@@ -20,7 +18,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
2018
];
2119

2220
let key_pair = KeyPair::generate()?;
23-
let cert = Certificate::generate_self_signed(params, &key_pair)?;
21+
let cert = params.self_signed(&key_pair)?;
2422

2523
let pem_serialized = cert.pem();
2624
let pem = pem::parse(&pem_serialized)?;

rcgen/src/certificate.rs

+48-52
Original file line numberDiff line numberDiff line change
@@ -27,52 +27,6 @@ pub struct Certificate {
2727
}
2828

2929
impl Certificate {
30-
/// Generates a new self-signed certificate from the given parameters.
31-
///
32-
/// The returned [`Certificate`] may be serialized using [`Certificate::der`] and
33-
/// [`Certificate::pem`].
34-
pub fn generate_self_signed(
35-
params: CertificateParams,
36-
key_pair: &KeyPair,
37-
) -> Result<Certificate, Error> {
38-
let subject_public_key_info = key_pair.public_key_der();
39-
let der =
40-
params.serialize_der_with_signer(key_pair, key_pair, &params.distinguished_name)?;
41-
Ok(Certificate {
42-
params,
43-
subject_public_key_info,
44-
der,
45-
})
46-
}
47-
/// Generate a new certificate from the given parameters, signed by the provided issuer.
48-
///
49-
/// The returned certificate will have its issuer field set to the subject of the
50-
/// provided `issuer`, and the authority key identifier extension will be populated using
51-
/// the subject public key of `issuer`. It will be signed by `issuer_key`.
52-
///
53-
/// Note that no validation of the `issuer` certificate is performed. Rcgen will not require
54-
/// the certificate to be a CA certificate, or have key usage extensions that allow signing.
55-
///
56-
/// The returned [`Certificate`] may be serialized using [`Certificate::der`] and
57-
/// [`Certificate::pem`].
58-
pub fn generate(
59-
params: CertificateParams,
60-
key_pair: &KeyPair,
61-
issuer: &Certificate,
62-
issuer_key: &KeyPair,
63-
) -> Result<Certificate, Error> {
64-
let subject_public_key_info = key_pair.public_key_der();
65-
let der = params.serialize_der_with_signer(
66-
key_pair,
67-
issuer_key,
68-
&issuer.params.distinguished_name,
69-
)?;
70-
Ok(Certificate {
71-
params,
72-
subject_public_key_info,
73-
der,
74-
})
75-
}
7630
/// Returns the certificate parameters
7731
pub fn params(&self) -> &CertificateParams {
7832
&self.params
@@ -214,6 +168,50 @@ impl CertificateParams {
214168
})
215169
}
216170

171+
/// Generate a new certificate from the given parameters, signed by the provided issuer.
172+
///
173+
/// The returned certificate will have its issuer field set to the subject of the
174+
/// provided `issuer`, and the authority key identifier extension will be populated using
175+
/// the subject public key of `issuer`. It will be signed by `issuer_key`.
176+
///
177+
/// Note that no validation of the `issuer` certificate is performed. Rcgen will not require
178+
/// the certificate to be a CA certificate, or have key usage extensions that allow signing.
179+
///
180+
/// The returned [`Certificate`] may be serialized using [`Certificate::der`] and
181+
/// [`Certificate::pem`].
182+
pub fn signed_by(
183+
self,
184+
key_pair: &KeyPair,
185+
issuer: &Certificate,
186+
issuer_key: &KeyPair,
187+
) -> Result<Certificate, Error> {
188+
let subject_public_key_info = key_pair.public_key_der();
189+
let der = self.serialize_der_with_signer(
190+
key_pair,
191+
issuer_key,
192+
&issuer.params.distinguished_name,
193+
)?;
194+
Ok(Certificate {
195+
params: self,
196+
subject_public_key_info,
197+
der,
198+
})
199+
}
200+
201+
/// Generates a new self-signed certificate from the given parameters.
202+
///
203+
/// The returned [`Certificate`] may be serialized using [`Certificate::der`] and
204+
/// [`Certificate::pem`].
205+
pub fn self_signed(self, key_pair: &KeyPair) -> Result<Certificate, Error> {
206+
let subject_public_key_info = key_pair.public_key_der();
207+
let der = self.serialize_der_with_signer(key_pair, key_pair, &self.distinguished_name)?;
208+
Ok(Certificate {
209+
params: self,
210+
subject_public_key_info,
211+
der,
212+
})
213+
}
214+
217215
/// Parses an existing ca certificate from the ASCII PEM format.
218216
///
219217
/// See [`from_ca_cert_der`](Self::from_ca_cert_der) for more details.
@@ -228,7 +226,7 @@ impl CertificateParams {
228226
/// This function is only of use if you have an existing CA certificate
229227
/// you would like to use to sign a certificate generated by `rcgen`.
230228
/// By providing the constructed [`CertificateParams`] and the [`KeyPair`]
231-
/// associated with your existing `ca_cert` you can use [`Certificate::generate()`]
229+
/// associated with your existing `ca_cert` you can use [`CertificateParams::signed_by()`]
232230
/// or [`crate::CertificateSigningRequestParams::signed_by()`] to issue new certificates
233231
/// using the CA cert.
234232
///
@@ -1328,17 +1326,15 @@ mod tests {
13281326
#[cfg(windows)]
13291327
fn test_windows_line_endings() {
13301328
let key_pair = KeyPair::generate().unwrap();
1331-
let cert =
1332-
Certificate::generate_self_signed(CertificateParams::default(), &key_pair).unwrap();
1329+
let cert = CertificateParams::default().self_signed(&key_pair).unwrap();
13331330
assert!(cert.pem().contains("\r\n"));
13341331
}
13351332

13361333
#[test]
13371334
#[cfg(not(windows))]
13381335
fn test_not_windows_line_endings() {
13391336
let key_pair = KeyPair::generate().unwrap();
1340-
let cert =
1341-
Certificate::generate_self_signed(CertificateParams::default(), &key_pair).unwrap();
1337+
let cert = CertificateParams::default().self_signed(&key_pair).unwrap();
13421338
assert!(!cert.pem().contains('\r'));
13431339
}
13441340
}
@@ -1445,7 +1441,7 @@ PITGdT9dgN88nHPCle0B1+OY+OZ5
14451441
);
14461442

14471443
let kp = KeyPair::from_pem(ca_key).unwrap();
1448-
let ca_cert = Certificate::generate_self_signed(params, &kp).unwrap();
1444+
let ca_cert = params.self_signed(&kp).unwrap();
14491445
assert_eq!(&expected_ski, &ca_cert.key_identifier());
14501446

14511447
let (_remainder, x509) = x509_parser::parse_x509_certificate(ca_cert.der()).unwrap();

rcgen/src/lib.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ This crate provides a way to generate self signed X.509 certificates.
55
66
The most simple way of using this crate is by calling the
77
[`generate_simple_self_signed`] function.
8-
For more customization abilities, we provide the lower level
9-
[`Certificate::generate_self_signed`] and [`Certificate::generate`] functions.
8+
For more customization abilities, construct a [`CertificateParams`] and
9+
a key pair to call [`CertificateParams::signed_by()`] or [`CertificateParams::self_signed()`].
1010
*/
1111
#![cfg_attr(
1212
feature = "pem",
@@ -124,8 +124,7 @@ pub fn generate_simple_self_signed(
124124
subject_alt_names: impl Into<Vec<String>>,
125125
) -> Result<CertifiedKey, Error> {
126126
let key_pair = KeyPair::generate()?;
127-
let cert =
128-
Certificate::generate_self_signed(CertificateParams::new(subject_alt_names)?, &key_pair)?;
127+
let cert = CertificateParams::new(subject_alt_names)?.self_signed(&key_pair)?;
129128
Ok(CertifiedKey { cert, key_pair })
130129
}
131130

rcgen/tests/botan.rs

+23-20
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ fn check_cert_ca(cert_der: &[u8], _cert: &Certificate, ca_der: &[u8]) {
5050
#[test]
5151
fn test_botan() {
5252
let (params, key_pair) = default_params();
53-
let cert = Certificate::generate_self_signed(params, &key_pair).unwrap();
53+
let cert = params.self_signed(&key_pair).unwrap();
5454

5555
// Now verify the certificate.
5656
check_cert(cert.der(), &cert);
@@ -60,7 +60,7 @@ fn test_botan() {
6060
fn test_botan_256() {
6161
let (params, _) = default_params();
6262
let key_pair = KeyPair::generate_for(&rcgen::PKCS_ECDSA_P256_SHA256).unwrap();
63-
let cert = Certificate::generate_self_signed(params, &key_pair).unwrap();
63+
let cert = params.self_signed(&key_pair).unwrap();
6464

6565
// Now verify the certificate.
6666
check_cert(cert.der(), &cert);
@@ -70,7 +70,7 @@ fn test_botan_256() {
7070
fn test_botan_384() {
7171
let (params, _) = default_params();
7272
let key_pair = KeyPair::generate_for(&rcgen::PKCS_ECDSA_P384_SHA384).unwrap();
73-
let cert = Certificate::generate_self_signed(params, &key_pair).unwrap();
73+
let cert = params.self_signed(&key_pair).unwrap();
7474

7575
// Now verify the certificate.
7676
check_cert(cert.der(), &cert);
@@ -80,7 +80,7 @@ fn test_botan_384() {
8080
fn test_botan_25519() {
8181
let (params, _) = default_params();
8282
let key_pair = KeyPair::generate_for(&rcgen::PKCS_ED25519).unwrap();
83-
let cert = Certificate::generate_self_signed(params, &key_pair).unwrap();
83+
let cert = params.self_signed(&key_pair).unwrap();
8484

8585
// Now verify the certificate.
8686
check_cert(cert.der(), &cert);
@@ -90,7 +90,7 @@ fn test_botan_25519() {
9090
fn test_botan_25519_v1_given() {
9191
let (params, _) = default_params();
9292
let key_pair = KeyPair::from_pem(util::ED25519_TEST_KEY_PAIR_PEM_V1).unwrap();
93-
let cert = Certificate::generate_self_signed(params, &key_pair).unwrap();
93+
let cert = params.self_signed(&key_pair).unwrap();
9494

9595
// Now verify the certificate.
9696
check_cert(cert.der(), &cert);
@@ -100,7 +100,7 @@ fn test_botan_25519_v1_given() {
100100
fn test_botan_25519_v2_given() {
101101
let (params, _) = default_params();
102102
let key_pair = KeyPair::from_pem(util::ED25519_TEST_KEY_PAIR_PEM_V2).unwrap();
103-
let cert = Certificate::generate_self_signed(params, &key_pair).unwrap();
103+
let cert = params.self_signed(&key_pair).unwrap();
104104

105105
// Now verify the certificate.
106106
check_cert(cert.der(), &cert);
@@ -110,7 +110,7 @@ fn test_botan_25519_v2_given() {
110110
fn test_botan_rsa_given() {
111111
let (params, _) = default_params();
112112
let key_pair = KeyPair::from_pem(util::RSA_TEST_KEY_PAIR_PEM).unwrap();
113-
let cert = Certificate::generate_self_signed(params, &key_pair).unwrap();
113+
let cert = params.self_signed(&key_pair).unwrap();
114114

115115
// Now verify the certificate.
116116
check_cert(cert.der(), &cert);
@@ -120,7 +120,7 @@ fn test_botan_rsa_given() {
120120
fn test_botan_separate_ca() {
121121
let (mut params, ca_key) = default_params();
122122
params.is_ca = IsCa::Ca(BasicConstraints::Unconstrained);
123-
let ca_cert = Certificate::generate_self_signed(params, &ca_key).unwrap();
123+
let ca_cert = params.self_signed(&ca_key).unwrap();
124124

125125
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]).unwrap();
126126
params
@@ -133,7 +133,7 @@ fn test_botan_separate_ca() {
133133
params.not_after = rcgen::date_time_ymd(3016, 1, 1);
134134

135135
let key_pair = KeyPair::generate().unwrap();
136-
let cert = Certificate::generate(params, &key_pair, &ca_cert, &ca_key).unwrap();
136+
let cert = params.signed_by(&key_pair, &ca_cert, &ca_key).unwrap();
137137
check_cert_ca(cert.der(), &cert, ca_cert.der());
138138
}
139139

@@ -142,13 +142,12 @@ fn test_botan_separate_ca() {
142142
fn test_botan_imported_ca() {
143143
let (mut params, ca_key) = default_params();
144144
params.is_ca = IsCa::Ca(BasicConstraints::Unconstrained);
145-
let ca_cert = Certificate::generate_self_signed(params, &ca_key).unwrap();
145+
let ca_cert = params.self_signed(&ca_key).unwrap();
146146

147147
let ca_cert_der = ca_cert.der();
148148

149149
let imported_ca_cert_params = CertificateParams::from_ca_cert_der(ca_cert_der).unwrap();
150-
let imported_ca_cert =
151-
Certificate::generate_self_signed(imported_ca_cert_params, &ca_key).unwrap();
150+
let imported_ca_cert = imported_ca_cert_params.self_signed(&ca_key).unwrap();
152151

153152
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]).unwrap();
154153
params
@@ -161,7 +160,9 @@ fn test_botan_imported_ca() {
161160
params.not_after = rcgen::date_time_ymd(3016, 1, 1);
162161

163162
let key_pair = KeyPair::generate().unwrap();
164-
let cert = Certificate::generate(params, &key_pair, &imported_ca_cert, &ca_key).unwrap();
163+
let cert = params
164+
.signed_by(&key_pair, &imported_ca_cert, &ca_key)
165+
.unwrap();
165166
check_cert_ca(cert.der(), &cert, ca_cert_der);
166167
}
167168

@@ -174,13 +175,14 @@ fn test_botan_imported_ca_with_printable_string() {
174175
DnValue::PrintableString("US".try_into().unwrap()),
175176
);
176177
params.is_ca = IsCa::Ca(BasicConstraints::Unconstrained);
177-
let ca_cert = Certificate::generate_self_signed(params, &imported_ca_key).unwrap();
178+
let ca_cert = params.self_signed(&imported_ca_key).unwrap();
178179

179180
let ca_cert_der = ca_cert.der();
180181

181182
let imported_ca_cert_params = CertificateParams::from_ca_cert_der(ca_cert_der).unwrap();
182-
let imported_ca_cert =
183-
Certificate::generate_self_signed(imported_ca_cert_params, &imported_ca_key).unwrap();
183+
let imported_ca_cert = imported_ca_cert_params
184+
.self_signed(&imported_ca_key)
185+
.unwrap();
184186

185187
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]).unwrap();
186188
params
@@ -192,8 +194,9 @@ fn test_botan_imported_ca_with_printable_string() {
192194
// Botan has a sanity check that enforces a maximum expiration date
193195
params.not_after = rcgen::date_time_ymd(3016, 1, 1);
194196
let key_pair = KeyPair::generate().unwrap();
195-
let cert =
196-
Certificate::generate(params, &key_pair, &imported_ca_cert, &imported_ca_key).unwrap();
197+
let cert = params
198+
.signed_by(&key_pair, &imported_ca_cert, &imported_ca_key)
199+
.unwrap();
197200

198201
check_cert_ca(cert.der(), &cert, ca_cert_der);
199202
}
@@ -210,7 +213,7 @@ fn test_botan_crl_parse() {
210213
KeyUsagePurpose::CrlSign,
211214
];
212215
let issuer_key = KeyPair::generate_for(alg).unwrap();
213-
let issuer = Certificate::generate_self_signed(issuer, &issuer_key).unwrap();
216+
let issuer = issuer.self_signed(&issuer_key).unwrap();
214217

215218
// Create an end entity cert issued by the issuer.
216219
let (mut ee, _) = util::default_params();
@@ -219,7 +222,7 @@ fn test_botan_crl_parse() {
219222
// Botan has a sanity check that enforces a maximum expiration date
220223
ee.not_after = rcgen::date_time_ymd(3016, 1, 1);
221224
let ee_key = KeyPair::generate_for(alg).unwrap();
222-
let ee = Certificate::generate(ee, &ee_key, &issuer, &issuer_key).unwrap();
225+
let ee = ee.signed_by(&ee_key, &issuer, &issuer_key).unwrap();
223226
let botan_ee = botan::Certificate::load(ee.der()).unwrap();
224227

225228
// Generate a CRL with the issuer that revokes the EE cert.

0 commit comments

Comments
 (0)