diff --git a/ext/node/ops/crypto/mod.rs b/ext/node/ops/crypto/mod.rs index e597a91090..7f593520b4 100644 --- a/ext/node/ops/crypto/mod.rs +++ b/ext/node/ops/crypto/mod.rs @@ -1480,14 +1480,11 @@ fn parse_public_key( } Ok(doc) } - "der" => { - match type_ { - "pkcs1" => pkcs8::Document::from_pkcs1_der(key) - .map_err(|_| type_error("Invalid PKCS1 public key")), - // TODO(@iuioiua): spki type - _ => Err(type_error(format!("Unsupported key type: {}", type_))), - } - } + "der" => match type_ { + "pkcs1" => pkcs8::Document::from_pkcs1_der(key) + .map_err(|_| type_error("Invalid PKCS1 public key")), + _ => Err(type_error(format!("Unsupported key type: {}", type_))), + }, _ => Err(type_error(format!("Unsupported key format: {}", format))), } } @@ -1499,8 +1496,14 @@ pub fn op_node_create_public_key( #[string] format: &str, #[string] type_: &str, ) -> Result { - let doc = parse_public_key(key, format, type_)?; - let pk_info = spki::SubjectPublicKeyInfoRef::try_from(doc.as_bytes())?; + let mut doc = None; + + let pk_info = if type_ != "spki" { + doc.replace(parse_public_key(key, format, type_)?); + spki::SubjectPublicKeyInfoRef::try_from(doc.as_ref().unwrap().as_bytes())? + } else { + spki::SubjectPublicKeyInfoRef::try_from(key)? + }; let alg = pk_info.algorithm.oid; diff --git a/ext/node/polyfills/internal/crypto/keys.ts b/ext/node/polyfills/internal/crypto/keys.ts index 33034d824c..74379015b4 100644 --- a/ext/node/polyfills/internal/crypto/keys.ts +++ b/ext/node/polyfills/internal/crypto/keys.ts @@ -66,7 +66,7 @@ export const getArrayBufferOrView = hideStackFrames( | Uint16Array | Uint32Array => { if (isAnyArrayBuffer(buffer)) { - return buffer; + return new Uint8Array(buffer); } if (typeof buffer === "string") { if (encoding === "buffer") { diff --git a/tests/unit_node/crypto/crypto_key_test.ts b/tests/unit_node/crypto/crypto_key_test.ts index 656c7bb241..bcb47b5a70 100644 --- a/tests/unit_node/crypto/crypto_key_test.ts +++ b/tests/unit_node/crypto/crypto_key_test.ts @@ -284,3 +284,32 @@ Deno.test("createPublicKey() EC", function () { assertEquals(key.asymmetricKeyType, "ec"); assertEquals(key.asymmetricKeyDetails?.namedCurve, "p256"); }); + +Deno.test("createPublicKey SPKI for DH", async function () { + const { publicKey, privateKey } = await crypto.subtle.generateKey( + { + name: "ECDH", + namedCurve: "P-384", + }, + true, + ["deriveKey", "deriveBits"], + ); + + const exportedPublicKey = await crypto.subtle.exportKey("spki", publicKey); + const exportedPrivateKey = await crypto.subtle.exportKey("pkcs8", privateKey); + + const pubKey = createPublicKey({ + key: Buffer.from(exportedPublicKey), + format: "der", + type: "spki", + }); + + const privKey = createPrivateKey({ + key: Buffer.from(exportedPrivateKey), + format: "der", + type: "pkcs8", + }); + + assertEquals(pubKey.asymmetricKeyType, "ec"); + assertEquals(privKey.asymmetricKeyType, "ec"); +});