Skip to content

Commit 2dd3590

Browse files
committed
Invert KeyPair/SigningKey hierarchy
1 parent b491b28 commit 2dd3590

File tree

4 files changed

+21
-62
lines changed

4 files changed

+21
-62
lines changed

rcgen/src/certificate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ impl CertificateParams {
200200
///
201201
/// This function is only of use if you have an existing CA certificate
202202
/// you would like to use to sign a certificate generated by `rcgen`.
203-
/// By providing the constructed [`CertificateParams`] and the [`KeyPair`]
203+
/// By providing the constructed [`CertificateParams`] and the [`SigningKey`]
204204
/// associated with your existing `ca_cert` you can use [`CertificateParams::signed_by()`]
205205
/// or [`crate::CertificateSigningRequestParams::signed_by()`] to issue new certificates
206206
/// using the CA cert.

rcgen/src/key_pair.rs

Lines changed: 7 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#[cfg(feature = "crypto")]
12
use std::fmt;
23

34
#[cfg(feature = "pem")]
@@ -29,30 +30,23 @@ use crate::{sign_algo::SignatureAlgorithm, Error};
2930

3031
/// A key pair variant
3132
#[allow(clippy::large_enum_variant)]
33+
#[cfg(feature = "crypto")]
3234
pub(crate) enum KeyPairKind {
3335
/// A Ecdsa key pair
34-
#[cfg(feature = "crypto")]
3536
Ec(EcdsaKeyPair),
3637
/// A Ed25519 key pair
37-
#[cfg(feature = "crypto")]
3838
Ed(Ed25519KeyPair),
3939
/// A RSA key pair
40-
#[cfg(feature = "crypto")]
4140
Rsa(RsaKeyPair, &'static dyn RsaEncoding),
42-
/// A remote key pair
43-
Remote(Box<dyn SigningKey + Send + Sync>),
4441
}
4542

43+
#[cfg(feature = "crypto")]
4644
impl fmt::Debug for KeyPairKind {
4745
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4846
match self {
49-
#[cfg(feature = "crypto")]
5047
Self::Ec(key_pair) => write!(f, "{:?}", key_pair),
51-
#[cfg(feature = "crypto")]
5248
Self::Ed(key_pair) => write!(f, "{:?}", key_pair),
53-
#[cfg(feature = "crypto")]
5449
Self::Rsa(key_pair, _) => write!(f, "{:?}", key_pair),
55-
Self::Remote(_) => write!(f, "Box<dyn RemotePrivateKey>"),
5650
}
5751
}
5852
}
@@ -64,12 +58,14 @@ impl fmt::Debug for KeyPairKind {
6458
/// `openssl genrsa` doesn't work. See ring's [documentation](ring::signature::RsaKeyPair::from_pkcs8)
6559
/// for how to generate RSA keys in the wanted format
6660
/// and conversion between the formats.
61+
#[cfg(feature = "crypto")]
6762
pub struct KeyPair {
6863
pub(crate) kind: KeyPairKind,
6964
pub(crate) alg: &'static SignatureAlgorithm,
7065
pub(crate) serialized_der: Vec<u8>,
7166
}
7267

68+
#[cfg(feature = "crypto")]
7369
impl fmt::Debug for KeyPair {
7470
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7571
f.debug_struct("KeyPair")
@@ -80,6 +76,7 @@ impl fmt::Debug for KeyPair {
8076
}
8177
}
8278

79+
#[cfg(feature = "crypto")]
8380
impl KeyPair {
8481
/// Generate a new random [`PKCS_ECDSA_P256_SHA256`] key pair
8582
#[cfg(feature = "crypto")]
@@ -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
///
@@ -419,40 +407,16 @@ impl KeyPair {
419407
}
420408

421409
/// Serializes the key pair (including the private key) in PKCS#8 format in DER
422-
///
423-
/// Panics if called on a remote key pair.
424410
pub fn serialize_der(&self) -> Vec<u8> {
425-
#[cfg_attr(not(feature = "crypto"), allow(irrefutable_let_patterns))]
426-
if let KeyPairKind::Remote(_) = self.kind {
427-
panic!("Serializing a remote key pair is not supported")
428-
}
429-
430411
self.serialized_der.clone()
431412
}
432413

433414
/// Returns a reference to the serialized key pair (including the private key)
434415
/// in PKCS#8 format in DER
435-
///
436-
/// Panics if called on a remote key pair.
437416
pub fn serialized_der(&self) -> &[u8] {
438-
#[cfg_attr(not(feature = "crypto"), allow(irrefutable_let_patterns))]
439-
if let KeyPairKind::Remote(_) = self.kind {
440-
panic!("Serializing a remote key pair is not supported")
441-
}
442-
443417
&self.serialized_der
444418
}
445419

446-
/// Access the remote key pair if it is a remote one
447-
pub fn as_remote(&self) -> Option<&(dyn SigningKey + Send + Sync)> {
448-
#[cfg_attr(not(feature = "crypto"), allow(irrefutable_let_patterns))]
449-
if let KeyPairKind::Remote(remote) = &self.kind {
450-
Some(remote.as_ref())
451-
} else {
452-
None
453-
}
454-
}
455-
456420
/// Serializes the key pair (including the private key) in PKCS#8 format in PEM
457421
#[cfg(feature = "pem")]
458422
pub fn serialize_pem(&self) -> String {
@@ -479,21 +443,17 @@ impl SigningKey for KeyPair {
479443
._err()?;
480444
signature
481445
},
482-
KeyPairKind::Remote(kp) => kp.sign(msg)?,
483446
})
484447
}
485448
}
486449

