Skip to content

Commit db6b565

Browse files
committed
use pki types in function that parse der
1 parent 3c3e984 commit db6b565

File tree

11 files changed

+90
-59
lines changed

11 files changed

+90
-59
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
@@ -4,6 +4,7 @@ resolver = "2"
44

55
[workspace.dependencies]
66
pem = "3.0.2"
7+
pki-types = { package = "rustls-pki-types", version = "1.3.0" }
78
rand = "0.8"
89
ring = "0.17"
910
x509-parser = "0.15.1"

rcgen/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,26 +33,26 @@ 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

4747
[package.metadata.cargo_check_external_types]
4848
allowed_external_types = [
4949
"time::offset_date_time::OffsetDateTime",
50-
"zeroize::Zeroize"
50+
"zeroize::Zeroize",
51+
"rustls_pki_types::*"
5152
]
5253

5354
[dev-dependencies]
5455
openssl = "0.10"
55-
pki-types = { package = "rustls-pki-types", version = "1" }
5656
x509-parser = { workspace = true, features = ["verify"] }
5757
rustls-webpki = { version = "0.102", features = ["std"] }
5858
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
@@ -16,7 +16,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
1616
let bits = 2048;
1717
let private_key = RsaPrivateKey::new(&mut rng, bits)?;
1818
let private_key_der = private_key.to_pkcs8_der()?;
19-
let key_pair = rcgen::KeyPair::try_from(private_key_der.as_bytes()).unwrap();
19+
let key_pair = rcgen::KeyPair::from_der(&pki_types::PrivatePkcs8KeyDer::from(
20+
private_key_der.as_bytes(),
21+
))?;
2022

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

rcgen/src/csr.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#[cfg(feature = "x509-parser")]
22
use crate::{DistinguishedName, Error, SanType};
3+
#[cfg(feature = "x509-parser")]
4+
use pki_types::CertificateSigningRequestDer;
35
use std::hash::Hash;
46

