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

perf: use ops for node:crypto ciphers #17819

Merged
merged 6 commits into from
Feb 20, 2023
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: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ url = { version = "2.3.1", features = ["serde", "expose_internals"] }
uuid = { version = "=1.1.2", features = ["v4"] }
zstd = "=0.11.2"

# crypto
rsa = { version = "0.7.0", default-features = false, features = ["std", "pem"] }

# webgpu
raw-window-handle = "0.5.0"
wgpu-core = "0.15"
Expand Down
50 changes: 50 additions & 0 deletions cli/tests/unit_node/crypto_cipher_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
import crypto from "node:crypto";
import { Buffer } from "node:buffer";
import {
assertEquals,
assertThrows,
} from "../../../test_util/std/testing/asserts.ts";

const rsaPrivateKey = Deno.readTextFileSync(
new URL("./testdata/rsa_private.pem", import.meta.url),
);
const rsaPublicKey = Deno.readTextFileSync(
new URL("./testdata/rsa_public.pem", import.meta.url),
);

const input = new TextEncoder().encode("hello world");

Deno.test({
name: "rsa public encrypt and private decrypt",
fn() {
const encrypted = crypto.publicEncrypt(Buffer.from(rsaPublicKey), input);
const decrypted = crypto.privateDecrypt(
Buffer.from(rsaPrivateKey),
Buffer.from(encrypted),
);
assertEquals(decrypted, input);
},
});

Deno.test({
name: "rsa private encrypt and private decrypt",
fn() {
const encrypted = crypto.privateEncrypt(rsaPrivateKey, input);
const decrypted = crypto.privateDecrypt(
rsaPrivateKey,
Buffer.from(encrypted),
);
assertEquals(decrypted, input);
},
});

