Skip to content

Commit

Permalink
Refactor the structure
Browse files Browse the repository at this point in the history
  • Loading branch information
nabetti1720 committed Nov 26, 2024
1 parent ae81bbc commit e996284
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 133 deletions.
3 changes: 2 additions & 1 deletion modules/llrt_crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
mod crc32;
mod md5_hash;
mod sha_hash;
use std::slice;
mod subtle;

use std::slice;

use llrt_buffer::Buffer;
use llrt_context::CtxExtension;
use llrt_encoding::{bytes_to_b64_string, bytes_to_hex_string};
Expand Down
20 changes: 16 additions & 4 deletions modules/llrt_crypto/src/subtle/decrypt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,28 @@
use aes::cipher::{block_padding::Pkcs7, BlockDecryptMut, KeyIvInit};
use aes_gcm::{aead::Aead, KeyInit, Nonce};
use ctr::{cipher::StreamCipher, Ctr128BE, Ctr32BE, Ctr64BE};
use llrt_utils::result::ResultExt;
use rquickjs::{Ctx, Exception, Result};
use llrt_utils::{bytes::ObjectBytes, result::ResultExt};
use rquickjs::{ArrayBuffer, Ctx, Exception, Result, Value};
use rsa::{pkcs1::DecodeRsaPrivateKey, Oaep, RsaPrivateKey};
use sha2::Sha256;

use crate::subtle::{Aes256Gcm, Algorithm};
use crate::subtle::{extract_algorithm_object, Aes256Gcm, Algorithm};

type Aes256CbcDec = cbc::Decryptor<aes::Aes256>;

pub fn decrypt(ctx: &Ctx<'_>, algorithm: &Algorithm, key: &[u8], data: &[u8]) -> Result<Vec<u8>> {
pub async fn subtle_decrypt<'js>(
ctx: Ctx<'js>,
algorithm: Value<'js>,
key: ObjectBytes<'js>,
data: ObjectBytes<'js>,
) -> Result<ArrayBuffer<'js>> {
let algorithm = extract_algorithm_object(&ctx, &algorithm)?;

let bytes = decrypt(&ctx, &algorithm, key.as_bytes(), data.as_bytes())?;
ArrayBuffer::new(ctx, bytes)
}