57
use crate::{CertificateParams, PublicKeyData, SignatureAlgorithm};
@@ -36,17 +38,17 @@ impl CertificateSigningRequestParams {
3638
#[cfg(all(feature = "pem", feature = "x509-parser"))]
3739
pub fn from_pem(pem_str: &str) -> Result<Self, Error> {
3840
let csr = pem::parse(pem_str).or(Err(Error::CouldNotParseCertificationRequest))?;
39-
Self::from_der(csr.contents())
41+
Self::from_der(&csr.contents().into())
4042
}
4143

4244
/// Parse a certificate signing request from DER-encoded bytes
4345
///
4446
/// Currently, this only supports the `Subject Alternative Name` extension.
4547
/// On encountering other extensions, this function will return an error.
4648
#[cfg(feature = "x509-parser")]
47-
pub fn from_der(csr: &[u8]) -> Result<Self, Error> {
49+
pub fn from_der(csr: &CertificateSigningRequestDer<'_>) -> Result<Self, Error> {
4850
use x509_parser::prelude::FromDer;
49-
let csr = x509_parser::certification_request::X509CertificationRequest::from_der(csr)
51+
let csr = x509_parser::certification_request::X509CertificationRequest::from_der(&csr)
5052
.map_err(|_| Error::CouldNotParseCertificationRequest)?
5153
.1;
5254
csr.verify_signature().map_err(|_| Error::RingUnspecified)?;

rcgen/src/key_pair.rs

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#[cfg(feature = "pem")]
22
use pem::Pem;
3+
#[cfg(feature = "crypto")]
4+
use pki_types::PrivatePkcs8KeyDer;
35
use std::fmt;
46
use yasna::DERWriter;
57

@@ -114,8 +116,8 @@ impl KeyPair {
114116
///
115117
/// Equivalent to using the [`TryFrom`] implementation.
116118
#[cfg(feature = "crypto")]
117-
pub fn from_der(der: &[u8]) -> Result<Self, Error> {
118-
Ok(der.try_into()?)
119+
pub fn from_der(der: &PrivatePkcs8KeyDer<'_>) -> Result<Self, Error> {
120+
der.try_into()
119121
}
120122

121123
/// Returns the key pair's signature algorithm
@@ -124,11 +126,15 @@ impl KeyPair {
124126
}
125127

126128
/// Parses the key pair from the ASCII PEM format
129+
///
130+
/// The key must be a DER-encoded plaintext private key; as specified in PKCS #8/RFC 5958;
131+
///
132+
/// Appears as "PRIVATE KEY" in PEM files
127133
#[cfg(all(feature = "pem", feature = "crypto"))]
128134
pub fn from_pem(pem_str: &str) -> Result<Self, Error> {
129135
let private_key = pem::parse(pem_str)._err()?;
130136
let private_key_der: &[_] = private_key.contents();
131-
Ok(private_key_der.try_into()?)
137+
Self::from_der(&PrivatePkcs8KeyDer::from(private_key_der))
132138
}
133139

134140
/// Obtains the key pair from a raw public key and a remote private key
@@ -143,6 +149,9 @@ impl KeyPair {
143149
/// Obtains the key pair from a DER formatted key
144150
/// using the specified [`SignatureAlgorithm`]
145151
///
152+
/// The key must be a DER-encoded plaintext private key; as specified in PKCS #8/RFC 5958;
153+
///
154+
/// Appears as "PRIVATE KEY" in PEM files
146155
/// Same as [from_pem_and_sign_algo](Self::from_pem_and_sign_algo).
147156
#[cfg(all(feature = "pem", feature = "crypto"))]
148157
pub fn from_pem_and_sign_algo(
@@ -151,7 +160,10 @@ impl KeyPair {
151160
) -> Result<Self, Error> {
152161
let private_key = pem::parse(pem_str)._err()?;
153162
let private_key_der: &[_] = private_key.contents();
154-
Ok(Self::from_der_and_sign_algo(private_key_der, alg)?)
163+
Ok(Self::from_der_and_sign_algo(
164+
&PrivatePkcs8KeyDer::from(private_key_der),
165+
alg,
166+
)?)
155167
}
156168

157169
/// Obtains the key pair from a DER formatted key
@@ -165,37 +177,36 @@ impl KeyPair {
165177
/// specify the `SignatureAlgorithm`.
166178
#[cfg(feature = "crypto")]
167179
pub fn from_der_and_sign_algo(
168-
pkcs8: &[u8],
180+
der: &PrivatePkcs8KeyDer<'_>,
169181
alg: &'static SignatureAlgorithm,
170182
) -> Result<Self, Error> {
171183
let rng = &SystemRandom::new();
172-
let pkcs8_vec = pkcs8.to_vec();
173-
184+
let serialized_der = der.secret_pkcs8_der().to_vec();
174185
let kind = if alg == &PKCS_ED25519 {
175-
KeyPairKind::Ed(Ed25519KeyPair::from_pkcs8_maybe_unchecked(pkcs8)._err()?)
186+
KeyPairKind::Ed(Ed25519KeyPair::from_pkcs8_maybe_unchecked(&serialized_der)._err()?)
176187
} else if alg == &PKCS_ECDSA_P256_SHA256 {
177188
KeyPairKind::Ec(ecdsa_from_pkcs8(
178189
&signature::ECDSA_P256_SHA256_ASN1_SIGNING,
179-
pkcs8,
190+
&serialized_der,
180191
rng,
181192
)?)
182193
} else if alg == &PKCS_ECDSA_P384_SHA384 {
183194
KeyPairKind::Ec(ecdsa_from_pkcs8(
184195
&signature::ECDSA_P384_SHA384_ASN1_SIGNING,
185-
pkcs8,
196+
&serialized_der,
186197
rng,
187198
)?)
188199
} else if alg == &PKCS_RSA_SHA256 {
189-
let rsakp = RsaKeyPair::from_pkcs8(pkcs8)._err()?;
200+
let rsakp = RsaKeyPair::from_pkcs8(&serialized_der)._err()?;
190201
KeyPairKind::Rsa(rsakp, &signature::RSA_PKCS1_SHA256)
191202
} else if alg == &PKCS_RSA_SHA384 {
192-
let rsakp = RsaKeyPair::from_pkcs8(pkcs8)._err()?;
203+
let rsakp = RsaKeyPair::from_pkcs8(&serialized_der)._err()?;
193204
KeyPairKind::Rsa(rsakp, &signature::RSA_PKCS1_SHA384)
194205
} else if alg == &PKCS_RSA_SHA512 {
195-
let rsakp = RsaKeyPair::from_pkcs8(pkcs8)._err()?;
206+
let rsakp = RsaKeyPair::from_pkcs8(&serialized_der)._err()?;
196207
KeyPairKind::Rsa(rsakp, &signature::RSA_PKCS1_SHA512)
197208
} else if alg == &PKCS_RSA_PSS_SHA256 {
198-
let rsakp = RsaKeyPair::from_pkcs8(pkcs8)._err()?;
209+
let rsakp = RsaKeyPair::from_pkcs8(&serialized_der)._err()?;
199210
KeyPairKind::Rsa(rsakp, &signature::RSA_PSS_SHA256)
200211
} else {
201212
panic!("Unknown SignatureAlgorithm specified!");
@@ -204,14 +215,15 @@ impl KeyPair {
204215
Ok(KeyPair {
205216
kind,
206217
alg,
207-
serialized_der: pkcs8_vec,
218+
serialized_der,
208219
})
209220
}
210221

211222
#[cfg(feature = "crypto")]
212223
pub(crate) fn from_raw(
213-
pkcs8: &[u8],
224+
pkcs8: &PrivatePkcs8KeyDer,
214225
) -> Result<(KeyPairKind, &'static SignatureAlgorithm), Error> {
226+
let pkcs8 = pkcs8.secret_pkcs8_der();
215227
let rng = SystemRandom::new();
216228
let (kind, alg) = if let Ok(edkp) = Ed25519KeyPair::from_pkcs8_maybe_unchecked(pkcs8) {
217229
(KeyPairKind::Ed(edkp), &PKCS_ED25519)
@@ -350,29 +362,29 @@ impl KeyPair {
350362
}
351363

352364
#[cfg(feature = "crypto")]
353-
impl TryFrom<&[u8]> for KeyPair {
365+
impl TryFrom<&PrivatePkcs8KeyDer<'_>> for KeyPair {
354366
type Error = Error;
355367

356-
fn try_from(pkcs8: &[u8]) -> Result<KeyPair, Error> {
357-
let (kind, alg) = KeyPair::from_raw(pkcs8)?;
368+
fn try_from(private_key: &PrivatePkcs8KeyDer<'_>) -> Result<KeyPair, Error> {
369+
let (kind, alg) = KeyPair::from_raw(private_key)?;
358370
Ok(KeyPair {
359371
kind,
360372
alg,
361-
serialized_der: pkcs8.to_vec(),
373+
serialized_der: private_key.secret_pkcs8_der().into(),
362374
})
363375
}
364376
}
365377

366378
#[cfg(feature = "crypto")]
367-
impl TryFrom<Vec<u8>> for KeyPair {
379+
impl TryFrom<PrivatePkcs8KeyDer<'_>> for KeyPair {
368380
type Error = Error;
369381

370-
fn try_from(pkcs8: Vec<u8>) -> Result<KeyPair, Error> {
371-
let (kind, alg) = KeyPair::from_raw(pkcs8.as_slice())?;
382+
fn try_from(private_key: PrivatePkcs8KeyDer<'_>) -> Result<KeyPair, Error> {
383+
let (kind, alg) = KeyPair::from_raw(&private_key)?;
372384
Ok(KeyPair {
373385
kind,
374386
alg,
375-
serialized_der: pkcs8,
387+
serialized_der: private_key.secret_pkcs8_der().into(),
376388
})
377389
}
378390
}

rcgen/src/lib.rs

Lines changed: 15 additions & 9 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, CertificateSigningRequestDer};
3839
#[cfg(feature = "crypto")]
3940
use ring_like::digest;
4041
use std::collections::HashMap;
@@ -82,7 +83,7 @@ pub struct CertifiedKey {
8283
pub struct Certificate {
8384
params: CertificateParams,
8485
subject_public_key_info: Vec<u8>,
85-
der: Vec<u8>,
86+
der: CertificateDer<'static>,
8687
}
8788

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

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

688689
let dn = DistinguishedName::from_name(&x509.tbs_certificate.subject)?;
@@ -1251,7 +1252,7 @@ impl CertificateParams {
12511252
pub_key: &K,
12521253
issuer: &KeyPair,
12531254
issuer_name: &DistinguishedName,
1254-
) -> Result<Vec<u8>, Error> {
1255+
) -> Result<CertificateDer<'static>, Error> {
12551256
yasna::try_construct_der(|writer| {
12561257
writer.write_sequence(|writer| {
12571258
let tbs_cert_list_serialized = yasna::try_construct_der(|writer| {
@@ -1270,6 +1271,7 @@ impl CertificateParams {
12701271
Ok(())
12711272
})
12721273
})
1274+
.map(CertificateDer::from)
12731275
}
12741276
}
12751277

@@ -1691,13 +1693,13 @@ impl Certificate {
16911693
.derive(&self.subject_public_key_info)
16921694
}
16931695
/// Get the certificate in DER encoded format.
1694-
pub fn der(&self) -> &[u8] {
1696+
pub fn der(&self) -> &CertificateDer<'static> {
16951697
&self.der
16961698
}
16971699
/// Get the certificate in PEM encoded format.
16981700
#[cfg(feature = "pem")]
16991701
pub fn pem(&self) -> String {
1700-
pem::encode_config(&Pem::new("CERTIFICATE", self.der()), ENCODE_CONFIG)
1702+
pem::encode_config(&Pem::new("CERTIFICATE", self.der().to_vec()), ENCODE_CONFIG)
17011703
}
17021704
/// Generate and serialize a certificate signing request (CSR) in binary DER format.
17031705
///
@@ -1709,7 +1711,10 @@ impl Certificate {
17091711
/// should not call `serialize_request_der` and then `serialize_request_pem`. This will
17101712
/// result in two different CSRs. Instead call only `serialize_request_pem` and base64
17111713
/// decode the inner content to get the DER encoded CSR using a library like `pem`.
1712-
pub fn serialize_request_der(&self, subject_key: &KeyPair) -> Result<Vec<u8>, Error> {
1714+
pub fn serialize_request_der(
1715+
&self,
1716+
subject_key: &KeyPair,
1717+
) -> Result<CertificateSigningRequestDer<'static>, Error> {
17131718
yasna::try_construct_der(|writer| {
17141719
writer.write_sequence(|writer| {
17151720
let cert_data = yasna::try_construct_der(|writer| {
@@ -1726,6 +1731,7 @@ impl Certificate {
17261731
Ok(())
17271732
})
17281733
})
1734+
.map(CertificateSigningRequestDer::from)
17291735
}
17301736
/// Generate and serialize a certificate signing request (CSR) in binary DER format.
17311737
///
@@ -1740,7 +1746,7 @@ impl Certificate {
17401746
#[cfg(feature = "pem")]
17411747
pub fn serialize_request_pem(&self, subject_key: &KeyPair) -> Result<String, Error> {
17421748
let contents = self.serialize_request_der(subject_key)?;
1743-
let p = Pem::new("CERTIFICATE REQUEST", contents);
1749+
let p = Pem::new("CERTIFICATE REQUEST", contents.to_vec());
17441750
Ok(pem::encode_config(&p, ENCODE_CONFIG))
17451751
}
17461752
}

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

0 commit comments

Comments
 (0)