diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/node/lib.rs | 1 | ||||
-rw-r--r-- | ext/node/ops/crypto/keys.rs | 40 | ||||
-rw-r--r-- | ext/node/polyfills/internal/crypto/keys.ts | 11 |
3 files changed, 51 insertions, 1 deletions
diff --git a/ext/node/lib.rs b/ext/node/lib.rs index f2c1576cf..1023fced3 100644 --- a/ext/node/lib.rs +++ b/ext/node/lib.rs @@ -233,6 +233,7 @@ deno_core::extension!(deno_node, ops::crypto::op_node_verify_ed25519, ops::crypto::keys::op_node_create_private_key, ops::crypto::keys::op_node_create_ed_raw, + ops::crypto::keys::op_node_create_ec_jwk, ops::crypto::keys::op_node_create_public_key, ops::crypto::keys::op_node_create_secret_key, ops::crypto::keys::op_node_derive_public_key_from_private_key, diff --git a/ext/node/ops/crypto/keys.rs b/ext/node/ops/crypto/keys.rs index 7d7ec140e..eccd08564 100644 --- a/ext/node/ops/crypto/keys.rs +++ b/ext/node/ops/crypto/keys.rs @@ -13,6 +13,7 @@ use deno_core::unsync::spawn_blocking; use deno_core::GarbageCollected; use deno_core::ToJsBuffer; use ed25519_dalek::pkcs8::BitStringRef; +use elliptic_curve::JwkEcKey; use num_bigint::BigInt; use num_traits::FromPrimitive as _; use pkcs8::DecodePrivateKey as _; @@ -571,6 +572,36 @@ impl KeyObjectHandle { Ok(KeyObjectHandle::AsymmetricPublic(key)) } + pub fn new_ec_jwk( + jwk: &JwkEcKey, + is_public: bool, + ) -> Result<KeyObjectHandle, AnyError> { + // https://datatracker.ietf.org/doc/html/rfc7518#section-6.2.1.1 + let handle = match jwk.crv() { + "P-256" if is_public => { + KeyObjectHandle::AsymmetricPublic(AsymmetricPublicKey::Ec( + EcPublicKey::P256(p256::PublicKey::from_jwk(jwk)?), + )) + } + "P-256" => KeyObjectHandle::AsymmetricPrivate(AsymmetricPrivateKey::Ec( + EcPrivateKey::P256(p256::SecretKey::from_jwk(jwk)?), + )), + "P-384" if is_public => { + KeyObjectHandle::AsymmetricPublic(AsymmetricPublicKey::Ec( + EcPublicKey::P384(p384::PublicKey::from_jwk(jwk)?), + )) + } + "P-384" => KeyObjectHandle::AsymmetricPrivate(AsymmetricPrivateKey::Ec( + EcPrivateKey::P384(p384::SecretKey::from_jwk(jwk)?), + )), + _ => { + return Err(type_error(format!("unsupported curve: {}", jwk.crv()))); + } + }; + + Ok(handle) + } + pub fn new_ed_raw( curve: &str, data: &[u8], @@ -1083,6 +1114,15 @@ pub fn op_node_create_ed_raw( #[op2] #[cppgc] +pub fn op_node_create_ec_jwk( + #[serde] jwk: elliptic_curve::JwkEcKey, + is_public: bool, +) -> Result<KeyObjectHandle, AnyError> { + KeyObjectHandle::new_ec_jwk(&jwk, is_public) +} + +#[op2] +#[cppgc] pub fn op_node_create_public_key( #[buffer] key: &[u8], #[string] format: &str, diff --git a/ext/node/polyfills/internal/crypto/keys.ts b/ext/node/polyfills/internal/crypto/keys.ts index 97e565023..c2e9d95ee 100644 --- a/ext/node/polyfills/internal/crypto/keys.ts +++ b/ext/node/polyfills/internal/crypto/keys.ts @@ -12,6 +12,7 @@ const { } = primordials; import { + op_node_create_ec_jwk, op_node_create_ed_raw, op_node_create_private_key, op_node_create_public_key, @@ -311,7 +312,15 @@ function getKeyObjectHandleFromJwk(key, ctx) { } if (key.kty === "EC") { - throw new TypeError("ec jwk imports not implemented"); + validateString(key.crv, "key.crv"); + validateString(key.x, "key.x"); + validateString(key.y, "key.y"); + + if (!isPublic) { + validateString(key.d, "key.d"); + } + + return op_node_create_ec_jwk(key, isPublic); } throw new TypeError("rsa jwk imports not implemented"); |