fn decrypt(ctx: &Ctx<'_>, algorithm: &Algorithm, key: &[u8], data: &[u8]) -> Result<Vec<u8>> {
match algorithm {
Algorithm::AesGcm(iv) => {
let cipher = Aes256Gcm::new_from_slice(key).or_throw(ctx)?;
Expand Down
20 changes: 16 additions & 4 deletions modules/llrt_crypto/src/subtle/derive_bits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
// SPDX-License-Identifier: Apache-2.0
use std::num::NonZeroU32;

use llrt_utils::result::ResultExt;
use llrt_utils::{bytes::ObjectBytes, result::ResultExt};
use p256::pkcs8::DecodePrivateKey;
use ring::{hkdf, pbkdf2};
use rquickjs::{Ctx, Exception, Result};
use rquickjs::{ArrayBuffer, Ctx, Exception, Result, Value};

use crate::subtle::{CryptoNamedCurve, DeriveAlgorithm, Sha};
use crate::subtle::{extract_derive_algorithm, CryptoNamedCurve, DeriveAlgorithm, Sha};

struct HkdfOutput(usize);

Expand All @@ -17,7 +17,19 @@ impl hkdf::KeyType for HkdfOutput {
}
}

pub fn derive_bits(
pub async fn subtle_derive_bits<'js>(
ctx: Ctx<'js>,
algorithm: Value<'js>,
base_key: ObjectBytes<'js>,
length: u32,
) -> Result<ArrayBuffer<'js>> {
let derive_algorithm = extract_derive_algorithm(&ctx, &algorithm)?;

let bytes = derive_bits(&ctx, &derive_algorithm, base_key.as_bytes(), length)?;
ArrayBuffer::new(ctx, bytes)
}

fn derive_bits(
ctx: &Ctx<'_>,
algorithm: &DeriveAlgorithm,
base_key: &[u8],
Expand Down
25 changes: 22 additions & 3 deletions modules/llrt_crypto/src/subtle/digest.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
use llrt_utils::result::ResultExt;
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
use rquickjs::{Ctx, Result};
use llrt_utils::{bytes::ObjectBytes, object::ObjectExt, result::ResultExt};
use rquickjs::{ArrayBuffer, Ctx, Exception, Result, Value};
use sha1::Sha1;
use sha2::{Digest, Sha256, Sha384, Sha512};

use crate::subtle::Sha;

pub fn digest(ctx: &Ctx<'_>, algorithm: &str, data: &[u8]) -> Result<Vec<u8>> {
pub async fn subtle_digest<'js>(
ctx: Ctx<'js>,
algorithm: Value<'js>,
data: ObjectBytes<'js>,
) -> Result<ArrayBuffer<'js>> {
let algorithm = if let Some(algorithm) = algorithm.as_string() {
algorithm.to_string().or_throw(&ctx)?
} else {
algorithm
.get_optional::<_, String>("name")?
.ok_or_else(|| {
Exception::throw_message(&ctx, "Missing algorithm name should cause TypeError")
})?
};

let bytes = digest(&ctx, &algorithm, data.as_bytes())?;
ArrayBuffer::new(ctx, bytes)
}

fn digest(ctx: &Ctx<'_>, algorithm: &str, data: &[u8]) -> Result<Vec<u8>> {
let sha = Sha::try_from(algorithm).or_throw(ctx)?;

match sha {
Expand Down
20 changes: 16 additions & 4 deletions modules/llrt_crypto/src/subtle/encrypt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,28 @@
use aes::cipher::{block_padding::Pkcs7, BlockEncryptMut, KeyIvInit};
use aes_gcm::{aead::Aead, KeyInit, Nonce};
use ctr::{cipher::StreamCipher, Ctr128BE, Ctr32BE, Ctr64BE};
use llrt_utils::result::ResultExt;
use rquickjs::{Ctx, Exception, Result};
use llrt_utils::{bytes::ObjectBytes, result::ResultExt};
use rquickjs::{ArrayBuffer, Ctx, Exception, Result, Value};
use rsa::{pkcs1::DecodeRsaPrivateKey, rand_core::OsRng, Oaep, RsaPrivateKey};
use sha2::Sha256;

use crate::subtle::{Aes256Gcm, Algorithm};
use crate::subtle::{extract_algorithm_object, Aes256Gcm, Algorithm};

type Aes256CbcEnc = cbc::Encryptor<aes::Aes256>;

pub fn encrypt(ctx: &Ctx<'_>, algorithm: &Algorithm, key: &[u8], data: &[u8]) -> Result<Vec<u8>> {
pub async fn subtle_encrypt<'js>(
ctx: Ctx<'js>,
algorithm: Value<'js>,
key: ObjectBytes<'js>,
data: ObjectBytes<'js>,
) -> Result<ArrayBuffer<'js>> {
let algorithm = extract_algorithm_object(&ctx, &algorithm)?;

let bytes = encrypt(&ctx, &algorithm, key.as_bytes(), data.as_bytes())?;
ArrayBuffer::new(ctx, bytes)
}

fn encrypt(ctx: &Ctx<'_>, algorithm: &Algorithm, key: &[u8], data: &[u8]) -> Result<Vec<u8>> {
match algorithm {
Algorithm::AesGcm(iv) => {
let cipher = Aes256Gcm::new_from_slice(key).or_throw(ctx)?;
Expand Down
18 changes: 15 additions & 3 deletions modules/llrt_crypto/src/subtle/generate_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,31 @@ use std::sync::OnceLock;
use llrt_utils::result::ResultExt;
use num_traits::FromPrimitive;
use ring::{rand::SecureRandom, signature::EcdsaKeyPair};
use rquickjs::{Ctx, Exception, Result};
use rquickjs::{Array, ArrayBuffer, Ctx, Exception, Result, Value};
use rsa::pkcs1::EncodeRsaPrivateKey;
use rsa::{rand_core::OsRng, BigUint, RsaPrivateKey};

use crate::{
subtle::{CryptoNamedCurve, KeyGenAlgorithm, Sha},
subtle::{extract_generate_key_algorithm, CryptoNamedCurve, KeyGenAlgorithm, Sha},
SYSTEM_RANDOM,
};

static PUB_EXPONENT_1: OnceLock<BigUint> = OnceLock::new();
static PUB_EXPONENT_2: OnceLock<BigUint> = OnceLock::new();

pub fn generate_key(ctx: &Ctx<'_>, algorithm: &KeyGenAlgorithm) -> Result<Vec<u8>> {
pub async fn subtle_generate_key<'js>(
ctx: Ctx<'js>,
algorithm: Value<'js>,
_extractable: bool,
_key_usages: Array<'js>,
) -> Result<ArrayBuffer<'js>> {
let key_gen_algorithm = extract_generate_key_algorithm(&ctx, &algorithm)?;

let bytes = generate_key(&ctx, &key_gen_algorithm)?;
ArrayBuffer::new(ctx, bytes)
}

fn generate_key(ctx: &Ctx<'_>, algorithm: &KeyGenAlgorithm) -> Result<Vec<u8>> {
match algorithm {
KeyGenAlgorithm::Rsa {
modulus_length,
Expand Down
115 changes: 9 additions & 106 deletions modules/llrt_crypto/src/subtle/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ mod generate_key;
mod sign;
mod verify;

use decrypt::decrypt;
use derive_bits::derive_bits;
use digest::digest;
use encrypt::encrypt;
use generate_key::generate_key;
use sign::sign;
use verify::verify;
pub use decrypt::subtle_decrypt;
pub use derive_bits::subtle_derive_bits;
pub use digest::subtle_digest;
pub use encrypt::subtle_encrypt;
pub use generate_key::subtle_generate_key;
pub use sign::subtle_sign;
pub use verify::subtle_verify;

use aes::{cipher::typenum::U16, Aes256};
use aes_gcm::AesGcm;
use hmac::Hmac;
use llrt_utils::{bytes::ObjectBytes, object::ObjectExt, result::ResultExt};
use rquickjs::{Array, ArrayBuffer, Ctx, Exception, Result, Value};
use llrt_utils::{object::ObjectExt, result::ResultExt};
use rquickjs::{Ctx, Exception, Result, Value};
use sha2::Sha256;

pub type HmacSha256 = Hmac<Sha256>;
Expand Down Expand Up @@ -114,103 +114,6 @@ pub enum KeyGenAlgorithm {
},
}

pub async fn subtle_decrypt<'js>(
ctx: Ctx<'js>,
algorithm: Value<'js>,
key: ObjectBytes<'js>,
data: ObjectBytes<'js>,
) -> Result<ArrayBuffer<'js>> {
let algorithm = extract_algorithm_object(&ctx, &algorithm)?;

let bytes = decrypt(&ctx, &algorithm, key.as_bytes(), data.as_bytes())?;
ArrayBuffer::new(ctx, bytes)
}

pub async fn subtle_derive_bits<'js>(
ctx: Ctx<'js>,
algorithm: Value<'js>,
base_key: ObjectBytes<'js>,
length: u32,
) -> Result<ArrayBuffer<'js>> {
let derive_algorithm = extract_derive_algorithm(&ctx, &algorithm)?;

let bytes = derive_bits(&ctx, &derive_algorithm, base_key.as_bytes(), length)?;
ArrayBuffer::new(ctx, bytes)
}

pub async fn subtle_digest<'js>(
ctx: Ctx<'js>,
algorithm: Value<'js>,
data: ObjectBytes<'js>,
) -> Result<ArrayBuffer<'js>> {
let algorithm = if let Some(algorithm) = algorithm.as_string() {
algorithm.to_string().or_throw(&ctx)?
} else {
algorithm
.get_optional::<_, String>("name")?
.ok_or_else(|| {
Exception::throw_message(&ctx, "Missing algorithm name should cause TypeError")
})?
};

let bytes = digest(&ctx, &algorithm, data.as_bytes())?;
ArrayBuffer::new(ctx, bytes)
}

