Skip to content

Commit 4e3028a

Browse files
committed
use pki types in function that parse der
1 parent 747b5d8 commit 4e3028a

File tree

10 files changed

+73
-62
lines changed

10 files changed

+73
-62
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 & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pem = "3.0.2"
77
rand = "0.8"
88
ring = "0.17"
99
x509-parser = "0.15.1"
10+
pki-types = { package = "rustls-pki-types", version = "1" }
1011

1112
[workspace.package]
1213
license = "MIT OR Apache-2.0"

rcgen/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,14 @@ pem = { workspace = true, optional = true }
3333
time = { version = "0.3.6", default-features = false }
3434
x509-parser = { workspace = true, features = ["verify"], optional = true }
3535
zeroize = { version = "1.2", optional = true }
36+
pki-types = { workspace = true }
3637

3738
[features]
3839
default = ["crypto", "pem", "ring"]
3940
crypto = []
4041
aws_lc_rs = ["crypto", "dep:aws-lc-rs"]
4142
ring = ["crypto", "dep:ring"]
4243

43-
4444
[package.metadata.docs.rs]
4545
features = ["x509-parser"]
4646

@@ -52,7 +52,6 @@ allowed_external_types = [
5252

5353
[dev-dependencies]
5454
openssl = "0.10"
55-
pki-types = { package = "rustls-pki-types", version = "1" }
5655
x509-parser = { workspace = true, features = ["verify"] }
5756
rustls-webpki = { version = "0.102", features = ["std"] }
5857
botan = { version = "0.10", features = ["vendored"] }

rcgen/examples/rsa-irc.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use pki_types::PrivatePkcs8KeyDer;
2+
13
fn main() -> Result<(), Box<dyn std::error::Error>> {
24
use rand::rngs::OsRng;
35
use rsa::pkcs8::EncodePrivateKey;
@@ -16,7 +18,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
1618
let bits = 2048;
1719
let private_key = RsaPrivateKey::new(&mut rng, bits)?;
1820
let private_key_der = private_key.to_pkcs8_der()?;
19-
let key_pair = rcgen::KeyPair::try_from(private_key_der.as_bytes()).unwrap();
21+
let key_pair = rcgen::KeyPair::from_der(PrivatePkcs8KeyDer::from(private_key_der.as_bytes()))?;
2022

2123
let cert = Certificate::generate_self_signed(params, &key_pair)?;
2224
let pem_serialized = cert.pem();

rcgen/src/key_pair.rs

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#[cfg(feature = "pem")]
22
use pem::Pem;
33
#[cfg(feature = "crypto")]
4+
use pki_types::{PrivateKeyDer, PrivatePkcs8KeyDer};
5+
#[cfg(feature = "crypto")]
46
use std::convert::TryFrom;
57
use std::fmt;
68
use yasna::DERWriter;
@@ -116,8 +118,8 @@ impl KeyPair {
116118
///
117119
/// Equivalent to using the [`TryFrom`] implementation.
118120
#[cfg(feature = "crypto")]
119-
pub fn from_der(der: &[u8]) -> Result<Self, Error> {
120-
Ok(der.try_into()?)
121+
pub fn from_der<'a>(der: impl Into<PrivateKeyDer<'a>>) -> Result<Self, Error> {
122+
der.into().try_into()
121123
}
122124

123125
/// Returns the key pair's signature algorithm
@@ -130,7 +132,7 @@ impl KeyPair {
130132
pub fn from_pem(pem_str: &str) -> Result<Self, Error> {
131133
let private_key = pem::parse(pem_str)._err()?;
132134
let private_key_der: &[_] = private_key.contents();
133-
Ok(private_key_der.try_into()?)
135+
Self::from_der(PrivatePkcs8KeyDer::from(private_key_der))
134136
}
135137

136138
/// Obtains the key pair from a raw public key and a remote private key
@@ -153,7 +155,10 @@ impl KeyPair {
153155
) -> Result<Self, Error> {
154156
let private_key = pem::parse(pem_str)._err()?;
155157
let private_key_der: &[_] = private_key.contents();
156-
Ok(Self::from_der_and_sign_algo(private_key_der, alg)?)
158+
Ok(Self::from_der_and_sign_algo(
159+
PrivatePkcs8KeyDer::from(private_key_der),
160+
alg,
161+
)?)
157162
}
158163

159164
/// Obtains the key pair from a DER formatted key
@@ -166,38 +171,42 @@ impl KeyPair {
166171
/// same der key. In that instance, you can use this function to precisely
167172
/// specify the `SignatureAlgorithm`.
168173
#[cfg(feature = "crypto")]
169-
pub fn from_der_and_sign_algo(
170-
pkcs8: &[u8],
174+
pub fn from_der_and_sign_algo<'a>(
175+
der: impl Into<PrivateKeyDer<'a>>,
171176
alg: &'static SignatureAlgorithm,
172177
) -> Result<Self, Error> {
173178
let rng = &SystemRandom::new();
174-
let pkcs8_vec = pkcs8.to_vec();
179+
let pkcs8_vec = match &der.into() {
180+
PrivateKeyDer::Pkcs8(private_key) => Ok(private_key.secret_pkcs8_der()),
181+
_ => Err(Error::CouldNotParseKeyPair),
182+
}?
183+
.to_vec();
175184

176185
let kind = if alg == &PKCS_ED25519 {
177-
KeyPairKind::Ed(Ed25519KeyPair::from_pkcs8_maybe_unchecked(pkcs8)._err()?)
186+
KeyPairKind::Ed(Ed25519KeyPair::from_pkcs8_maybe_unchecked(&pkcs8_vec)._err()?)
178187
} else if alg == &PKCS_ECDSA_P256_SHA256 {
179188
KeyPairKind::Ec(ecdsa_from_pkcs8(
180189
&signature::ECDSA_P256_SHA256_ASN1_SIGNING,
181-
pkcs8,
190+
&pkcs8_vec,
182191
rng,
183192
)?)
184193
} else if alg == &PKCS_ECDSA_P384_SHA384 {
185194
KeyPairKind::Ec(ecdsa_from_pkcs8(
186195
&signature::ECDSA_P384_SHA384_ASN1_SIGNING,
187-
pkcs8,
196+
&pkcs8_vec,
188197
rng,
189198
)?)
190199
} else if alg == &PKCS_RSA_SHA256 {
191-
let rsakp = RsaKeyPair::from_pkcs8(pkcs8)._err()?;
200+
let rsakp = RsaKeyPair::from_pkcs8(&pkcs8_vec)._err()?;
192201
KeyPairKind::Rsa(rsakp, &signature::RSA_PKCS1_SHA256)
193202
} else if alg == &PKCS_RSA_SHA384 {
194-
let rsakp = RsaKeyPair::from_pkcs8(pkcs8)._err()?;
203+
let rsakp = RsaKeyPair::from_pkcs8(&pkcs8_vec)._err()?;
195204
KeyPairKind::Rsa(rsakp, &signature::RSA_PKCS1_SHA384)
196205
} else if alg == &PKCS_RSA_SHA512 {
197-
let rsakp = RsaKeyPair::from_pkcs8(pkcs8)._err()?;
206+
let rsakp = RsaKeyPair::from_pkcs8(&pkcs8_vec)._err()?;
198207
KeyPairKind::Rsa(rsakp, &signature::RSA_PKCS1_SHA512)
199208
} else if alg == &PKCS_RSA_PSS_SHA256 {
200-
let rsakp = RsaKeyPair::from_pkcs8(pkcs8)._err()?;
209+
let rsakp = RsaKeyPair::from_pkcs8(&pkcs8_vec)._err()?;
201210
KeyPairKind::Rsa(rsakp, &signature::RSA_PSS_SHA256)
202211
} else {
203212
panic!("Unknown SignatureAlgorithm specified!");
@@ -212,8 +221,9 @@ impl KeyPair {
212221

213222
#[cfg(feature = "crypto")]
214223
pub(crate) fn from_raw(
215-
pkcs8: &[u8],
224+
pkcs8: &PrivatePkcs8KeyDer,
216225
) -> Result<(KeyPairKind, &'static SignatureAlgorithm), Error> {
226+
let pkcs8 = pkcs8.secret_pkcs8_der();
217227
let rng = SystemRandom::new();
218228
let (kind, alg) = if let Ok(edkp) = Ed25519KeyPair::from_pkcs8_maybe_unchecked(pkcs8) {
219229
(KeyPairKind::Ed(edkp), &PKCS_ED25519)
@@ -352,29 +362,18 @@ impl KeyPair {
352362
}
353363

354364
#[cfg(feature = "crypto")]
355-
impl TryFrom<&[u8]> for KeyPair {
356-
type Error = Error;
357-
358-
fn try_from(pkcs8: &[u8]) -> Result<KeyPair, Error> {
359-
let (kind, alg) = KeyPair::from_raw(pkcs8)?;
360-
Ok(KeyPair {
361-
kind,
362-
alg,
363-
serialized_der: pkcs8.to_vec(),
364-
})
365-
}
366-
}
367-
368-
#[cfg(feature = "crypto")]
369-
impl TryFrom<Vec<u8>> for KeyPair {
365+
impl TryFrom<PrivateKeyDer<'_>> for KeyPair {
370366
type Error = Error;
371367

372-
fn try_from(pkcs8: Vec<u8>) -> Result<KeyPair, Error> {
373-
let (kind, alg) = KeyPair::from_raw(pkcs8.as_slice())?;
368+
fn try_from(private_key: PrivateKeyDer) -> Result<KeyPair, Error> {
369+
let (kind, alg) = match &private_key {
370+
PrivateKeyDer::Pkcs8(private_key) => KeyPair::from_raw(private_key),
371+
_ => Err(Error::CouldNotParseKeyPair),
372+
}?;
374373
Ok(KeyPair {
375374
kind,
376375
alg,
377-
serialized_der: pkcs8,
376+
serialized_der: private_key.secret_der().to_vec(),
378377
})
379378
}
380379
}

rcgen/src/lib.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ println!("{}", key_pair.serialize_pem());
3535

3636
#[cfg(feature = "pem")]
3737
use pem::Pem;
38+
use pki_types::CertificateDer;
3839
#[cfg(feature = "crypto")]
3940
use ring_like::digest;
4041
use std::collections::HashMap;
@@ -83,7 +84,7 @@ pub struct CertifiedKey {
8384
pub struct Certificate {
8485
params: CertificateParams,
8586
subject_public_key_info: Vec<u8>,
86-
der: Vec<u8>,
87+
der: CertificateDer<'static>,
8788
}
8889

8990
/**
@@ -664,7 +665,7 @@ impl CertificateParams {
664665
#[cfg(all(feature = "pem", feature = "x509-parser"))]
665666
pub fn from_ca_cert_pem(pem_str: &str) -> Result<Self, Error> {
666667
let certificate = pem::parse(pem_str).or(Err(Error::CouldNotParseCertificate))?;
667-
Self::from_ca_cert_der(certificate.contents())
668+
Self::from_ca_cert_der(&CertificateDer::from(certificate.contents()))
668669
}
669670

670671
/// Parses an existing ca certificate from the DER format.
@@ -682,8 +683,8 @@ impl CertificateParams {
682683
/// for the presence of the `BasicConstraints` extension, or perform any other
683684
/// validation.
684685
#[cfg(feature = "x509-parser")]
685-
pub fn from_ca_cert_der(ca_cert: &[u8]) -> Result<Self, Error> {
686-
let (_remainder, x509) = x509_parser::parse_x509_certificate(ca_cert)
686+
pub fn from_ca_cert_der(ca_cert: &CertificateDer) -> Result<Self, Error> {
687+
let (_remainder, x509) = x509_parser::parse_x509_certificate(&ca_cert)
687688
.or(Err(Error::CouldNotParseCertificate))?;
688689

689690
let dn = DistinguishedName::from_name(&x509.tbs_certificate.subject)?;
@@ -1252,7 +1253,7 @@ impl CertificateParams {
12521253
pub_key: &K,
12531254
issuer: &KeyPair,
12541255
issuer_name: &DistinguishedName,
1255-
) -> Result<Vec<u8>, Error> {
1256+
) -> Result<CertificateDer<'static>, Error> {
12561257
yasna::try_construct_der(|writer| {
12571258
writer.write_sequence(|writer| {
12581259
let tbs_cert_list_serialized = yasna::try_construct_der(|writer| {
@@ -1271,6 +1272,7 @@ impl CertificateParams {
12711272
Ok(())
12721273
})
12731274
})
1275+
.map(CertificateDer::from)
12741276
}
12751277
}
12761278

@@ -1692,13 +1694,13 @@ impl Certificate {
16921694
.derive(&self.subject_public_key_info)
16931695
}
16941696
/// Get the certificate in DER encoded format.
1695-
pub fn der(&self) -> &[u8] {
1697+
pub fn der(&self) -> &CertificateDer {
16961698
&self.der
16971699
}
16981700
/// Get the certificate in PEM encoded format.
16991701
#[cfg(feature = "pem")]
17001702
pub fn pem(&self) -> String {
1701-
pem::encode_config(&Pem::new("CERTIFICATE", self.der()), ENCODE_CONFIG)
1703+
pem::encode_config(&Pem::new("CERTIFICATE", self.der().to_vec()), ENCODE_CONFIG)
17021704
}
17031705
/// Generate and serialize a certificate signing request (CSR) in binary DER format.
17041706
///

rcgen/tests/botan.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![cfg(all(feature = "crypto", feature = "x509-parser"))]
22

3+
use pki_types::CertificateDer;
34
use rcgen::{BasicConstraints, Certificate, CertificateParams, DnType, IsCa};
45
use rcgen::{
56
CertificateRevocationList, CertificateRevocationListParams, RevocationReason, RevokedCertParams,
@@ -17,12 +18,12 @@ fn default_params() -> (CertificateParams, KeyPair) {
1718
(params, key_pair)
1819
}
1920

20-
fn check_cert(cert_der: &[u8], cert: &Certificate) {
21+
fn check_cert(cert_der: &CertificateDer, cert: &Certificate) {
2122
println!("{}", cert.pem());
2223
check_cert_ca(cert_der, cert, cert_der);
2324
}
2425

25-
fn check_cert_ca(cert_der: &[u8], _cert: &Certificate, ca_der: &[u8]) {
26+
fn check_cert_ca(cert_der: &CertificateDer, _cert: &Certificate, ca_der: &CertificateDer) {
2627
println!(
2728
"botan version: {}",
2829
botan::Version::current().unwrap().string

rcgen/tests/webpki.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ fn sign_msg_rsa(key_pair: &KeyPair, msg: &[u8], encoding: &'static dyn RsaEncodi
5454
}
5555

5656
fn check_cert<'a, 'b>(
57-
cert_der: &[u8],
57+
cert_der: &CertificateDer,
5858
cert: &'a Certificate,
5959
cert_key: &'a KeyPair,
6060
alg: &dyn SignatureVerificationAlgorithm,
@@ -68,18 +68,16 @@ fn check_cert<'a, 'b>(
6868
}
6969

7070
fn check_cert_ca<'a, 'b>(
71-
cert_der: &[u8],
71+
cert_der: &CertificateDer,
7272
cert_key: &'a KeyPair,
73-
ca_der: &[u8],
73+
ca_der: &CertificateDer,
7474
cert_alg: &dyn SignatureVerificationAlgorithm,
7575
ca_alg: &dyn SignatureVerificationAlgorithm,
7676
sign_fn: impl FnOnce(&'a KeyPair, &'b [u8]) -> Vec<u8>,
7777
) {
78-
let ca_der = CertificateDer::from(ca_der);
79-
let trust_anchor = anchor_from_trusted_cert(&ca_der).unwrap();
78+
let trust_anchor = anchor_from_trusted_cert(ca_der).unwrap();
8079
let trust_anchor_list = &[trust_anchor];
81-
let cert_der = CertificateDer::from(cert_der);
82-
let end_entity_cert = EndEntityCert::try_from(&cert_der).unwrap();
80+
let end_entity_cert = EndEntityCert::try_from(cert_der).unwrap();
8381

8482
// Set time to Jan 10, 2004
8583
let time = UnixTime::since_unix_epoch(StdDuration::from_secs(0x40_00_00_00));
@@ -590,11 +588,9 @@ fn test_webpki_crl_revoke() {
590588
let ee = Certificate::generate(ee, &ee_key, &issuer, &issuer_key).unwrap();
591589

592590
// Set up webpki's verification requirements.
593-
let ca_der = CertificateDer::from(issuer.der());
594-
let trust_anchor = anchor_from_trusted_cert(&ca_der).unwrap();
591+
let trust_anchor = anchor_from_trusted_cert(issuer.der()).unwrap();
595592
let trust_anchor_list = &[trust_anchor];
596-
let ee_der = CertificateDer::from(ee.der());
597-
let end_entity_cert = EndEntityCert::try_from(&ee_der).unwrap();
593+
let end_entity_cert = EndEntityCert::try_from(ee.der()).unwrap();
598594
let unix_time = 0x40_00_00_00;
599595
let time = UnixTime::since_unix_epoch(StdDuration::from_secs(unix_time));
600596

rustls-cert-gen/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ bpaf = { version = "0.9.5", features = ["derive"] }
1212
pem = { workspace = true }
1313
ring = { workspace = true }
1414
rand = { workspace = true }
15+
pki-types = { workspace = true }
1516
anyhow = "1.0.75"
1617

1718
[dev-dependencies]

rustls-cert-gen/src/cert.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use bpaf::Bpaf;
2+
use pki_types::PrivatePkcs8KeyDer;
23
use rcgen::{
34
BasicConstraints, Certificate, CertificateParams, DistinguishedName, DnType,
45
DnValue::PrintableString, ExtendedKeyUsagePurpose, IsCa, KeyPair, KeyUsagePurpose, SanType,
@@ -232,8 +233,10 @@ impl KeyPairAlgorithm {
232233
let alg = &rcgen::PKCS_ED25519;
233234
let pkcs8_bytes =
234235
Ed25519KeyPair::generate_pkcs8(&rng).or(Err(rcgen::Error::RingUnspecified))?;
235-
236-
rcgen::KeyPair::from_der_and_sign_algo(pkcs8_bytes.as_ref(), alg)
236+
rcgen::KeyPair::from_der_and_sign_algo(
237+
PrivatePkcs8KeyDer::from(pkcs8_bytes.as_ref()),
238+
alg,
239+
)
237240
},
238241
KeyPairAlgorithm::EcdsaP256 => {
239242
use ring::signature::EcdsaKeyPair;
@@ -244,7 +247,10 @@ impl KeyPairAlgorithm {
244247
let pkcs8_bytes =
245248
EcdsaKeyPair::generate_pkcs8(&ECDSA_P256_SHA256_ASN1_SIGNING, &rng)
246249
.or(Err(rcgen::Error::RingUnspecified))?;
247-
rcgen::KeyPair::from_der_and_sign_algo(pkcs8_bytes.as_ref(), alg)
250+
rcgen::KeyPair::from_der_and_sign_algo(
251+
PrivatePkcs8KeyDer::from(pkcs8_bytes.as_ref()),
252+
alg,
253+
)
248254
},
249255
KeyPairAlgorithm::EcdsaP384 => {
250256
use ring::signature::EcdsaKeyPair;
@@ -256,7 +262,10 @@ impl KeyPairAlgorithm {
256262
EcdsaKeyPair::generate_pkcs8(&ECDSA_P384_SHA384_ASN1_SIGNING, &rng)
257263
.or(Err(rcgen::Error::RingUnspecified))?;
258264

259-
rcgen::KeyPair::from_der_and_sign_algo(pkcs8_bytes.as_ref(), alg)
265+
rcgen::KeyPair::from_der_and_sign_algo(
266+
PrivatePkcs8KeyDer::from(pkcs8_bytes.as_ref()),
267+
alg,
268+
)
260269
},
261270
}
262271
}

0 commit comments

Comments
 (0)