Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/rust/cryptography-key-parsing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ impl From<openssl::error::ErrorStack> for KeyParsingError {

pub type KeyParsingResult<T> = Result<T, KeyParsingError>;

pub enum ParsedPrivateKey {
Pkey(openssl::pkey::PKey<openssl::pkey::Private>),
}

pub enum ParsedPublicKey {
Pkey(openssl::pkey::PKey<openssl::pkey::Public>),
}

pub enum KeySerializationError {
PasswordMustBeUtf8,
Write(asn1::WriteError),
Expand Down
48 changes: 26 additions & 22 deletions src/rust/cryptography-key-parsing/src/pkcs8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use cryptography_x509::pkcs8::EncryptedPrivateKeyInfo;

#[cfg(not(CRYPTOGRAPHY_IS_BORINGSSL))]
use crate::MIN_DH_MODULUS_SIZE;
use crate::{ec, pbe, rsa, KeyParsingError, KeyParsingResult};
use crate::{ec, pbe, rsa, KeyParsingError, KeyParsingResult, ParsedPrivateKey};

// RFC 5208 Section 5
#[derive(asn1::Asn1Read, asn1::Asn1Write)]
Expand Down Expand Up @@ -44,19 +44,17 @@ pub fn mldsa_seed_from_pkey(
Ok(asn1::parse_single::<MlDsaPrivateKey>(pki.private_key).unwrap())
}

pub fn parse_private_key(
data: &[u8],
) -> KeyParsingResult<openssl::pkey::PKey<openssl::pkey::Private>> {
pub fn parse_private_key(data: &[u8]) -> KeyParsingResult<ParsedPrivateKey> {
let k = asn1::parse_single::<PrivateKeyInfo<'_>>(data)?;
if k.version != 0 {
return Err(crate::KeyParsingError::InvalidKey);
}
match k.algorithm.params {
AlgorithmParameters::Rsa(_) | AlgorithmParameters::RsaPss(_) => {
rsa::parse_pkcs1_private_key(k.private_key)
rsa::parse_pkcs1_private_key(k.private_key).map(ParsedPrivateKey::Pkey)
}
AlgorithmParameters::Ec(ec_params) => {
ec::parse_pkcs1_private_key(k.private_key, Some(ec_params))
ec::parse_pkcs1_private_key(k.private_key, Some(ec_params)).map(ParsedPrivateKey::Pkey)
}

AlgorithmParameters::Dsa(dsa_params) => {
Expand All @@ -73,30 +71,31 @@ pub fn parse_private_key(

let dsa =
openssl::dsa::Dsa::from_private_components(p, q, g, dsa_private_key, pub_key)?;
Ok(openssl::pkey::PKey::from_dsa(dsa)?)
Ok(ParsedPrivateKey::Pkey(openssl::pkey::PKey::from_dsa(dsa)?))
}

#[cfg(not(CRYPTOGRAPHY_IS_BORINGSSL))]
AlgorithmParameters::Dh(dh_params) => {
let p = openssl::bn::BigNum::from_slice(dh_params.p.as_bytes())?;
let g = openssl::bn::BigNum::from_slice(dh_params.g.as_bytes())?;
let q = Some(openssl::bn::BigNum::from_slice(dh_params.q.as_bytes())?);
parse_dh_private_key(k.private_key, p, g, q)
parse_dh_private_key(k.private_key, p, g, q).map(ParsedPrivateKey::Pkey)
}

#[cfg(not(CRYPTOGRAPHY_IS_BORINGSSL))]
AlgorithmParameters::DhKeyAgreement(dh_params) => {
let p = openssl::bn::BigNum::from_slice(dh_params.p.as_bytes())?;
let g = openssl::bn::BigNum::from_slice(dh_params.g.as_bytes())?;
parse_dh_private_key(k.private_key, p, g, None)
parse_dh_private_key(k.private_key, p, g, None).map(ParsedPrivateKey::Pkey)
}

AlgorithmParameters::X25519 => {
let key_bytes = asn1::parse_single(k.private_key)?;
Ok(openssl::pkey::PKey::private_key_from_raw_bytes(
let pkey = openssl::pkey::PKey::private_key_from_raw_bytes(
key_bytes,
openssl::pkey::Id::X25519,
)?)
)?;
Ok(ParsedPrivateKey::Pkey(pkey))
}
#[cfg(not(any(
CRYPTOGRAPHY_IS_LIBRESSL,
Expand All @@ -105,17 +104,19 @@ pub fn parse_private_key(
)))]
AlgorithmParameters::X448 => {
let key_bytes = asn1::parse_single(k.private_key)?;
Ok(openssl::pkey::PKey::private_key_from_raw_bytes(
let pkey = openssl::pkey::PKey::private_key_from_raw_bytes(
key_bytes,
openssl::pkey::Id::X448,
)?)
)?;
Ok(ParsedPrivateKey::Pkey(pkey))
}
AlgorithmParameters::Ed25519 => {
let key_bytes = asn1::parse_single(k.private_key)?;
Ok(openssl::pkey::PKey::private_key_from_raw_bytes(
let pkey = openssl::pkey::PKey::private_key_from_raw_bytes(
key_bytes,
openssl::pkey::Id::ED25519,
)?)
)?;
Ok(ParsedPrivateKey::Pkey(pkey))
}
#[cfg(not(any(
CRYPTOGRAPHY_IS_LIBRESSL,
Expand All @@ -124,19 +125,22 @@ pub fn parse_private_key(
)))]
AlgorithmParameters::Ed448 => {
let key_bytes = asn1::parse_single(k.private_key)?;
Ok(openssl::pkey::PKey::private_key_from_raw_bytes(
let pkey = openssl::pkey::PKey::private_key_from_raw_bytes(
key_bytes,
openssl::pkey::Id::ED448,
)?)
)?;
Ok(ParsedPrivateKey::Pkey(pkey))
}

