Skip to content

Ensure ConstPointers don't outlive parent #693

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
20 changes: 13 additions & 7 deletions aws-lc-rs/src/agreement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ use crate::ec::verify_evp_key_nid;
use crate::ec::{encoding, evp_key_generate};
use crate::error::{KeyRejected, Unspecified};
use crate::hex;
use crate::ptr::ConstPointer;
pub use ephemeral::{agree_ephemeral, EphemeralPrivateKey};

use crate::aws_lc::{
Expand Down Expand Up @@ -416,7 +415,9 @@ impl PrivateKey {
}
KeyInner::X25519(priv_key) => {
let mut buffer = [0u8; MAX_PUBLIC_KEY_LEN];
let out_len = priv_key.marshal_raw_public_to_buffer(&mut buffer)?;
let out_len = priv_key
.as_const()
.marshal_raw_public_to_buffer(&mut buffer)?;
Ok(PublicKey {
inner_key: self.inner_key.clone(),
key_bytes: buffer,
Expand Down Expand Up @@ -448,9 +449,11 @@ impl AsDer<EcPrivateKeyRfc5915Der<'static>> for PrivateKey {

let mut outp = null_mut::<u8>();
let ec_key = {
ConstPointer::new(unsafe {
EVP_PKEY_get0_EC_KEY(*self.inner_key.get_evp_pkey().as_const())
})?
self.inner_key
.get_evp_pkey()
.project_const_lifetime(unsafe {
|evp_pkey| EVP_PKEY_get0_EC_KEY(*evp_pkey.as_const())
})?
};
let length = usize::try_from(unsafe { aws_lc::i2d_ECPrivateKey(*ec_key, &mut outp) })
.map_err(|_| Unspecified)?;
Expand All @@ -476,6 +479,7 @@ impl AsDer<Pkcs8V1Der<'static>> for PrivateKey {
Ok(Pkcs8V1Der::new(
self.inner_key
.get_evp_pkey()
.as_const()
.marshal_rfc5208_private_key(Version::V1)?,
))
}
Expand Down Expand Up @@ -509,7 +513,9 @@ impl AsBigEndian<Curve25519SeedBin<'static>> for PrivateKey {
return Err(Unspecified);
}
let evp_pkey = self.inner_key.get_evp_pkey();
Ok(Curve25519SeedBin::new(evp_pkey.marshal_raw_private_key()?))
Ok(Curve25519SeedBin::new(
evp_pkey.as_const().marshal_raw_private_key()?,
))
}
}

Expand Down Expand Up @@ -576,7 +582,7 @@ impl AsDer<PublicKeyX509Der<'static>> for PublicKey {
| KeyInner::ECDH_P384(evp_pkey)
| KeyInner::ECDH_P521(evp_pkey)
| KeyInner::X25519(evp_pkey) => {
let der = evp_pkey.marshal_rfc5280_public_key()?;
let der = evp_pkey.as_const().marshal_rfc5280_public_key()?;
Ok(PublicKeyX509Der::from(Buffer::new(der)))
}
}
Expand Down
2 changes: 1 addition & 1 deletion aws-lc-rs/src/bn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl TryFrom<u64> for DetachableLcPtr<BIGNUM> {
}
}

