From 149a04486c416219854c51ae338710ece95265a3 Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Mon, 24 Apr 2023 16:15:58 +0200 Subject: [PATCH 01/23] feat(node/crypto): ECDH support for Node Crypto --- Cargo.lock | 20 ++++++++ ext/node/Cargo.toml | 1 + ext/node/lib.rs | 5 +- ext/node/ops/crypto/mod.rs | 48 +++++++++++++++++++ .../internal/crypto/diffiehellman.ts | 42 ++++++++++++---- ext/node/polyfills/internal/crypto/util.ts | 6 ++- third_party | 2 +- 7 files changed, 113 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 352ca751067ac5..825e5a961e7537 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1158,6 +1158,7 @@ dependencies = [ "ripemd", "rsa", "scrypt", + "secp256k1", "serde", "sha-1", "sha2", @@ -3963,6 +3964,25 @@ dependencies = [ "zeroize", ] +[[package]] +name = "secp256k1" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" +dependencies = [ + "rand", + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" +dependencies = [ + "cc", +] + [[package]] name = "security-framework" version = "2.8.2" diff --git a/ext/node/Cargo.toml b/ext/node/Cargo.toml index 576e62d5593e79..cfd32e7a91a27f 100644 --- a/ext/node/Cargo.toml +++ b/ext/node/Cargo.toml @@ -55,3 +55,4 @@ typenum = "1.15.0" # https://github.com/dalek-cryptography/x25519-dalek/pull/89 x25519-dalek = "2.0.0-pre.1" x509-parser = "0.15.0" +secp256k1 = { version = "0.27.0", features = ["rand-std"] } diff --git a/ext/node/lib.rs b/ext/node/lib.rs index cc4afb2b807ad4..7344a5b609bcc2 100644 --- a/ext/node/lib.rs +++ b/ext/node/lib.rs @@ -194,6 +194,7 @@ deno_core::extension!(deno_node, deps = [ deno_io, deno_fs ], parameters = [Env: NodeEnv], ops = [ +<<<<<<< HEAD ops::crypto::op_node_create_decipheriv, ops::crypto::op_node_cipheriv_encrypt, ops::crypto::op_node_cipheriv_final, @@ -238,6 +239,9 @@ deno_core::extension!(deno_node, ops::crypto::op_node_random_int, ops::crypto::op_node_scrypt_sync, ops::crypto::op_node_scrypt_async, + ops::crypto::op_node_ecdh_generate_keys, + ops::crypto::op_node_ecdh_compute_secret, + ops::crypto::op_node_ecdh_compute_public_key, ops::crypto::x509::op_node_x509_parse, ops::crypto::x509::op_node_x509_ca, ops::crypto::x509::op_node_x509_check_email, @@ -265,7 +269,6 @@ deno_core::extension!(deno_node, ops::zlib::op_zlib_init, ops::zlib::op_zlib_reset, op_node_build_os, - ops::require::op_require_init_paths, ops::require::op_require_node_module_paths, ops::require::op_require_proxy_path, diff --git a/ext/node/ops/crypto/mod.rs b/ext/node/ops/crypto/mod.rs index d224b40f7218bd..5adde183c2b2bf 100644 --- a/ext/node/ops/crypto/mod.rs +++ b/ext/node/ops/crypto/mod.rs @@ -24,6 +24,9 @@ use rsa::pkcs8::DecodePublicKey; use rsa::PublicKey; use rsa::RsaPrivateKey; use rsa::RsaPublicKey; +use secp256k1::ecdh::SharedSecret; +use secp256k1::Secp256k1; +use secp256k1::SecretKey; mod cipher; mod dh; @@ -901,3 +904,48 @@ pub async fn op_node_scrypt_async( }) .await? } + +#[op] +pub fn op_node_ecdh_generate_keys( + _curve: String, + pubbuf: &mut [u8], + privbuf: &mut [u8], +) -> Result<(), AnyError> { + let mut rng = rand::thread_rng(); + let secp = Secp256k1::new(); + let (privkey, pubkey) = secp.generate_keypair(&mut rng); + pubbuf.copy_from_slice(&pubkey.serialize_uncompressed()); + privbuf.copy_from_slice(&privkey.secret_bytes()); + + Ok(()) +} + +#[op] +pub fn op_node_ecdh_compute_secret( + _curve: String, + this_priv: &mut [u8], + their_pub: &mut [u8], + secret: &mut [u8], +) -> Result<(), AnyError> { + let this_secret_key = SecretKey::from_slice(this_priv).unwrap(); + let their_public_key = secp256k1::PublicKey::from_slice(their_pub).unwrap(); + let shared_secret = SharedSecret::new(&their_public_key, &this_secret_key); + + secret.copy_from_slice(&shared_secret.secret_bytes()); + Ok(()) +} + +#[op] +pub fn op_node_ecdh_compute_public_key( + _curve: String, + privkey: &[u8], + pubkey: &mut [u8], +) -> Result<(), AnyError> { + let secp = Secp256k1::new(); + let secret_key = SecretKey::from_slice(privkey).unwrap(); + let public_key = secp256k1::PublicKey::from_secret_key(&secp, &secret_key); + + pubkey.copy_from_slice(&public_key.serialize_uncompressed()); + + Ok(()) +} diff --git a/ext/node/polyfills/internal/crypto/diffiehellman.ts b/ext/node/polyfills/internal/crypto/diffiehellman.ts index 3aa1f80809b3c6..a8f000ff28ae77 100644 --- a/ext/node/polyfills/internal/crypto/diffiehellman.ts +++ b/ext/node/polyfills/internal/crypto/diffiehellman.ts @@ -10,10 +10,12 @@ import { ERR_INVALID_ARG_TYPE } from "ext:deno_node/internal/errors.ts"; import { validateInt32, validateString, + validateOneOf, } from "ext:deno_node/internal/validators.mjs"; import { Buffer } from "ext:deno_node/buffer.ts"; import { getDefaultEncoding, + getCurves, toBuf, } from "ext:deno_node/internal/crypto/util.ts"; import type { @@ -24,6 +26,8 @@ import type { import { KeyObject } from "ext:deno_node/internal/crypto/keys.ts"; import type { BufferEncoding } from "ext:deno_node/_global.d.ts"; +const { ops } = Deno.core; + const DH_GENERATOR = 2; export class DiffieHellman { @@ -219,10 +223,15 @@ export class DiffieHellmanGroup { } export class ECDH { + curve: string; // the selected curve + privbuf: Buffer; // the private key + pubbuf: Buffer; // the public key + constructor(curve: string) { validateString(curve, "curve"); + validateOneOf(curve, "curve", getCurves()); - notImplemented("crypto.ECDH"); + this.curve = curve; } static convertKey( @@ -250,11 +259,15 @@ export class ECDH { outputEncoding: BinaryToTextEncoding, ): string; computeSecret( - _otherPublicKey: ArrayBufferView | string, + otherPublicKey: ArrayBufferView | string, _inputEncoding?: BinaryToTextEncoding, _outputEncoding?: BinaryToTextEncoding, ): Buffer | string { - notImplemented("crypto.ECDH.prototype.computeSecret"); + let secretBuf = Buffer.alloc(32); + + ops.op_node_ecdh_compute_secret(this.curve, this.privbuf, otherPublicKey, secretBuf); + + return secretBuf; } generateKeys(): Buffer; @@ -263,13 +276,20 @@ export class ECDH { _encoding?: BinaryToTextEncoding, _format?: ECDHKeyFormat, ): Buffer | string { - notImplemented("crypto.ECDH.prototype.generateKeys"); + let pubbuf = Buffer.alloc(65); + let privbuf = Buffer.alloc(32); + + ops.op_node_ecdh_generate_keys(this.curve, pubbuf, privbuf); + + this.pubbuf = pubbuf; + this.privbuf = privbuf; + return pubbuf; } getPrivateKey(): Buffer; getPrivateKey(encoding: BinaryToTextEncoding): string; getPrivateKey(_encoding?: BinaryToTextEncoding): Buffer | string { - notImplemented("crypto.ECDH.prototype.getPrivateKey"); + return this.privbuf; } getPublicKey(): Buffer; @@ -278,16 +298,22 @@ export class ECDH { _encoding?: BinaryToTextEncoding, _format?: ECDHKeyFormat, ): Buffer | string { - notImplemented("crypto.ECDH.prototype.getPublicKey"); + return this.pubbuf; } setPrivateKey(privateKey: ArrayBufferView): void; setPrivateKey(privateKey: string, encoding: BinaryToTextEncoding): void; setPrivateKey( - _privateKey: ArrayBufferView | string, + privateKey: ArrayBufferView | string, _encoding?: BinaryToTextEncoding, ): Buffer | string { - notImplemented("crypto.ECDH.prototype.setPrivateKey"); + this.privbuf = privateKey; + let pubbuf = Buffer.alloc(65); + + ops.op_node_ecdh_compute_public_key(this.curve, this.privbuf, pubbuf); + this.pubbuf = pubbuf; + + return this.pubbuf; } } diff --git a/ext/node/polyfills/internal/crypto/util.ts b/ext/node/polyfills/internal/crypto/util.ts index ccb7726316319b..2f6b4b0fe1a074 100644 --- a/ext/node/polyfills/internal/crypto/util.ts +++ b/ext/node/polyfills/internal/crypto/util.ts @@ -46,6 +46,10 @@ const digestAlgorithms = [ "sha1", ]; +const ellipticCurves = [ + "secp256k1" +]; + // deno-fmt-ignore const supportedCiphers = [ "aes-128-ecb", "aes-192-ecb", @@ -115,7 +119,7 @@ export function getHashes(): readonly string[] { } export function getCurves(): readonly string[] { - notImplemented("crypto.getCurves"); + return ellipticCurves; } export interface SecureHeapUsage { diff --git a/third_party b/third_party index ee59830ca23fd0..fef5eaa2e364db 160000 --- a/third_party +++ b/third_party @@ -1 +1 @@ -Subproject commit ee59830ca23fd0aa423a3905005835c586e73e77 +Subproject commit fef5eaa2e364db431cfbf8089afdd81f71fd46d2 From 0071b10e9f48a4e3394d80b4e482c51057d194f1 Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Mon, 24 Apr 2023 17:31:00 +0200 Subject: [PATCH 02/23] bartek stuff --- Cargo.lock | 155 ++++++++++++++++++--- ext/node/Cargo.toml | 1 + ext/node/ops/crypto/mod.rs | 58 +++++--- ext/node/polyfills/internal/crypto/util.ts | 4 +- 4 files changed, 179 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 825e5a961e7537..772af1c165e374 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -243,6 +243,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base32" version = "0.4.0" @@ -595,6 +601,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "crypto-bigint" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c2538c4e68e52548bacb3e83ac549f903d44f011ac9d5abb5e132e67d0808f7" +dependencies = [ + "generic-array 0.14.6", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -877,15 +895,15 @@ dependencies = [ "curve25519-dalek 2.1.3", "deno_core", "deno_web", - "elliptic-curve", + "elliptic-curve 0.12.3", "num-traits", "once_cell", - "p256", + "p256 0.11.1", "p384", "rand", "ring", "rsa", - "sec1", + "sec1 0.3.0", "serde", "serde_bytes", "sha1", @@ -1150,6 +1168,7 @@ dependencies = [ "num-integer", "num-traits", "once_cell", + "p256 0.13.2", "path-clean", "pbkdf2", "rand", @@ -1372,7 +1391,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ "const-oid", - "pem-rfc7468", + "pem-rfc7468 0.6.0", "zeroize", ] @@ -1383,6 +1402,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82b10af9f9f9f2134a42d3f8aa74658660f2e0234b0eb81bd171df8aa32779ed" dependencies = [ "const-oid", + "pem-rfc7468 0.7.0", "zeroize", ] @@ -1629,11 +1649,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ "der 0.6.1", - "elliptic-curve", + "elliptic-curve 0.12.3", "rfc6979 0.3.1", "signature 1.6.4", ] +[[package]] +name = "ecdsa" +version = "0.16.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a48e5d537b8a30c0b023116d981b16334be1485af7ca68db3a2b7024cbc957fd" +dependencies = [ + "der 0.7.3", + "digest 0.10.6", + "elliptic-curve 0.13.4", + "rfc6979 0.4.0", + "signature 2.1.0", +] + [[package]] name = "either" version = "1.8.1" @@ -1646,18 +1679,38 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ - "base16ct", - "crypto-bigint", + "base16ct 0.1.1", + "crypto-bigint 0.4.9", "der 0.6.1", "digest 0.10.6", - "ff", + "ff 0.12.1", "generic-array 0.14.6", - "group", + "group 0.12.1", "hkdf", - "pem-rfc7468", + "pem-rfc7468 0.6.0", "pkcs8 0.9.0", "rand_core 0.6.4", - "sec1", + "sec1 0.3.0", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75c71eaa367f2e5d556414a8eea812bc62985c879748d6403edabd9cb03f16e7" +dependencies = [ + "base16ct 0.2.0", + "crypto-bigint 0.5.1", + "digest 0.10.6", + "ff 0.13.0", + "generic-array 0.14.6", + "group 0.13.0", + "pem-rfc7468 0.7.0", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "sec1 0.7.1", "subtle", "zeroize", ] @@ -1829,6 +1882,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "filetime" version = "0.2.20" @@ -2052,6 +2115,7 @@ checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -2107,7 +2171,18 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ - "ff", + "ff 0.12.1", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", "rand_core 0.6.4", "subtle", ] @@ -3130,8 +3205,20 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" dependencies = [ - "ecdsa", - "elliptic-curve", + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", + "sha2", +] + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa 0.16.6", + "elliptic-curve 0.13.4", + "primeorder", "sha2", ] @@ -3141,8 +3228,8 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfc8c5bf642dde52bb9e87c0ecd8ca5a76faac2eeed98dedb7c717997e1080aa" dependencies = [ - "ecdsa", - "elliptic-curve", + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", "sha2", ] @@ -3245,6 +3332,15 @@ dependencies = [ "base64ct", ] +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.2.0" @@ -3432,6 +3528,15 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "primeorder" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8d3875361e28f7753baefef104386e7aa47642c93023356d97fdef4003bfb5" +dependencies = [ + "elliptic-curve 0.13.4", +] + [[package]] name = "proc-macro-crate" version = "1.3.1" @@ -3690,7 +3795,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ - "crypto-bigint", + "crypto-bigint 0.4.9", "hmac", "zeroize", ] @@ -3956,7 +4061,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ - "base16ct", + "base16ct 0.1.1", "der 0.6.1", "generic-array 0.14.6", "pkcs8 0.9.0", @@ -3964,6 +4069,20 @@ dependencies = [ "zeroize", ] +[[package]] +name = "sec1" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48518a2b5775ba8ca5b46596aae011caa431e6ce7e4a67ead66d92f08884220e" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.3", + "generic-array 0.14.6", + "pkcs8 0.10.2", + "subtle", + "zeroize", +] + [[package]] name = "secp256k1" version = "0.27.0" diff --git a/ext/node/Cargo.toml b/ext/node/Cargo.toml index cfd32e7a91a27f..eb3876795bb987 100644 --- a/ext/node/Cargo.toml +++ b/ext/node/Cargo.toml @@ -56,3 +56,4 @@ typenum = "1.15.0" x25519-dalek = "2.0.0-pre.1" x509-parser = "0.15.0" secp256k1 = { version = "0.27.0", features = ["rand-std"] } +p256 = "0.13.2" diff --git a/ext/node/ops/crypto/mod.rs b/ext/node/ops/crypto/mod.rs index 5adde183c2b2bf..3548bf6d9b9978 100644 --- a/ext/node/ops/crypto/mod.rs +++ b/ext/node/ops/crypto/mod.rs @@ -907,45 +907,63 @@ pub async fn op_node_scrypt_async( #[op] pub fn op_node_ecdh_generate_keys( - _curve: String, + curve: &str, pubbuf: &mut [u8], privbuf: &mut [u8], ) -> Result<(), AnyError> { let mut rng = rand::thread_rng(); - let secp = Secp256k1::new(); - let (privkey, pubkey) = secp.generate_keypair(&mut rng); - pubbuf.copy_from_slice(&pubkey.serialize_uncompressed()); - privbuf.copy_from_slice(&privkey.secret_bytes()); - - Ok(()) + match curve { + "secp256k1" => { + let secp = Secp256k1::new(); + let (privkey, pubkey) = secp.generate_keypair(&mut rng); + pubbuf.copy_from_slice(&pubkey.serialize_uncompressed()); + privbuf.copy_from_slice(&privkey.secret_bytes()); + + Ok(()) + } + &_ => todo!(), + } } #[op] pub fn op_node_ecdh_compute_secret( - _curve: String, + curve: &str, this_priv: &mut [u8], their_pub: &mut [u8], secret: &mut [u8], ) -> Result<(), AnyError> { - let this_secret_key = SecretKey::from_slice(this_priv).unwrap(); - let their_public_key = secp256k1::PublicKey::from_slice(their_pub).unwrap(); - let shared_secret = SharedSecret::new(&their_public_key, &this_secret_key); - - secret.copy_from_slice(&shared_secret.secret_bytes()); - Ok(()) + match curve { + "secp256k1" => { + let this_secret_key = SecretKey::from_slice(this_priv).unwrap(); + let their_public_key = + secp256k1::PublicKey::from_slice(their_pub).unwrap(); + let shared_secret = + SharedSecret::new(&their_public_key, &this_secret_key); + + secret.copy_from_slice(&shared_secret.secret_bytes()); + Ok(()) + } + &_ => todo!(), + } } #[op] pub fn op_node_ecdh_compute_public_key( - _curve: String, + curve: &str, privkey: &[u8], pubkey: &mut [u8], ) -> Result<(), AnyError> { - let secp = Secp256k1::new(); - let secret_key = SecretKey::from_slice(privkey).unwrap(); - let public_key = secp256k1::PublicKey::from_secret_key(&secp, &secret_key); + match curve { + "secp256k1" => { + let secp = Secp256k1::new(); + let secret_key = SecretKey::from_slice(privkey).unwrap(); + let public_key = + secp256k1::PublicKey::from_secret_key(&secp, &secret_key); - pubkey.copy_from_slice(&public_key.serialize_uncompressed()); + pubkey.copy_from_slice(&public_key.serialize_uncompressed()); - Ok(()) + Ok(()) + } + &_ => todo!(), + } } diff --git a/ext/node/polyfills/internal/crypto/util.ts b/ext/node/polyfills/internal/crypto/util.ts index 2f6b4b0fe1a074..725f3f97ce5221 100644 --- a/ext/node/polyfills/internal/crypto/util.ts +++ b/ext/node/polyfills/internal/crypto/util.ts @@ -47,7 +47,9 @@ const digestAlgorithms = [ ]; const ellipticCurves = [ - "secp256k1" + "secp256k1", // Weirerstrass-class EC used by Bitcoin + "prime256v1", // NIST P-256 EC + "secp256r1" // NIST P-256 EC (same as above) ]; // deno-fmt-ignore From d5c23717ffa8893ab63db6adb4f7b61e54504603 Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Tue, 25 Apr 2023 02:31:28 +0200 Subject: [PATCH 03/23] two more curves --- Cargo.lock | 2 + ext/node/Cargo.toml | 3 +- ext/node/ops/crypto/mod.rs | 49 +++++++++++++++++-- .../internal/crypto/diffiehellman.ts | 25 ++++++++-- ext/node/polyfills/internal/crypto/util.ts | 11 ++++- 5 files changed, 80 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 772af1c165e374..d512309d43a88b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1155,6 +1155,7 @@ dependencies = [ "digest 0.10.6", "dsa", "ecb", + "elliptic-curve 0.13.4", "hex", "hkdf", "idna 0.3.0", @@ -1707,6 +1708,7 @@ dependencies = [ "ff 0.13.0", "generic-array 0.14.6", "group 0.13.0", + "hkdf", "pem-rfc7468 0.7.0", "pkcs8 0.10.2", "rand_core 0.6.4", diff --git a/ext/node/Cargo.toml b/ext/node/Cargo.toml index eb3876795bb987..64d42ae13ddc72 100644 --- a/ext/node/Cargo.toml +++ b/ext/node/Cargo.toml @@ -56,4 +56,5 @@ typenum = "1.15.0" x25519-dalek = "2.0.0-pre.1" x509-parser = "0.15.0" secp256k1 = { version = "0.27.0", features = ["rand-std"] } -p256 = "0.13.2" +p256 = { version = "0.13.2", features = ["ecdh"] } +elliptic-curve = { version = "0.13.4", features = ["alloc"] } diff --git a/ext/node/ops/crypto/mod.rs b/ext/node/ops/crypto/mod.rs index 3548bf6d9b9978..526b1b5c86af3f 100644 --- a/ext/node/ops/crypto/mod.rs +++ b/ext/node/ops/crypto/mod.rs @@ -5,6 +5,7 @@ use deno_core::error::AnyError; use deno_core::op; use deno_core::serde_v8; use deno_core::OpState; +use deno_core::Resource; use deno_core::ResourceId; use deno_core::StringOrBuffer; use deno_core::ZeroCopyBuf; @@ -15,9 +16,12 @@ use rand::distributions::Distribution; use rand::distributions::Uniform; use rand::thread_rng; use rand::Rng; +use std::borrow::Cow; use std::future::Future; use std::rc::Rc; +use p256::elliptic_curve::ecdh::EphemeralSecret; +use p256::NistP256; use rsa::padding::PaddingScheme; use rsa::pkcs8::DecodePrivateKey; use rsa::pkcs8::DecodePublicKey; @@ -905,12 +909,23 @@ pub async fn op_node_scrypt_async( .await? } +struct NodeCryptoWrapper { + secret: EphemeralSecret, +} + +impl Resource for NodeCryptoWrapper { + fn name(&self) -> Cow { + "node-crypto-secret-nist-p256".into() + } +} + #[op] pub fn op_node_ecdh_generate_keys( + state: &mut OpState, curve: &str, pubbuf: &mut [u8], privbuf: &mut [u8], -) -> Result<(), AnyError> { +) -> Result { let mut rng = rand::thread_rng(); match curve { "secp256k1" => { @@ -919,7 +934,17 @@ pub fn op_node_ecdh_generate_keys( pubbuf.copy_from_slice(&pubkey.serialize_uncompressed()); privbuf.copy_from_slice(&privkey.secret_bytes()); - Ok(()) + Ok(0) + } + "prime256v1" | "secp256r1" => { + let privkey = p256::ecdh::EphemeralSecret::random(&mut rng); + let pubkey = privkey.public_key(); + pubbuf.copy_from_slice(pubkey.to_sec1_bytes().as_ref()); + let rid = state + .resource_table + .add(NodeCryptoWrapper:: { secret: privkey }); + + Ok(rid) } &_ => todo!(), } @@ -927,14 +952,18 @@ pub fn op_node_ecdh_generate_keys( #[op] pub fn op_node_ecdh_compute_secret( + state: &mut OpState, curve: &str, - this_priv: &mut [u8], + resource_id: u32, + this_priv: Option<&mut [u8]>, their_pub: &mut [u8], secret: &mut [u8], ) -> Result<(), AnyError> { match curve { "secp256k1" => { - let this_secret_key = SecretKey::from_slice(this_priv).unwrap(); + let this_secret_key = + SecretKey::from_slice(this_priv.expect("no private key provided?")) + .unwrap(); let their_public_key = secp256k1::PublicKey::from_slice(their_pub).unwrap(); let shared_secret = @@ -943,6 +972,18 @@ pub fn op_node_ecdh_compute_secret( secret.copy_from_slice(&shared_secret.secret_bytes()); Ok(()) } + "prime256v1" | "secp256r1" => { + let ncp = state + .resource_table + .get::>(resource_id) + .expect("Invalid resource id"); + let es = &ncp.secret; + let public_key = + p256::PublicKey::from_sec1_bytes(their_pub).expect("bad public key"); + let shared_secret = es.diffie_hellman(&public_key); + secret.copy_from_slice(shared_secret.raw_secret_bytes()); + Ok(()) + } &_ => todo!(), } } diff --git a/ext/node/polyfills/internal/crypto/diffiehellman.ts b/ext/node/polyfills/internal/crypto/diffiehellman.ts index a8f000ff28ae77..ef055af8fe760e 100644 --- a/ext/node/polyfills/internal/crypto/diffiehellman.ts +++ b/ext/node/polyfills/internal/crypto/diffiehellman.ts @@ -16,6 +16,7 @@ import { Buffer } from "ext:deno_node/buffer.ts"; import { getDefaultEncoding, getCurves, + isCurveEphemeral, toBuf, } from "ext:deno_node/internal/crypto/util.ts"; import type { @@ -226,12 +227,15 @@ export class ECDH { curve: string; // the selected curve privbuf: Buffer; // the private key pubbuf: Buffer; // the public key + ephemeral_secret: boolean; // if true the secret is in the resource table + ephemeral_secret_resource: number; // the resource id in the table constructor(curve: string) { validateString(curve, "curve"); validateOneOf(curve, "curve", getCurves()); this.curve = curve; + this.ephemeral_secret = isCurveEphemeral(this.curve); } static convertKey( @@ -265,7 +269,14 @@ export class ECDH { ): Buffer | string { let secretBuf = Buffer.alloc(32); - ops.op_node_ecdh_compute_secret(this.curve, this.privbuf, otherPublicKey, secretBuf); + if (this.ephemeral_secret) { + console.log("ephemeral curve: ", this.curve); + ops.op_node_ecdh_compute_secret(this.curve, this.ephemeral_secret_resource, null, otherPublicKey, secretBuf); + } else { + console.log("computeSecret/NOT ephemeral curve:", this.curve); + console.log(this.privbuf); + ops.op_node_ecdh_compute_secret(this.curve, 0, this.privbuf, otherPublicKey, secretBuf); + } return secretBuf; } @@ -278,11 +289,17 @@ export class ECDH { ): Buffer | string { let pubbuf = Buffer.alloc(65); let privbuf = Buffer.alloc(32); - - ops.op_node_ecdh_generate_keys(this.curve, pubbuf, privbuf); + let rid = ops.op_node_ecdh_generate_keys(this.curve, pubbuf, privbuf); this.pubbuf = pubbuf; - this.privbuf = privbuf; + if (this.ephemeral_secret) { + console.log("genKeys/ephemeral curve: ", this.curve); + this.ephemeral_secret_resource = rid; + } else { + console.log("genKeys/NOT ephemeral curve: ", this.curve); + this.privbuf = privbuf; + } + return pubbuf; } diff --git a/ext/node/polyfills/internal/crypto/util.ts b/ext/node/polyfills/internal/crypto/util.ts index 725f3f97ce5221..a8ba90540ce994 100644 --- a/ext/node/polyfills/internal/crypto/util.ts +++ b/ext/node/polyfills/internal/crypto/util.ts @@ -47,11 +47,16 @@ const digestAlgorithms = [ ]; const ellipticCurves = [ - "secp256k1", // Weirerstrass-class EC used by Bitcoin + "secp256k1", // Weierstrass-class EC used by Bitcoin "prime256v1", // NIST P-256 EC "secp256r1" // NIST P-256 EC (same as above) ]; +const ephemeralEllipticCurves = [ + "prime256v1", + "secp256r1" +] + // deno-fmt-ignore const supportedCiphers = [ "aes-128-ecb", "aes-192-ecb", @@ -124,6 +129,10 @@ export function getCurves(): readonly string[] { return ellipticCurves; } +export function isCurveEphemeral(curve: string): boolean { + return ephemeralEllipticCurves.includes(curve); +} + export interface SecureHeapUsage { total: number; min: number; From 74d978b5b0cd5592afec00f07953d6f2ca959e37 Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Tue, 25 Apr 2023 02:39:04 +0200 Subject: [PATCH 04/23] zerooooo coppppyyyyy buffeeeeer i ran out of tea --- ext/node/ops/crypto/mod.rs | 9 +++++---- ext/node/polyfills/internal/crypto/diffiehellman.ts | 5 ----- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/ext/node/ops/crypto/mod.rs b/ext/node/ops/crypto/mod.rs index 526b1b5c86af3f..99ffa5ce48e704 100644 --- a/ext/node/ops/crypto/mod.rs +++ b/ext/node/ops/crypto/mod.rs @@ -955,15 +955,16 @@ pub fn op_node_ecdh_compute_secret( state: &mut OpState, curve: &str, resource_id: u32, - this_priv: Option<&mut [u8]>, + this_priv: Option, their_pub: &mut [u8], secret: &mut [u8], ) -> Result<(), AnyError> { match curve { "secp256k1" => { - let this_secret_key = - SecretKey::from_slice(this_priv.expect("no private key provided?")) - .unwrap(); + let this_secret_key = SecretKey::from_slice( + this_priv.expect("no private key provided?").as_ref(), + ) + .unwrap(); let their_public_key = secp256k1::PublicKey::from_slice(their_pub).unwrap(); let shared_secret = diff --git a/ext/node/polyfills/internal/crypto/diffiehellman.ts b/ext/node/polyfills/internal/crypto/diffiehellman.ts index ef055af8fe760e..783c6c68c3a131 100644 --- a/ext/node/polyfills/internal/crypto/diffiehellman.ts +++ b/ext/node/polyfills/internal/crypto/diffiehellman.ts @@ -270,11 +270,8 @@ export class ECDH { let secretBuf = Buffer.alloc(32); if (this.ephemeral_secret) { - console.log("ephemeral curve: ", this.curve); ops.op_node_ecdh_compute_secret(this.curve, this.ephemeral_secret_resource, null, otherPublicKey, secretBuf); } else { - console.log("computeSecret/NOT ephemeral curve:", this.curve); - console.log(this.privbuf); ops.op_node_ecdh_compute_secret(this.curve, 0, this.privbuf, otherPublicKey, secretBuf); } @@ -293,10 +290,8 @@ export class ECDH { this.pubbuf = pubbuf; if (this.ephemeral_secret) { - console.log("genKeys/ephemeral curve: ", this.curve); this.ephemeral_secret_resource = rid; } else { - console.log("genKeys/NOT ephemeral curve: ", this.curve); this.privbuf = privbuf; } From 4c88be70f93402a8c4a24229f1846439dd5cd50d Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Tue, 25 Apr 2023 02:41:29 +0200 Subject: [PATCH 05/23] setPrivateKey is not supported for EDCHE --- ext/node/polyfills/internal/crypto/diffiehellman.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ext/node/polyfills/internal/crypto/diffiehellman.ts b/ext/node/polyfills/internal/crypto/diffiehellman.ts index 783c6c68c3a131..16c1e863cce322 100644 --- a/ext/node/polyfills/internal/crypto/diffiehellman.ts +++ b/ext/node/polyfills/internal/crypto/diffiehellman.ts @@ -319,6 +319,10 @@ export class ECDH { privateKey: ArrayBufferView | string, _encoding?: BinaryToTextEncoding, ): Buffer | string { + if (this.ephemeral_secret) { + throw new Error("Curve " + this.curve + " does not support setPrivateKey"); + } + this.privbuf = privateKey; let pubbuf = Buffer.alloc(65); From d7a70324663b46f31deb2685a52b8af87f50e2bb Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Tue, 25 Apr 2023 16:29:08 +0200 Subject: [PATCH 06/23] p384 curve + cleanup --- Cargo.lock | 15 ++++- ext/node/Cargo.toml | 7 ++- ext/node/ops/crypto/mod.rs | 29 ++++++++++ .../internal/crypto/diffiehellman.ts | 58 ++++++++++++------- ext/node/polyfills/internal/crypto/util.ts | 52 ++++++++++++----- 5 files changed, 123 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d512309d43a88b..dc55f6d9666008 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -899,7 +899,7 @@ dependencies = [ "num-traits", "once_cell", "p256 0.11.1", - "p384", + "p384 0.11.2", "rand", "ring", "rsa", @@ -1170,6 +1170,7 @@ dependencies = [ "num-traits", "once_cell", "p256 0.13.2", + "p384 0.13.0", "path-clean", "pbkdf2", "rand", @@ -3235,6 +3236,18 @@ dependencies = [ "sha2", ] +[[package]] +name = "p384" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" +dependencies = [ + "ecdsa 0.16.6", + "elliptic-curve 0.13.4", + "primeorder", + "sha2", +] + [[package]] name = "parking_lot" version = "0.11.2" diff --git a/ext/node/Cargo.toml b/ext/node/Cargo.toml index 64d42ae13ddc72..268cc76bbd36a7 100644 --- a/ext/node/Cargo.toml +++ b/ext/node/Cargo.toml @@ -24,6 +24,7 @@ deno_semver.workspace = true digest = { version = "0.10.5", features = ["core-api", "std"] } dsa = "0.6.1" ecb.workspace = true +elliptic-curve = { version = "0.13.4", features = ["alloc"] } hex.workspace = true hkdf.workspace = true idna = "0.3.0" @@ -37,6 +38,8 @@ num-bigint-dig = "0.8.2" num-integer = "0.1.45" num-traits = "0.2.14" once_cell.workspace = true +p256 = { version = "0.13.2", features = ["ecdh"] } +p384 = { version = "0.13.0", features = ["ecdh"] } path-clean = "=0.1.0" pbkdf2 = "0.12.1" rand.workspace = true @@ -45,6 +48,7 @@ ring.workspace = true ripemd = "0.1.3" rsa.workspace = true scrypt = "0.11.0" +secp256k1 = { version = "0.27.0", features = ["rand-std"] } serde = "1.0.149" sha-1 = "0.10.0" sha2.workspace = true @@ -55,6 +59,3 @@ typenum = "1.15.0" # https://github.com/dalek-cryptography/x25519-dalek/pull/89 x25519-dalek = "2.0.0-pre.1" x509-parser = "0.15.0" -secp256k1 = { version = "0.27.0", features = ["rand-std"] } -p256 = { version = "0.13.2", features = ["ecdh"] } -elliptic-curve = { version = "0.13.4", features = ["alloc"] } diff --git a/ext/node/ops/crypto/mod.rs b/ext/node/ops/crypto/mod.rs index 99ffa5ce48e704..af2e922609da8f 100644 --- a/ext/node/ops/crypto/mod.rs +++ b/ext/node/ops/crypto/mod.rs @@ -22,6 +22,7 @@ use std::rc::Rc; use p256::elliptic_curve::ecdh::EphemeralSecret; use p256::NistP256; +use p384::NistP384; use rsa::padding::PaddingScheme; use rsa::pkcs8::DecodePrivateKey; use rsa::pkcs8::DecodePublicKey; @@ -919,6 +920,12 @@ impl Resource for NodeCryptoWrapper { } } +impl Resource for NodeCryptoWrapper { + fn name(&self) -> Cow { + "node-crypto-secret-nist-p384".into() + } +} + #[op] pub fn op_node_ecdh_generate_keys( state: &mut OpState, @@ -946,6 +953,16 @@ pub fn op_node_ecdh_generate_keys( Ok(rid) } + "secp384r1" => { + let privkey = p384::ecdh::EphemeralSecret::random(&mut rng); + let pubkey = privkey.public_key(); + pubbuf.copy_from_slice(pubkey.to_sec1_bytes().as_ref()); + let rid = state + .resource_table + .add(NodeCryptoWrapper:: { secret: privkey }); + + Ok(rid) + } &_ => todo!(), } } @@ -985,6 +1002,18 @@ pub fn op_node_ecdh_compute_secret( secret.copy_from_slice(shared_secret.raw_secret_bytes()); Ok(()) } + "secp384r1" => { + let ncp = state + .resource_table + .get::>(resource_id) + .expect("Invalid resource id"); + let es = &ncp.secret; + let public_key = + p384::PublicKey::from_sec1_bytes(their_pub).expect("bad public key"); + let shared_secret = es.diffie_hellman(&public_key); + secret.copy_from_slice(shared_secret.raw_secret_bytes()); + Ok(()) + } &_ => todo!(), } } diff --git a/ext/node/polyfills/internal/crypto/diffiehellman.ts b/ext/node/polyfills/internal/crypto/diffiehellman.ts index 16c1e863cce322..056fd81b0cacda 100644 --- a/ext/node/polyfills/internal/crypto/diffiehellman.ts +++ b/ext/node/polyfills/internal/crypto/diffiehellman.ts @@ -9,14 +9,15 @@ import { import { ERR_INVALID_ARG_TYPE } from "ext:deno_node/internal/errors.ts"; import { validateInt32, - validateString, validateOneOf, + validateString, } from "ext:deno_node/internal/validators.mjs"; import { Buffer } from "ext:deno_node/buffer.ts"; import { - getDefaultEncoding, + EllipticCurve, + ellipticCurves, getCurves, - isCurveEphemeral, + getDefaultEncoding, toBuf, } from "ext:deno_node/internal/crypto/util.ts"; import type { @@ -224,18 +225,21 @@ export class DiffieHellmanGroup { } export class ECDH { - curve: string; // the selected curve + curve: EllipticCurve; // the selected curve privbuf: Buffer; // the private key pubbuf: Buffer; // the public key - ephemeral_secret: boolean; // if true the secret is in the resource table ephemeral_secret_resource: number; // the resource id in the table constructor(curve: string) { validateString(curve, "curve"); validateOneOf(curve, "curve", getCurves()); - this.curve = curve; - this.ephemeral_secret = isCurveEphemeral(this.curve); + let c = ellipticCurves.find((x) => x.name == curve); + if (c == undefined) { + throw new Error("invalid curve"); + } + + this.curve = c; } static convertKey( @@ -267,12 +271,24 @@ export class ECDH { _inputEncoding?: BinaryToTextEncoding, _outputEncoding?: BinaryToTextEncoding, ): Buffer | string { - let secretBuf = Buffer.alloc(32); - - if (this.ephemeral_secret) { - ops.op_node_ecdh_compute_secret(this.curve, this.ephemeral_secret_resource, null, otherPublicKey, secretBuf); + let secretBuf = Buffer.alloc(this.curve.sharedSecretSize); + + if (this.curve.ephemeral) { + ops.op_node_ecdh_compute_secret( + this.curve.name, + this.ephemeral_secret_resource, + null, + otherPublicKey, + secretBuf, + ); } else { - ops.op_node_ecdh_compute_secret(this.curve, 0, this.privbuf, otherPublicKey, secretBuf); + ops.op_node_ecdh_compute_secret( + this.curve.name, + 0, + this.privbuf, + otherPublicKey, + secretBuf, + ); } return secretBuf; @@ -284,12 +300,12 @@ export class ECDH { _encoding?: BinaryToTextEncoding, _format?: ECDHKeyFormat, ): Buffer | string { - let pubbuf = Buffer.alloc(65); - let privbuf = Buffer.alloc(32); - let rid = ops.op_node_ecdh_generate_keys(this.curve, pubbuf, privbuf); + let pubbuf = Buffer.alloc(this.curve.publicKeySize); + let privbuf = Buffer.alloc(this.curve.privateKeySize); + let rid = ops.op_node_ecdh_generate_keys(this.curve.name, pubbuf, privbuf); this.pubbuf = pubbuf; - if (this.ephemeral_secret) { + if (this.curve.ephemeral) { this.ephemeral_secret_resource = rid; } else { this.privbuf = privbuf; @@ -319,14 +335,16 @@ export class ECDH { privateKey: ArrayBufferView | string, _encoding?: BinaryToTextEncoding, ): Buffer | string { - if (this.ephemeral_secret) { - throw new Error("Curve " + this.curve + " does not support setPrivateKey"); + if (this.curve.ephemeral) { + throw new Error( + "Curve " + this.curve.name + " does not support setPrivateKey", + ); } this.privbuf = privateKey; - let pubbuf = Buffer.alloc(65); + let pubbuf = Buffer.alloc(this.curve.publicKeySize); - ops.op_node_ecdh_compute_public_key(this.curve, this.privbuf, pubbuf); + ops.op_node_ecdh_compute_public_key(this.curve.name, this.privbuf, pubbuf); this.pubbuf = pubbuf; return this.pubbuf; diff --git a/ext/node/polyfills/internal/crypto/util.ts b/ext/node/polyfills/internal/crypto/util.ts index a8ba90540ce994..d3077208894704 100644 --- a/ext/node/polyfills/internal/crypto/util.ts +++ b/ext/node/polyfills/internal/crypto/util.ts @@ -46,16 +46,44 @@ const digestAlgorithms = [ "sha1", ]; -const ellipticCurves = [ - "secp256k1", // Weierstrass-class EC used by Bitcoin - "prime256v1", // NIST P-256 EC - "secp256r1" // NIST P-256 EC (same as above) -]; +export type EllipticCurve = { + name: string; + ephemeral: boolean; + privateKeySize: number; + publicKeySize: number; + sharedSecretSize: number; +}; -const ephemeralEllipticCurves = [ - "prime256v1", - "secp256r1" -] +export const ellipticCurves: Array = [ + { + name: "secp256k1", + ephemeral: false, + privateKeySize: 32, + publicKeySize: 65, + sharedSecretSize: 32, + }, // Weierstrass-class EC used by Bitcoin + { + name: "prime256v1", + ephemeral: true, + privateKeySize: 32, + publicKeySize: 65, + sharedSecretSize: 32, + }, // NIST P-256 EC + { + name: "secp256r1", + ephemeral: true, + privateKeySize: 32, + publicKeySize: 65, + sharedSecretSize: 32, + }, // NIST P-256 EC (same as above) + { + name: "secp384r1", + ephemeral: true, + privateKeySize: 48, + publicKeySize: 97, + sharedSecretSize: 48, + }, // NIST P-384 EC +]; // deno-fmt-ignore const supportedCiphers = [ @@ -126,11 +154,7 @@ export function getHashes(): readonly string[] { } export function getCurves(): readonly string[] { - return ellipticCurves; -} - -export function isCurveEphemeral(curve: string): boolean { - return ephemeralEllipticCurves.includes(curve); + return ellipticCurves.map((x) => x.name); } export interface SecureHeapUsage { From c538456df0078ac3e695a942e66ebbbb0fdda4b6 Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Tue, 25 Apr 2023 16:38:58 +0200 Subject: [PATCH 07/23] add NIST P-224 --- Cargo.lock | 13 ++++++++++ ext/node/Cargo.toml | 1 + ext/node/ops/crypto/mod.rs | 29 ++++++++++++++++++++++ ext/node/polyfills/internal/crypto/util.ts | 7 ++++++ 4 files changed, 50 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index dc55f6d9666008..2e146e49087aec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1169,6 +1169,7 @@ dependencies = [ "num-integer", "num-traits", "once_cell", + "p224", "p256 0.13.2", "p384 0.13.0", "path-clean", @@ -3202,6 +3203,18 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4030760ffd992bef45b0ae3f10ce1aba99e33464c90d14dd7c039884963ddc7a" +[[package]] +name = "p224" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30c06436d66652bc2f01ade021592c80a2aad401570a18aa18b82e440d2b9aa1" +dependencies = [ + "ecdsa 0.16.6", + "elliptic-curve 0.13.4", + "primeorder", + "sha2", +] + [[package]] name = "p256" version = "0.11.1" diff --git a/ext/node/Cargo.toml b/ext/node/Cargo.toml index 268cc76bbd36a7..84ee8e7ddbeb69 100644 --- a/ext/node/Cargo.toml +++ b/ext/node/Cargo.toml @@ -38,6 +38,7 @@ num-bigint-dig = "0.8.2" num-integer = "0.1.45" num-traits = "0.2.14" once_cell.workspace = true +p224 = { version = "0.13.0", features = ["ecdh"] } p256 = { version = "0.13.2", features = ["ecdh"] } p384 = { version = "0.13.0", features = ["ecdh"] } path-clean = "=0.1.0" diff --git a/ext/node/ops/crypto/mod.rs b/ext/node/ops/crypto/mod.rs index af2e922609da8f..ee956cd0f055bc 100644 --- a/ext/node/ops/crypto/mod.rs +++ b/ext/node/ops/crypto/mod.rs @@ -20,6 +20,7 @@ use std::borrow::Cow; use std::future::Future; use std::rc::Rc; +use p224::NistP224; use p256::elliptic_curve::ecdh::EphemeralSecret; use p256::NistP256; use p384::NistP384; @@ -926,6 +927,12 @@ impl Resource for NodeCryptoWrapper { } } +impl Resource for NodeCryptoWrapper { + fn name(&self) -> Cow { + "node-crypto-secret-nist-p224".into() + } +} + #[op] pub fn op_node_ecdh_generate_keys( state: &mut OpState, @@ -963,6 +970,16 @@ pub fn op_node_ecdh_generate_keys( Ok(rid) } + "secp224r1" => { + let privkey = p224::ecdh::EphemeralSecret::random(&mut rng); + let pubkey = privkey.public_key(); + pubbuf.copy_from_slice(pubkey.to_sec1_bytes().as_ref()); + let rid = state + .resource_table + .add(NodeCryptoWrapper:: { secret: privkey }); + + Ok(rid) + } &_ => todo!(), } } @@ -1014,6 +1031,18 @@ pub fn op_node_ecdh_compute_secret( secret.copy_from_slice(shared_secret.raw_secret_bytes()); Ok(()) } + "secp224r1" => { + let ncp = state + .resource_table + .get::>(resource_id) + .expect("Invalid resource id"); + let es = &ncp.secret; + let public_key = + p224::PublicKey::from_sec1_bytes(their_pub).expect("bad public key"); + let shared_secret = es.diffie_hellman(&public_key); + secret.copy_from_slice(shared_secret.raw_secret_bytes()); + Ok(()) + } &_ => todo!(), } } diff --git a/ext/node/polyfills/internal/crypto/util.ts b/ext/node/polyfills/internal/crypto/util.ts index d3077208894704..44e479d9106836 100644 --- a/ext/node/polyfills/internal/crypto/util.ts +++ b/ext/node/polyfills/internal/crypto/util.ts @@ -83,6 +83,13 @@ export const ellipticCurves: Array = [ publicKeySize: 97, sharedSecretSize: 48, }, // NIST P-384 EC + { + name: "secp224r1", + ephemeral: true, + privateKeySize: 28, + publicKeySize: 57, + sharedSecretSize: 28, + }, // NIST P-224 EC ]; // deno-fmt-ignore From 3a699e4dfcc64fb1e22d4ac2b318bb2462d83260 Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Tue, 25 Apr 2023 17:37:08 +0200 Subject: [PATCH 08/23] encoding support --- .../internal/crypto/diffiehellman.ts | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/ext/node/polyfills/internal/crypto/diffiehellman.ts b/ext/node/polyfills/internal/crypto/diffiehellman.ts index 056fd81b0cacda..267671d41e5556 100644 --- a/ext/node/polyfills/internal/crypto/diffiehellman.ts +++ b/ext/node/polyfills/internal/crypto/diffiehellman.ts @@ -297,9 +297,10 @@ export class ECDH { generateKeys(): Buffer; generateKeys(encoding: BinaryToTextEncoding, format?: ECDHKeyFormat): string; generateKeys( - _encoding?: BinaryToTextEncoding, + encoding?: BinaryToTextEncoding, _format?: ECDHKeyFormat, ): Buffer | string { + encoding = encoding ?? "__buffer"; let pubbuf = Buffer.alloc(this.curve.publicKeySize); let privbuf = Buffer.alloc(this.curve.privateKeySize); let rid = ops.op_node_ecdh_generate_keys(this.curve.name, pubbuf, privbuf); @@ -311,21 +312,31 @@ export class ECDH { this.privbuf = privbuf; } + if (encoding !== undefined) + return pubbuf.toString(encoding); return pubbuf; } getPrivateKey(): Buffer; getPrivateKey(encoding: BinaryToTextEncoding): string; - getPrivateKey(_encoding?: BinaryToTextEncoding): Buffer | string { + getPrivateKey(encoding?: BinaryToTextEncoding): Buffer | string { + if (this.curve.ephemeral) { + throw new Error("Curves that use ephemeral ECDH cannot be queried for their private key"); + } + + if (encoding !== undefined) + return this.privbuf.toString(encoding); return this.privbuf; } getPublicKey(): Buffer; getPublicKey(encoding: BinaryToTextEncoding, format?: ECDHKeyFormat): string; getPublicKey( - _encoding?: BinaryToTextEncoding, + encoding?: BinaryToTextEncoding, _format?: ECDHKeyFormat, ): Buffer | string { + if (encoding !== undefined) + return this.pubbuf.toString(encoding); return this.pubbuf; } @@ -333,7 +344,7 @@ export class ECDH { setPrivateKey(privateKey: string, encoding: BinaryToTextEncoding): void; setPrivateKey( privateKey: ArrayBufferView | string, - _encoding?: BinaryToTextEncoding, + encoding?: BinaryToTextEncoding, ): Buffer | string { if (this.curve.ephemeral) { throw new Error( @@ -347,6 +358,8 @@ export class ECDH { ops.op_node_ecdh_compute_public_key(this.curve.name, this.privbuf, pubbuf); this.pubbuf = pubbuf; + if (encoding !== undefined) + return this.pubbuf.toString(encoding); return this.pubbuf; } } From 45a4009c726ec045be8f205e70df65a194511c8e Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Tue, 25 Apr 2023 17:38:59 +0200 Subject: [PATCH 09/23] lint + fmt --- .../internal/crypto/diffiehellman.ts | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/ext/node/polyfills/internal/crypto/diffiehellman.ts b/ext/node/polyfills/internal/crypto/diffiehellman.ts index 267671d41e5556..ea23c8980c5f62 100644 --- a/ext/node/polyfills/internal/crypto/diffiehellman.ts +++ b/ext/node/polyfills/internal/crypto/diffiehellman.ts @@ -234,7 +234,7 @@ export class ECDH { validateString(curve, "curve"); validateOneOf(curve, "curve", getCurves()); - let c = ellipticCurves.find((x) => x.name == curve); + const c = ellipticCurves.find((x) => x.name == curve); if (c == undefined) { throw new Error("invalid curve"); } @@ -271,7 +271,7 @@ export class ECDH { _inputEncoding?: BinaryToTextEncoding, _outputEncoding?: BinaryToTextEncoding, ): Buffer | string { - let secretBuf = Buffer.alloc(this.curve.sharedSecretSize); + const secretBuf = Buffer.alloc(this.curve.sharedSecretSize); if (this.curve.ephemeral) { ops.op_node_ecdh_compute_secret( @@ -301,9 +301,13 @@ export class ECDH { _format?: ECDHKeyFormat, ): Buffer | string { encoding = encoding ?? "__buffer"; - let pubbuf = Buffer.alloc(this.curve.publicKeySize); - let privbuf = Buffer.alloc(this.curve.privateKeySize); - let rid = ops.op_node_ecdh_generate_keys(this.curve.name, pubbuf, privbuf); + const pubbuf = Buffer.alloc(this.curve.publicKeySize); + const privbuf = Buffer.alloc(this.curve.privateKeySize); + const rid = ops.op_node_ecdh_generate_keys( + this.curve.name, + pubbuf, + privbuf, + ); this.pubbuf = pubbuf; if (this.curve.ephemeral) { @@ -312,8 +316,9 @@ export class ECDH { this.privbuf = privbuf; } - if (encoding !== undefined) - return pubbuf.toString(encoding); + if (encoding !== undefined) { + return pubbuf.toString(encoding); + } return pubbuf; } @@ -321,11 +326,14 @@ export class ECDH { getPrivateKey(encoding: BinaryToTextEncoding): string; getPrivateKey(encoding?: BinaryToTextEncoding): Buffer | string { if (this.curve.ephemeral) { - throw new Error("Curves that use ephemeral ECDH cannot be queried for their private key"); + throw new Error( + "Curves that use ephemeral ECDH cannot be queried for their private key", + ); } - if (encoding !== undefined) + if (encoding !== undefined) { return this.privbuf.toString(encoding); + } return this.privbuf; } @@ -335,8 +343,9 @@ export class ECDH { encoding?: BinaryToTextEncoding, _format?: ECDHKeyFormat, ): Buffer | string { - if (encoding !== undefined) + if (encoding !== undefined) { return this.pubbuf.toString(encoding); + } return this.pubbuf; } @@ -353,13 +362,14 @@ export class ECDH { } this.privbuf = privateKey; - let pubbuf = Buffer.alloc(this.curve.publicKeySize); + const pubbuf = Buffer.alloc(this.curve.publicKeySize); ops.op_node_ecdh_compute_public_key(this.curve.name, this.privbuf, pubbuf); this.pubbuf = pubbuf; - if (encoding !== undefined) + if (encoding !== undefined) { return this.pubbuf.toString(encoding); + } return this.pubbuf; } } From 20d10a30675d5c9a9e8c973e6b5bf48232458d52 Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Tue, 25 Apr 2023 17:42:54 +0200 Subject: [PATCH 10/23] ?? --- ext/node/polyfills/internal/crypto/diffiehellman.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/ext/node/polyfills/internal/crypto/diffiehellman.ts b/ext/node/polyfills/internal/crypto/diffiehellman.ts index ea23c8980c5f62..5f73b63b36d0f8 100644 --- a/ext/node/polyfills/internal/crypto/diffiehellman.ts +++ b/ext/node/polyfills/internal/crypto/diffiehellman.ts @@ -300,7 +300,6 @@ export class ECDH { encoding?: BinaryToTextEncoding, _format?: ECDHKeyFormat, ): Buffer | string { - encoding = encoding ?? "__buffer"; const pubbuf = Buffer.alloc(this.curve.publicKeySize); const privbuf = Buffer.alloc(this.curve.privateKeySize); const rid = ops.op_node_ecdh_generate_keys( From cfe9f66a5eb52b7eb418918747c063a046df1d4d Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Wed, 26 Apr 2023 14:55:39 +0200 Subject: [PATCH 11/23] Convert ECDH fields to private --- .../internal/crypto/diffiehellman.ts | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/ext/node/polyfills/internal/crypto/diffiehellman.ts b/ext/node/polyfills/internal/crypto/diffiehellman.ts index 5f73b63b36d0f8..0c02ada23ca1f3 100644 --- a/ext/node/polyfills/internal/crypto/diffiehellman.ts +++ b/ext/node/polyfills/internal/crypto/diffiehellman.ts @@ -225,10 +225,10 @@ export class DiffieHellmanGroup { } export class ECDH { - curve: EllipticCurve; // the selected curve - privbuf: Buffer; // the private key - pubbuf: Buffer; // the public key - ephemeral_secret_resource: number; // the resource id in the table + #curve: EllipticCurve; // the selected curve + #privbuf: Buffer; // the private key + #pubbuf: Buffer; // the public key + #ephemeral_secret_resource: number; // the resource id in the table constructor(curve: string) { validateString(curve, "curve"); @@ -239,7 +239,7 @@ export class ECDH { throw new Error("invalid curve"); } - this.curve = c; + this.#curve = c; } static convertKey( @@ -271,21 +271,21 @@ export class ECDH { _inputEncoding?: BinaryToTextEncoding, _outputEncoding?: BinaryToTextEncoding, ): Buffer | string { - const secretBuf = Buffer.alloc(this.curve.sharedSecretSize); + const secretBuf = Buffer.alloc(this.#curve.sharedSecretSize); - if (this.curve.ephemeral) { + if (this.#curve.ephemeral) { ops.op_node_ecdh_compute_secret( - this.curve.name, - this.ephemeral_secret_resource, + this.#curve.name, + this.#ephemeral_secret_resource, null, otherPublicKey, secretBuf, ); } else { ops.op_node_ecdh_compute_secret( - this.curve.name, + this.#curve.name, 0, - this.privbuf, + this.#privbuf, otherPublicKey, secretBuf, ); @@ -300,19 +300,19 @@ export class ECDH { encoding?: BinaryToTextEncoding, _format?: ECDHKeyFormat, ): Buffer | string { - const pubbuf = Buffer.alloc(this.curve.publicKeySize); - const privbuf = Buffer.alloc(this.curve.privateKeySize); + const pubbuf = Buffer.alloc(this.#curve.publicKeySize); + const privbuf = Buffer.alloc(this.#curve.privateKeySize); const rid = ops.op_node_ecdh_generate_keys( - this.curve.name, + this.#curve.name, pubbuf, privbuf, ); - this.pubbuf = pubbuf; - if (this.curve.ephemeral) { - this.ephemeral_secret_resource = rid; + this.#pubbuf = pubbuf; + if (this.#curve.ephemeral) { + this.#ephemeral_secret_resource = rid; } else { - this.privbuf = privbuf; + this.#privbuf = privbuf; } if (encoding !== undefined) { @@ -324,16 +324,16 @@ export class ECDH { getPrivateKey(): Buffer; getPrivateKey(encoding: BinaryToTextEncoding): string; getPrivateKey(encoding?: BinaryToTextEncoding): Buffer | string { - if (this.curve.ephemeral) { + if (this.#curve.ephemeral) { throw new Error( "Curves that use ephemeral ECDH cannot be queried for their private key", ); } if (encoding !== undefined) { - return this.privbuf.toString(encoding); + return this.#privbuf.toString(encoding); } - return this.privbuf; + return this.#privbuf; } getPublicKey(): Buffer; @@ -343,9 +343,9 @@ export class ECDH { _format?: ECDHKeyFormat, ): Buffer | string { if (encoding !== undefined) { - return this.pubbuf.toString(encoding); + return this.#pubbuf.toString(encoding); } - return this.pubbuf; + return this.#pubbuf; } setPrivateKey(privateKey: ArrayBufferView): void; @@ -354,22 +354,22 @@ export class ECDH { privateKey: ArrayBufferView | string, encoding?: BinaryToTextEncoding, ): Buffer | string { - if (this.curve.ephemeral) { + if (this.#curve.ephemeral) { throw new Error( - "Curve " + this.curve.name + " does not support setPrivateKey", + "Curve " + this.#curve.name + " does not support setPrivateKey", ); } - this.privbuf = privateKey; - const pubbuf = Buffer.alloc(this.curve.publicKeySize); + this.#privbuf = privateKey; + const pubbuf = Buffer.alloc(this.#curve.publicKeySize); - ops.op_node_ecdh_compute_public_key(this.curve.name, this.privbuf, pubbuf); - this.pubbuf = pubbuf; + ops.op_node_ecdh_compute_public_key(this.#curve.name, this.#privbuf, pubbuf); + this.#pubbuf = pubbuf; if (encoding !== undefined) { - return this.pubbuf.toString(encoding); + return this.#pubbuf.toString(encoding); } - return this.pubbuf; + return this.#pubbuf; } } From f2ec7d0369ca39585d10a0dd20cbe58446fa16e9 Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Wed, 26 Apr 2023 14:57:14 +0200 Subject: [PATCH 12/23] nitpick camelcase --- ext/node/polyfills/internal/crypto/diffiehellman.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/node/polyfills/internal/crypto/diffiehellman.ts b/ext/node/polyfills/internal/crypto/diffiehellman.ts index 0c02ada23ca1f3..3d457bdbec68ac 100644 --- a/ext/node/polyfills/internal/crypto/diffiehellman.ts +++ b/ext/node/polyfills/internal/crypto/diffiehellman.ts @@ -228,7 +228,7 @@ export class ECDH { #curve: EllipticCurve; // the selected curve #privbuf: Buffer; // the private key #pubbuf: Buffer; // the public key - #ephemeral_secret_resource: number; // the resource id in the table + #ephemeralSecretResource: number; // the resource id in the table constructor(curve: string) { validateString(curve, "curve"); @@ -276,7 +276,7 @@ export class ECDH { if (this.#curve.ephemeral) { ops.op_node_ecdh_compute_secret( this.#curve.name, - this.#ephemeral_secret_resource, + this.#ephemeralSecretResource, null, otherPublicKey, secretBuf, @@ -310,7 +310,7 @@ export class ECDH { this.#pubbuf = pubbuf; if (this.#curve.ephemeral) { - this.#ephemeral_secret_resource = rid; + this.#ephemeralSecretResource = rid; } else { this.#privbuf = privbuf; } From e288daa77de8a2f4cd341034f2e01fa607eab876 Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Thu, 27 Apr 2023 11:19:23 +0200 Subject: [PATCH 13/23] use a lower level library --- ext/node/Cargo.toml | 2 +- ext/node/ops/crypto/mod.rs | 115 +++++++----------- .../internal/crypto/diffiehellman.ts | 42 ++----- ext/node/polyfills/internal/crypto/util.ts | 7 +- 4 files changed, 54 insertions(+), 112 deletions(-) diff --git a/ext/node/Cargo.toml b/ext/node/Cargo.toml index 84ee8e7ddbeb69..7c6ebcd703ffba 100644 --- a/ext/node/Cargo.toml +++ b/ext/node/Cargo.toml @@ -24,7 +24,7 @@ deno_semver.workspace = true digest = { version = "0.10.5", features = ["core-api", "std"] } dsa = "0.6.1" ecb.workspace = true -elliptic-curve = { version = "0.13.4", features = ["alloc"] } +elliptic-curve = { version = "0.13.4", features = ["alloc", "arithmetic", "ecdh"] } hex.workspace = true hkdf.workspace = true idna = "0.3.0" diff --git a/ext/node/ops/crypto/mod.rs b/ext/node/ops/crypto/mod.rs index ee956cd0f055bc..67ef16247ef22b 100644 --- a/ext/node/ops/crypto/mod.rs +++ b/ext/node/ops/crypto/mod.rs @@ -5,7 +5,6 @@ use deno_core::error::AnyError; use deno_core::op; use deno_core::serde_v8; use deno_core::OpState; -use deno_core::Resource; use deno_core::ResourceId; use deno_core::StringOrBuffer; use deno_core::ZeroCopyBuf; @@ -16,12 +15,10 @@ use rand::distributions::Distribution; use rand::distributions::Uniform; use rand::thread_rng; use rand::Rng; -use std::borrow::Cow; use std::future::Future; use std::rc::Rc; use p224::NistP224; -use p256::elliptic_curve::ecdh::EphemeralSecret; use p256::NistP256; use p384::NistP384; use rsa::padding::PaddingScheme; @@ -911,31 +908,8 @@ pub async fn op_node_scrypt_async( .await? } -struct NodeCryptoWrapper { - secret: EphemeralSecret, -} - -impl Resource for NodeCryptoWrapper { - fn name(&self) -> Cow { - "node-crypto-secret-nist-p256".into() - } -} - -impl Resource for NodeCryptoWrapper { - fn name(&self) -> Cow { - "node-crypto-secret-nist-p384".into() - } -} - -impl Resource for NodeCryptoWrapper { - fn name(&self) -> Cow { - "node-crypto-secret-nist-p224".into() - } -} - #[op] pub fn op_node_ecdh_generate_keys( - state: &mut OpState, curve: &str, pubbuf: &mut [u8], privbuf: &mut [u8], @@ -951,34 +925,25 @@ pub fn op_node_ecdh_generate_keys( Ok(0) } "prime256v1" | "secp256r1" => { - let privkey = p256::ecdh::EphemeralSecret::random(&mut rng); + let privkey = elliptic_curve::SecretKey::::random(&mut rng); let pubkey = privkey.public_key(); pubbuf.copy_from_slice(pubkey.to_sec1_bytes().as_ref()); - let rid = state - .resource_table - .add(NodeCryptoWrapper:: { secret: privkey }); - - Ok(rid) + privbuf.copy_from_slice(privkey.to_nonzero_scalar().to_bytes().as_ref()); + Ok(0) } "secp384r1" => { - let privkey = p384::ecdh::EphemeralSecret::random(&mut rng); + let privkey = elliptic_curve::SecretKey::::random(&mut rng); let pubkey = privkey.public_key(); pubbuf.copy_from_slice(pubkey.to_sec1_bytes().as_ref()); - let rid = state - .resource_table - .add(NodeCryptoWrapper:: { secret: privkey }); - - Ok(rid) + privbuf.copy_from_slice(privkey.to_nonzero_scalar().to_bytes().as_ref()); + Ok(0) } "secp224r1" => { - let privkey = p224::ecdh::EphemeralSecret::random(&mut rng); + let privkey = elliptic_curve::SecretKey::::random(&mut rng); let pubkey = privkey.public_key(); pubbuf.copy_from_slice(pubkey.to_sec1_bytes().as_ref()); - let rid = state - .resource_table - .add(NodeCryptoWrapper:: { secret: privkey }); - - Ok(rid) + privbuf.copy_from_slice(privkey.to_nonzero_scalar().to_bytes().as_ref()); + Ok(0) } &_ => todo!(), } @@ -986,9 +951,7 @@ pub fn op_node_ecdh_generate_keys( #[op] pub fn op_node_ecdh_compute_secret( - state: &mut OpState, curve: &str, - resource_id: u32, this_priv: Option, their_pub: &mut [u8], secret: &mut [u8], @@ -1008,39 +971,51 @@ pub fn op_node_ecdh_compute_secret( Ok(()) } "prime256v1" | "secp256r1" => { - let ncp = state - .resource_table - .get::>(resource_id) - .expect("Invalid resource id"); - let es = &ncp.secret; - let public_key = - p256::PublicKey::from_sec1_bytes(their_pub).expect("bad public key"); - let shared_secret = es.diffie_hellman(&public_key); + let their_public_key = + elliptic_curve::PublicKey::::from_sec1_bytes(their_pub) + .expect("bad public key"); + let this_private_key = elliptic_curve::SecretKey::::from_slice( + &this_priv.expect("must supply private key"), + ) + .expect("bad private key"); + let shared_secret = elliptic_curve::ecdh::diffie_hellman( + this_private_key.to_nonzero_scalar(), + their_public_key.as_affine(), + ); secret.copy_from_slice(shared_secret.raw_secret_bytes()); + Ok(()) } "secp384r1" => { - let ncp = state - .resource_table - .get::>(resource_id) - .expect("Invalid resource id"); - let es = &ncp.secret; - let public_key = - p384::PublicKey::from_sec1_bytes(their_pub).expect("bad public key"); - let shared_secret = es.diffie_hellman(&public_key); + let their_public_key = + elliptic_curve::PublicKey::::from_sec1_bytes(their_pub) + .expect("bad public key"); + let this_private_key = elliptic_curve::SecretKey::::from_slice( + &this_priv.expect("must supply private key"), + ) + .expect("bad private key"); + let shared_secret = elliptic_curve::ecdh::diffie_hellman( + this_private_key.to_nonzero_scalar(), + their_public_key.as_affine(), + ); secret.copy_from_slice(shared_secret.raw_secret_bytes()); + Ok(()) } "secp224r1" => { - let ncp = state - .resource_table - .get::>(resource_id) - .expect("Invalid resource id"); - let es = &ncp.secret; - let public_key = - p224::PublicKey::from_sec1_bytes(their_pub).expect("bad public key"); - let shared_secret = es.diffie_hellman(&public_key); + let their_public_key = + elliptic_curve::PublicKey::::from_sec1_bytes(their_pub) + .expect("bad public key"); + let this_private_key = elliptic_curve::SecretKey::::from_slice( + &this_priv.expect("must supply private key"), + ) + .expect("bad private key"); + let shared_secret = elliptic_curve::ecdh::diffie_hellman( + this_private_key.to_nonzero_scalar(), + their_public_key.as_affine(), + ); secret.copy_from_slice(shared_secret.raw_secret_bytes()); + Ok(()) } &_ => todo!(), diff --git a/ext/node/polyfills/internal/crypto/diffiehellman.ts b/ext/node/polyfills/internal/crypto/diffiehellman.ts index 3d457bdbec68ac..4e15cb3a1b3af8 100644 --- a/ext/node/polyfills/internal/crypto/diffiehellman.ts +++ b/ext/node/polyfills/internal/crypto/diffiehellman.ts @@ -228,7 +228,6 @@ export class ECDH { #curve: EllipticCurve; // the selected curve #privbuf: Buffer; // the private key #pubbuf: Buffer; // the public key - #ephemeralSecretResource: number; // the resource id in the table constructor(curve: string) { validateString(curve, "curve"); @@ -273,23 +272,12 @@ export class ECDH { ): Buffer | string { const secretBuf = Buffer.alloc(this.#curve.sharedSecretSize); - if (this.#curve.ephemeral) { - ops.op_node_ecdh_compute_secret( - this.#curve.name, - this.#ephemeralSecretResource, - null, - otherPublicKey, - secretBuf, - ); - } else { - ops.op_node_ecdh_compute_secret( - this.#curve.name, - 0, - this.#privbuf, - otherPublicKey, - secretBuf, - ); - } + ops.op_node_ecdh_compute_secret( + this.#curve.name, + this.#privbuf, + otherPublicKey, + secretBuf, + ); return secretBuf; } @@ -309,11 +297,7 @@ export class ECDH { ); this.#pubbuf = pubbuf; - if (this.#curve.ephemeral) { - this.#ephemeralSecretResource = rid; - } else { - this.#privbuf = privbuf; - } + this.#privbuf = privbuf; if (encoding !== undefined) { return pubbuf.toString(encoding); @@ -324,12 +308,6 @@ export class ECDH { getPrivateKey(): Buffer; getPrivateKey(encoding: BinaryToTextEncoding): string; getPrivateKey(encoding?: BinaryToTextEncoding): Buffer | string { - if (this.#curve.ephemeral) { - throw new Error( - "Curves that use ephemeral ECDH cannot be queried for their private key", - ); - } - if (encoding !== undefined) { return this.#privbuf.toString(encoding); } @@ -354,12 +332,6 @@ export class ECDH { privateKey: ArrayBufferView | string, encoding?: BinaryToTextEncoding, ): Buffer | string { - if (this.#curve.ephemeral) { - throw new Error( - "Curve " + this.#curve.name + " does not support setPrivateKey", - ); - } - this.#privbuf = privateKey; const pubbuf = Buffer.alloc(this.#curve.publicKeySize); diff --git a/ext/node/polyfills/internal/crypto/util.ts b/ext/node/polyfills/internal/crypto/util.ts index 44e479d9106836..2a5920dfc202d9 100644 --- a/ext/node/polyfills/internal/crypto/util.ts +++ b/ext/node/polyfills/internal/crypto/util.ts @@ -57,39 +57,34 @@ export type EllipticCurve = { export const ellipticCurves: Array = [ { name: "secp256k1", - ephemeral: false, privateKeySize: 32, publicKeySize: 65, sharedSecretSize: 32, }, // Weierstrass-class EC used by Bitcoin { name: "prime256v1", - ephemeral: true, privateKeySize: 32, publicKeySize: 65, sharedSecretSize: 32, }, // NIST P-256 EC { name: "secp256r1", - ephemeral: true, privateKeySize: 32, publicKeySize: 65, sharedSecretSize: 32, }, // NIST P-256 EC (same as above) { name: "secp384r1", - ephemeral: true, privateKeySize: 48, publicKeySize: 97, sharedSecretSize: 48, }, // NIST P-384 EC { name: "secp224r1", - ephemeral: true, privateKeySize: 28, publicKeySize: 57, sharedSecretSize: 28, - }, // NIST P-224 EC + } // NIST P-224 EC ]; // deno-fmt-ignore From 167fd741526dcb588605ad1529711d0cf9f24a0d Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Thu, 27 Apr 2023 13:17:31 +0200 Subject: [PATCH 14/23] setPrivateKey() using EC lllib --- ext/node/ops/crypto/mod.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/ext/node/ops/crypto/mod.rs b/ext/node/ops/crypto/mod.rs index 67ef16247ef22b..70316d225cdf17 100644 --- a/ext/node/ops/crypto/mod.rs +++ b/ext/node/ops/crypto/mod.rs @@ -1039,6 +1039,30 @@ pub fn op_node_ecdh_compute_public_key( Ok(()) } + "prime256v1" | "secp256r1" => { + let this_private_key = + elliptic_curve::SecretKey::::from_slice(&privkey) + .expect("bad private key"); + let public_key = this_private_key.public_key(); + pubkey.copy_from_slice(public_key.to_sec1_bytes().as_ref()); + Ok(()) + } + "secp384r1" => { + let this_private_key = + elliptic_curve::SecretKey::::from_slice(&privkey) + .expect("bad private key"); + let public_key = this_private_key.public_key(); + pubkey.copy_from_slice(public_key.to_sec1_bytes().as_ref()); + Ok(()) + } + "secp224r1" => { + let this_private_key = + elliptic_curve::SecretKey::::from_slice(&privkey) + .expect("bad private key"); + let public_key = this_private_key.public_key(); + pubkey.copy_from_slice(public_key.to_sec1_bytes().as_ref()); + Ok(()) + } &_ => todo!(), } } From ff2bff2a495a5e091610bad516aa68b25d0a8e6d Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Thu, 27 Apr 2023 15:39:35 +0200 Subject: [PATCH 15/23] review feedback --- Cargo.lock | 6 ++--- Cargo.toml | 4 ++++ ext/node/Cargo.toml | 8 +++---- .../internal/crypto/diffiehellman.ts | 24 +++++++------------ ext/node/polyfills/internal/crypto/util.ts | 3 ++- 5 files changed, 22 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2e146e49087aec..ddd92ea833813a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -603,9 +603,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2538c4e68e52548bacb3e83ac549f903d44f011ac9d5abb5e132e67d0808f7" +checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" dependencies = [ "generic-array 0.14.6", "rand_core 0.6.4", @@ -1705,7 +1705,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75c71eaa367f2e5d556414a8eea812bc62985c879748d6403edabd9cb03f16e7" dependencies = [ "base16ct 0.2.0", - "crypto-bigint 0.5.1", + "crypto-bigint 0.5.2", "digest 0.10.6", "ff 0.13.0", "generic-array 0.14.6", diff --git a/Cargo.toml b/Cargo.toml index 3b0a0abf2a8f51..5664a69ed224e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -139,6 +139,10 @@ tower-lsp = { version = "=0.17.0", features = ["proposed"] } url = { version = "2.3.1", features = ["serde", "expose_internals"] } uuid = { version = "1.3.0", features = ["v4"] } zstd = "=0.11.2" +elliptic-curve = { version = "0.13.4", features = ["alloc", "arithmetic", "ecdh", "std", "pem"] } +p224 = { version = "0.13.0", features = ["ecdh"] } +p256 = { version = "0.13.2", features = ["ecdh"] } +p384 = { version = "0.13.0", features = ["ecdh"] } # crypto rsa = { version = "0.7.0", default-features = false, features = ["std", "pem", "hazmat"] } # hazmat needed for PrehashSigner in ext/node diff --git a/ext/node/Cargo.toml b/ext/node/Cargo.toml index 7c6ebcd703ffba..2d0466a5f3669f 100644 --- a/ext/node/Cargo.toml +++ b/ext/node/Cargo.toml @@ -24,7 +24,6 @@ deno_semver.workspace = true digest = { version = "0.10.5", features = ["core-api", "std"] } dsa = "0.6.1" ecb.workspace = true -elliptic-curve = { version = "0.13.4", features = ["alloc", "arithmetic", "ecdh"] } hex.workspace = true hkdf.workspace = true idna = "0.3.0" @@ -38,9 +37,6 @@ num-bigint-dig = "0.8.2" num-integer = "0.1.45" num-traits = "0.2.14" once_cell.workspace = true -p224 = { version = "0.13.0", features = ["ecdh"] } -p256 = { version = "0.13.2", features = ["ecdh"] } -p384 = { version = "0.13.0", features = ["ecdh"] } path-clean = "=0.1.0" pbkdf2 = "0.12.1" rand.workspace = true @@ -60,3 +56,7 @@ typenum = "1.15.0" # https://github.com/dalek-cryptography/x25519-dalek/pull/89 x25519-dalek = "2.0.0-pre.1" x509-parser = "0.15.0" +p224.workspace = true +p256.workspace = true +p384.workspace = true +elliptic-curve.workspace = true diff --git a/ext/node/polyfills/internal/crypto/diffiehellman.ts b/ext/node/polyfills/internal/crypto/diffiehellman.ts index 4e15cb3a1b3af8..2ed7356de00428 100644 --- a/ext/node/polyfills/internal/crypto/diffiehellman.ts +++ b/ext/node/polyfills/internal/crypto/diffiehellman.ts @@ -9,7 +9,6 @@ import { import { ERR_INVALID_ARG_TYPE } from "ext:deno_node/internal/errors.ts"; import { validateInt32, - validateOneOf, validateString, } from "ext:deno_node/internal/validators.mjs"; import { Buffer } from "ext:deno_node/buffer.ts"; @@ -231,7 +230,6 @@ export class ECDH { constructor(curve: string) { validateString(curve, "curve"); - validateOneOf(curve, "curve", getCurves()); const c = ellipticCurves.find((x) => x.name == curve); if (c == undefined) { @@ -239,6 +237,8 @@ export class ECDH { } this.#curve = c; + this.#pubbuf = Buffer.alloc(this.#curve.publicKeySize); + this.#privbuf = Buffer.alloc(this.#curve.privateKeySize); } static convertKey( @@ -288,21 +288,16 @@ export class ECDH { encoding?: BinaryToTextEncoding, _format?: ECDHKeyFormat, ): Buffer | string { - const pubbuf = Buffer.alloc(this.#curve.publicKeySize); - const privbuf = Buffer.alloc(this.#curve.privateKeySize); - const rid = ops.op_node_ecdh_generate_keys( + ops.op_node_ecdh_generate_keys( this.#curve.name, - pubbuf, - privbuf, + this.#pubbuf, + this.#privbuf, ); - this.#pubbuf = pubbuf; - this.#privbuf = privbuf; - if (encoding !== undefined) { - return pubbuf.toString(encoding); + return this.#pubbuf.toString(encoding); } - return pubbuf; + return this.#pubbuf; } getPrivateKey(): Buffer; @@ -333,10 +328,9 @@ export class ECDH { encoding?: BinaryToTextEncoding, ): Buffer | string { this.#privbuf = privateKey; - const pubbuf = Buffer.alloc(this.#curve.publicKeySize); + this.#pubbuf = Buffer.alloc(this.#curve.publicKeySize); - ops.op_node_ecdh_compute_public_key(this.#curve.name, this.#privbuf, pubbuf); - this.#pubbuf = pubbuf; + ops.op_node_ecdh_compute_public_key(this.#curve.name, this.#privbuf, this.#pubbuf); if (encoding !== undefined) { return this.#pubbuf.toString(encoding); diff --git a/ext/node/polyfills/internal/crypto/util.ts b/ext/node/polyfills/internal/crypto/util.ts index 2a5920dfc202d9..b0f02e06c73486 100644 --- a/ext/node/polyfills/internal/crypto/util.ts +++ b/ext/node/polyfills/internal/crypto/util.ts @@ -155,8 +155,9 @@ export function getHashes(): readonly string[] { return digestAlgorithms; } +const curveNames = ellipticCurves.map((x) => x.name); export function getCurves(): readonly string[] { - return ellipticCurves.map((x) => x.name); + return curveNames; } export interface SecureHeapUsage { From 8f8aea00f78ce1a879b1ab89666c92a0edfe42fd Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Thu, 27 Apr 2023 15:42:14 +0200 Subject: [PATCH 16/23] fmt --- ext/node/Cargo.toml | 8 ++++---- ext/node/polyfills/internal/crypto/diffiehellman.ts | 6 +++++- ext/node/polyfills/internal/crypto/util.ts | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/ext/node/Cargo.toml b/ext/node/Cargo.toml index 2d0466a5f3669f..14928db3074122 100644 --- a/ext/node/Cargo.toml +++ b/ext/node/Cargo.toml @@ -24,6 +24,7 @@ deno_semver.workspace = true digest = { version = "0.10.5", features = ["core-api", "std"] } dsa = "0.6.1" ecb.workspace = true +elliptic-curve.workspace = true hex.workspace = true hkdf.workspace = true idna = "0.3.0" @@ -37,6 +38,9 @@ num-bigint-dig = "0.8.2" num-integer = "0.1.45" num-traits = "0.2.14" once_cell.workspace = true +p224.workspace = true +p256.workspace = true +p384.workspace = true path-clean = "=0.1.0" pbkdf2 = "0.12.1" rand.workspace = true @@ -56,7 +60,3 @@ typenum = "1.15.0" # https://github.com/dalek-cryptography/x25519-dalek/pull/89 x25519-dalek = "2.0.0-pre.1" x509-parser = "0.15.0" -p224.workspace = true -p256.workspace = true -p384.workspace = true -elliptic-curve.workspace = true diff --git a/ext/node/polyfills/internal/crypto/diffiehellman.ts b/ext/node/polyfills/internal/crypto/diffiehellman.ts index 2ed7356de00428..e549274525b19d 100644 --- a/ext/node/polyfills/internal/crypto/diffiehellman.ts +++ b/ext/node/polyfills/internal/crypto/diffiehellman.ts @@ -330,7 +330,11 @@ export class ECDH { this.#privbuf = privateKey; this.#pubbuf = Buffer.alloc(this.#curve.publicKeySize); - ops.op_node_ecdh_compute_public_key(this.#curve.name, this.#privbuf, this.#pubbuf); + ops.op_node_ecdh_compute_public_key( + this.#curve.name, + this.#privbuf, + this.#pubbuf, + ); if (encoding !== undefined) { return this.#pubbuf.toString(encoding); diff --git a/ext/node/polyfills/internal/crypto/util.ts b/ext/node/polyfills/internal/crypto/util.ts index b0f02e06c73486..2e269b7fad8d32 100644 --- a/ext/node/polyfills/internal/crypto/util.ts +++ b/ext/node/polyfills/internal/crypto/util.ts @@ -84,7 +84,7 @@ export const ellipticCurves: Array = [ privateKeySize: 28, publicKeySize: 57, sharedSecretSize: 28, - } // NIST P-224 EC + }, // NIST P-224 EC ]; // deno-fmt-ignore From 4f66175c90ccd09da797d8cd3660ff8cced141a5 Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Thu, 27 Apr 2023 15:43:18 +0200 Subject: [PATCH 17/23] Revert --- third_party | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party b/third_party index fef5eaa2e364db..ee59830ca23fd0 160000 --- a/third_party +++ b/third_party @@ -1 +1 @@ -Subproject commit fef5eaa2e364db431cfbf8089afdd81f71fd46d2 +Subproject commit ee59830ca23fd0aa423a3905005835c586e73e77 From efab55220e836caa356d1e1239b01cbb2a4236fd Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Thu, 27 Apr 2023 15:44:27 +0200 Subject: [PATCH 18/23] brain meltdown --- ext/node/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/ext/node/lib.rs b/ext/node/lib.rs index 7344a5b609bcc2..4e525fbab13d65 100644 --- a/ext/node/lib.rs +++ b/ext/node/lib.rs @@ -194,7 +194,6 @@ deno_core::extension!(deno_node, deps = [ deno_io, deno_fs ], parameters = [Env: NodeEnv], ops = [ -<<<<<<< HEAD ops::crypto::op_node_create_decipheriv, ops::crypto::op_node_cipheriv_encrypt, ops::crypto::op_node_cipheriv_final, From 169d685030b95bbe67d6e1d2822fc99eab49f123 Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Thu, 27 Apr 2023 15:49:01 +0200 Subject: [PATCH 19/23] lint --- ext/node/ops/crypto/mod.rs | 6 +++--- ext/node/polyfills/internal/crypto/diffiehellman.ts | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/ext/node/ops/crypto/mod.rs b/ext/node/ops/crypto/mod.rs index 70316d225cdf17..36497bc6a387ae 100644 --- a/ext/node/ops/crypto/mod.rs +++ b/ext/node/ops/crypto/mod.rs @@ -1041,7 +1041,7 @@ pub fn op_node_ecdh_compute_public_key( } "prime256v1" | "secp256r1" => { let this_private_key = - elliptic_curve::SecretKey::::from_slice(&privkey) + elliptic_curve::SecretKey::::from_slice(privkey) .expect("bad private key"); let public_key = this_private_key.public_key(); pubkey.copy_from_slice(public_key.to_sec1_bytes().as_ref()); @@ -1049,7 +1049,7 @@ pub fn op_node_ecdh_compute_public_key( } "secp384r1" => { let this_private_key = - elliptic_curve::SecretKey::::from_slice(&privkey) + elliptic_curve::SecretKey::::from_slice(privkey) .expect("bad private key"); let public_key = this_private_key.public_key(); pubkey.copy_from_slice(public_key.to_sec1_bytes().as_ref()); @@ -1057,7 +1057,7 @@ pub fn op_node_ecdh_compute_public_key( } "secp224r1" => { let this_private_key = - elliptic_curve::SecretKey::::from_slice(&privkey) + elliptic_curve::SecretKey::::from_slice(privkey) .expect("bad private key"); let public_key = this_private_key.public_key(); pubkey.copy_from_slice(public_key.to_sec1_bytes().as_ref()); diff --git a/ext/node/polyfills/internal/crypto/diffiehellman.ts b/ext/node/polyfills/internal/crypto/diffiehellman.ts index e549274525b19d..62a802126fa394 100644 --- a/ext/node/polyfills/internal/crypto/diffiehellman.ts +++ b/ext/node/polyfills/internal/crypto/diffiehellman.ts @@ -15,7 +15,6 @@ import { Buffer } from "ext:deno_node/buffer.ts"; import { EllipticCurve, ellipticCurves, - getCurves, getDefaultEncoding, toBuf, } from "ext:deno_node/internal/crypto/util.ts"; From e1edd6626318c4bbce8378e3fc414750273f1494 Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Thu, 27 Apr 2023 16:05:02 +0200 Subject: [PATCH 20/23] Fix deps --- ext/crypto/Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/crypto/Cargo.toml b/ext/crypto/Cargo.toml index 7f0d1fdf0ea5f7..a527190c81e37c 100644 --- a/ext/crypto/Cargo.toml +++ b/ext/crypto/Cargo.toml @@ -26,11 +26,11 @@ ctr = "0.9.1" curve25519-dalek = "2.1.3" deno_core.workspace = true deno_web.workspace = true -elliptic-curve = { version = "0.12.1", features = ["std", "pem"] } +elliptic-curve.workspace = true num-traits = "0.2.14" once_cell.workspace = true -p256 = { version = "0.11.1", features = ["ecdh"] } -p384 = "0.11.1" +p256.workspace = true +p384.workspace = true rand.workspace = true ring = { workspace = true, features = ["std"] } rsa.workspace = true From 8e75af4ab56894e0352b56ca8473f34d2d0de344 Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Thu, 27 Apr 2023 16:58:29 +0200 Subject: [PATCH 21/23] ? --- Cargo.lock | 143 ++++++++--------------------------------------------- Cargo.toml | 2 +- 2 files changed, 21 insertions(+), 124 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ddd92ea833813a..19ae0c566da55a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -589,18 +589,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crypto-bigint" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" -dependencies = [ - "generic-array 0.14.6", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - [[package]] name = "crypto-bigint" version = "0.5.2" @@ -895,11 +883,11 @@ dependencies = [ "curve25519-dalek 2.1.3", "deno_core", "deno_web", - "elliptic-curve 0.12.3", + "elliptic-curve", "num-traits", "once_cell", - "p256 0.11.1", - "p384 0.11.2", + "p256", + "p384", "rand", "ring", "rsa", @@ -1155,7 +1143,7 @@ dependencies = [ "digest 0.10.6", "dsa", "ecb", - "elliptic-curve 0.13.4", + "elliptic-curve", "hex", "hkdf", "idna 0.3.0", @@ -1170,8 +1158,8 @@ dependencies = [ "num-traits", "once_cell", "p224", - "p256 0.13.2", - "p384 0.13.0", + "p256", + "p384", "path-clean", "pbkdf2", "rand", @@ -1598,7 +1586,7 @@ dependencies = [ "num-bigint-dig", "num-traits", "pkcs8 0.10.2", - "rfc6979 0.4.0", + "rfc6979", "sha2", "signature 2.1.0", "zeroize", @@ -1645,18 +1633,6 @@ dependencies = [ "cipher", ] -[[package]] -name = "ecdsa" -version = "0.14.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" -dependencies = [ - "der 0.6.1", - "elliptic-curve 0.12.3", - "rfc6979 0.3.1", - "signature 1.6.4", -] - [[package]] name = "ecdsa" version = "0.16.6" @@ -1665,8 +1641,8 @@ checksum = "a48e5d537b8a30c0b023116d981b16334be1485af7ca68db3a2b7024cbc957fd" dependencies = [ "der 0.7.3", "digest 0.10.6", - "elliptic-curve 0.13.4", - "rfc6979 0.4.0", + "elliptic-curve", + "rfc6979", "signature 2.1.0", ] @@ -1676,28 +1652,6 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" -[[package]] -name = "elliptic-curve" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" -dependencies = [ - "base16ct 0.1.1", - "crypto-bigint 0.4.9", - "der 0.6.1", - "digest 0.10.6", - "ff 0.12.1", - "generic-array 0.14.6", - "group 0.12.1", - "hkdf", - "pem-rfc7468 0.6.0", - "pkcs8 0.9.0", - "rand_core 0.6.4", - "sec1 0.3.0", - "subtle", - "zeroize", -] - [[package]] name = "elliptic-curve" version = "0.13.4" @@ -1705,11 +1659,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75c71eaa367f2e5d556414a8eea812bc62985c879748d6403edabd9cb03f16e7" dependencies = [ "base16ct 0.2.0", - "crypto-bigint 0.5.2", + "crypto-bigint", "digest 0.10.6", - "ff 0.13.0", + "ff", "generic-array 0.14.6", - "group 0.13.0", + "group", "hkdf", "pem-rfc7468 0.7.0", "pkcs8 0.10.2", @@ -1876,16 +1830,6 @@ dependencies = [ "windows-sys 0.45.0", ] -[[package]] -name = "ff" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "ff" version = "0.13.0" @@ -2169,24 +2113,13 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" -[[package]] -name = "group" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" -dependencies = [ - "ff 0.12.1", - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "group" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "ff 0.13.0", + "ff", "rand_core 0.6.4", "subtle", ] @@ -3209,54 +3142,32 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30c06436d66652bc2f01ade021592c80a2aad401570a18aa18b82e440d2b9aa1" dependencies = [ - "ecdsa 0.16.6", - "elliptic-curve 0.13.4", + "ecdsa", + "elliptic-curve", "primeorder", "sha2", ] -[[package]] -name = "p256" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" -dependencies = [ - "ecdsa 0.14.8", - "elliptic-curve 0.12.3", - "sha2", -] - [[package]] name = "p256" version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" dependencies = [ - "ecdsa 0.16.6", - "elliptic-curve 0.13.4", + "ecdsa", + "elliptic-curve", "primeorder", "sha2", ] -[[package]] -name = "p384" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc8c5bf642dde52bb9e87c0ecd8ca5a76faac2eeed98dedb7c717997e1080aa" -dependencies = [ - "ecdsa 0.14.8", - "elliptic-curve 0.12.3", - "sha2", -] - [[package]] name = "p384" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" dependencies = [ - "ecdsa 0.16.6", - "elliptic-curve 0.13.4", + "ecdsa", + "elliptic-curve", "primeorder", "sha2", ] @@ -3562,7 +3473,7 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf8d3875361e28f7753baefef104386e7aa47642c93023356d97fdef4003bfb5" dependencies = [ - "elliptic-curve 0.13.4", + "elliptic-curve", ] [[package]] @@ -3817,17 +3728,6 @@ dependencies = [ "quick-error", ] -[[package]] -name = "rfc6979" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" -dependencies = [ - "crypto-bigint 0.4.9", - "hmac", - "zeroize", -] - [[package]] name = "rfc6979" version = "0.4.0" @@ -4092,9 +3992,6 @@ dependencies = [ "base16ct 0.1.1", "der 0.6.1", "generic-array 0.14.6", - "pkcs8 0.9.0", - "subtle", - "zeroize", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 5664a69ed224e0..0f7b2aa6248063 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -139,7 +139,7 @@ tower-lsp = { version = "=0.17.0", features = ["proposed"] } url = { version = "2.3.1", features = ["serde", "expose_internals"] } uuid = { version = "1.3.0", features = ["v4"] } zstd = "=0.11.2" -elliptic-curve = { version = "0.13.4", features = ["alloc", "arithmetic", "ecdh", "std", "pem"] } +elliptic-curve = { version = "0.13.4", features = ["alloc", "arithmetic", "ecdh", "std", "pem", "pkcs8"] } p224 = { version = "0.13.0", features = ["ecdh"] } p256 = { version = "0.13.2", features = ["ecdh"] } p384 = { version = "0.13.0", features = ["ecdh"] } From 4ff7487d9de867980a1728c3769be1f9cf5f7c52 Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Thu, 27 Apr 2023 17:16:32 +0200 Subject: [PATCH 22/23] Revert "?" This reverts commit 8e75af4ab56894e0352b56ca8473f34d2d0de344. --- Cargo.lock | 143 +++++++++++++++++++++++++++++++++++++++++++++-------- Cargo.toml | 2 +- 2 files changed, 124 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 19ae0c566da55a..ddd92ea833813a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -589,6 +589,18 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array 0.14.6", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + [[package]] name = "crypto-bigint" version = "0.5.2" @@ -883,11 +895,11 @@ dependencies = [ "curve25519-dalek 2.1.3", "deno_core", "deno_web", - "elliptic-curve", + "elliptic-curve 0.12.3", "num-traits", "once_cell", - "p256", - "p384", + "p256 0.11.1", + "p384 0.11.2", "rand", "ring", "rsa", @@ -1143,7 +1155,7 @@ dependencies = [ "digest 0.10.6", "dsa", "ecb", - "elliptic-curve", + "elliptic-curve 0.13.4", "hex", "hkdf", "idna 0.3.0", @@ -1158,8 +1170,8 @@ dependencies = [ "num-traits", "once_cell", "p224", - "p256", - "p384", + "p256 0.13.2", + "p384 0.13.0", "path-clean", "pbkdf2", "rand", @@ -1586,7 +1598,7 @@ dependencies = [ "num-bigint-dig", "num-traits", "pkcs8 0.10.2", - "rfc6979", + "rfc6979 0.4.0", "sha2", "signature 2.1.0", "zeroize", @@ -1633,6 +1645,18 @@ dependencies = [ "cipher", ] +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + [[package]] name = "ecdsa" version = "0.16.6" @@ -1641,8 +1665,8 @@ checksum = "a48e5d537b8a30c0b023116d981b16334be1485af7ca68db3a2b7024cbc957fd" dependencies = [ "der 0.7.3", "digest 0.10.6", - "elliptic-curve", - "rfc6979", + "elliptic-curve 0.13.4", + "rfc6979 0.4.0", "signature 2.1.0", ] @@ -1652,6 +1676,28 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", + "digest 0.10.6", + "ff 0.12.1", + "generic-array 0.14.6", + "group 0.12.1", + "hkdf", + "pem-rfc7468 0.6.0", + "pkcs8 0.9.0", + "rand_core 0.6.4", + "sec1 0.3.0", + "subtle", + "zeroize", +] + [[package]] name = "elliptic-curve" version = "0.13.4" @@ -1659,11 +1705,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75c71eaa367f2e5d556414a8eea812bc62985c879748d6403edabd9cb03f16e7" dependencies = [ "base16ct 0.2.0", - "crypto-bigint", + "crypto-bigint 0.5.2", "digest 0.10.6", - "ff", + "ff 0.13.0", "generic-array 0.14.6", - "group", + "group 0.13.0", "hkdf", "pem-rfc7468 0.7.0", "pkcs8 0.10.2", @@ -1830,6 +1876,16 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "ff" version = "0.13.0" @@ -2113,13 +2169,24 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "group" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "ff", + "ff 0.13.0", "rand_core 0.6.4", "subtle", ] @@ -3142,32 +3209,54 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30c06436d66652bc2f01ade021592c80a2aad401570a18aa18b82e440d2b9aa1" dependencies = [ - "ecdsa", - "elliptic-curve", + "ecdsa 0.16.6", + "elliptic-curve 0.13.4", "primeorder", "sha2", ] +[[package]] +name = "p256" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" +dependencies = [ + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", + "sha2", +] + [[package]] name = "p256" version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" dependencies = [ - "ecdsa", - "elliptic-curve", + "ecdsa 0.16.6", + "elliptic-curve 0.13.4", "primeorder", "sha2", ] +[[package]] +name = "p384" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc8c5bf642dde52bb9e87c0ecd8ca5a76faac2eeed98dedb7c717997e1080aa" +dependencies = [ + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", + "sha2", +] + [[package]] name = "p384" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" dependencies = [ - "ecdsa", - "elliptic-curve", + "ecdsa 0.16.6", + "elliptic-curve 0.13.4", "primeorder", "sha2", ] @@ -3473,7 +3562,7 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf8d3875361e28f7753baefef104386e7aa47642c93023356d97fdef4003bfb5" dependencies = [ - "elliptic-curve", + "elliptic-curve 0.13.4", ] [[package]] @@ -3728,6 +3817,17 @@ dependencies = [ "quick-error", ] +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint 0.4.9", + "hmac", + "zeroize", +] + [[package]] name = "rfc6979" version = "0.4.0" @@ -3992,6 +4092,9 @@ dependencies = [ "base16ct 0.1.1", "der 0.6.1", "generic-array 0.14.6", + "pkcs8 0.9.0", + "subtle", + "zeroize", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 0f7b2aa6248063..5664a69ed224e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -139,7 +139,7 @@ tower-lsp = { version = "=0.17.0", features = ["proposed"] } url = { version = "2.3.1", features = ["serde", "expose_internals"] } uuid = { version = "1.3.0", features = ["v4"] } zstd = "=0.11.2" -elliptic-curve = { version = "0.13.4", features = ["alloc", "arithmetic", "ecdh", "std", "pem", "pkcs8"] } +elliptic-curve = { version = "0.13.4", features = ["alloc", "arithmetic", "ecdh", "std", "pem"] } p224 = { version = "0.13.0", features = ["ecdh"] } p256 = { version = "0.13.2", features = ["ecdh"] } p384 = { version = "0.13.0", features = ["ecdh"] } From e2c99681bf1e53a5c00d09c589bdaf4507e38d9f Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Thu, 27 Apr 2023 17:16:41 +0200 Subject: [PATCH 23/23] Revert "Fix deps" This reverts commit e1edd6626318c4bbce8378e3fc414750273f1494. --- ext/crypto/Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/crypto/Cargo.toml b/ext/crypto/Cargo.toml index a527190c81e37c..7f0d1fdf0ea5f7 100644 --- a/ext/crypto/Cargo.toml +++ b/ext/crypto/Cargo.toml @@ -26,11 +26,11 @@ ctr = "0.9.1" curve25519-dalek = "2.1.3" deno_core.workspace = true deno_web.workspace = true -elliptic-curve.workspace = true +elliptic-curve = { version = "0.12.1", features = ["std", "pem"] } num-traits = "0.2.14" once_cell.workspace = true -p256.workspace = true -p384.workspace = true +p256 = { version = "0.11.1", features = ["ecdh"] } +p384 = "0.11.1" rand.workspace = true ring = { workspace = true, features = ["std"] } rsa.workspace = true