#[cfg(feature = "crypto")]
use std::fmt;
#[cfg(feature = "pem")]
use pem::Pem;
#[cfg(feature = "crypto")]
use pki_types::{PrivateKeyDer, PrivatePkcs8KeyDer};
use yasna::{DERWriter, DERWriterSeq};
#[cfg(any(feature = "crypto", feature = "pem"))]
use crate::error::ExternalError;
#[cfg(all(feature = "crypto", feature = "aws_lc_rs"))]
use crate::ring_like::ecdsa_from_private_key_der;
#[cfg(all(feature = "crypto", feature = "aws_lc_rs"))]
use crate::ring_like::rsa::KeySize;
#[cfg(feature = "crypto")]
use crate::ring_like::{
error as ring_error,
rand::SystemRandom,
signature::{
self, EcdsaKeyPair, Ed25519KeyPair, KeyPair as RingKeyPair, RsaEncoding, RsaKeyPair,
},
{ecdsa_from_pkcs8, rsa_key_pair_public_modulus_len},
};
#[cfg(feature = "crypto")]
use crate::sign_algo::{algo::*, SignAlgo};
#[cfg(feature = "pem")]
use crate::ENCODE_CONFIG;
use crate::{sign_algo::SignatureAlgorithm, Error};
#[cfg(all(feature = "aws_lc_rs_unstable", not(feature = "fips")))]
use aws_lc_rs::unstable::signature::PqdsaKeyPair;
#[allow(clippy::large_enum_variant)]
#[cfg(feature = "crypto")]
pub(crate) enum KeyPairKind {
Ec(EcdsaKeyPair),
Ed(Ed25519KeyPair),
#[cfg(all(feature = "aws_lc_rs_unstable", not(feature = "fips")))]
Pq(PqdsaKeyPair),
Rsa(RsaKeyPair, &'static dyn RsaEncoding),
}
#[cfg(feature = "crypto")]
impl fmt::Debug for KeyPairKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Ec(key_pair) => write!(f, "{key_pair:?}"),
Self::Ed(key_pair) => write!(f, "{key_pair:?}"),
#[cfg(all(feature = "aws_lc_rs_unstable", not(feature = "fips")))]
Self::Pq(key_pair) => write!(f, "{key_pair:?}"),
Self::Rsa(key_pair, _) => write!(f, "{key_pair:?}"),
}
}
}
#[cfg(feature = "crypto")]
pub struct KeyPair {
pub(crate) kind: KeyPairKind,
pub(crate) alg: &'static SignatureAlgorithm,
pub(crate) serialized_der: Vec<u8>,
}
#[cfg(feature = "crypto")]
impl fmt::Debug for KeyPair {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("KeyPair")
.field("kind", &self.kind)
.field("alg", &self.alg)
.field("serialized_der", &"[secret key elided]")
.finish()
}
}
#[cfg(feature = "crypto")]
impl KeyPair {
#[cfg(feature = "crypto")]
pub fn generate() -> Result<Self, Error> {
Self::generate_for(&PKCS_ECDSA_P256_SHA256)
}
#[cfg(feature = "crypto")]
pub fn generate_for(alg: &'static SignatureAlgorithm) -> Result<Self, Error> {
let rng = &SystemRandom::new();
match alg.sign_alg {
SignAlgo::EcDsa(sign_alg) => {
let key_pair_doc = EcdsaKeyPair::generate_pkcs8(sign_alg, rng)._err()?;
let key_pair_serialized = key_pair_doc.as_ref().to_vec();
let key_pair = ecdsa_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(rng)._err()?;
let key_pair_serialized = key_pair_doc.as_ref().to_vec();
let key_pair = Ed25519KeyPair::from_pkcs8(key_pair_doc.as_ref()).unwrap();
Ok(KeyPair {
kind: KeyPairKind::Ed(key_pair),
alg,
serialized_der: key_pair_serialized,
})
},
#[cfg(all(feature = "aws_lc_rs_unstable", not(feature = "fips")))]
SignAlgo::PqDsa(sign_alg) => {
let key_pair = PqdsaKeyPair::generate(sign_alg)._err()?;
let key_pair_serialized = key_pair.to_pkcs8()._err()?.as_ref().to_vec();
Ok(KeyPair {
kind: KeyPairKind::Pq(key_pair),
alg,
serialized_der: key_pair_serialized,
})
},
#[cfg(feature = "aws_lc_rs")]
SignAlgo::Rsa(sign_alg) => Self::generate_rsa_inner(alg, sign_alg, KeySize::Rsa2048),
#[cfg(all(feature = "ring", not(feature = "aws_lc_rs")))]
SignAlgo::Rsa(_sign_alg) => Err(Error::KeyGenerationUnavailable),
}
}
#[cfg(all(feature = "crypto", feature = "aws_lc_rs"))]
pub fn generate_rsa_for(
alg: &'static SignatureAlgorithm,
key_size: RsaKeySize,
) -> Result<Self, Error> {
match alg.sign_alg {
SignAlgo::Rsa(sign_alg) => {
let key_size = match key_size {
RsaKeySize::_2048 => KeySize::Rsa2048,
RsaKeySize::_3072 => KeySize::Rsa3072,
RsaKeySize::_4096 => KeySize::Rsa4096,
};
Self::generate_rsa_inner(alg, sign_alg, key_size)
},
_ => Err(Error::KeyGenerationUnavailable),
}
}
#[cfg(all(feature = "crypto", feature = "aws_lc_rs"))]
fn generate_rsa_inner(
alg: &'static SignatureAlgorithm,
sign_alg: &'static dyn RsaEncoding,
key_size: KeySize,
) -> Result<Self, Error> {
use aws_lc_rs::encoding::AsDer;
let key_pair = RsaKeyPair::generate(key_size)._err()?;
let key_pair_serialized = key_pair.as_der()._err()?.as_ref().to_vec();
Ok(KeyPair {
kind: KeyPairKind::Rsa(key_pair, sign_alg),
alg,
serialized_der: key_pair_serialized,
})
}
pub fn algorithm(&self) -> &'static SignatureAlgorithm {
self.alg
}
#[cfg(all(feature = "pem", feature = "crypto"))]
pub fn from_pem(pem_str: &str) -> Result<Self, Error> {
let private_key = pem::parse(pem_str)._err()?;
Self::try_from(private_key.contents())
}
#[cfg(all(feature = "pem", feature = "crypto"))]
pub fn from_pkcs8_pem_and_sign_algo(
pem_str: &str,
alg: &'static SignatureAlgorithm,
) -> Result<Self, Error> {
let private_key = pem::parse(pem_str)._err()?;
let private_key_der: &[_] = private_key.contents();
Self::from_pkcs8_der_and_sign_algo(&PrivatePkcs8KeyDer::from(private_key_der), alg)
}
#[cfg(feature = "crypto")]
pub fn from_pkcs8_der_and_sign_algo(
pkcs8: &PrivatePkcs8KeyDer<'_>,
alg: &'static SignatureAlgorithm,
) -> Result<Self, Error> {
let rng = &SystemRandom::new();
let serialized_der = pkcs8.secret_pkcs8_der().to_vec();
let kind = if alg == &PKCS_ED25519 {
KeyPairKind::Ed(Ed25519KeyPair::from_pkcs8_maybe_unchecked(&serialized_der)._err()?)
} else if alg == &PKCS_ECDSA_P256_SHA256 {
KeyPairKind::Ec(ecdsa_from_pkcs8(
&signature::ECDSA_P256_SHA256_ASN1_SIGNING,
&serialized_der,
rng,
)?)
} else if alg == &PKCS_ECDSA_P384_SHA384 {
KeyPairKind::Ec(ecdsa_from_pkcs8(
&signature::ECDSA_P384_SHA384_ASN1_SIGNING,
&serialized_der,
rng,
)?)
} else if alg == &PKCS_RSA_SHA256 {
let rsakp = RsaKeyPair::from_pkcs8(&serialized_der)._err()?;
KeyPairKind::Rsa(rsakp, &signature::RSA_PKCS1_SHA256)
} else if alg == &PKCS_RSA_SHA384 {
let rsakp = RsaKeyPair::from_pkcs8(&serialized_der)._err()?;
KeyPairKind::Rsa(rsakp, &signature::RSA_PKCS1_SHA384)
} else if alg == &PKCS_RSA_SHA512 {
let rsakp = RsaKeyPair::from_pkcs8(&serialized_der)._err()?;
KeyPairKind::Rsa(rsakp, &signature::RSA_PKCS1_SHA512)
} else if alg == &PKCS_RSA_PSS_SHA256 {
let rsakp = RsaKeyPair::from_pkcs8(&serialized_der)._err()?;
KeyPairKind::Rsa(rsakp, &signature::RSA_PSS_SHA256)
} else {
#[cfg(feature = "aws_lc_rs")]
if alg == &PKCS_ECDSA_P521_SHA512 {
KeyPairKind::Ec(ecdsa_from_pkcs8(
&signature::ECDSA_P521_SHA512_ASN1_SIGNING,
&serialized_der,
rng,
)?)
} else {
panic!("Unknown SignatureAlgorithm specified!");
}
#[cfg(all(feature = "ring", not(feature = "aws_lc_rs")))]
panic!("Unknown SignatureAlgorithm specified!");
};
Ok(KeyPair {
kind,
alg,
serialized_der,
})
}
#[cfg(all(feature = "pem", feature = "crypto"))]
pub fn from_pem_and_sign_algo(
pem_str: &str,
alg: &'static SignatureAlgorithm,
) -> Result<Self, Error> {
let private_key = pem::parse(pem_str)._err()?;
let private_key: &[_] = private_key.contents();
Self::from_der_and_sign_algo(
&PrivateKeyDer::try_from(private_key).map_err(|_| Error::CouldNotParseKeyPair)?,
alg,
)
}
#[cfg(feature = "crypto")]
pub fn from_der_and_sign_algo(
key: &PrivateKeyDer<'_>,
alg: &'static SignatureAlgorithm,
) -> Result<Self, Error> {
#[cfg(all(feature = "ring", not(feature = "aws_lc_rs")))]
{
if let PrivateKeyDer::Pkcs8(key) = key {
Self::from_pkcs8_der_and_sign_algo(key, alg)
} else {
Err(Error::CouldNotParseKeyPair)
}
}
#[cfg(feature = "aws_lc_rs")]
{
let is_pkcs8 = matches!(key, PrivateKeyDer::Pkcs8(_));
let rsa_key_pair_from = if is_pkcs8 {
RsaKeyPair::from_pkcs8
} else {
RsaKeyPair::from_der
};
let serialized_der = key.secret_der().to_vec();
let kind = if alg == &PKCS_ED25519 {
KeyPairKind::Ed(Ed25519KeyPair::from_pkcs8_maybe_unchecked(&serialized_der)._err()?)
} else if alg == &PKCS_ECDSA_P256_SHA256 {
KeyPairKind::Ec(ecdsa_from_private_key_der(
&signature::ECDSA_P256_SHA256_ASN1_SIGNING,
&serialized_der,
)?)
} else if alg == &PKCS_ECDSA_P384_SHA384 {
KeyPairKind::Ec(ecdsa_from_private_key_der(
&signature::ECDSA_P384_SHA384_ASN1_SIGNING,
&serialized_der,
)?)
} else if alg == &PKCS_ECDSA_P521_SHA512 {
KeyPairKind::Ec(ecdsa_from_private_key_der(
&signature::ECDSA_P521_SHA512_ASN1_SIGNING,
&serialized_der,
)?)
} else if alg == &PKCS_RSA_SHA256 {
let rsakp = rsa_key_pair_from(&serialized_der)._err()?;
KeyPairKind::Rsa(rsakp, &signature::RSA_PKCS1_SHA256)
} else if alg == &PKCS_RSA_SHA384 {
let rsakp = rsa_key_pair_from(&serialized_der)._err()?;
KeyPairKind::Rsa(rsakp, &signature::RSA_PKCS1_SHA384)
} else if alg == &PKCS_RSA_SHA512 {
let rsakp = rsa_key_pair_from(&serialized_der)._err()?;
KeyPairKind::Rsa(rsakp, &signature::RSA_PKCS1_SHA512)
} else if alg == &PKCS_RSA_PSS_SHA256 {
let rsakp = rsa_key_pair_from(&serialized_der)._err()?;
KeyPairKind::Rsa(rsakp, &signature::RSA_PSS_SHA256)
} else {
panic!("Unknown SignatureAlgorithm specified!");
};
Ok(KeyPair {
kind,
alg,
serialized_der,
})
}
}
pub fn public_key_raw(&self) -> &[u8] {
self.der_bytes()
}
pub fn is_compatible(&self, signature_algorithm: &SignatureAlgorithm) -> bool {
self.alg == signature_algorithm
}
pub fn compatible_algs(&self) -> impl Iterator<Item = &'static SignatureAlgorithm> {
std::iter::once(self.alg)
}
#[cfg(feature = "pem")]
pub fn public_key_pem(&self) -> String {
let contents = self.subject_public_key_info();
let p = Pem::new("PUBLIC KEY", contents);
pem::encode_config(&p, ENCODE_CONFIG)
}
pub fn serialize_der(&self) -> Vec<u8> {
self.serialized_der.clone()
}
pub fn serialized_der(&self) -> &[u8] {
&self.serialized_der
}
#[cfg(feature = "pem")]
pub fn serialize_pem(&self) -> String {
let contents = self.serialize_der();
let p = Pem::new("PRIVATE KEY", contents);
pem::encode_config(&p, ENCODE_CONFIG)
}
}
#[cfg(feature = "crypto")]
impl SigningKey for KeyPair {
fn sign(&self, msg: &[u8]) -> Result<Vec<u8>, Error> {
Ok(match &self.kind {
KeyPairKind::Ec(kp) => {
let system_random = SystemRandom::new();
let signature = kp.sign(&system_random, msg)._err()?;
signature.as_ref().to_owned()
},
KeyPairKind::Ed(kp) => kp.sign(msg).as_ref().to_owned(),
#[cfg(all(feature = "aws_lc_rs_unstable", not(feature = "fips")))]
KeyPairKind::Pq(kp) => {
let mut signature = vec![0; kp.algorithm().signature_len()];
kp.sign(msg, &mut signature)._err()?;
signature
},
KeyPairKind::Rsa(kp, padding_alg) => {
let system_random = SystemRandom::new();
let mut signature = vec![0; rsa_key_pair_public_modulus_len(kp)];
kp.sign(*padding_alg, &system_random, msg, &mut signature)
._err()?;
signature
},
})
}
}
#[cfg(feature = "crypto")]
impl PublicKeyData for KeyPair {
fn der_bytes(&self) -> &[u8] {
match &self.kind {
KeyPairKind::Ec(kp) => kp.public_key().as_ref(),
KeyPairKind::Ed(kp) => kp.public_key().as_ref(),
#[cfg(all(feature = "aws_lc_rs_unstable", not(feature = "fips")))]
KeyPairKind::Pq(kp) => kp.public_key().as_ref(),
KeyPairKind::Rsa(kp, _) => kp.public_key().as_ref(),
}
}
fn algorithm(&self) -> &'static SignatureAlgorithm {
self.alg
}
}
#[cfg(feature = "crypto")]
impl TryFrom<&[u8]> for KeyPair {
type Error = Error;
fn try_from(key: &[u8]) -> Result<KeyPair, Error> {
let key = &PrivateKeyDer::try_from(key).map_err(|_| Error::CouldNotParseKeyPair)?;
key.try_into()
}
}
#[cfg(feature = "crypto")]
impl TryFrom<Vec<u8>> for KeyPair {
type Error = Error;
fn try_from(key: Vec<u8>) -> Result<KeyPair, Error> {
let key = &PrivateKeyDer::try_from(key).map_err(|_| Error::CouldNotParseKeyPair)?;
key.try_into()
}
}
#[cfg(feature = "crypto")]
impl TryFrom<&PrivatePkcs8KeyDer<'_>> for KeyPair {
type Error = Error;
fn try_from(key: &PrivatePkcs8KeyDer) -> Result<KeyPair, Error> {
key.secret_pkcs8_der().try_into()
}
}
#[cfg(feature = "crypto")]
impl TryFrom<&PrivateKeyDer<'_>> for KeyPair {
type Error = Error;
fn try_from(key: &PrivateKeyDer) -> Result<KeyPair, Error> {
#[cfg(all(feature = "ring", not(feature = "aws_lc_rs")))]
let (kind, alg) = {
let PrivateKeyDer::Pkcs8(pkcs8) = key else {
return Err(Error::CouldNotParseKeyPair);
};
let pkcs8 = pkcs8.secret_pkcs8_der();
let rng = SystemRandom::new();
let (kind, alg) = if let Ok(edkp) = Ed25519KeyPair::from_pkcs8_maybe_unchecked(pkcs8) {
(KeyPairKind::Ed(edkp), &PKCS_ED25519)
} else if let Ok(eckp) =
ecdsa_from_pkcs8(&signature::ECDSA_P256_SHA256_ASN1_SIGNING, pkcs8, &rng)
{
(KeyPairKind::Ec(eckp), &PKCS_ECDSA_P256_SHA256)
} else if let Ok(eckp) =
ecdsa_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) {
(
KeyPairKind::Rsa(rsakp, &signature::RSA_PKCS1_SHA256),
&PKCS_RSA_SHA256,
)
} else {
return Err(Error::CouldNotParseKeyPair);
};
(kind, alg)
};
#[cfg(feature = "aws_lc_rs")]
let (kind, alg) = {
let is_pkcs8 = matches!(key, PrivateKeyDer::Pkcs8(_));
let key = key.secret_der();
let rsa_key_pair_from = if is_pkcs8 {
RsaKeyPair::from_pkcs8
} else {
RsaKeyPair::from_der
};
let (kind, alg) = if let Ok(edkp) = Ed25519KeyPair::from_pkcs8_maybe_unchecked(key) {
(KeyPairKind::Ed(edkp), &PKCS_ED25519)
} else if let Ok(eckp) =
ecdsa_from_private_key_der(&signature::ECDSA_P256_SHA256_ASN1_SIGNING, key)
{
(KeyPairKind::Ec(eckp), &PKCS_ECDSA_P256_SHA256)
} else if let Ok(eckp) =
ecdsa_from_private_key_der(&signature::ECDSA_P384_SHA384_ASN1_SIGNING, key)
{
(KeyPairKind::Ec(eckp), &PKCS_ECDSA_P384_SHA384)
} else if let Ok(eckp) =
ecdsa_from_private_key_der(&signature::ECDSA_P521_SHA512_ASN1_SIGNING, key)
{
(KeyPairKind::Ec(eckp), &PKCS_ECDSA_P521_SHA512)
} else if let Ok(rsakp) = rsa_key_pair_from(key) {
(
KeyPairKind::Rsa(rsakp, &signature::RSA_PKCS1_SHA256),
&PKCS_RSA_SHA256,
)
} else {
return Err(Error::CouldNotParseKeyPair);
};
(kind, alg)
};
Ok(KeyPair {
kind,
alg,
serialized_der: key.secret_der().into(),
})
}
}
#[cfg(all(feature = "crypto", feature = "aws_lc_rs"))]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum RsaKeySize {
_2048,
_3072,
_4096,
}
pub(crate) fn sign_der(
key: &impl SigningKey,
f: impl FnOnce(&mut DERWriterSeq<'_>) -> Result<(), Error>,
) -> Result<Vec<u8>, Error> {
yasna::try_construct_der(|writer| {
writer.write_sequence(|writer| {
let data = yasna::try_construct_der(|writer| writer.write_sequence(f))?;
writer.next().write_der(&data);
key.algorithm().write_alg_ident(writer.next());
let sig = key.sign(&data)?;
let writer = writer.next();
writer.write_bitvec_bytes(&sig, sig.len() * 8);
Ok(())
})
})
}
impl<S: SigningKey + ?Sized> SigningKey for &S {
fn sign(&self, msg: &[u8]) -> Result<Vec<u8>, Error> {
(*self).sign(msg)
}
}
pub trait SigningKey: PublicKeyData {
fn sign(&self, msg: &[u8]) -> Result<Vec<u8>, Error>;
}
#[cfg(feature = "crypto")]
impl<T> ExternalError<T> for Result<T, ring_error::KeyRejected> {
fn _err(self) -> Result<T, Error> {
self.map_err(|e| Error::RingKeyRejected(e.to_string()))
}
}
#[cfg(feature = "crypto")]
impl<T> ExternalError<T> for Result<T, ring_error::Unspecified> {
fn _err(self) -> Result<T, Error> {
self.map_err(|_| Error::RingUnspecified)
}
}
#[cfg(feature = "pem")]
impl<T> ExternalError<T> for Result<T, pem::PemError> {
fn _err(self) -> Result<T, Error> {
self.map_err(|e| Error::PemError(e.to_string()))
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SubjectPublicKeyInfo {
pub(crate) alg: &'static SignatureAlgorithm,
pub(crate) subject_public_key: Vec<u8>,
}
impl SubjectPublicKeyInfo {
#[cfg(all(feature = "x509-parser", feature = "pem"))]
pub fn from_pem(pem_str: &str) -> Result<Self, Error> {
Self::from_der(&pem::parse(pem_str)._err()?.into_contents())
}
#[cfg(feature = "x509-parser")]
pub fn from_der(spki_der: &[u8]) -> Result<Self, Error> {
use x509_parser::{
prelude::FromDer,
x509::{AlgorithmIdentifier, SubjectPublicKeyInfo},
};
let (rem, spki) =
SubjectPublicKeyInfo::from_der(spki_der).map_err(|e| Error::X509(e.to_string()))?;
if !rem.is_empty() {
return Err(Error::X509(
"trailing bytes in SubjectPublicKeyInfo".to_string(),
));
}
let alg = SignatureAlgorithm::iter()
.find(|alg| {
let bytes = yasna::construct_der(|writer| {
alg.write_oids_sign_alg(writer);
});
let Ok((rest, aid)) = AlgorithmIdentifier::from_der(&bytes) else {
return false;
};
if !rest.is_empty() {
return false;
}
aid == spki.algorithm
})
.ok_or(Error::UnsupportedSignatureAlgorithm)?;
Ok(Self {
alg,
subject_public_key: Vec::from(spki.subject_public_key.as_ref()),
})
}
}
impl PublicKeyData for SubjectPublicKeyInfo {
fn der_bytes(&self) -> &[u8] {
&self.subject_public_key
}
fn algorithm(&self) -> &'static SignatureAlgorithm {
self.alg
}
}
impl<K: PublicKeyData + ?Sized> PublicKeyData for &K {
fn der_bytes(&self) -> &[u8] {
(*self).der_bytes()
}
fn algorithm(&self) -> &'static SignatureAlgorithm {
(*self).algorithm()
}
}
pub trait PublicKeyData {
fn subject_public_key_info(&self) -> Vec<u8> {
yasna::construct_der(|writer| serialize_public_key_der(self, writer))
}
fn der_bytes(&self) -> &[u8];
fn algorithm(&self) -> &'static SignatureAlgorithm;
}
pub(crate) fn serialize_public_key_der(key: &(impl PublicKeyData + ?Sized), writer: DERWriter) {
writer.write_sequence(|writer| {
key.algorithm().write_oids_sign_alg(writer.next());
let pk = key.der_bytes();
writer.next().write_bitvec_bytes(pk, pk.len() * 8);
})
}
#[cfg(all(test, feature = "crypto"))]
mod test {
use super::*;
use crate::ring_like::{
rand::SystemRandom,
signature::{EcdsaKeyPair, ECDSA_P256_SHA256_FIXED_SIGNING},
};
#[cfg(all(feature = "x509-parser", feature = "pem"))]
#[test]
fn test_subject_public_key_parsing() {
for alg in [
&PKCS_ED25519,
&PKCS_ECDSA_P256_SHA256,
&PKCS_ECDSA_P384_SHA384,
#[cfg(feature = "aws_lc_rs")]
&PKCS_ECDSA_P521_SHA512,
#[cfg(feature = "aws_lc_rs")]
&PKCS_RSA_SHA256,
] {
let kp = KeyPair::generate_for(alg).expect("keygen");
let pem = kp.public_key_pem();
let der = kp.subject_public_key_info();
let pkd_pem = SubjectPublicKeyInfo::from_pem(&pem).expect("from pem");
assert_eq!(kp.der_bytes(), pkd_pem.der_bytes());
let pkd_der = SubjectPublicKeyInfo::from_der(&der).expect("from der");
assert_eq!(kp.der_bytes(), pkd_der.der_bytes());
}
}
#[test]
fn test_algorithm() {
let rng = SystemRandom::new();
let pkcs8 = EcdsaKeyPair::generate_pkcs8(&ECDSA_P256_SHA256_FIXED_SIGNING, &rng).unwrap();
let der = pkcs8.as_ref().to_vec();
let key_pair = KeyPair::try_from(der).unwrap();
assert_eq!(key_pair.algorithm(), &PKCS_ECDSA_P256_SHA256);
}
}