diff --git a/ext/node/ops/crypto/cipher.rs b/ext/node/ops/crypto/cipher.rs index 94bd5780eb409f..b80aa33fe8352f 100644 --- a/ext/node/ops/crypto/cipher.rs +++ b/ext/node/ops/crypto/cipher.rs @@ -4,6 +4,7 @@ use aes::cipher::block_padding::Pkcs7; use aes::cipher::BlockDecryptMut; use aes::cipher::BlockEncryptMut; use aes::cipher::KeyIvInit; +use deno_core::error::range_error; use deno_core::error::type_error; use deno_core::error::AnyError; use deno_core::Resource; @@ -157,6 +158,13 @@ impl Cipher { Aes256Gcm(Box::new(cipher)) } "aes256" | "aes-256-cbc" => { + if key.len() != 32 { + return Err(range_error("Invalid key length")); + } + if iv.len() != 16 { + return Err(type_error("Invalid initialization vector")); + } + Aes256Cbc(Box::new(cbc::Encryptor::new(key.into(), iv.into()))) } _ => return Err(type_error(format!("Unknown cipher {algorithm_name}"))), @@ -346,6 +354,13 @@ impl Decipher { Aes256Gcm(Box::new(decipher)) } "aes256" | "aes-256-cbc" => { + if key.len() != 32 { + return Err(range_error("Invalid key length")); + } + if iv.len() != 16 { + return Err(type_error("Invalid initialization vector")); + } + Aes256Cbc(Box::new(cbc::Decryptor::new(key.into(), iv.into()))) } _ => return Err(type_error(format!("Unknown cipher {algorithm_name}"))), diff --git a/ext/node/ops/crypto/mod.rs b/ext/node/ops/crypto/mod.rs index 7384375773c454..600d315587167e 100644 --- a/ext/node/ops/crypto/mod.rs +++ b/ext/node/ops/crypto/mod.rs @@ -220,13 +220,9 @@ pub fn op_node_create_cipheriv( #[string] algorithm: &str, #[buffer] key: &[u8], #[buffer] iv: &[u8], -) -> u32 { - state.resource_table.add( - match cipher::CipherContext::new(algorithm, key, iv) { - Ok(context) => context, - Err(_) => return 0, - }, - ) +) -> Result { + let context = cipher::CipherContext::new(algorithm, key, iv)?; + Ok(state.resource_table.add(context)) } #[op2(fast)] @@ -292,13 +288,9 @@ pub fn op_node_create_decipheriv( #[string] algorithm: &str, #[buffer] key: &[u8], #[buffer] iv: &[u8], -) -> u32 { - state.resource_table.add( - match cipher::DecipherContext::new(algorithm, key, iv) { - Ok(context) => context, - Err(_) => return 0, - }, - ) +) -> Result { + let context = cipher::DecipherContext::new(algorithm, key, iv)?; + Ok(state.resource_table.add(context)) } #[op2(fast)] diff --git a/tests/unit_node/crypto/crypto_cipher_test.ts b/tests/unit_node/crypto/crypto_cipher_test.ts index 91227cf0060e4a..ad424e5d4eb12f 100644 --- a/tests/unit_node/crypto/crypto_cipher_test.ts +++ b/tests/unit_node/crypto/crypto_cipher_test.ts @@ -245,6 +245,44 @@ Deno.test({ }, }); +Deno.test({ + name: "createCipheriv - invalid inputs", + fn() { + assertThrows( + () => + crypto.createCipheriv("aes256", new Uint8Array(31), new Uint8Array(16)), + RangeError, + "Invalid key length", + ); + assertThrows( + () => + crypto.createCipheriv( + "aes-256-cbc", + new Uint8Array(31), + new Uint8Array(16), + ), + RangeError, + "Invalid key length", + ); + assertThrows( + () => + crypto.createCipheriv("aes256", new Uint8Array(32), new Uint8Array(15)), + TypeError, + "Invalid initialization vector", + ); + assertThrows( + () => + crypto.createCipheriv( + "aes-256-cbc", + new Uint8Array(32), + new Uint8Array(15), + ), + TypeError, + "Invalid initialization vector", + ); + }, +}); + Deno.test({ name: "createDecipheriv - invalid algorithm", fn() { @@ -257,6 +295,52 @@ Deno.test({ }, }); +Deno.test({ + name: "createDecipheriv - invalid inputs", + fn() { + assertThrows( + () => + crypto.createDecipheriv( + "aes256", + new Uint8Array(31), + new Uint8Array(16), + ), + RangeError, + "Invalid key length", + ); + assertThrows( + () => + crypto.createDecipheriv( + "aes-256-cbc", + new Uint8Array(31), + new Uint8Array(16), + ), + RangeError, + "Invalid key length", + ); + assertThrows( + () => + crypto.createDecipheriv( + "aes256", + new Uint8Array(32), + new Uint8Array(15), + ), + TypeError, + "Invalid initialization vector", + ); + assertThrows( + () => + crypto.createDecipheriv( + "aes-256-cbc", + new Uint8Array(32), + new Uint8Array(15), + ), + TypeError, + "Invalid initialization vector", + ); + }, +}); + Deno.test({ name: "getCiphers", fn() {