#[cfg(CRYPTOGRAPHY_IS_AWSLC)]
AlgorithmParameters::MlDsa65 => {
let MlDsaPrivateKey::Seed(seed) = asn1::parse_single::<MlDsaPrivateKey>(k.private_key)?;
Ok(cryptography_openssl::mldsa::new_raw_private_key(
cryptography_openssl::mldsa::MlDsaVariant::MlDsa65,
&seed,
)?)
Ok(ParsedPrivateKey::Pkey(
cryptography_openssl::mldsa::new_raw_private_key(
cryptography_openssl::mldsa::MlDsaVariant::MlDsa65,
&seed,
)?,
))
}

_ => Err(KeyParsingError::UnsupportedKeyType(
Expand Down Expand Up @@ -223,7 +227,7 @@ fn pkcs5_pbe_decrypt(
pub fn parse_encrypted_private_key(
data: &[u8],
password: Option<&[u8]>,
) -> KeyParsingResult<openssl::pkey::PKey<openssl::pkey::Private>> {
) -> KeyParsingResult<ParsedPrivateKey> {
let epki = asn1::parse_single::<EncryptedPrivateKeyInfo<'_>>(data)?;
let password = match password {
None | Some(b"") => return Err(KeyParsingError::EncryptedKeyWithoutPassword),
Expand Down
76 changes: 43 additions & 33 deletions src/rust/cryptography-key-parsing/src/spki.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@ use cryptography_x509::common::{
SubjectPublicKeyInfo,
};

use crate::{KeyParsingError, KeyParsingResult, KeySerializationResult};
use crate::{KeyParsingError, KeyParsingResult, KeySerializationResult, ParsedPublicKey};

pub fn parse_public_key(
data: &[u8],
) -> KeyParsingResult<openssl::pkey::PKey<openssl::pkey::Public>> {
pub fn parse_public_key(data: &[u8]) -> KeyParsingResult<ParsedPublicKey> {
let k = asn1::parse_single::<SubjectPublicKeyInfo<'_>>(data)?;

match k.algorithm.params {
Expand All @@ -25,41 +23,51 @@ pub fn parse_public_key(
)
.map_err(|_| KeyParsingError::InvalidKey)?;
let ec_key = openssl::ec::EcKey::from_public_key(&group, &ec_point)?;
Ok(openssl::pkey::PKey::from_ec_key(ec_key)?)
let pkey = openssl::pkey::PKey::from_ec_key(ec_key)?;
Ok(ParsedPublicKey::Pkey(pkey))
}
AlgorithmParameters::Ed25519 => Ok(openssl::pkey::PKey::public_key_from_raw_bytes(
k.subject_public_key.as_bytes(),
openssl::pkey::Id::ED25519,
)
.map_err(|_| KeyParsingError::InvalidKey)?),
AlgorithmParameters::Ed25519 => Ok(ParsedPublicKey::Pkey(
openssl::pkey::PKey::public_key_from_raw_bytes(
k.subject_public_key.as_bytes(),
openssl::pkey::Id::ED25519,
)
.map_err(|_| KeyParsingError::InvalidKey)?,
)),
#[cfg(not(any(
CRYPTOGRAPHY_IS_LIBRESSL,
CRYPTOGRAPHY_IS_BORINGSSL,
CRYPTOGRAPHY_IS_AWSLC
)))]
AlgorithmParameters::Ed448 => Ok(openssl::pkey::PKey::public_key_from_raw_bytes(
k.subject_public_key.as_bytes(),
openssl::pkey::Id::ED448,
)
.map_err(|_| KeyParsingError::InvalidKey)?),
AlgorithmParameters::X25519 => Ok(openssl::pkey::PKey::public_key_from_raw_bytes(
k.subject_public_key.as_bytes(),
openssl::pkey::Id::X25519,
)
.map_err(|_| KeyParsingError::InvalidKey)?),
AlgorithmParameters::Ed448 => Ok(ParsedPublicKey::Pkey(
openssl::pkey::PKey::public_key_from_raw_bytes(
k.subject_public_key.as_bytes(),
openssl::pkey::Id::ED448,
)
.map_err(|_| KeyParsingError::InvalidKey)?,
)),
AlgorithmParameters::X25519 => Ok(ParsedPublicKey::Pkey(
openssl::pkey::PKey::public_key_from_raw_bytes(
k.subject_public_key.as_bytes(),
openssl::pkey::Id::X25519,
)
.map_err(|_| KeyParsingError::InvalidKey)?,
)),
#[cfg(not(any(
CRYPTOGRAPHY_IS_LIBRESSL,
CRYPTOGRAPHY_IS_BORINGSSL,
CRYPTOGRAPHY_IS_AWSLC
)))]
AlgorithmParameters::X448 => Ok(openssl::pkey::PKey::public_key_from_raw_bytes(
k.subject_public_key.as_bytes(),
openssl::pkey::Id::X448,
)
.map_err(|_| KeyParsingError::InvalidKey)?),
AlgorithmParameters::X448 => Ok(ParsedPublicKey::Pkey(
openssl::pkey::PKey::public_key_from_raw_bytes(
k.subject_public_key.as_bytes(),
openssl::pkey::Id::X448,
)
.map_err(|_| KeyParsingError::InvalidKey)?,
)),
AlgorithmParameters::Rsa(_) | AlgorithmParameters::RsaPss(_) => {
// RSA-PSS keys are treated the same as bare RSA keys.
crate::rsa::parse_pkcs1_public_key(k.subject_public_key.as_bytes())
.map(ParsedPublicKey::Pkey)
}
AlgorithmParameters::Dsa(dsa_params) => {
let p = openssl::bn::BigNum::from_slice(dsa_params.p.as_bytes())?;
Expand All @@ -71,7 +79,7 @@ pub fn parse_public_key(
let pub_key = openssl::bn::BigNum::from_slice(pub_key_int.as_bytes())?;

let dsa = openssl::dsa::Dsa::from_public_components(p, q, g, pub_key)?;
Ok(openssl::pkey::PKey::from_dsa(dsa)?)
Ok(ParsedPublicKey::Pkey(openssl::pkey::PKey::from_dsa(dsa)?))
}
#[cfg(not(CRYPTOGRAPHY_IS_BORINGSSL))]
AlgorithmParameters::Dh(dh_params) => {
Expand All @@ -85,7 +93,7 @@ pub fn parse_public_key(
let pub_key = openssl::bn::BigNum::from_slice(pub_key_int.as_bytes())?;
let dh = dh.set_public_key(pub_key)?;

Ok(openssl::pkey::PKey::from_dh(dh)?)
Ok(ParsedPublicKey::Pkey(openssl::pkey::PKey::from_dh(dh)?))
}
#[cfg(not(CRYPTOGRAPHY_IS_BORINGSSL))]
AlgorithmParameters::DhKeyAgreement(dh_params) => {
Expand All @@ -98,14 +106,16 @@ pub fn parse_public_key(
let pub_key = openssl::bn::BigNum::from_slice(pub_key_int.as_bytes())?;
let dh = dh.set_public_key(pub_key)?;

Ok(openssl::pkey::PKey::from_dh(dh)?)
Ok(ParsedPublicKey::Pkey(openssl::pkey::PKey::from_dh(dh)?))
}
#[cfg(CRYPTOGRAPHY_IS_AWSLC)]
AlgorithmParameters::MlDsa65 => Ok(cryptography_openssl::mldsa::new_raw_public_key(
cryptography_openssl::mldsa::MlDsaVariant::MlDsa65,
k.subject_public_key.as_bytes(),
)
.map_err(|_| KeyParsingError::InvalidKey)?),
AlgorithmParameters::MlDsa65 => Ok(ParsedPublicKey::Pkey(
cryptography_openssl::mldsa::new_raw_public_key(
cryptography_openssl::mldsa::MlDsaVariant::MlDsa65,
k.subject_public_key.as_bytes(),
)
.map_err(|_| KeyParsingError::InvalidKey)?,
)),

_ => Err(KeyParsingError::UnsupportedKeyType(
k.algorithm.oid().clone(),
Expand Down
Loading