Deno.test({
name: "rsa public decrypt fail",
fn() {
const encrypted = crypto.publicEncrypt(rsaPublicKey, input);
assertThrows(() =>
crypto.publicDecrypt(rsaPublicKey, Buffer.from(encrypted))
);
},
});
28 changes: 28 additions & 0 deletions cli/tests/unit_node/testdata/rsa_private.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC33FiIiiexwLe/
P8DZx5HsqFlmUO7/lvJ7necJVNwqdZ3ax5jpQB0p6uxfqeOvzcN3k5V7UFb/Am+n
kSNZMAZhsWzCU2Z4Pjh50QYz3f0Hour7/yIGStOLyYY3hgLK2K8TbhgjQPhdkw9+
QtKlpvbL8fLgONAoGrVOFnRQGcr70iFffsm79mgZhKVMgYiHPJqJgGHvCtkGg9zM
gS7p63+Q3ZWedtFS2RhMX3uCBy/mH6EOlRCNBbRmA4xxNzyf5GQaki3T+Iz9tOMj
dPP+CwV2LqEdylmBuik8vrfTb3qIHLKKBAI8lXN26wWtA3kN4L7NP+cbKlCRlqct
vhmylLH1AgMBAAECggEBAJLZ6ti7yDKgY+LcT/NiBDqKyEUBlbMNZIW5vAPnBKbh
JIDO9WIv9Fs7qSpLbnFHnr0OYtGIfMPXtUiYkyw0QJSc+upHZMvbno4llpes0eHc
jWVTBWETON4oywvj/Kz53vRc9eiKhxVuVWyagNcQgYSprjzLA+9UTcWeB67Guyrf
8YJUE2LC23RiMA5nGYoSHfVRl0c75gj7A0X9nwpAI+xw3kcaVHRIhA6WowA3Pj1o
pK2t692+NLVRylpvMMSS4rziDexomFykCFukYWYB/kZOOSSETSsTWoMXXl1KqsoZ
8IW06NR4rXtIgQ3sTfbYKGZNF5nWFgZ+hJVx0We1Qg0CgYEA8UovlB4nrBm7xH+u
7XXBMbqxADQm5vaEZxw9eluc+tP7cIAI4sglMIvL/FMpbd2pEeP/BkR76NTDzzDu
PAZvUGRavgEjy0O9j2NAs/WPK4tZF+vFdunhnSh4EHAF4Ij9kbsUi90NOpbGfVqP
dOaHqzgHKoR23Cuusk9wFQ2XTV8CgYEAwxHdEYT9xrpfrHPqSBQPpO0dWGKJEkrW
Ob+76rSfuL8wGR4OBNmQdhLuU9zTIh22pog+XPnLPAecC+4yu/wtJ2SPCKiKDbJB
re0CKPyRfGqzvA3njXwMxXazU4kGs+2Fg+xu/iKbaIjxXrclBLhkxhBtySrwAFhx
xOk6fFcPLSsCgYEAqS/Mdr5CMRGGMH0bKhPUWEtAixUGZhJaunX5wY71Xoc/Gh4c
nO+b7BNJ/+5L8WZog0vr6PgiLhrqBaCYm2wjpyoG2o2wDHm+NAlzN/wp3G2EFhrS
xdOux+S1c0kpRcyoiAO2n29rNDa+jOzwBBcU8ACEPdLOCQl0IEFFJO33tl8CgYBY
DOIqnEsovsucvh3MNzHwkg8i7CdPGHSmUIN0J9/ItpPxYn2VdtccVOM6+3xZ8+uU
M/9iXGZ+TDkFsZk4/VUsaNmfYOQf1oyLA2ZsNcU90bQbeHNCi/H/19qOJFXgNaCE
sd5P3DMl9lptFGIjRVBHjvbfTQBUR5fi+BusMGfrTQKBgQCTtzMEJP2sef883AJr
XuGVPLzwLi9eTBvPzc5r5pfkvh7mDDmWFxHZm5kctvavqgy32uUPsQgMi1Kz67bU
s5dY9MCVrN2elhTLD8LOiAz8836o3AxFefm5cUWGaU/aZWDYR0QtNqFdyHyRaodo
JJfnfK+oK1Eq7+PvpXfVN9BkYw==
-----END PRIVATE KEY-----
9 changes: 9 additions & 0 deletions cli/tests/unit_node/testdata/rsa_public.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt9xYiIonscC3vz/A2ceR
7KhZZlDu/5bye53nCVTcKnWd2seY6UAdKersX6njr83Dd5OVe1BW/wJvp5EjWTAG
YbFswlNmeD44edEGM939B6Lq+/8iBkrTi8mGN4YCytivE24YI0D4XZMPfkLSpab2
y/Hy4DjQKBq1ThZ0UBnK+9IhX37Ju/ZoGYSlTIGIhzyaiYBh7wrZBoPczIEu6et/
kN2VnnbRUtkYTF97ggcv5h+hDpUQjQW0ZgOMcTc8n+RkGpIt0/iM/bTjI3Tz/gsF
di6hHcpZgbopPL630296iByyigQCPJVzdusFrQN5DeC+zT/nGypQkZanLb4ZspSx
9QIDAQAB
-----END PUBLIC KEY-----
2 changes: 1 addition & 1 deletion ext/crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ p256 = { version = "0.11.1", features = ["ecdh"] }
p384 = "0.11.1"
rand.workspace = true
ring = { workspace = true, features = ["std"] }
rsa = { version = "0.7.0", default-features = false, features = ["std"] }
rsa.workspace = true
sec1 = "0.3.0"
serde.workspace = true
serde_bytes.workspace = true
Expand Down
2 changes: 2 additions & 0 deletions ext/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ md-5 = "0.10.5"
md4 = "0.10.2"
once_cell.workspace = true
path-clean = "=0.1.0"
rand.workspace = true
regex.workspace = true
ripemd = "0.1.3"
rsa.workspace = true
serde = "1.0.149"
sha-1 = "0.10.0"
sha2 = "0.10.6"
Expand Down
79 changes: 79 additions & 0 deletions ext/node/crypto/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@ use deno_core::error::AnyError;
use deno_core::op;
use deno_core::OpState;
use deno_core::ResourceId;
use deno_core::StringOrBuffer;
use deno_core::ZeroCopyBuf;
use std::rc::Rc;

use rsa::padding::PaddingScheme;
use rsa::pkcs8::DecodePrivateKey;
use rsa::pkcs8::DecodePublicKey;
use rsa::PublicKey;
use rsa::RsaPrivateKey;
use rsa::RsaPublicKey;

mod digest;

#[op]
Expand Down Expand Up @@ -47,3 +55,74 @@ pub fn op_node_hash_clone(
let context = state.resource_table.get::<digest::Context>(rid)?;
Ok(state.resource_table.add(context.as_ref().clone()))
}

#[op]
pub fn op_node_private_encrypt(
key: StringOrBuffer,
msg: StringOrBuffer,
padding: u32,
) -> Result<ZeroCopyBuf, AnyError> {
let key = RsaPrivateKey::from_pkcs8_pem((&key).try_into()?)?;

let mut rng = rand::thread_rng();
match padding {
1 => Ok(
key
.encrypt(&mut rng, PaddingScheme::new_pkcs1v15_encrypt(), &msg)?
.into(),
),
4 => Ok(
key
.encrypt(&mut rng, PaddingScheme::new_oaep::<sha1::Sha1>(), &msg)?
.into(),
),
_ => Err(type_error("Unknown padding")),
}
}

#[op]
pub fn op_node_private_decrypt(
key: StringOrBuffer,
msg: StringOrBuffer,
padding: u32,
) -> Result<ZeroCopyBuf, AnyError> {
let key = RsaPrivateKey::from_pkcs8_pem((&key).try_into()?)?;

match padding {
1 => Ok(
key
.decrypt(PaddingScheme::new_pkcs1v15_encrypt(), &msg)?
.into(),
),
4 => Ok(
key
.decrypt(PaddingScheme::new_oaep::<sha1::Sha1>(), &msg)?
.into(),
),
_ => Err(type_error("Unknown padding")),
}
}