450+
#[cfg(feature = "crypto")]
487451
impl PublicKeyData for KeyPair {
488452
fn der_bytes(&self) -> &[u8] {
489453
match &self.kind {
490-
#[cfg(feature = "crypto")]
491454
KeyPairKind::Ec(kp) => kp.public_key().as_ref(),
492-
#[cfg(feature = "crypto")]
493455
KeyPairKind::Ed(kp) => kp.public_key().as_ref(),
494-
#[cfg(feature = "crypto")]
495456
KeyPairKind::Rsa(kp, _) => kp.public_key().as_ref(),
496-
KeyPairKind::Remote(kp) => kp.der_bytes(),
497457
}
498458
}
499459

@@ -647,9 +607,6 @@ pub(crate) fn sign_der(
647607
}
648608

649609
/// A key that can be used to sign messages
650-
///
651-
/// Trait objects based on this trait can be passed to the [`KeyPair::from_remote`] function for generating certificates
652-
/// from a remote and raw private key, for example an HSM.
653610
pub trait SigningKey: PublicKeyData {
654611
/// Signs `msg` using the selected algorithm
655612
fn sign(&self, msg: &[u8]) -> Result<Vec<u8>, Error>;

rcgen/src/lib.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,12 @@ pub use crl::{
5959
};
6060
pub use csr::{CertificateSigningRequest, CertificateSigningRequestParams, PublicKey};
6161
pub use error::{Error, InvalidAsn1String};
62+
#[cfg(feature = "crypto")]
63+
pub use key_pair::KeyPair;
6264
pub use key_pair::PublicKeyData;
6365
#[cfg(all(feature = "crypto", feature = "aws_lc_rs"))]
6466
pub use key_pair::RsaKeySize;
65-
pub use key_pair::{KeyPair, SigningKey, SubjectPublicKeyInfo};
67+
pub use key_pair::{SigningKey, SubjectPublicKeyInfo};
6668
#[cfg(feature = "crypto")]
6769
use ring_like::digest;
6870
pub use sign_algo::algo::*;
@@ -85,11 +87,11 @@ pub mod string;
8587
pub type RcgenError = Error;
8688

8789
/// An issued certificate, together with the subject keypair.
88-
pub struct CertifiedKey {
90+
pub struct CertifiedKey<S: SigningKey> {
8991
/// An issued certificate.
9092
pub cert: Certificate,
9193
/// The certificate's subject key pair.
92-
pub key_pair: KeyPair,
94+
pub key_pair: S,
9395
}
9496

9597
/**
@@ -124,7 +126,7 @@ println!("{}", key_pair.serialize_pem());
124126
)]
125127
pub fn generate_simple_self_signed(
126128
subject_alt_names: impl Into<Vec<String>>,
127-
) -> Result<CertifiedKey, Error> {
129+
) -> Result<CertifiedKey<KeyPair>, Error> {
128130
let key_pair = KeyPair::generate()?;
129131
let cert = CertificateParams::new(subject_alt_names)?.self_signed(&key_pair)?;
130132
Ok(CertifiedKey { cert, key_pair })

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)