Skip to content

Commit 9bd2b37

Browse files
authored
Merge pull request #3733 from Bravo555/improve/rcgen-bump
bump rcgen to 0.14.2
2 parents a93d3fb + 4cc7cad commit 9bd2b37

File tree

10 files changed

+134
-104
lines changed

10 files changed

+134
-104
lines changed

Cargo.lock

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ quote = "1"
159159
rand = "0.8"
160160
rasn = "0.18" # Not using the latest version which requires rust 1.85
161161
rasn-cms = "0.18" # Not using the latest version which requires rust 1.85
162-
rcgen = { version = "0.12", features = ["pem", "zeroize"] }
162+
rcgen = { version = "0.14", features = ["pem", "zeroize"] }
163163
regex = "1.4"
164164
reqwest = { version = "0.12", default-features = false }
165165
ron = "0.8"

crates/common/axum_tls/src/acceptor.rs

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,7 @@ mod tests {
175175
let permitted_certificate =
176176
rcgen::generate_simple_self_signed(vec!["not-my-client".into()]).unwrap();
177177
let mut roots = RootCertStore::empty();
178-
roots
179-
.add(permitted_certificate.serialize_der().unwrap().into())
180-
.unwrap();
178+
roots.add(permitted_certificate.cert.der().clone()).unwrap();
181179
let server = Server::with_trusted_roots(roots);
182180
let client = Client::builder()
183181
.add_root_certificate(server.certificate.clone())
@@ -198,9 +196,7 @@ mod tests {
198196
let permitted_certificate =
199197
rcgen::generate_simple_self_signed(vec!["not-my-client".into()]).unwrap();
200198
let mut roots = RootCertStore::empty();
201-
roots
202-
.add(permitted_certificate.serialize_der().unwrap().into())
203-
.unwrap();
199+
roots.add(permitted_certificate.cert.der().clone()).unwrap();
204200
let server = Server::with_trusted_roots(roots);
205201
let client = Client::builder()
206202
.add_root_certificate(server.certificate.clone())
@@ -223,9 +219,8 @@ mod tests {
223219
let client_cert = rcgen::generate_simple_self_signed(["my-client".into()]).unwrap();
224220
let identity = identity_from(&client_cert);
225221
let mut cert_store = RootCertStore::empty();
226-
cert_store.add_parsable_certificates([CertificateDer::from(
227-
client_cert.serialize_der().unwrap(),
228-
)]);
222+
cert_store
223+
.add_parsable_certificates([CertificateDer::from(client_cert.cert.der().as_ref())]);
229224

230225
let server = Server::with_trusted_roots(cert_store);
231226
let client = Client::builder()
@@ -253,9 +248,9 @@ mod tests {
253248
identity_from(&client_cert)
254249
}
255250

256-
fn identity_from(cert: &rcgen::Certificate) -> Identity {
257-
let mut pem = cert.serialize_private_key_pem().into_bytes();
258-
pem.append(&mut cert.serialize_pem().unwrap().into_bytes());
251+
fn identity_from(cert: &rcgen::CertifiedKey<rcgen::KeyPair>) -> Identity {
252+
let mut pem = cert.signing_key.serialize_pem().into_bytes();
253+
pem.append(&mut cert.cert.pem().into_bytes());
259254
Identity::from_pem(&pem).unwrap()
260255
}
261256

@@ -293,9 +288,9 @@ mod tests {
293288
port += 1;
294289
};
295290
let certificate = rcgen::generate_simple_self_signed(["localhost".to_owned()]).unwrap();
296-
let certificate_der = CertificateDer::from(certificate.serialize_der().unwrap());
291+
let certificate_der = certificate.cert.der().clone();
297292
let private_key_der =
298-
PrivateKeyDer::from_pem_slice(certificate.serialize_private_key_pem().as_bytes())
293+
PrivateKeyDer::from_pem_slice(certificate.signing_key.serialize_pem().as_bytes())
299294
.unwrap();
300295
let certificate = reqwest::Certificate::from_der(&certificate_der).unwrap();
301296
let config = ssl_config(vec![certificate_der], private_key_der, trusted_roots).unwrap();

crates/common/axum_tls/src/config.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ use yansi::Paint;
4949
/// use tedge_config::{OptionalConfig, TEdgeConfig};
5050
///
5151
/// let cert = rcgen::generate_simple_self_signed(["localhost".to_owned()]).unwrap();
52-
/// let cert_pem = cert.serialize_pem().unwrap();
53-
/// let key_pem = cert.serialize_private_key_pem();
52+
/// let cert_pem = cert.cert.pem();
53+
/// let key_pem = cert.signing_key.serialize_pem();
5454
///
5555
/// let config = load_ssl_config(
5656
/// OptionalConfig::present(InjectedValue(cert_pem), "http.cert_path"),
@@ -147,7 +147,7 @@ pub trait TrustStoreLoader {
147147
/// use axum_tls::config::InjectedValue;
148148
/// use axum_tls::load_cert;
149149
/// let cert = rcgen::generate_simple_self_signed(["localhost".to_owned()]).unwrap();
150-
/// let pem_data = cert.serialize_pem().unwrap();
150+
/// let pem_data = cert.cert.pem();
151151
///
152152
/// let loaded_chain = load_cert(&InjectedValue(pem_data)).unwrap();
153153
///

crates/common/certificate/src/lib.rs

Lines changed: 88 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use anyhow::Context;
22
use camino::Utf8Path;
33
use device_id::DeviceIdError;
4-
use rcgen::Certificate;
54
use rcgen::CertificateParams;
65
use rcgen::KeyPair;
76
use sha1::Digest;
@@ -224,17 +223,17 @@ pub struct RemoteKeyPair {
224223
algorithm: &'static rcgen::SignatureAlgorithm,
225224
}
226225

227-
impl RemoteKeyPair {
228-
pub fn to_key_pair(&self) -> Result<KeyPair, CertificateError> {
229-
Ok(KeyPair::from_remote(Box::new(self.clone()))?)
226+
impl rcgen::PublicKeyData for RemoteKeyPair {
227+
fn der_bytes(&self) -> &[u8] {
228+
&self.public_key_raw
230229
}
231-
}
232230

233-
impl rcgen::RemoteKeyPair for RemoteKeyPair {
234-
fn public_key(&self) -> &[u8] {
235-
&self.public_key_raw
231+
fn algorithm(&self) -> &'static rcgen::SignatureAlgorithm {
232+
self.algorithm
236233
}
234+
}
237235

236+
impl rcgen::SigningKey for RemoteKeyPair {
238237
fn sign(&self, msg: &[u8]) -> Result<Vec<u8>, rcgen::Error> {
239238
// the error here is not PEM-related, but we need to return a foreign error type, and there
240239
// are no other better variants that could let us return context, so we'll have to use this
@@ -245,14 +244,43 @@ impl rcgen::RemoteKeyPair for RemoteKeyPair {
245244
.sign(msg)
246245
.map_err(|e| rcgen::Error::PemError(e.to_string()))
247246
}
247+
}
248+
249+
pub struct KeyCertPair {
250+
certificate: rcgen::Certificate,
251+
// in rcgen 0.14 params are necessary to generate the CSR
252+
params: rcgen::CertificateParams,
253+
signing_key: SigningKeyWrapper,
254+
}
255+
256+
enum SigningKeyWrapper {
257+
Local(Zeroizing<rcgen::KeyPair>),
258+
Remote(RemoteKeyPair),
259+
}
260+
261+
impl rcgen::PublicKeyData for SigningKeyWrapper {
262+
fn der_bytes(&self) -> &[u8] {
263+
match self {
264+
Self::Local(k) => k.der_bytes(),
265+
Self::Remote(k) => k.der_bytes(),
266+
}
267+
}
248268

249269
fn algorithm(&self) -> &'static rcgen::SignatureAlgorithm {
250-
self.algorithm
270+
match self {
271+
Self::Local(k) => k.algorithm(),
272+
Self::Remote(k) => k.algorithm(),
273+
}
251274
}
252275
}
253276

254-
pub struct KeyCertPair {
255-
certificate: Zeroizing<rcgen::Certificate>,
277+
impl rcgen::SigningKey for SigningKeyWrapper {
278+
fn sign(&self, msg: &[u8]) -> Result<Vec<u8>, rcgen::Error> {
279+
match self {
280+
Self::Local(k) => k.sign(msg),
281+
Self::Remote(k) => k.sign(msg),
282+
}
283+
}
256284
}
257285

258286
impl KeyCertPair {
@@ -263,11 +291,13 @@ impl KeyCertPair {
263291
) -> Result<KeyCertPair, CertificateError> {
264292
let today = OffsetDateTime::now_utc();
265293
let not_before = today - Duration::days(1); // Ensure the certificate is valid today
266-
let params =
294+
let (params, signing_key) =
267295
Self::create_selfsigned_certificate_parameters(config, id, key_kind, not_before)?;
268296

269297
Ok(KeyCertPair {
270-
certificate: Zeroizing::new(Certificate::from_params(params)?),
298+
certificate: params.self_signed(&signing_key)?,
299+
signing_key,
300+
params,
271301
})
272302
}
273303

@@ -278,11 +308,14 @@ impl KeyCertPair {
278308
) -> Result<KeyCertPair, CertificateError> {
279309
// Create Certificate without `not_before` and `not_after` fields
280310
// as rcgen library will not parse it for certificate signing request
281-
let params = Self::create_csr_parameters(config, id, key_kind)?;
311+
let (params, signing_key) = Self::create_csr_parameters(config, id, key_kind)?;
312+
let issuer = rcgen::Issuer::from_params(&params, &signing_key);
282313
Ok(KeyCertPair {
283-
certificate: Zeroizing::new(
284-
Certificate::from_params(params).context("Failed to create CSR")?,
285-
),
314+
certificate: params
315+
.signed_by(&signing_key, &issuer)
316+
.context("Failed to create CSR")?,
317+
signing_key,
318+
params,
286319
})
287320
}
288321

@@ -291,8 +324,8 @@ impl KeyCertPair {
291324
id: &str,
292325
key_kind: &KeyKind,
293326
not_before: OffsetDateTime,
294-
) -> Result<CertificateParams, CertificateError> {
295-
let mut params = Self::create_csr_parameters(config, id, key_kind)?;
327+
) -> Result<(CertificateParams, SigningKeyWrapper), CertificateError> {
328+
let (mut params, signing_key) = Self::create_csr_parameters(config, id, key_kind)?;
296329

297330
let not_after = not_before + Duration::days(config.validity_period_days.into());
298331
params.not_before = not_before;
@@ -301,14 +334,14 @@ impl KeyCertPair {
301334
// IsCa::SelfSignedOnly is rejected by C8Y with "422 Unprocessable Entity"
302335
params.is_ca = rcgen::IsCa::Ca(rcgen::BasicConstraints::Unconstrained);
303336

304-
Ok(params)
337+
Ok((params, signing_key))
305338
}
306339

307340
fn create_csr_parameters(
308341
config: &CsrTemplate,
309342
id: &str,
310343
key_kind: &KeyKind,
311-
) -> Result<CertificateParams, CertificateError> {
344+
) -> Result<(CertificateParams, SigningKeyWrapper), CertificateError> {
312345
KeyCertPair::check_identifier(id, config.max_cn_size)?;
313346
let mut distinguished_name = rcgen::DistinguishedName::new();
314347
distinguished_name.push(rcgen::DnType::CommonName, id);
@@ -321,38 +354,38 @@ impl KeyCertPair {
321354
let mut params = CertificateParams::default();
322355
params.distinguished_name = distinguished_name;
323356

324-
match key_kind {
357+
let signing_key: SigningKeyWrapper = match key_kind {
325358
KeyKind::New => {
326359
// ECDSA signing using the P-256 curves and SHA-256 hashing as per RFC 5758
327-
params.alg = &rcgen::PKCS_ECDSA_P256_SHA256;
360+
SigningKeyWrapper::Local(Zeroizing::new(KeyPair::generate_for(
361+
&rcgen::PKCS_ECDSA_P256_SHA256,
362+
)?))
328363
}
329364
KeyKind::Reuse { keypair_pem } => {
330365
// Use the same signing algorithm as the existing key
331366
// Failing to do so leads to an error telling the algorithm is not compatible
332-
let key_pair = KeyPair::from_pem(keypair_pem)?;
333-
params.alg = key_pair.algorithm();
334-
params.key_pair = Some(key_pair);
335-
}
336-
KeyKind::ReuseRemote(key_pair) => {
337-
let key_pair = key_pair.to_key_pair()?;
338-
params.alg = key_pair.algorithm();
339-
params.key_pair = Some(key_pair)
367+
SigningKeyWrapper::Local(Zeroizing::new(KeyPair::from_pem(keypair_pem)?))
340368
}
341-
}
369+
KeyKind::ReuseRemote(remote) => SigningKeyWrapper::Remote(remote.clone()),
370+
};
342371

343-
Ok(params)
372+
Ok((params, signing_key))
344373
}
345374

346375
pub fn certificate_pem_string(&self) -> Result<String, CertificateError> {
347-
Ok(self.certificate.serialize_pem()?)
376+
Ok(self.certificate.pem())
348377
}
349378

350379
pub fn private_key_pem_string(&self) -> Result<Zeroizing<String>, CertificateError> {
351-
Ok(Zeroizing::new(self.certificate.serialize_private_key_pem()))
380+
if let SigningKeyWrapper::Local(keypair) = &self.signing_key {
381+
Ok(Zeroizing::new(keypair.serialize_pem()))
382+
} else {
383+
Err(anyhow::anyhow!("Can't serialize private key PEM for remote private key").into())
384+
}
352385
}
353386

354387
pub fn certificate_signing_request_string(&self) -> Result<String, CertificateError> {
355-
Ok(self.certificate.serialize_request_pem()?)
388+
Ok(self.params.serialize_request(&self.signing_key)?.pem()?)
356389
}
357390

358391
fn check_identifier(id: &str, max_cn_size: usize) -> Result<(), CertificateError> {
@@ -555,7 +588,7 @@ mod tests {
555588
let id = "some-id";
556589
let birthdate = datetime!(2021-03-31 16:39:57 +01:00);
557590

558-
let params = KeyCertPair::create_selfsigned_certificate_parameters(
591+
let (params, signing_key) = KeyCertPair::create_selfsigned_certificate_parameters(
559592
&config,
560593
id,
561594
&KeyKind::New,
@@ -564,9 +597,11 @@ mod tests {
564597
.expect("Fail to get a certificate parameters");
565598

566599
let keypair = KeyCertPair {
567-
certificate: Zeroizing::new(
568-
Certificate::from_params(params).expect("Fail to create a certificate"),
569-
),
600+
certificate: params
601+
.self_signed(&signing_key)
602+
.expect("Fail to create a certificate"),
603+
params,
604+
signing_key,
570605
};
571606

572607
// Check the not_before date
@@ -587,7 +622,7 @@ mod tests {
587622
let id = "some-id";
588623
let birthdate = datetime!(2021-03-31 16:39:57 +01:00);
589624

590-
let params = KeyCertPair::create_selfsigned_certificate_parameters(
625+
let (params, signing_key) = KeyCertPair::create_selfsigned_certificate_parameters(
591626
&config,
592627
id,
593628
&KeyKind::New,
@@ -596,9 +631,11 @@ mod tests {
596631
.expect("Fail to get a certificate parameters");
597632

598633
let keypair = KeyCertPair {
599-
certificate: Zeroizing::new(
600-
Certificate::from_params(params).expect("Fail to create a certificate"),
601-
),
634+
certificate: params
635+
.self_signed(&signing_key)
636+
.expect("Fail to create a certificate"),
637+
params,
638+
signing_key,
602639
};
603640

604641
// Check the not_after date
@@ -613,13 +650,16 @@ mod tests {
613650
let config = CsrTemplate::default();
614651
let id = "some-id";
615652

616-
let params = KeyCertPair::create_csr_parameters(&config, id, &KeyKind::New)
653+
let (params, signing_key) = KeyCertPair::create_csr_parameters(&config, id, &KeyKind::New)
617654
.expect("Fail to get a certificate parameters");
618655

656+
let issuer = rcgen::Issuer::from_params(&params, &signing_key);
619657
let keypair = KeyCertPair {
620-
certificate: Zeroizing::new(
621-
Certificate::from_params(params).expect("Fail to create a certificate"),
622-
),
658+
certificate: params
659+
.signed_by(&signing_key, &issuer)
660+
.expect("Fail to create a certificate"),
661+
params,
662+
signing_key,
623663
};
624664

625665
// Check the subject

crates/common/download/src/download.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,6 @@ mod tests {
466466
use axum::Router;
467467
use hyper::header::AUTHORIZATION;
468468
use rustls::pki_types::pem::PemObject;
469-
use rustls::pki_types::CertificateDer;
470469
use rustls::pki_types::PrivateKeyDer;
471470
use rustls::RootCertStore;
472471
use std::io::Write;
@@ -970,8 +969,8 @@ mod tests {
970969
let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
971970
let port = listener.local_addr().unwrap().port();
972971
let server_cert = rcgen::generate_simple_self_signed(["localhost".into()]).unwrap();
973-
let cert = CertificateDer::from(server_cert.serialize_der().unwrap());
974-
let key = PrivateKeyDer::from_pem_slice(server_cert.serialize_private_key_pem().as_bytes())
972+
let cert = server_cert.cert.der().clone();
973+
let key = PrivateKeyDer::from_pem_slice(server_cert.signing_key.serialize_pem().as_bytes())
975974
.unwrap();
976975
let mut accepted_certs = RootCertStore::empty();
977976
accepted_certs.add(cert.clone()).unwrap();

0 commit comments

Comments
 (0)