Skip to content

Commit

Permalink
Bump to ring 0.17
Browse files Browse the repository at this point in the history
  • Loading branch information
thomaseizinger committed Oct 3, 2023
1 parent b1fd2cb commit a2d126e
Show file tree
Hide file tree
Showing 11 changed files with 220 additions and 49 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
Errors are usually not comparable.
Use `matches!` instead.
- Remove `TryFrom<[u8]>` and `TryFrom<Vec<u8>>` for `KeyPair` in favor of allowing `KeyPair::from_der` to take `impl Into<Cow<'b, [u8]>>` which allows `Vec<u8>` as well as `[u8]`.
- Upgrade to `ring` `v0.17`.
- Add `ring::rand::SecureRandom` parameter to:
- `KeyPair::generate`
- `KeyPair::from_der`
- `KeyPair::from_der_and_sign_algo`
- `KeyPair::from_pem`
- `KeyPair::from_pem_and_sign_algo`

## Release 0.11.3 - October 1, 2023

Expand Down
106 changes: 99 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ required-features = ["pem"]

[dependencies]
yasna = { version = "0.5.2", features = ["time", "std"] }
ring = "0.16"
ring = "0.17"
pem = { version = "3.0.2", optional = true }
time = { version = "0.3.6", default-features = false }
x509-parser = { version = "0.15", features = ["verify"], optional = true }
Expand Down
2 changes: 1 addition & 1 deletion examples/rsa-irc-openssl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {

let pkey: openssl::pkey::PKey<_> = openssl::rsa::Rsa::generate(2048)?.try_into()?;
let key_pair_pem = String::from_utf8(pkey.private_key_to_pem_pkcs8()?)?;
let key_pair = rcgen::KeyPair::from_pem(&key_pair_pem)?;
let key_pair = rcgen::KeyPair::from_pem(&key_pair_pem, &ring::rand::SystemRandom::new())?;
params.key_pair = Some(key_pair);

let cert = Certificate::from_params(params)?;
Expand Down
4 changes: 3 additions & 1 deletion examples/rsa-irc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let bits = 2048;
let private_key = RsaPrivateKey::new(&mut rng, bits)?;
let private_key_der = private_key.to_pkcs8_der()?;
let key_pair = rcgen::KeyPair::from_der(private_key_der.as_bytes()).unwrap();
let key_pair =
rcgen::KeyPair::from_der(private_key_der.as_bytes(), &ring::rand::SystemRandom::new())
.unwrap();
params.key_pair = Some(key_pair);

let cert = Certificate::from_params(params)?;
Expand Down
41 changes: 25 additions & 16 deletions src/key_pair.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#[cfg(feature = "pem")]
use pem::Pem;
use ring::rand::SystemRandom;
use ring::rand::{SecureRandom, SystemRandom};
use ring::signature::KeyPair as RingKeyPair;
use ring::signature::{self, EcdsaKeyPair, Ed25519KeyPair, RsaEncoding, RsaKeyPair};
use std::borrow::Cow;
Expand Down Expand Up @@ -55,19 +55,19 @@ impl KeyPair {
/// Parses the key pair from the DER format
///
/// Equivalent to using the [`TryFrom`] implementation.
pub fn from_der(der: &[u8]) -> Result<Self, RcgenError> {
Ok(KeyPair::from_raw(der)?)
pub fn from_der(der: &[u8], rng: &dyn SecureRandom) -> Result<Self, RcgenError> {
Ok(KeyPair::from_raw(der, rng)?)
}
/// Returns the key pair's signature algorithm
pub fn algorithm(&self) -> &'static SignatureAlgorithm {
self.alg
}
/// Parses the key pair from the ASCII PEM format
#[cfg(feature = "pem")]
pub fn from_pem(pem_str: &str) -> Result<Self, RcgenError> {
pub fn from_pem(pem_str: &str, rng: &dyn SecureRandom) -> Result<Self, RcgenError> {
let private_key = pem::parse(pem_str)?;
let private_key_der: &[_] = private_key.contents();
Ok(KeyPair::from_raw(private_key_der)?)
Ok(KeyPair::from_raw(private_key_der, rng)?)
}

/// Obtains the key pair from a raw public key and a remote private key
Expand All @@ -87,10 +87,11 @@ impl KeyPair {
pub fn from_pem_and_sign_algo(
pem_str: &str,
alg: &'static SignatureAlgorithm,
rng: &dyn SecureRandom,
) -> Result<Self, RcgenError> {
let private_key = pem::parse(pem_str)?;
let private_key_der: &[_] = private_key.contents();
Ok(Self::from_der_and_sign_algo(private_key_der, alg)?)
Ok(Self::from_der_and_sign_algo(private_key_der, alg, rng)?)
}

/// Obtains the key pair from a DER formatted key
Expand All @@ -105,6 +106,7 @@ impl KeyPair {
pub fn from_der_and_sign_algo(
pkcs8: &[u8],
alg: &'static SignatureAlgorithm,
rng: &dyn SecureRandom,
) -> Result<Self, RcgenError> {
let pkcs8_vec = pkcs8.to_vec();

Expand All @@ -114,11 +116,13 @@ impl KeyPair {
KeyPairKind::Ec(EcdsaKeyPair::from_pkcs8(
&signature::ECDSA_P256_SHA256_ASN1_SIGNING,
pkcs8,
rng,
)?)
} else if alg == &PKCS_ECDSA_P384_SHA384 {
KeyPairKind::Ec(EcdsaKeyPair::from_pkcs8(
&signature::ECDSA_P384_SHA384_ASN1_SIGNING,
pkcs8,
rng,
)?)
} else if alg == &PKCS_RSA_SHA256 {
let rsakp = RsaKeyPair::from_pkcs8(pkcs8)?;
Expand All @@ -143,17 +147,20 @@ impl KeyPair {
})
}

pub(crate) fn from_raw<'b>(pkcs8: impl Into<Cow<'b, [u8]>>) -> Result<KeyPair, RcgenError> {
pub(crate) fn from_raw<'b>(
pkcs8: impl Into<Cow<'b, [u8]>>,
rng: &dyn SecureRandom,
) -> Result<KeyPair, RcgenError> {
let pkcs8 = pkcs8.into();

let (kind, alg) = if let Ok(edkp) = Ed25519KeyPair::from_pkcs8_maybe_unchecked(&pkcs8) {
(KeyPairKind::Ed(edkp), &PKCS_ED25519)
} else if let Ok(eckp) =
EcdsaKeyPair::from_pkcs8(&signature::ECDSA_P256_SHA256_ASN1_SIGNING, &pkcs8)
EcdsaKeyPair::from_pkcs8(&signature::ECDSA_P256_SHA256_ASN1_SIGNING, &pkcs8, rng)
{
(KeyPairKind::Ec(eckp), &PKCS_ECDSA_P256_SHA256)
} else if let Ok(eckp) =
EcdsaKeyPair::from_pkcs8(&signature::ECDSA_P384_SHA384_ASN1_SIGNING, &pkcs8)
EcdsaKeyPair::from_pkcs8(&signature::ECDSA_P384_SHA384_ASN1_SIGNING, &pkcs8, rng)
{
(KeyPairKind::Ec(eckp), &PKCS_ECDSA_P384_SHA384)
} else if let Ok(rsakp) = RsaKeyPair::from_pkcs8(&pkcs8) {
Expand Down Expand Up @@ -190,23 +197,25 @@ pub trait RemoteKeyPair {

impl KeyPair {
/// Generate a new random key pair for the specified signature algorithm
pub fn generate(alg: &'static SignatureAlgorithm) -> Result<Self, RcgenError> {
let system_random = SystemRandom::new();
pub fn generate(
alg: &'static SignatureAlgorithm,
rng: &dyn SecureRandom,
) -> Result<Self, RcgenError> {
match alg.sign_alg {
SignAlgo::EcDsa(sign_alg) => {
let key_pair_doc = EcdsaKeyPair::generate_pkcs8(sign_alg, &system_random)?;
let key_pair_doc = EcdsaKeyPair::generate_pkcs8(sign_alg, rng)?;
let key_pair_serialized = key_pair_doc.as_ref().to_vec();

let key_pair =
EcdsaKeyPair::from_pkcs8(&sign_alg, &&key_pair_doc.as_ref()).unwrap();
EcdsaKeyPair::from_pkcs8(&sign_alg, &&key_pair_doc.as_ref(), rng).unwrap();
Ok(KeyPair {
kind: KeyPairKind::Ec(key_pair),
alg,
serialized_der: key_pair_serialized,
})
},
SignAlgo::EdDsa(_sign_alg) => {
let key_pair_doc = Ed25519KeyPair::generate_pkcs8(&system_random)?;
let key_pair_doc = Ed25519KeyPair::generate_pkcs8(rng)?;
let key_pair_serialized = key_pair_doc.as_ref().to_vec();

let key_pair = Ed25519KeyPair::from_pkcs8(&&key_pair_doc.as_ref()).unwrap();
Expand Down Expand Up @@ -254,7 +263,7 @@ impl KeyPair {
},
KeyPairKind::Rsa(kp, padding_alg) => {
let system_random = SystemRandom::new();
let mut signature = vec![0; kp.public_modulus_len()];
let mut signature = vec![0; kp.public().modulus_len()];
kp.sign(*padding_alg, &system_random, msg, &mut signature)?;
let sig = &signature.as_ref();
writer.write_bitvec_bytes(&sig, &sig.len() * 8);
Expand Down Expand Up @@ -363,7 +372,7 @@ mod test {
let pkcs8 = EcdsaKeyPair::generate_pkcs8(&ECDSA_P256_SHA256_FIXED_SIGNING, &rng).unwrap();
let der = pkcs8.as_ref().to_vec();

let key_pair = KeyPair::from_der(&der).unwrap();
let key_pair = KeyPair::from_der(&der, &rng).unwrap();
assert_eq!(key_pair.algorithm(), &PKCS_ECDSA_P256_SHA256);
}
}
5 changes: 3 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1492,15 +1492,16 @@ fn write_general_subtrees(writer: DERWriter, tag: u64, general_subtrees: &[Gener
impl Certificate {
/// Generates a new certificate from the given parameters.
///
/// If there is no key pair included, then a new key pair will be generated and used.
/// If there is no key pair included, then a new key pair will be randomly generated and used.
/// If you want to control the [`KeyPair`] or the randomness used to generate it, set it ahead of time before calling this function.
pub fn from_params(mut params: CertificateParams) -> Result<Self, RcgenError> {
let key_pair = if let Some(key_pair) = params.key_pair.take() {
if !key_pair.is_compatible(&params.alg) {
return Err(RcgenError::CertificateKeyPairMismatch);
}
key_pair
} else {
KeyPair::generate(&params.alg)?
KeyPair::generate(&params.alg, &ring::rand::SystemRandom::new())?
};

Ok(Certificate { params, key_pair })
Expand Down
Loading

0 comments on commit a2d126e

Please sign in to comment.