pub async fn subtle_encrypt<'js>(
ctx: Ctx<'js>,
algorithm: Value<'js>,
key: ObjectBytes<'js>,
data: ObjectBytes<'js>,
) -> Result<ArrayBuffer<'js>> {
let algorithm = extract_algorithm_object(&ctx, &algorithm)?;

let bytes = encrypt(&ctx, &algorithm, key.as_bytes(), data.as_bytes())?;
ArrayBuffer::new(ctx, bytes)
}

pub async fn subtle_generate_key<'js>(
ctx: Ctx<'js>,
algorithm: Value<'js>,
_extractable: bool,
_key_usages: Array<'js>,
) -> Result<ArrayBuffer<'js>> {
let key_gen_algorithm = extract_generate_key_algorithm(&ctx, &algorithm)?;

let bytes = generate_key(&ctx, &key_gen_algorithm)?;
ArrayBuffer::new(ctx, bytes)
}

pub async fn subtle_sign<'js>(
ctx: Ctx<'js>,
algorithm: Value<'js>,
key: ObjectBytes<'js>,
data: ObjectBytes<'js>,
) -> Result<ArrayBuffer<'js>> {
let algorithm = extract_sign_verify_algorithm(&ctx, &algorithm)?;

let bytes = sign(&ctx, &algorithm, key.as_bytes(), data.as_bytes())?;
ArrayBuffer::new(ctx, bytes)
}

