Skip to content

Commit 275a576

Browse files
committed
Invert KeyPair/SigningKey hierarchy
1 parent 1dd6a29 commit 275a576

File tree

5 files changed

+46
-85
lines changed

5 files changed

+46
-85
lines changed

rcgen/src/certificate.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::ENCODE_CONFIG;
1818
use crate::{
1919
oid, write_distinguished_name, write_dt_utc_or_generalized,
2020
write_x509_authority_key_identifier, write_x509_extension, DistinguishedName, Error, Issuer,
21-
KeyIdMethod, KeyPair, KeyUsagePurpose, SanType, SerialNumber,
21+
KeyIdMethod, KeyPair, KeyUsagePurpose, SanType, SerialNumber, SigningKey,
2222
};
2323

2424
/// An issued certificate together with the parameters used to generate it.
@@ -158,7 +158,7 @@ impl CertificateParams {
158158
///
159159
/// The returned [`Certificate`] may be serialized using [`Certificate::der`] and
160160
/// [`Certificate::pem`].
161-
pub fn self_signed(&self, key_pair: &KeyPair) -> Result<Certificate, Error> {
161+
pub fn self_signed(&self, key_pair: &impl SigningKey) -> Result<Certificate, Error> {
162162
let issuer = Issuer {
163163
distinguished_name: &self.distinguished_name,
164164
key_identifier_method: &self.key_identifier_method,
@@ -616,9 +616,9 @@ impl CertificateParams {
616616
pub(crate) fn serialize_der_with_signer<K: PublicKeyData>(
617617
&self,
618618
pub_key: &K,
619-
issuer: Issuer<'_>,
619+
issuer: Issuer<'_, impl SigningKey>,
620620
) -> Result<CertificateDer<'static>, Error> {
621-
let der = sign_der(&issuer.key_pair, |writer| {
621+
let der = sign_der(issuer.key_pair, |writer| {
622622
let pub_key_spki =
623623
yasna::construct_der(|writer| serialize_public_key_der(pub_key, writer));
624624
// Write version
@@ -643,7 +643,7 @@ impl CertificateParams {
643643
}
644644
};
645645
// Write signature algorithm
646-
issuer.key_pair.alg.write_alg_ident(writer.next());
646+
issuer.key_pair.algorithm().write_alg_ident(writer.next());
647647
// Write issuer name
648648
write_distinguished_name(writer.next(), &issuer.distinguished_name);
649649
// Write validity

rcgen/src/crl.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use yasna::Tag;
77

88
use crate::key_pair::sign_der;
99
use crate::CertificateParams;
10+
use crate::SigningKey;
1011
#[cfg(feature = "pem")]
1112
use crate::ENCODE_CONFIG;
1213
use crate::{
@@ -216,8 +217,8 @@ impl CertificateRevocationListParams {
216217
})
217218
}
218219

219-
fn serialize_der(&self, issuer: Issuer) -> Result<Vec<u8>, Error> {
220-
sign_der(&issuer.key_pair, |writer| {
220+
fn serialize_der(&self, issuer: Issuer<'_, impl SigningKey>) -> Result<Vec<u8>, Error> {
221+
sign_der(issuer.key_pair, |writer| {
221222
// Write CRL version.
222223
// RFC 5280 §5.1.2.1:
223224
// This optional field describes the version of the encoded CRL. When
@@ -233,7 +234,7 @@ impl CertificateRevocationListParams {
233234
// RFC 5280 §5.1.2.2:
234235
// This field MUST contain the same algorithm identifier as the
235236
// signatureAlgorithm field in the sequence CertificateList
236-
issuer.key_pair.alg.write_alg_ident(writer.next());
237+
issuer.key_pair.algorithm().write_alg_ident(writer.next());
237238

238239
// Write issuer.
239240
// RFC 5280 §5.1.2.3:

rcgen/src/key_pair.rs

Lines changed: 28 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ pub(crate) enum KeyPairKind {
3939
/// A RSA key pair
4040
#[cfg(feature = "crypto")]
4141
Rsa(RsaKeyPair, &'static dyn RsaEncoding),
42-
/// A remote key pair
43-
Remote(Box<dyn SigningKey + Send + Sync>),
4442
}
4543

4644
impl fmt::Debug for KeyPairKind {
@@ -52,7 +50,6 @@ impl fmt::Debug for KeyPairKind {
5250
Self::Ed(key_pair) => write!(f, "{:?}", key_pair),
5351
#[cfg(feature = "crypto")]
5452
Self::Rsa(key_pair, _) => write!(f, "{:?}", key_pair),
55-
Self::Remote(_) => write!(f, "Box<dyn RemotePrivateKey>"),
5653
}
5754
}
5855
}
@@ -187,15 +184,6 @@ impl KeyPair {
187184
Self::try_from(private_key.contents())
188185
}
189186

190-
/// Obtains the key pair from a raw public key and a remote private key
191-
pub fn from_remote(key_pair: Box<dyn SigningKey + Send + Sync>) -> Result<Self, Error> {
192-
Ok(Self {
193-
alg: key_pair.algorithm(),
194-
kind: KeyPairKind::Remote(key_pair),
195-
serialized_der: Vec::new(),
196-
})
197-
}
198-
199187
/// Obtains the key pair from a DER formatted key
200188
/// using the specified [`SignatureAlgorithm`]
201189
///
@@ -399,38 +387,6 @@ impl KeyPair {
399387
std::iter::once(self.alg)
400388
}
401389

402-
pub(crate) fn sign(&self, msg: &[u8], writer: DERWriter) -> Result<(), Error> {
403-
match &self.kind {
404-
#[cfg(feature = "crypto")]
405-
KeyPairKind::Ec(kp) => {
406-
let system_random = SystemRandom::new();
407-
let signature = kp.sign(&system_random, msg)._err()?;
408-
let sig = &signature.as_ref();
409-
writer.write_bitvec_bytes(sig, &sig.len() * 8);
410-
},
411-
#[cfg(feature = "crypto")]
412-
KeyPairKind::Ed(kp) => {
413-
let signature = kp.sign(msg);
414-
let sig = &signature.as_ref();
415-
writer.write_bitvec_bytes(sig, &sig.len() * 8);
416-
},
417-
#[cfg(feature = "crypto")]
418-
KeyPairKind::Rsa(kp, padding_alg) => {
419-
let system_random = SystemRandom::new();
420-
let mut signature = vec![0; rsa_key_pair_public_modulus_len(kp)];
421-
kp.sign(*padding_alg, &system_random, msg, &mut signature)
422-
._err()?;
423-
let sig = &signature.as_ref();
424-
writer.write_bitvec_bytes(sig, &sig.len() * 8);
425-
},
426-
KeyPairKind::Remote(kp) => {
427-
let signature = kp.sign(msg)?;
428-
writer.write_bitvec_bytes(&signature, &signature.len() * 8);
429-
},
430-
}
431-
Ok(())
432-
}
433-
434390
/// Return the key pair's public key in DER format
435391
///
436392
/// The key is formatted according to the SubjectPublicKeyInfo struct of
@@ -454,11 +410,6 @@ impl KeyPair {
454410
///
455411
/// Panics if called on a remote key pair.
456412
pub fn serialize_der(&self) -> Vec<u8> {
457-
#[cfg_attr(not(feature = "crypto"), allow(irrefutable_let_patterns))]
458-
if let KeyPairKind::Remote(_) = self.kind {
459-
panic!("Serializing a remote key pair is not supported")
460-
}
461-
462413
self.serialized_der.clone()
463414
}
464415

@@ -467,24 +418,9 @@ impl KeyPair {
467418
///
468419
/// Panics if called on a remote key pair.
469420
pub fn serialized_der(&self) -> &[u8] {
470-
#[cfg_attr(not(feature = "crypto"), allow(irrefutable_let_patterns))]
471-
if let KeyPairKind::Remote(_) = self.kind {
472-
panic!("Serializing a remote key pair is not supported")
473-
}
474-
475421
&self.serialized_der
476422
}
477423

478-
/// Access the remote key pair if it is a remote one
479-
pub fn as_remote(&self) -> Option<&(dyn SigningKey + Send + Sync)> {
480-
#[cfg_attr(not(feature = "crypto"), allow(irrefutable_let_patterns))]
481-
if let KeyPairKind::Remote(remote) = &self.kind {
482-
Some(remote.as_ref())
483-
} else {
484-
None
485-
}
486-
}
487-
488424
/// Serializes the key pair (including the private key) in PKCS#8 format in PEM
489425
#[cfg(feature = "pem")]
490426
pub fn serialize_pem(&self) -> String {
@@ -494,6 +430,29 @@ impl KeyPair {
494430
}
495431
}
496432

433+
impl SigningKey for KeyPair {
434+
fn sign(&self, msg: &[u8]) -> Result<Vec<u8>, Error> {
435+
Ok(match &self.kind {
436+
#[cfg(feature = "crypto")]
437+
KeyPairKind::Ec(kp) => {
438+
let system_random = SystemRandom::new();
439+
let signature = kp.sign(&system_random, msg)._err()?;
440+
signature.as_ref().to_owned()
441+
},
442+
#[cfg(feature = "crypto")]
443+
KeyPairKind::Ed(kp) => kp.sign(msg).as_ref().to_owned(),
444+
#[cfg(feature = "crypto")]
445+
KeyPairKind::Rsa(kp, padding_alg) => {
446+
let system_random = SystemRandom::new();
447+
let mut signature = vec![0; rsa_key_pair_public_modulus_len(kp)];
448+
kp.sign(*padding_alg, &system_random, msg, &mut signature)
449+
._err()?;
450+
signature
451+
},
452+
})
453+
}
454+
}
455+
497456
impl PublicKeyData for KeyPair {
498457
fn public_key_der(&self) -> &[u8] {
499458
match &self.kind {
@@ -503,7 +462,6 @@ impl PublicKeyData for KeyPair {
503462
KeyPairKind::Ed(kp) => kp.public_key().as_ref(),
504463
#[cfg(feature = "crypto")]
505464
KeyPairKind::Rsa(kp, _) => kp.public_key().as_ref(),
506-
KeyPairKind::Remote(kp) => kp.public_key_der(),
507465
}
508466
}
509467

@@ -635,7 +593,7 @@ pub enum RsaKeySize {
635593
}
636594

637595
pub(crate) fn sign_der(
638-
key: &KeyPair,
596+
key: &impl SigningKey,
639597
f: impl FnOnce(&mut DERWriterSeq<'_>) -> Result<(), Error>,
640598
) -> Result<Vec<u8>, Error> {
641599
yasna::try_construct_der(|writer| {
@@ -644,10 +602,12 @@ pub(crate) fn sign_der(
644602
writer.next().write_der(&data);
645603

646604
// Write signatureAlgorithm
647-
key.alg.write_alg_ident(writer.next());
605+
key.algorithm().write_alg_ident(writer.next());
648606

649607
// Write signature
650-
key.sign(&data, writer.next())?;
608+
let sig = key.sign(&data)?;
609+
let writer = writer.next();
610+
writer.write_bitvec_bytes(&sig, sig.len() * 8);
651611

652612
Ok(())
653613
})

rcgen/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,11 @@ pub fn generate_simple_self_signed(
129129
Ok(CertifiedKey { cert, key_pair })
130130
}
131131

132-
struct Issuer<'a> {
132+
struct Issuer<'a, S> {
133133
distinguished_name: &'a DistinguishedName,
134134
key_identifier_method: &'a KeyIdMethod,
135135
key_usages: &'a [KeyUsagePurpose],
136-
key_pair: &'a KeyPair,
136+
key_pair: &'a S,
137137
}
138138

139139
// https://tools.ietf.org/html/rfc5280#section-4.1.1

rcgen/tests/webpki.rs

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

55-
fn check_cert<'a, 'b>(
55+
fn check_cert<'a, 'b, S: SigningKey + 'a>(
5656
cert_der: &CertificateDer<'_>,
5757
cert: &'a Certificate,
58-
cert_key: &'a KeyPair,
58+
cert_key: &'a S,
5959
alg: &dyn SignatureVerificationAlgorithm,
60-
sign_fn: impl FnOnce(&'a KeyPair, &'b [u8]) -> Vec<u8>,
60+
sign_fn: impl FnOnce(&'a S, &'b [u8]) -> Vec<u8>,
6161
) {
6262
#[cfg(feature = "pem")]
6363
{
@@ -66,13 +66,13 @@ fn check_cert<'a, 'b>(
6666
check_cert_ca(cert_der, cert_key, cert_der, alg, alg, sign_fn);
6767
}
6868

69-
fn check_cert_ca<'a, 'b>(
69+
fn check_cert_ca<'a, 'b, S: SigningKey + 'a>(
7070
cert_der: &CertificateDer<'_>,
71-
cert_key: &'a KeyPair,
71+
cert_key: &'a S,
7272
ca_der: &CertificateDer<'_>,
7373
cert_alg: &dyn SignatureVerificationAlgorithm,
7474
ca_alg: &dyn SignatureVerificationAlgorithm,
75-
sign_fn: impl FnOnce(&'a KeyPair, &'b [u8]) -> Vec<u8>,
75+
sign_fn: impl FnOnce(&'a S, &'b [u8]) -> Vec<u8>,
7676
) {
7777
let trust_anchor = anchor_from_trusted_cert(ca_der).unwrap();
7878
let trust_anchor_list = &[trust_anchor];
@@ -352,7 +352,7 @@ fn from_remote() {
352352
&rng,
353353
)
354354
.unwrap();
355-
let remote = KeyPair::from_remote(Box::new(Remote(remote))).unwrap();
355+
let remote = Remote(remote);
356356

357357
let (params, _) = util::default_params();
358358
let cert = params.self_signed(&remote).unwrap();

0 commit comments

Comments
 (0)