From a401a79c751dbe8f1bed1d4c542f1aa97ac70199 Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Thu, 6 Feb 2025 12:11:42 +0530 Subject: [PATCH] fix(ext/node): fix missing privateKey.x in curve25519 JWK (#27990) Fixes https://github.com/denoland/deno/issues/27972 --- ext/node/ops/crypto/keys.rs | 13 +++++++++++-- tests/unit_node/crypto/crypto_key_test.ts | 13 +++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/ext/node/ops/crypto/keys.rs b/ext/node/ops/crypto/keys.rs index 79b09faa267a7d..db16d9e4ddb06e 100644 --- a/ext/node/ops/crypto/keys.rs +++ b/ext/node/ops/crypto/keys.rs @@ -1463,19 +1463,28 @@ impl AsymmetricPrivateKey { AsymmetricPrivateKey::X25519(static_secret) => { let bytes = static_secret.to_bytes(); + let AsymmetricPublicKey::X25519(x) = self.to_public_key() else { + unreachable!(); + }; + Ok(deno_core::serde_json::json!({ - "kty": "OKP", "crv": "X25519", + "x": bytes_to_b64(x.as_bytes()), "d": bytes_to_b64(&bytes), + "kty": "OKP", })) } AsymmetricPrivateKey::Ed25519(key) => { let bytes = key.to_bytes(); + let AsymmetricPublicKey::Ed25519(x) = self.to_public_key() else { + unreachable!(); + }; Ok(deno_core::serde_json::json!({ - "kty": "OKP", "crv": "Ed25519", + "x": bytes_to_b64(x.as_bytes()), "d": bytes_to_b64(&bytes), + "kty": "OKP", })) } _ => Err(AsymmetricPrivateKeyJwkError::JwkExportNotImplementedForKeyType), diff --git a/tests/unit_node/crypto/crypto_key_test.ts b/tests/unit_node/crypto/crypto_key_test.ts index c8535fb7681a5f..d0685257953050 100644 --- a/tests/unit_node/crypto/crypto_key_test.ts +++ b/tests/unit_node/crypto/crypto_key_test.ts @@ -755,3 +755,16 @@ Deno.test("X509Certificate checkHost", function () { assertEquals(cert.checkHost("www.google.com"), undefined); assertEquals(cert.checkHost("agent1"), "agent1"); }); + +// https://github.com/denoland/deno/issues/27972 +Deno.test("curve25519 generate valid private jwk", function () { + const { publicKey, privateKey } = generateKeyPairSync("ed25519", { + publicKeyEncoding: { format: "jwk" }, + privateKeyEncoding: { format: "jwk" }, + }); + + // @ts-ignore @types/node broken + assert(!publicKey.d); + // @ts-ignore @types/node broken + assert(privateKey.d); +});