pub async fn subtle_verify<'js>(
ctx: Ctx<'js>,
algorithm: Value<'js>,
key: ObjectBytes<'js>,
signature: ObjectBytes<'js>,
data: ObjectBytes<'js>,
) -> Result<bool> {
let algorithm = extract_sign_verify_algorithm(&ctx, &algorithm)?;

verify(
&ctx,
&algorithm,
key.as_bytes(),
signature.as_bytes(),
data.as_bytes(),
)
}

fn extract_algorithm_object(ctx: &Ctx<'_>, algorithm: &Value) -> Result<Algorithm> {
let name = algorithm
.get_optional::<_, String>("name")?
Expand Down
20 changes: 16 additions & 4 deletions modules/llrt_crypto/src/subtle/sign.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
use hmac::Mac;
use llrt_utils::result::ResultExt;
use llrt_utils::{bytes::ObjectBytes, result::ResultExt};
use rand::rngs::OsRng;
use ring::signature::EcdsaKeyPair;
use rquickjs::{Ctx, Exception, Result};
use rquickjs::{ArrayBuffer, Ctx, Exception, Result, Value};
use rsa::{
pkcs1::DecodeRsaPrivateKey,
pss::Pss,
Expand All @@ -13,11 +13,23 @@ use rsa::{
use rsa::{Pkcs1v15Sign, RsaPrivateKey};

use crate::{
subtle::{Algorithm, HmacSha256, Sha},
subtle::{extract_sign_verify_algorithm, Algorithm, HmacSha256, Sha},
SYSTEM_RANDOM,
};

pub fn sign(ctx: &Ctx<'_>, algorithm: &Algorithm, key: &[u8], data: &[u8]) -> Result<Vec<u8>> {
pub async fn subtle_sign<'js>(
ctx: Ctx<'js>,
algorithm: Value<'js>,
key: ObjectBytes<'js>,
data: ObjectBytes<'js>,
) -> Result<ArrayBuffer<'js>> {
let algorithm = extract_sign_verify_algorithm(&ctx, &algorithm)?;

let bytes = sign(&ctx, &algorithm, key.as_bytes(), data.as_bytes())?;
ArrayBuffer::new(ctx, bytes)
}

fn sign(ctx: &Ctx<'_>, algorithm: &Algorithm, key: &[u8], data: &[u8]) -> Result<Vec<u8>> {
match algorithm {
Algorithm::Hmac => {
let mut mac = HmacSha256::new_from_slice(key).or_throw(ctx)?;
Expand Down
Loading

0 comments on commit e996284

Please sign in to comment.