#[op]
pub fn op_node_public_encrypt(
key: StringOrBuffer,
msg: StringOrBuffer,
padding: u32,
) -> Result<ZeroCopyBuf, AnyError> {
let key = RsaPublicKey::from_public_key_pem((&key).try_into()?)?;

let mut rng = rand::thread_rng();
match padding {
1 => Ok(
key
.encrypt(&mut rng, PaddingScheme::new_pkcs1v15_encrypt(), &msg)?
.into(),
),
4 => Ok(
key
.encrypt(&mut rng, PaddingScheme::new_oaep::<sha1::Sha1>(), &msg)?
.into(),
),
_ => Err(type_error("Unknown padding")),
}
}
44 changes: 3 additions & 41 deletions ext/node/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,47 +98,6 @@ pub fn init_polyfill() -> Extension {
let esm_files = include_js_files!(
dir "polyfills",
"_core.ts",
"_crypto/crypto_browserify/asn1.js/base/buffer.js",
"_crypto/crypto_browserify/asn1.js/base/node.js",
"_crypto/crypto_browserify/asn1.js/base/reporter.js",
"_crypto/crypto_browserify/asn1.js/constants/der.js",
"_crypto/crypto_browserify/asn1.js/decoders/der.js",
"_crypto/crypto_browserify/asn1.js/decoders/pem.js",
"_crypto/crypto_browserify/asn1.js/encoders/der.js",
"_crypto/crypto_browserify/asn1.js/encoders/pem.js",
"_crypto/crypto_browserify/asn1.js/mod.js",
"_crypto/crypto_browserify/bn.js/bn.js",
"_crypto/crypto_browserify/browserify_aes/aes.js",
"_crypto/crypto_browserify/browserify_aes/auth_cipher.js",
"_crypto/crypto_browserify/browserify_aes/decrypter.js",
"_crypto/crypto_browserify/browserify_aes/encrypter.js",
"_crypto/crypto_browserify/browserify_aes/ghash.js",
"_crypto/crypto_browserify/browserify_aes/incr32.js",
"_crypto/crypto_browserify/browserify_aes/mod.js",
"_crypto/crypto_browserify/browserify_aes/modes/cbc.js",
"_crypto/crypto_browserify/browserify_aes/modes/cfb.js",
"_crypto/crypto_browserify/browserify_aes/modes/cfb1.js",
"_crypto/crypto_browserify/browserify_aes/modes/cfb8.js",
"_crypto/crypto_browserify/browserify_aes/modes/ctr.js",
"_crypto/crypto_browserify/browserify_aes/modes/ecb.js",
"_crypto/crypto_browserify/browserify_aes/modes/mod.js",
"_crypto/crypto_browserify/browserify_aes/modes/ofb.js",
"_crypto/crypto_browserify/browserify_aes/stream_cipher.js",
"_crypto/crypto_browserify/browserify_aes/xor.ts",
"_crypto/crypto_browserify/browserify_rsa.js",
"_crypto/crypto_browserify/cipher_base.js",
"_crypto/crypto_browserify/evp_bytes_to_key.ts",
"_crypto/crypto_browserify/parse_asn1/asn1.js",
"_crypto/crypto_browserify/parse_asn1/certificate.js",
"_crypto/crypto_browserify/parse_asn1/fix_proc.js",
"_crypto/crypto_browserify/parse_asn1/mod.js",
"_crypto/crypto_browserify/public_encrypt/mgf.js",
"_crypto/crypto_browserify/public_encrypt/mod.js",
"_crypto/crypto_browserify/public_encrypt/private_decrypt.js",
"_crypto/crypto_browserify/public_encrypt/public_encrypt.js",
"_crypto/crypto_browserify/public_encrypt/with_public.js",
"_crypto/crypto_browserify/public_encrypt/xor.js",
"_crypto/crypto_browserify/randombytes.ts",
"_events.mjs",
"_fs/_fs_access.ts",
"_fs/_fs_appendFile.ts",
Expand Down Expand Up @@ -411,6 +370,9 @@ pub fn init_polyfill() -> Extension {
crypto::op_node_hash_update::decl(),
crypto::op_node_hash_digest::decl(),
crypto::op_node_hash_clone::decl(),
crypto::op_node_private_encrypt::decl(),
crypto::op_node_private_decrypt::decl(),
crypto::op_node_public_encrypt::decl(),
winerror::op_node_sys_to_uv_error::decl(),
v8::op_v8_cached_data_version_tag::decl(),
v8::op_v8_get_heap_statistics::decl(),
Expand Down
2 changes: 0 additions & 2 deletions ext/node/polyfills/_crypto/crypto_browserify/README.md

This file was deleted.

Loading