Skip to content

Commit c85822e

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

File tree

7 files changed

+75
-45
lines changed

7 files changed

+75
-45
lines changed

Cargo.lock

+14-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ 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" }
11+
rustls-pemfile = "2"
1012

1113
[workspace.package]
1214
license = "MIT OR Apache-2.0"

rcgen/Cargo.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,15 @@ 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 }
37+
rustls-pemfile = { workspace = true, optional = true }
3638

3739
[features]
3840
default = ["crypto", "pem", "ring"]
3941
crypto = []
4042
aws_lc_rs = ["crypto", "dep:aws-lc-rs"]
4143
ring = ["crypto", "dep:ring"]
44+
pem = ["dep:rustls-pemfile", "dep:pem"]
4245

4346

4447
[package.metadata.docs.rs]
@@ -52,7 +55,6 @@ allowed_external_types = [
5255

5356
[dev-dependencies]
5457
openssl = "0.10"
55-
pki-types = { package = "rustls-pki-types", version = "1" }
5658
x509-parser = { workspace = true, features = ["verify"] }
5759
rustls-webpki = { version = "0.102", features = ["std"] }
5860
botan = { version = "0.10", features = ["vendored"] }

rcgen/examples/rsa-irc.rs

+3-1
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

+39-37
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
@@ -128,9 +130,12 @@ impl KeyPair {
128130
/// Parses the key pair from the ASCII PEM format
129131
#[cfg(all(feature = "pem", feature = "crypto"))]
130132
pub fn from_pem(pem_str: &str) -> Result<Self, Error> {
131-
let private_key = pem::parse(pem_str)._err()?;
132-
let private_key_der: &[_] = private_key.contents();
133-
Ok(private_key_der.try_into()?)
133+
let mut reader = std::io::BufReader::new(pem_str.as_bytes());
134+
let private_key = rustls_pemfile::private_key(&mut reader)
135+
.ok()
136+
.flatten()
137+
.ok_or_else(|| Error::CouldNotParseKeyPair)?;
138+
private_key.try_into()
134139
}
135140

136141
/// Obtains the key pair from a raw public key and a remote private key
@@ -151,9 +156,12 @@ impl KeyPair {
151156
pem_str: &str,
152157
alg: &'static SignatureAlgorithm,
153158
) -> Result<Self, Error> {
154-
let private_key = pem::parse(pem_str)._err()?;
155-
let private_key_der: &[_] = private_key.contents();
156-
Ok(Self::from_der_and_sign_algo(private_key_der, alg)?)
159+
let mut reader = std::io::BufReader::new(pem_str.as_bytes());
160+
let private_key = rustls_pemfile::private_key(&mut reader)
161+
.ok()
162+
.flatten()
163+
.ok_or_else(|| Error::CouldNotParseKeyPair)?;
164+
Ok(Self::from_der_and_sign_algo(private_key, alg)?)
157165
}
158166

159167
/// Obtains the key pair from a DER formatted key
@@ -166,38 +174,42 @@ impl KeyPair {
166174
/// same der key. In that instance, you can use this function to precisely
167175
/// specify the `SignatureAlgorithm`.
168176
#[cfg(feature = "crypto")]
169-
pub fn from_der_and_sign_algo(
170-
pkcs8: &[u8],
177+
pub fn from_der_and_sign_algo<'a>(
178+
der: impl Into<PrivateKeyDer<'a>>,
171179
alg: &'static SignatureAlgorithm,
172180
) -> Result<Self, Error> {
173181
let rng = &SystemRandom::new();
174-
let pkcs8_vec = pkcs8.to_vec();
182+
let pkcs8_vec = match &der.into() {
183+
PrivateKeyDer::Pkcs8(private_key) => Ok(private_key.secret_pkcs8_der()),
184+
_ => Err(Error::CouldNotParseKeyPair),
185+
}?
186+
.to_vec();
175187

176188
let kind = if alg == &PKCS_ED25519 {
177-
KeyPairKind::Ed(Ed25519KeyPair::from_pkcs8_maybe_unchecked(pkcs8)._err()?)
189+
KeyPairKind::Ed(Ed25519KeyPair::from_pkcs8_maybe_unchecked(&pkcs8_vec)._err()?)
178190
} else if alg == &PKCS_ECDSA_P256_SHA256 {
179191
KeyPairKind::Ec(ecdsa_from_pkcs8(
180192
&signature::ECDSA_P256_SHA256_ASN1_SIGNING,
181-
pkcs8,
193+
&pkcs8_vec,
182194
rng,
183195
)?)
184196
} else if alg == &PKCS_ECDSA_P384_SHA384 {
185197
KeyPairKind::Ec(ecdsa_from_pkcs8(
186198
&signature::ECDSA_P384_SHA384_ASN1_SIGNING,
187-
pkcs8,
199+
&pkcs8_vec,
188200
rng,
189201
)?)
190202
} else if alg == &PKCS_RSA_SHA256 {
191-
let rsakp = RsaKeyPair::from_pkcs8(pkcs8)._err()?;
203+
let rsakp = RsaKeyPair::from_pkcs8(&pkcs8_vec)._err()?;
192204
KeyPairKind::Rsa(rsakp, &signature::RSA_PKCS1_SHA256)
193205
} else if alg == &PKCS_RSA_SHA384 {
194-
let rsakp = RsaKeyPair::from_pkcs8(pkcs8)._err()?;
206+
let rsakp = RsaKeyPair::from_pkcs8(&pkcs8_vec)._err()?;
195207
KeyPairKind::Rsa(rsakp, &signature::RSA_PKCS1_SHA384)
196208
} else if alg == &PKCS_RSA_SHA512 {
197-
let rsakp = RsaKeyPair::from_pkcs8(pkcs8)._err()?;
209+
let rsakp = RsaKeyPair::from_pkcs8(&pkcs8_vec)._err()?;
198210
KeyPairKind::Rsa(rsakp, &signature::RSA_PKCS1_SHA512)
199211
} else if alg == &PKCS_RSA_PSS_SHA256 {
200-
let rsakp = RsaKeyPair::from_pkcs8(pkcs8)._err()?;
212+
let rsakp = RsaKeyPair::from_pkcs8(&pkcs8_vec)._err()?;
201213
KeyPairKind::Rsa(rsakp, &signature::RSA_PSS_SHA256)
202214
} else {
203215
panic!("Unknown SignatureAlgorithm specified!");
@@ -212,8 +224,9 @@ impl KeyPair {
212224

213225
#[cfg(feature = "crypto")]
214226
pub(crate) fn from_raw(
215-
pkcs8: &[u8],
227+
pkcs8: &PrivatePkcs8KeyDer,
216228
) -> Result<(KeyPairKind, &'static SignatureAlgorithm), Error> {
229+
let pkcs8 = pkcs8.secret_pkcs8_der();
217230
let rng = SystemRandom::new();
218231
let (kind, alg) = if let Ok(edkp) = Ed25519KeyPair::from_pkcs8_maybe_unchecked(pkcs8) {
219232
(KeyPairKind::Ed(edkp), &PKCS_ED25519)
@@ -352,29 +365,18 @@ impl KeyPair {
352365
}
353366

354367
#[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 {
368+
impl TryFrom<PrivateKeyDer<'_>> for KeyPair {
370369
type Error = Error;
371370

372-
fn try_from(pkcs8: Vec<u8>) -> Result<KeyPair, Error> {
373-
let (kind, alg) = KeyPair::from_raw(pkcs8.as_slice())?;
371+
fn try_from(private_key: PrivateKeyDer) -> Result<KeyPair, Error> {
372+
let (kind, alg) = match &private_key {
373+
PrivateKeyDer::Pkcs8(private_key) => KeyPair::from_raw(private_key),
374+
_ => Err(Error::CouldNotParseKeyPair),
375+
}?;
374376
Ok(KeyPair {
375377
kind,
376378
alg,
377-
serialized_der: pkcs8,
379+
serialized_der: private_key.secret_der().to_vec(),
378380
})
379381
}
380382
}

rustls-cert-gen/Cargo.toml

+1
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

+13-4
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)