Skip to content

Commit 5233f51

Browse files
committed
Invert KeyPair/SigningKey hierarchy
1 parent c247eef commit 5233f51

File tree

4 files changed

+21
-58
lines changed

4 files changed

+21
-58
lines changed

rcgen/src/certificate.rs

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

rcgen/src/key_pair.rs

Lines changed: 7 additions & 46 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
///
@@ -422,11 +410,6 @@ impl KeyPair {
422410
///
423411
/// Panics if called on a remote key pair.
424412
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-
430413
self.serialized_der.clone()
431414
}
432415

@@ -435,24 +418,9 @@ impl KeyPair {
435418
///
436419
/// Panics if called on a remote key pair.
437420
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-
443421
&self.serialized_der
444422
}
445423

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-
456424
/// Serializes the key pair (including the private key) in PKCS#8 format in PEM
457425
#[cfg(feature = "pem")]
458426
pub fn serialize_pem(&self) -> String {
@@ -479,21 +447,17 @@ impl SigningKey for KeyPair {
479447
._err()?;
480448
signature
481449
},
482-
KeyPairKind::Remote(kp) => kp.sign(msg)?,
483450
})
484451
}
485452
}
486453

454+
#[cfg(feature = "crypto")]
487455
impl PublicKeyData for KeyPair {
488456
fn der_bytes(&self) -> &[u8] {
489457
match &self.kind {
490-
#[cfg(feature = "crypto")]
491458
KeyPairKind::Ec(kp) => kp.public_key().as_ref(),
492-
#[cfg(feature = "crypto")]
493459
KeyPairKind::Ed(kp) => kp.public_key().as_ref(),
494-
#[cfg(feature = "crypto")]
495460
KeyPairKind::Rsa(kp, _) => kp.public_key().as_ref(),
496-
KeyPairKind::Remote(kp) => kp.der_bytes(),
497461
}
498462
}
499463

@@ -647,9 +611,6 @@ pub(crate) fn sign_der(
647611
}
648612

649613
/// A private key that is not directly accessible, but 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.
653614
pub trait SigningKey: PublicKeyData {
654615
/// Signs `msg` using the selected algorithm
655616
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
@@ -57,10 +57,12 @@ pub use crl::{
5757
};
5858
pub use csr::{CertificateSigningRequest, CertificateSigningRequestParams, PublicKey};
5959
pub use error::{Error, InvalidAsn1String};
60+
#[cfg(feature = "crypto")]
61+
pub use key_pair::KeyPair;
6062
pub use key_pair::PublicKeyData;
6163
#[cfg(all(feature = "crypto", feature = "aws_lc_rs"))]
6264
pub use key_pair::RsaKeySize;
63-
pub use key_pair::{KeyPair, SigningKey, SubjectPublicKeyInfo};
65+
pub use key_pair::{SigningKey, SubjectPublicKeyInfo};
6466
#[cfg(feature = "crypto")]
6567
use ring_like::digest;
6668
pub use sign_algo::algo::*;
@@ -84,11 +86,11 @@ mod string_types;
8486
pub type RcgenError = Error;
8587

8688
/// An issued certificate, together with the subject keypair.
87-
pub struct CertifiedKey {
89+
pub struct CertifiedKey<S: SigningKey> {
8890
/// An issued certificate.
8991
pub cert: Certificate,
9092
/// The certificate's subject key pair.
91-
pub key_pair: KeyPair,
93+
pub key_pair: S,
9294
}
9395

9496
/**
@@ -123,7 +125,7 @@ println!("{}", key_pair.serialize_pem());
123125
)]
124126
pub fn generate_simple_self_signed(
125127
subject_alt_names: impl Into<Vec<String>>,
126-
) -> Result<CertifiedKey, Error> {
128+
) -> Result<CertifiedKey<KeyPair>, Error> {
127129
let key_pair = KeyPair::generate()?;
128130
let cert = CertificateParams::new(subject_alt_names)?.self_signed(&key_pair)?;
129131
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)