Skip to content

Commit cc9ce2b

Browse files
committed
Unbundle params from output types
1 parent 5f7af28 commit cc9ce2b

File tree

10 files changed

+122
-175
lines changed

10 files changed

+122
-175
lines changed

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use time::{Duration, OffsetDateTime};
66

77
/// Example demonstrating signing end-entity certificate with ca
88
fn main() {
9-
let (ca, ca_key) = new_ca();
10-
let end_entity = new_end_entity(&ca, &ca_key);
9+
let (ca_params, ca, ca_key) = new_ca();
10+
let end_entity = new_end_entity(&ca_params, &ca_key);
1111

1212
let end_entity_pem = end_entity.pem();
1313
println!("directly signed end-entity certificate: {end_entity_pem}");
@@ -16,7 +16,7 @@ fn main() {
1616
println!("ca certificate: {ca_cert_pem}");
1717
}
1818

19-
fn new_ca() -> (Certificate, KeyPair) {
19+
fn new_ca() -> (CertificateParams, Certificate, KeyPair) {
2020
let mut params =
2121
CertificateParams::new(Vec::default()).expect("empty subject alt name can't produce error");
2222
let (yesterday, tomorrow) = validity_period();
@@ -36,10 +36,11 @@ fn new_ca() -> (Certificate, KeyPair) {
3636
params.not_after = tomorrow;
3737

3838
let key_pair = KeyPair::generate().unwrap();
39-
(params.self_signed(&key_pair).unwrap(), key_pair)
39+
let cert = params.self_signed(&key_pair).unwrap();
40+
(params, cert, key_pair)
4041
}
4142

42-
fn new_end_entity(ca: &Certificate, ca_key: &KeyPair) -> Certificate {
43+
fn new_end_entity(ca: &CertificateParams, ca_key: &KeyPair) -> Certificate {
4344
let name = "entity.other.host";
4445
let mut params = CertificateParams::new(vec![name.into()]).expect("we know the name is valid");
4546
let (yesterday, tomorrow) = validity_period();

rcgen/src/certificate.rs

Lines changed: 10 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -24,30 +24,18 @@ use crate::{
2424
/// An issued certificate together with the parameters used to generate it.
2525
#[derive(Debug, Clone)]
2626
pub struct Certificate {
27-
pub(crate) params: CertificateParams,
28-
pub(crate) subject_public_key_info: Vec<u8>,
2927
pub(crate) der: CertificateDer<'static>,
3028
}
3129

3230
impl Certificate {
33-
/// Returns the certificate parameters
34-
pub fn params(&self) -> &CertificateParams {
35-
&self.params
36-
}
37-
/// Calculates a subject key identifier for the certificate subject's public key.
38-
/// This key identifier is used in the SubjectKeyIdentifier X.509v3 extension.
39-
pub fn key_identifier(&self) -> Vec<u8> {
40-
self.params
41-
.key_identifier_method
42-
.derive(&self.subject_public_key_info)
43-
}
4431
/// Get the certificate in DER encoded format.
4532
///
4633
/// [`CertificateDer`] implements `Deref<Target = [u8]>` and `AsRef<[u8]>`, so you can easily
4734
/// extract the DER bytes from the return value.
4835
pub fn der(&self) -> &CertificateDer<'static> {
4936
&self.der
5037
}
38+
5139
/// Get the certificate in PEM encoded format.
5240
#[cfg(feature = "pem")]
5341
pub fn pem(&self) -> String {
@@ -61,12 +49,6 @@ impl From<Certificate> for CertificateDer<'static> {
6149
}
6250
}
6351

64-
impl AsRef<CertificateParams> for Certificate {
65-
fn as_ref(&self) -> &CertificateParams {
66-
&self.params
67-
}
68-
}
69-
7052
/// Parameters used for certificate generation
7153
#[allow(missing_docs)]
7254
#[non_exhaustive]
@@ -156,45 +138,36 @@ impl CertificateParams {
156138
/// The returned [`Certificate`] may be serialized using [`Certificate::der`] and
157139
/// [`Certificate::pem`].
158140
pub fn signed_by(
159-
self,
141+
&self,
160142
public_key: &impl PublicKeyData,
161-
issuer: &Certificate,
143+
issuer: &CertificateParams,
162144
issuer_key: &impl SigningKey,
163145
) -> Result<Certificate, Error> {
164146
let issuer = Issuer {
165-
distinguished_name: &issuer.params.distinguished_name,
166-
key_identifier_method: &issuer.params.key_identifier_method,
167-
key_usages: &issuer.params.key_usages,
147+
distinguished_name: &issuer.distinguished_name,
148+
key_identifier_method: &issuer.key_identifier_method,
149+
key_usages: &issuer.key_usages,
168150
key_pair: issuer_key,
169151
};
170152

171153
let der = self.serialize_der_with_signer(public_key, issuer)?;
172-
Ok(Certificate {
173-
params: self,
174-
subject_public_key_info: public_key.subject_public_key_info(),
175-
der,
176-
})
154+
Ok(Certificate { der })
177155
}
178156

179157
/// Generates a new self-signed certificate from the given parameters.
180158
///
181159
/// The returned [`Certificate`] may be serialized using [`Certificate::der`] and
182160
/// [`Certificate::pem`].
183-
pub fn self_signed(self, key_pair: &impl SigningKey) -> Result<Certificate, Error> {
161+
pub fn self_signed(&self, key_pair: &impl SigningKey) -> Result<Certificate, Error> {
184162
let issuer = Issuer {
185163
distinguished_name: &self.distinguished_name,
186164
key_identifier_method: &self.key_identifier_method,
187165
key_usages: &self.key_usages,
188166
key_pair,
189167
};
190168

191-
let subject_public_key_info = key_pair.subject_public_key_info();
192169
let der = self.serialize_der_with_signer(key_pair, issuer)?;
193-
Ok(Certificate {
194-
params: self,
195-
subject_public_key_info,
196-
der,
197-
})
170+
Ok(Certificate { der })
198171
}
199172

200173
/// Parses an existing ca certificate from the ASCII PEM format.
@@ -1492,7 +1465,6 @@ PITGdT9dgN88nHPCle0B1+OY+OZ5
14921465

14931466
let ca_kp = KeyPair::from_pem(ca_key).unwrap();
14941467
let ca_cert = params.self_signed(&ca_kp).unwrap();
1495-
assert_eq!(&ca_ski, &ca_cert.key_identifier());
14961468

14971469
let (_, x509_ca) = x509_parser::parse_x509_certificate(ca_cert.der()).unwrap();
14981470
assert_eq!(
@@ -1511,7 +1483,7 @@ PITGdT9dgN88nHPCle0B1+OY+OZ5
15111483
let ee_key = KeyPair::generate().unwrap();
15121484
let mut ee_params = CertificateParams::default();
15131485
ee_params.use_authority_key_identifier_extension = true;
1514-
let ee_cert = ee_params.signed_by(&ee_key, &ca_cert, &ee_key).unwrap();
1486+
let ee_cert = ee_params.signed_by(&ee_key, &params, &ee_key).unwrap();
15151487

15161488
let (_, x509_ee) = x509_parser::parse_x509_certificate(ee_cert.der()).unwrap();
15171489
assert_eq!(

rcgen/src/crl.rs

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ use crate::key_pair::sign_der;
1010
use crate::ENCODE_CONFIG;
1111
use crate::{
1212
oid, write_distinguished_name, write_dt_utc_or_generalized,
13-
write_x509_authority_key_identifier, write_x509_extension, Certificate, Error, Issuer,
14-
KeyIdMethod, KeyUsagePurpose, SerialNumber, SigningKey,
13+
write_x509_authority_key_identifier, write_x509_extension, CertificateParams, Error, Issuer,
14+
KeyIdMethod, KeyPair, KeyUsagePurpose, SerialNumber, SigningKey,
1515
};
1616

1717
/// A certificate revocation list (CRL)
@@ -61,20 +61,14 @@ use crate::{
6161
/// key_identifier_method: KeyIdMethod::Sha256,
6262
/// #[cfg(not(feature = "crypto"))]
6363
/// key_identifier_method: KeyIdMethod::PreSpecified(vec![]),
64-
/// }.signed_by(&issuer, &key_pair).unwrap();
64+
/// }.signed_by(&issuer_params, &key_pair).unwrap();
6565
///# }
6666
#[derive(Debug)]
6767
pub struct CertificateRevocationList {
68-
params: CertificateRevocationListParams,
6968
der: CertificateRevocationListDer<'static>,
7069
}
7170

7271
impl CertificateRevocationList {
73-
/// Returns the certificate revocation list (CRL) parameters.
74-
pub fn params(&self) -> &CertificateRevocationListParams {
75-
&self.params
76-
}
77-
7872
/// Get the CRL in PEM encoded format.
7973
#[cfg(feature = "pem")]
8074
pub fn pem(&self) -> Result<String, Error> {
@@ -190,18 +184,18 @@ impl CertificateRevocationListParams {
190184
///
191185
/// Including a signature from the issuing certificate authority's key.
192186
pub fn signed_by(
193-
self,
194-
issuer: &Certificate,
195-
issuer_key: &impl SigningKey,
187+
&self,
188+
issuer: &CertificateParams,
189+
issuer_key: &KeyPair,
196190
) -> Result<CertificateRevocationList, Error> {
197191
if self.next_update.le(&self.this_update) {
198192
return Err(Error::InvalidCrlNextUpdate);
199193
}
200194

201195
let issuer = Issuer {
202-
distinguished_name: &issuer.params.distinguished_name,
203-
key_identifier_method: &issuer.params.key_identifier_method,
204-
key_usages: &issuer.params.key_usages,
196+
distinguished_name: &issuer.distinguished_name,
197+
key_identifier_method: &issuer.key_identifier_method,
198+
key_usages: &issuer.key_usages,
205199
key_pair: issuer_key,
206200
};
207201

@@ -211,7 +205,6 @@ impl CertificateRevocationListParams {
211205

212206
Ok(CertificateRevocationList {
213207
der: self.serialize_der(&issuer)?.into(),
214-
params: self,
215208
})
216209
}
217210

rcgen/src/csr.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -201,25 +201,20 @@ impl CertificateSigningRequestParams {
201201
/// The returned [`Certificate`] may be serialized using [`Certificate::der`] and
202202
/// [`Certificate::pem`].
203203
pub fn signed_by(
204-
self,
205-
issuer: &Certificate,
204+
&self,
205+
issuer: &CertificateParams,
206206
issuer_key: &impl SigningKey,
207207
) -> Result<Certificate, Error> {
208208
let issuer = Issuer {
209-
distinguished_name: &issuer.params.distinguished_name,
210-
key_identifier_method: &issuer.params.key_identifier_method,
211-
key_usages: &issuer.params.key_usages,
209+
distinguished_name: &issuer.distinguished_name,
210+
key_identifier_method: &issuer.key_identifier_method,
211+
key_usages: &issuer.key_usages,
212212
key_pair: issuer_key,
213213
};
214214

215215
let der = self
216216
.params
217217
.serialize_der_with_signer(&self.public_key, issuer)?;
218-
219-
Ok(Certificate {
220-
params: self.params,
221-
subject_public_key_info: self.public_key.subject_public_key_info(),
222-
der,
223-
})
218+
Ok(Certificate { der })
224219
}
225220
}

rcgen/tests/botan.rs

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,9 @@ fn test_botan_rsa_given() {
128128

129129
#[test]
130130
fn test_botan_separate_ca() {
131-
let (mut params, ca_key) = default_params();
132-
params.is_ca = IsCa::Ca(BasicConstraints::Unconstrained);
133-
let ca_cert = params.self_signed(&ca_key).unwrap();
131+
let (mut ca_params, ca_key) = default_params();
132+
ca_params.is_ca = IsCa::Ca(BasicConstraints::Unconstrained);
133+
let ca_cert = ca_params.self_signed(&ca_key).unwrap();
134134

135135
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]).unwrap();
136136
params
@@ -143,7 +143,7 @@ fn test_botan_separate_ca() {
143143
params.not_after = rcgen::date_time_ymd(3016, 1, 1);
144144

145145
let key_pair = KeyPair::generate().unwrap();
146-
let cert = params.signed_by(&key_pair, &ca_cert, &ca_key).unwrap();
146+
let cert = params.signed_by(&key_pair, &ca_params, &ca_key).unwrap();
147147
check_cert_ca(cert.der(), &cert, ca_cert.der());
148148
}
149149

@@ -157,7 +157,6 @@ fn test_botan_imported_ca() {
157157
let ca_cert_der = ca_cert.der();
158158

159159
let imported_ca_cert_params = CertificateParams::from_ca_cert_der(ca_cert_der).unwrap();
160-
let imported_ca_cert = imported_ca_cert_params.self_signed(&ca_key).unwrap();
161160

162161
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]).unwrap();
163162
params
@@ -171,7 +170,7 @@ fn test_botan_imported_ca() {
171170

172171
let key_pair = KeyPair::generate().unwrap();
173172
let cert = params
174-
.signed_by(&key_pair, &imported_ca_cert, &ca_key)
173+
.signed_by(&key_pair, &imported_ca_cert_params, &ca_key)
175174
.unwrap();
176175
check_cert_ca(cert.der(), &cert, ca_cert_der);
177176
}
@@ -190,9 +189,6 @@ fn test_botan_imported_ca_with_printable_string() {
190189
let ca_cert_der = ca_cert.der();
191190

192191
let imported_ca_cert_params = CertificateParams::from_ca_cert_der(ca_cert_der).unwrap();
193-
let imported_ca_cert = imported_ca_cert_params
194-
.self_signed(&imported_ca_key)
195-
.unwrap();
196192

197193
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]).unwrap();
198194
params
@@ -205,7 +201,7 @@ fn test_botan_imported_ca_with_printable_string() {
205201
params.not_after = rcgen::date_time_ymd(3016, 1, 1);
206202
let key_pair = KeyPair::generate().unwrap();
207203
let cert = params
208-
.signed_by(&key_pair, &imported_ca_cert, &imported_ca_key)
204+
.signed_by(&key_pair, &imported_ca_cert_params, &imported_ca_key)
209205
.unwrap();
210206

211207
check_cert_ca(cert.der(), &cert, ca_cert_der);
@@ -223,7 +219,6 @@ fn test_botan_crl_parse() {
223219
KeyUsagePurpose::CrlSign,
224220
];
225221
let issuer_key = KeyPair::generate_for(alg).unwrap();
226-
let issuer = issuer.self_signed(&issuer_key).unwrap();
227222

228223
// Create an end entity cert issued by the issuer.
229224
let (mut ee, _) = util::default_params();
@@ -232,8 +227,8 @@ fn test_botan_crl_parse() {
232227
// Botan has a sanity check that enforces a maximum expiration date
233228
ee.not_after = rcgen::date_time_ymd(3016, 1, 1);
234229
let ee_key = KeyPair::generate_for(alg).unwrap();
235-
let ee = ee.signed_by(&ee_key, &issuer, &issuer_key).unwrap();
236-
let botan_ee = botan::Certificate::load(ee.der()).unwrap();
230+
let ee_cert = ee.signed_by(&ee_key, &issuer, &issuer_key).unwrap();
231+
let botan_ee = botan::Certificate::load(ee_cert.der()).unwrap();
237232

238233
// Generate a CRL with the issuer that revokes the EE cert.
239234
let now = OffsetDateTime::now_utc();
@@ -243,7 +238,7 @@ fn test_botan_crl_parse() {
243238
crl_number: rcgen::SerialNumber::from(1234),
244239
issuing_distribution_point: None,
245240
revoked_certs: vec![RevokedCertParams {
246-
serial_number: ee.params().serial_number.clone().unwrap(),
241+
serial_number: ee.serial_number.clone().unwrap(),
247242
revocation_time: now,
248243
reason_code: Some(RevocationReason::KeyCompromise),
249244
invalidity_date: None,

rcgen/tests/generic.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ mod test_x509_custom_ext {
107107
assert_eq!(favorite_drink_ext.value, test_ext);
108108

109109
// Generate a CSR with the custom extension, parse it with x509-parser.
110-
let test_cert_csr = test_cert.params().serialize_request(&test_key).unwrap();
110+
let test_cert_csr = params.serialize_request(&test_key).unwrap();
111111
let (_, x509_csr) = X509CertificationRequest::from_der(test_cert_csr.der()).unwrap();
112112

113113
// We should find that the CSR contains requested extensions.
@@ -204,8 +204,8 @@ mod test_x509_parser_crl {
204204
#[test]
205205
fn parse_crl() {
206206
// Create a CRL with one revoked cert, and an issuer to sign the CRL.
207-
let (crl, issuer) = util::test_crl();
208-
let revoked_cert = crl.params().revoked_certs.first().unwrap();
207+
let (crl_params, crl, issuer) = util::test_crl();
208+
let revoked_cert = crl_params.revoked_certs.first().unwrap();
209209
let revoked_cert_serial = BigUint::from_bytes_be(revoked_cert.serial_number.as_ref());
210210
let (_, x509_issuer) = X509Certificate::from_der(issuer.der()).unwrap();
211211

@@ -218,17 +218,17 @@ mod test_x509_parser_crl {
218218
assert_eq!(x509_crl.issuer(), x509_issuer.subject());
219219
assert_eq!(
220220
x509_crl.last_update().to_datetime().unix_timestamp(),
221-
crl.params().this_update.unix_timestamp()
221+
crl_params.this_update.unix_timestamp()
222222
);
223223
assert_eq!(
224224
x509_crl
225225
.next_update()
226226
.unwrap()
227227
.to_datetime()
228228
.unix_timestamp(),
229-
crl.params().next_update.unix_timestamp()
229+
crl_params.next_update.unix_timestamp()
230230
);
231-
let crl_number = BigUint::from_bytes_be(crl.params().crl_number.as_ref());
231+
let crl_number = BigUint::from_bytes_be(crl_params.crl_number.as_ref());
232232
assert_eq!(x509_crl.crl_number().unwrap(), &crl_number);
233233

234234
// We should find the expected revoked certificate serial with the correct reason code.

0 commit comments

Comments
 (0)