impl ConstPointer<BIGNUM> {
impl ConstPointer<'_, BIGNUM> {
pub(crate) fn to_be_bytes(&self) -> Vec<u8> {
unsafe {
let bn_bytes = BN_num_bytes(**self);
Expand Down
32 changes: 17 additions & 15 deletions aws-lc-rs/src/cipher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,21 +285,23 @@ pub enum OperatingMode {

impl OperatingMode {
fn evp_cipher(&self, algorithm: &Algorithm) -> ConstPointer<EVP_CIPHER> {
ConstPointer::new(match (self, algorithm.id) {
(OperatingMode::CBC, AlgorithmId::Aes128) => unsafe { EVP_aes_128_cbc() },
(OperatingMode::CTR, AlgorithmId::Aes128) => unsafe { EVP_aes_128_ctr() },
(OperatingMode::CFB128, AlgorithmId::Aes128) => unsafe { EVP_aes_128_cfb128() },
(OperatingMode::ECB, AlgorithmId::Aes128) => unsafe { EVP_aes_128_ecb() },
(OperatingMode::CBC, AlgorithmId::Aes192) => unsafe { EVP_aes_192_cbc() },
(OperatingMode::CTR, AlgorithmId::Aes192) => unsafe { EVP_aes_192_ctr() },
(OperatingMode::CFB128, AlgorithmId::Aes192) => unsafe { EVP_aes_192_cfb128() },
(OperatingMode::ECB, AlgorithmId::Aes192) => unsafe { EVP_aes_192_ecb() },
(OperatingMode::CBC, AlgorithmId::Aes256) => unsafe { EVP_aes_256_cbc() },
(OperatingMode::CTR, AlgorithmId::Aes256) => unsafe { EVP_aes_256_ctr() },
(OperatingMode::CFB128, AlgorithmId::Aes256) => unsafe { EVP_aes_256_cfb128() },
(OperatingMode::ECB, AlgorithmId::Aes256) => unsafe { EVP_aes_256_ecb() },
})
.unwrap()
unsafe {
ConstPointer::new_static(match (self, algorithm.id) {
(OperatingMode::CBC, AlgorithmId::Aes128) => EVP_aes_128_cbc(),
(OperatingMode::CTR, AlgorithmId::Aes128) => EVP_aes_128_ctr(),
(OperatingMode::CFB128, AlgorithmId::Aes128) => EVP_aes_128_cfb128(),
(OperatingMode::ECB, AlgorithmId::Aes128) => EVP_aes_128_ecb(),
(OperatingMode::CBC, AlgorithmId::Aes192) => EVP_aes_192_cbc(),
(OperatingMode::CTR, AlgorithmId::Aes192) => EVP_aes_192_ctr(),
(OperatingMode::CFB128, AlgorithmId::Aes192) => EVP_aes_192_cfb128(),
(OperatingMode::ECB, AlgorithmId::Aes192) => EVP_aes_192_ecb(),
(OperatingMode::CBC, AlgorithmId::Aes256) => EVP_aes_256_cbc(),
(OperatingMode::CTR, AlgorithmId::Aes256) => EVP_aes_256_ctr(),
(OperatingMode::CFB128, AlgorithmId::Aes256) => EVP_aes_256_cfb128(),
(OperatingMode::ECB, AlgorithmId::Aes256) => EVP_aes_256_ecb(),
})
.unwrap()
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion aws-lc-rs/src/digest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ pub const MAX_CHAINING_LEN: usize = MAX_OUTPUT_LEN;
/// Match digest types for `EVP_MD` functions.
pub(crate) fn match_digest_type(algorithm_id: &AlgorithmID) -> ConstPointer<EVP_MD> {
unsafe {
ConstPointer::new(match algorithm_id {
ConstPointer::new_static(match algorithm_id {
AlgorithmID::SHA1 => EVP_sha1(),
AlgorithmID::SHA224 => EVP_sha224(),
AlgorithmID::SHA256 => EVP_sha256(),
Expand Down
50 changes: 29 additions & 21 deletions aws-lc-rs/src/ec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@
// Modifications copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 OR ISC

use crate::ec::signature::AlgorithmID;
// TODO: Uncomment when MSRV >= 1.64
use std::os::raw::c_int;

#[cfg(feature = "fips")]
use crate::aws_lc::EC_KEY_check_fips;
#[cfg(not(feature = "fips"))]
Expand All @@ -18,11 +14,16 @@ use crate::aws_lc::{
NID_X9_62_prime256v1, NID_secp224r1, NID_secp256k1, NID_secp384r1, NID_secp521r1, EC_GROUP,
EC_KEY, EVP_PKEY, EVP_PKEY_EC,
};
use crate::ec::signature::AlgorithmID;
use crate::error::{KeyRejected, Unspecified};
#[cfg(feature = "fips")]
use crate::fips::indicator_check;
use crate::ptr::{ConstPointer, LcPtr};
use crate::signature::Signature;
// TODO: Uncomment when MSRV >= 1.64
//use core::ffi::c_int;
use std::os::raw::c_int;
use std::ptr::null;

pub(crate) mod encoding;
pub(crate) mod key_pair;
Expand All @@ -38,7 +39,8 @@ fn verify_ec_key_nid(
ec_key: &ConstPointer<EC_KEY>,
expected_curve_nid: i32,
) -> Result<(), KeyRejected> {
let ec_group = ConstPointer::new(unsafe { EC_KEY_get0_group(**ec_key) })?;
let ec_group =
ec_key.project_const_lifetime(unsafe { |ec_key| EC_KEY_get0_group(**ec_key) })?;
let key_nid = unsafe { EC_GROUP_get_curve_name(*ec_group) };

if key_nid != expected_curve_nid {
Expand All @@ -53,7 +55,8 @@ pub(crate) fn verify_evp_key_nid(
evp_pkey: &ConstPointer<EVP_PKEY>,
expected_curve_nid: i32,
) -> Result<(), KeyRejected> {
let ec_key = ConstPointer::new(unsafe { EVP_PKEY_get0_EC_KEY(**evp_pkey) })?;
let ec_key =
evp_pkey.project_const_lifetime(unsafe { |evp_pkey| EVP_PKEY_get0_EC_KEY(**evp_pkey) })?;
verify_ec_key_nid(&ec_key, expected_curve_nid)?;

Ok(())
Expand All @@ -64,7 +67,8 @@ pub(crate) fn validate_ec_evp_key(
evp_pkey: &ConstPointer<EVP_PKEY>,
expected_curve_nid: i32,
) -> Result<(), KeyRejected> {
let ec_key = ConstPointer::new(unsafe { EVP_PKEY_get0_EC_KEY(**evp_pkey) })?;
let ec_key =
evp_pkey.project_const_lifetime(unsafe { |evp_pkey| EVP_PKEY_get0_EC_KEY(**evp_pkey) })?;
verify_ec_key_nid(&ec_key, expected_curve_nid)?;

#[cfg(not(feature = "fips"))]
Expand Down Expand Up @@ -94,18 +98,20 @@ pub(crate) fn evp_key_generate(nid: c_int) -> Result<LcPtr<EVP_PKEY>, Unspecifie

#[inline]
#[allow(non_upper_case_globals)]
pub(crate) fn ec_group_from_nid(nid: i32) -> Result<ConstPointer<EC_GROUP>, Unspecified> {
Ok(ConstPointer::new(match nid {
NID_secp224r1 => Ok(unsafe { EC_group_p224() }),
NID_X9_62_prime256v1 => Ok(unsafe { EC_group_p256() }),
NID_secp384r1 => Ok(unsafe { EC_group_p384() }),
NID_secp521r1 => Ok(unsafe { EC_group_p521() }),
NID_secp256k1 => Ok(unsafe { EC_group_secp256k1() }),
_ => {
// OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
Err(Unspecified)
}
}?)?)
pub(crate) fn ec_group_from_nid(nid: i32) -> Result<ConstPointer<'static, EC_GROUP>, Unspecified> {
Ok(unsafe {
ConstPointer::new_static(match nid {
NID_secp224r1 => EC_group_p224(),
NID_X9_62_prime256v1 => EC_group_p256(),
NID_secp384r1 => EC_group_p384(),
NID_secp521r1 => EC_group_p521(),
NID_secp256k1 => EC_group_secp256k1(),
_ => {
// OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
null()
}
})?
})
}

#[inline]
Expand All @@ -114,10 +120,12 @@ fn ecdsa_asn1_to_fixed(alg_id: &'static AlgorithmID, sig: &[u8]) -> Result<Signa

let ecdsa_sig = LcPtr::new(unsafe { ECDSA_SIG_from_bytes(sig.as_ptr(), sig.len()) })?;

let r_bn = ConstPointer::new(unsafe { ECDSA_SIG_get0_r(*ecdsa_sig.as_const()) })?;
let r_bn = ecdsa_sig
.project_const_lifetime(unsafe { |ecdsa_sig| ECDSA_SIG_get0_r(*ecdsa_sig.as_const()) })?;
let r_buffer = r_bn.to_be_bytes();

let s_bn = ConstPointer::new(unsafe { ECDSA_SIG_get0_s(*ecdsa_sig.as_const()) })?;
let s_bn = ecdsa_sig
.project_const_lifetime(unsafe { |ecdsa_sig| ECDSA_SIG_get0_s(*ecdsa_sig.as_const()) })?;
let s_buffer = s_bn.to_be_bytes();

Ok(Signature::new(|slice| {
Expand Down
32 changes: 21 additions & 11 deletions aws-lc-rs/src/ec/encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,9 @@ pub(crate) mod sec1 {
compressed: bool,
) -> Result<Vec<u8>, Unspecified> {
let pub_key_size = if compressed {
compressed_public_key_size_bytes(evp_pkey.key_size_bits())
compressed_public_key_size_bytes(evp_pkey.as_const().key_size_bits())
} else {
uncompressed_public_key_size_bytes(evp_pkey.key_size_bits())
uncompressed_public_key_size_bytes(evp_pkey.as_const().key_size_bits())
};
let mut cbb = LcCBB::new(pub_key_size);
marshal_sec1_public_point_into_cbb(&mut cbb, evp_pkey, compressed)?;
Expand All @@ -159,9 +159,13 @@ pub(crate) mod sec1 {
evp_pkey: &LcPtr<EVP_PKEY>,
compressed: bool,
) -> Result<(), Unspecified> {
let ec_key = ConstPointer::new(unsafe { EVP_PKEY_get0_EC_KEY(*evp_pkey.as_const()) })?;
let ec_group = ConstPointer::new(unsafe { EC_KEY_get0_group(*ec_key) })?;
let ec_point = ConstPointer::new(unsafe { EC_KEY_get0_public_key(*ec_key) })?;
let ec_key = evp_pkey.project_const_lifetime(unsafe {
|evp_pkey| EVP_PKEY_get0_EC_KEY(*evp_pkey.as_const())
})?;
let ec_group =
ec_key.project_const_lifetime(unsafe { |ec_key| EC_KEY_get0_group(**ec_key) })?;
let ec_point =
ec_key.project_const_lifetime(unsafe { |ec_key| EC_KEY_get0_public_key(**ec_key) })?;

let point_conversion_form = if compressed {
point_conversion_form_t::POINT_CONVERSION_COMPRESSED
Expand All @@ -186,8 +190,11 @@ pub(crate) mod sec1 {
pub(crate) fn marshal_sec1_private_key(
evp_pkey: &LcPtr<EVP_PKEY>,
) -> Result<Vec<u8>, Unspecified> {
let ec_key = ConstPointer::new(unsafe { EVP_PKEY_get0_EC_KEY(*evp_pkey.as_const()) })?;
let ec_group = ConstPointer::new(unsafe { EC_KEY_get0_group(*ec_key) })?;
let ec_key = evp_pkey.project_const_lifetime(unsafe {
|evp_pkey| EVP_PKEY_get0_EC_KEY(*evp_pkey.as_const())
})?;
let ec_group =
ec_key.project_const_lifetime(unsafe { |ec_key| EC_KEY_get0_group(**ec_key) })?;
let nid = unsafe { EC_GROUP_get_curve_name(*ec_group) };
#[allow(non_upper_case_globals)]
let key_size: usize = match nid {
Expand All @@ -196,7 +203,8 @@ pub(crate) mod sec1 {
NID_secp521r1 => Ok(66usize),
_ => Err(Unspecified),
}?;
let private_bn = ConstPointer::new(unsafe { EC_KEY_get0_private_key(*ec_key) })?;
let private_bn =
ec_key.project_const_lifetime(unsafe { |ec_key| EC_KEY_get0_private_key(**ec_key) })?;

let mut cbb = LcCBB::new(key_size);
if 1 != unsafe { BN_bn2cbb_padded(cbb.as_mut_ptr(), key_size, *private_bn) } {
Expand All @@ -215,7 +223,7 @@ pub(crate) mod rfc5915 {
use crate::cbs::build_CBS;
use crate::ec::ec_group_from_nid;
use crate::error::{KeyRejected, Unspecified};
use crate::ptr::{ConstPointer, LcPtr};
use crate::ptr::LcPtr;

pub(crate) fn parse_rfc5915_private_key(
key_bytes: &[u8],
Expand All @@ -234,8 +242,10 @@ pub(crate) mod rfc5915 {
pub(crate) fn marshal_rfc5915_private_key(
evp_pkey: &LcPtr<EVP_PKEY>,
) -> Result<Vec<u8>, Unspecified> {
let ec_key = ConstPointer::new(unsafe { EVP_PKEY_get0_EC_KEY(*evp_pkey.as_const()) })?;
let mut cbb = LcCBB::new(evp_pkey.key_size_bytes());
let ec_key = evp_pkey.project_const_lifetime(unsafe {
|evp_pkey| EVP_PKEY_get0_EC_KEY(*evp_pkey.as_const())
})?;
let mut cbb = LcCBB::new(evp_pkey.as_const().key_size_bytes());
let enc_flags = unsafe { EC_KEY_get_enc_flags(*ec_key) };
if 1 != unsafe { EC_KEY_marshal_private_key(cbb.as_mut_ptr(), *ec_key, enc_flags) } {
return Err(Unspecified);
Expand Down
4 changes: 3 additions & 1 deletion aws-lc-rs/src/ec/key_pair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@ impl EcdsaKeyPair {
///
pub fn to_pkcs8v1(&self) -> Result<Document, Unspecified> {
Ok(Document::new(
self.evp_pkey.marshal_rfc5208_private_key(Version::V1)?,
self.evp_pkey
.as_const()
.marshal_rfc5208_private_key(Version::V1)?,
))
}

Expand Down
2 changes: 1 addition & 1 deletion aws-lc-rs/src/ec/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ impl AsDer<PublicKeyX509Der<'static>> for PublicKey {
/// # Errors
/// Returns an error if the public key fails to marshal to X.509.
fn as_der(&self) -> Result<PublicKeyX509Der<'static>, Unspecified> {
let der = self.evp_pkey.marshal_rfc5280_public_key()?;
let der = self.evp_pkey.as_const().marshal_rfc5280_public_key()?;
Ok(PublicKeyX509Der::new(der))
}
}
Expand Down
Loading
Loading