Skip to content
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

Implement TryInto<PublicEncryptingKey> for PublicKeyComponents #582

Merged
merged 3 commits into from
Nov 22, 2024
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
2 changes: 1 addition & 1 deletion aws-lc-rs/src/rsa/encryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ impl Clone for PrivateDecryptingKey {
pub struct PublicEncryptingKey(LcPtr<EVP_PKEY>);

impl PublicEncryptingKey {
fn new(evp_pkey: LcPtr<EVP_PKEY>) -> Result<Self, Unspecified> {
pub(crate) fn new(evp_pkey: LcPtr<EVP_PKEY>) -> Result<Self, Unspecified> {
Self::validate_key(&evp_pkey)?;
Ok(Self(evp_pkey))
}
Expand Down
19 changes: 18 additions & 1 deletion aws-lc-rs/src/rsa/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use crate::{
hex,
ptr::{DetachableLcPtr, LcPtr},
rand,
rsa::PublicEncryptingKey,
sealed::Sealed,
};
#[cfg(feature = "fips")]
Expand Down Expand Up @@ -366,7 +367,7 @@ impl PublicKey {
}
}

/// Low-level API for the verification of RSA signatures.
/// Low-level API for RSA public keys.
///
/// When the public key is in DER-encoded PKCS#1 ASN.1 format, it is
/// recommended to use `aws_lc_rs::signature::verify()` with
Expand Down Expand Up @@ -456,6 +457,22 @@ where
}
}

impl<B> TryInto<PublicEncryptingKey> for PublicKeyComponents<B>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure it's needed, but we could potentially have a non-consuming implementation:

impl<B> TryInto<PublicEncryptingKey> for &PublicKeyComponents<B>
...

Its use would be more cumbersome: TryInto::try_into(&public_key)? or (&public_key).try_into()?.

where
B: AsRef<[u8]> + Debug,
{
type Error = Unspecified;

/// Try to build a `PublicEncryptingKey` from the public key components.
///
/// # Errors
/// `error::Unspecified` if the key failed to verify.
fn try_into(self) -> Result<PublicEncryptingKey, Self::Error> {
let rsa = self.build_rsa()?;
PublicEncryptingKey::new(rsa)
}
}

pub(super) fn generate_rsa_key(size: c_int, fips: bool) -> Result<LcPtr<EVP_PKEY>, Unspecified> {
// We explicitly don't use `EVP_PKEY_keygen`, as it will force usage of either the FIPS or non-FIPS
// keygen function based on the whether the build of AWS-LC had FIPS enbaled. Rather we delegate to the desired
Expand Down
25 changes: 25 additions & 0 deletions aws-lc-rs/tests/basic_rsa_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0 OR ISC

use aws_lc_rs::rand::SystemRandom;
use aws_lc_rs::rsa::{Pkcs1PublicEncryptingKey, PublicEncryptingKey};
use aws_lc_rs::signature;
use aws_lc_rs::signature::RsaKeyPair;
use aws_lc_rs::test::from_dirty_hex;
Expand Down Expand Up @@ -193,3 +194,27 @@ fn test_signature_rsa_primitive_verification() {
let result = public_key.verify(&signature::RSA_PKCS1_2048_8192_SHA256, &msg, &sig);
assert!(result.is_ok());
}

#[test]
fn test_encryption_rsa_primitive() {
let n = from_dirty_hex(
r"CEA80475324C1DC8347827818DA58BAC069D3419C614A6EA1AC6A3B510DCD72CC516954905E9FEF908D45
E13006ADF27D467A7D83C111D1A5DF15EF293771AEFB920032A5BB989F8E4F5E1B05093D3F130F984C07A772
A3683F4DC6FB28A96815B32123CCDD13954F19D5B8B24A103E771A34C328755C65ED64E1924FFD04D30B2142
CC262F6E0048FEF6DBC652F21479EA1C4B1D66D28F4D46EF7185E390CBFA2E02380582F3188BB94EBBF05D31
487A09AFF01FCBB4CD4BFD1F0A833B38C11813C84360BB53C7D4481031C40BAD8713BB6B835CB08098ED15BA
31EE4BA728A8C8E10F7294E1B4163B7AEE57277BFD881A6F9D43E02C6925AA3A043FB7FB78D",
);

let e = from_dirty_hex(r"260445");
let msg = from_dirty_hex(r"68656c6c6f2c20776f726c64");

let public_key = signature::RsaPublicKeyComponents { n: &n, e: &e };
let public_encrypting_key: PublicEncryptingKey = public_key.try_into().unwrap();
let pkcs_encrypting_key = Pkcs1PublicEncryptingKey::new(public_encrypting_key).unwrap();

let mut encrypted = vec![0u8; pkcs_encrypting_key.ciphertext_size()];
pkcs_encrypting_key.encrypt(&msg, &mut encrypted).unwrap();

assert_ne!(encrypted, msg);
}
Loading