Skip to content

Commit 066942b

Browse files
committed
Unbundle params from output types
1 parent 0430bc7 commit 066942b

File tree

10 files changed

+98
-135
lines changed

10 files changed

+98
-135
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: 8 additions & 34 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,24 +138,20 @@ 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: &KeyPair,
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

171-
let subject_public_key_info =
172-
yasna::construct_der(|writer| serialize_public_key_der(public_key, writer));
173153
let der = self.serialize_der_with_signer(public_key, issuer)?;
174154
Ok(Certificate {
175-
params: self,
176-
subject_public_key_info,
177155
der,
178156
})
179157
}
@@ -182,19 +160,16 @@ impl CertificateParams {
182160
///
183161
/// The returned [`Certificate`] may be serialized using [`Certificate::der`] and
184162
/// [`Certificate::pem`].
185-
pub fn self_signed(self, key_pair: &KeyPair) -> Result<Certificate, Error> {
163+
pub fn self_signed(&self, key_pair: &KeyPair) -> Result<Certificate, Error> {
186164
let issuer = Issuer {
187165
distinguished_name: &self.distinguished_name,
188166
key_identifier_method: &self.key_identifier_method,
189167
key_usages: &self.key_usages,
190168
key_pair,
191169
};
192170

193-
let subject_public_key_info = key_pair.public_key_der();
194171
let der = self.serialize_der_with_signer(key_pair, issuer)?;
195172
Ok(Certificate {
196-
params: self,
197-
subject_public_key_info,
198173
der,
199174
})
200175
}
@@ -1493,7 +1468,6 @@ PITGdT9dgN88nHPCle0B1+OY+OZ5
14931468

14941469
let ca_kp = KeyPair::from_pem(ca_key).unwrap();
14951470
let ca_cert = params.self_signed(&ca_kp).unwrap();
1496-
assert_eq!(&ca_ski, &ca_cert.key_identifier());
14971471

14981472
let (_, x509_ca) = x509_parser::parse_x509_certificate(ca_cert.der()).unwrap();
14991473
assert_eq!(
@@ -1512,7 +1486,7 @@ PITGdT9dgN88nHPCle0B1+OY+OZ5
15121486
let ee_key = KeyPair::generate().unwrap();
15131487
let mut ee_params = CertificateParams::default();
15141488
ee_params.use_authority_key_identifier_extension = true;
1515-
let ee_cert = ee_params.signed_by(&ee_key, &ca_cert, &ee_key).unwrap();
1489+
let ee_cert = ee_params.signed_by(&ee_key, &params, &ee_key).unwrap();
15161490

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

rcgen/src/crl.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ use time::OffsetDateTime;
55
use yasna::DERWriter;
66
use yasna::Tag;
77

8+
use crate::CertificateParams;
89
#[cfg(feature = "pem")]
910
use crate::ENCODE_CONFIG;
1011
use crate::{
1112
oid, write_distinguished_name, write_dt_utc_or_generalized,
12-
write_x509_authority_key_identifier, write_x509_extension, Certificate, Error, Issuer,
13+
write_x509_authority_key_identifier, write_x509_extension, Error, Issuer,
1314
KeyIdMethod, KeyPair, KeyUsagePurpose, SerialNumber,
1415
};
1516

@@ -60,7 +61,7 @@ use crate::{
6061
/// key_identifier_method: KeyIdMethod::Sha256,
6162
/// #[cfg(not(feature = "crypto"))]
6263
/// key_identifier_method: KeyIdMethod::PreSpecified(vec![]),
63-
/// }.signed_by(&issuer, &key_pair).unwrap();
64+
/// }.signed_by(&issuer_params, &key_pair).unwrap();
6465
///# }
6566
#[derive(Debug)]
6667
pub struct CertificateRevocationList {
@@ -190,17 +191,17 @@ impl CertificateRevocationListParams {
190191
/// Including a signature from the issuing certificate authority's key.
191192
pub fn signed_by(
192193
self,
193-
issuer: &Certificate,
194+
issuer: &CertificateParams,
194195
issuer_key: &KeyPair,
195196
) -> Result<CertificateRevocationList, Error> {
196197
if self.next_update.le(&self.this_update) {
197198
return Err(Error::InvalidCrlNextUpdate);
198199
}
199200

200201
let issuer = Issuer {
201-
distinguished_name: &issuer.params.distinguished_name,
202-
key_identifier_method: &issuer.params.key_identifier_method,
203-
key_usages: &issuer.params.key_usages,
202+
distinguished_name: &issuer.distinguished_name,
203+
key_identifier_method: &issuer.key_identifier_method,
204+
key_usages: &issuer.key_usages,
204205
key_pair: issuer_key,
205206
};
206207

rcgen/src/csr.rs

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ use pki_types::CertificateSigningRequestDer;
77
#[cfg(feature = "pem")]
88
use crate::ENCODE_CONFIG;
99
use crate::{
10-
key_pair::serialize_public_key_der, Certificate, CertificateParams, Error, Issuer, KeyPair,
11-
PublicKeyData, SignatureAlgorithm,
10+
Certificate, CertificateParams, Error, Issuer, KeyPair, PublicKeyData, SignatureAlgorithm,
1211
};
1312
#[cfg(feature = "x509-parser")]
1413
use crate::{DistinguishedName, SanType};
@@ -202,27 +201,20 @@ impl CertificateSigningRequestParams {
202201
/// The returned [`Certificate`] may be serialized using [`Certificate::der`] and
203202
/// [`Certificate::pem`].
204203
pub fn signed_by(
205-
self,
206-
issuer: &Certificate,
204+
&self,
205+
issuer: &CertificateParams,
207206
issuer_key: &KeyPair,
208207
) -> Result<Certificate, Error> {
209208
let issuer = Issuer {
210-
distinguished_name: &issuer.params.distinguished_name,
211-
key_identifier_method: &issuer.params.key_identifier_method,
212-
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,
213212
key_pair: issuer_key,
214213
};
215214

216215
let der = self
217216
.params
218217
.serialize_der_with_signer(&self.public_key, issuer)?;
219-
let subject_public_key_info = yasna::construct_der(|writer| {
220-
serialize_public_key_der(&self.public_key, writer);
221-
});
222-
Ok(Certificate {
223-
params: self.params,
224-
subject_public_key_info,
225-
der,
226-
})
218+
Ok(Certificate { der })
227219
}
228220
}

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: 1 addition & 1 deletion
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.

0 commit comments

Comments
 (0)