From d0b5ff6db9ec42f645210de7c4806bad385bdfaf Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Mon, 13 Sep 2021 11:35:49 +0200 Subject: [PATCH] feat(ext/crypto): generate ECDH keys (#11870) Add support for ECDH algorithm in SubtleCrypto#generateKey. --- ext/crypto/00_crypto.js | 60 +++++++++++++++++- ext/crypto/lib.rs | 2 +- tools/wpt/expectation.json | 121 ++++++++----------------------------- 3 files changed, 86 insertions(+), 97 deletions(-) diff --git a/ext/crypto/00_crypto.js b/ext/crypto/00_crypto.js index 68a8e4f9f4..b3131a4f8c 100644 --- a/ext/crypto/00_crypto.js +++ b/ext/crypto/00_crypto.js @@ -82,6 +82,7 @@ "RSA-PSS": "RsaHashedKeyGenParams", "RSA-OAEP": "RsaHashedKeyGenParams", "ECDSA": "EcKeyGenParams", + "ECDH": "EcKeyGenParams", "AES-CTR": "AesKeyGenParams", "AES-CBC": "AesKeyGenParams", "AES-GCM": "AesKeyGenParams", @@ -1575,7 +1576,64 @@ // 17-20. return { publicKey, privateKey }; } - // TODO(lucacasonato): ECDH + case "ECDH": { + // 1. + if ( + ArrayPrototypeFind( + usages, + (u) => !ArrayPrototypeIncludes(["deriveKey", "deriveBits"], u), + ) !== undefined + ) { + throw new DOMException("Invalid key usages", "SyntaxError"); + } + + // 2-3. + const handle = {}; + if ( + ArrayPrototypeIncludes( + supportedNamedCurves, + normalizedAlgorithm.namedCurve, + ) + ) { + const keyData = await core.opAsync("op_crypto_generate_key", { + name: "ECDH", + namedCurve: normalizedAlgorithm.namedCurve, + }); + WeakMapPrototypeSet(KEY_STORE, handle, { + type: "pkcs8", + data: keyData, + }); + } else { + throw new DOMException("Curve not supported", "NotSupportedError"); + } + + // 4-6. + const algorithm = { + name: "ECDH", + namedCurve: normalizedAlgorithm.namedCurve, + }; + + // 7-11. + const publicKey = constructKey( + "public", + true, + usageIntersection(usages, []), + algorithm, + handle, + ); + + // 12-16. + const privateKey = constructKey( + "private", + extractable, + usageIntersection(usages, ["deriveKey", "deriveBits"]), + algorithm, + handle, + ); + + // 17-20. + return { publicKey, privateKey }; + } case "AES-CTR": case "AES-CBC": case "AES-GCM": { diff --git a/ext/crypto/lib.rs b/ext/crypto/lib.rs index cf2c379a08..47137b2109 100644 --- a/ext/crypto/lib.rs +++ b/ext/crypto/lib.rs @@ -168,7 +168,7 @@ pub async fn op_crypto_generate_key( private_key.to_pkcs1_der()?.as_ref().to_vec() } - Algorithm::Ecdsa => { + Algorithm::Ecdsa | Algorithm::Ecdh => { let curve: &EcdsaSigningAlgorithm = args.named_curve.ok_or_else(not_supported)?.into(); let rng = RingRand::SystemRandom::new(); diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json index 3ff6968991..b6968b7d63 100644 --- a/tools/wpt/expectation.json +++ b/tools/wpt/expectation.json @@ -12060,100 +12060,6 @@ "failures_AES-GCM.https.any.html": true, "failures_AES-KW.https.any.html": true, "failures_ECDH.https.any.html": [ - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [encrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, encrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, deriveKey, encrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, encrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, encrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [decrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, decrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, deriveKey, decrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, decrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, decrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [sign])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, sign])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, deriveKey, sign])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, sign])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, sign])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [verify])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, verify])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, deriveKey, verify])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, verify])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, verify])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [wrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, wrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, deriveKey, wrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, wrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, wrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [unwrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, unwrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, deriveKey, unwrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, unwrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, unwrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [encrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, encrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, deriveKey, encrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, encrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, encrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [decrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, decrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, deriveKey, decrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, decrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, decrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [sign])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, sign])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, deriveKey, sign])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, sign])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, sign])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [verify])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, verify])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, deriveKey, verify])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, verify])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, verify])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [wrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, wrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, deriveKey, wrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, wrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, wrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [unwrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, unwrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, deriveKey, unwrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, unwrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, unwrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [encrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, encrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, deriveKey, encrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, encrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, encrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [decrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, decrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, deriveKey, decrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, decrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, decrypt])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [sign])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, sign])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, deriveKey, sign])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, sign])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, sign])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [verify])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, verify])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, deriveKey, verify])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, verify])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, verify])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [wrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, wrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, deriveKey, wrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, wrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, wrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [unwrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, unwrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, deriveKey, unwrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, unwrapKey])", - "Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, unwrapKey])", - "Empty usages: generateKey({name: ECDH, namedCurve: P-256}, false, [])", - "Empty usages: generateKey({name: ECDH, namedCurve: P-256}, true, [])", - "Empty usages: generateKey({name: ECDH, namedCurve: P-384}, false, [])", - "Empty usages: generateKey({name: ECDH, namedCurve: P-384}, true, [])", "Empty usages: generateKey({name: ECDH, namedCurve: P-521}, false, [])", "Empty usages: generateKey({name: ECDH, namedCurve: P-521}, true, [])" ], @@ -12170,7 +12076,32 @@ "successes_AES-GCM.https.any.html": true, "successes_AES-KW.https.any.html": true, "successes_HMAC.https.any.html": true, - "successes_ECDH.https.any.html": false, + "successes_ECDH.https.any.html": [ + "Success: generateKey({name: ECDH, namedCurve: P-521}, false, [deriveKey])", + "Success: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey])", + "Success: generateKey({name: ECDH, namedCurve: P-521}, false, [deriveBits, deriveKey])", + "Success: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, deriveKey])", + "Success: generateKey({name: ECDH, namedCurve: P-521}, false, [deriveBits])", + "Success: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits])", + "Success: generateKey({name: ECDH, namedCurve: P-521}, false, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])", + "Success: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])", + "Success: generateKey({name: ecdh, namedCurve: P-521}, false, [deriveKey])", + "Success: generateKey({name: ecdh, namedCurve: P-521}, true, [deriveKey])", + "Success: generateKey({name: ecdh, namedCurve: P-521}, false, [deriveBits, deriveKey])", + "Success: generateKey({name: ecdh, namedCurve: P-521}, true, [deriveBits, deriveKey])", + "Success: generateKey({name: ecdh, namedCurve: P-521}, false, [deriveBits])", + "Success: generateKey({name: ecdh, namedCurve: P-521}, true, [deriveBits])", + "Success: generateKey({name: ecdh, namedCurve: P-521}, false, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])", + "Success: generateKey({name: ecdh, namedCurve: P-521}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])", + "Success: generateKey({name: Ecdh, namedCurve: P-521}, false, [deriveKey])", + "Success: generateKey({name: Ecdh, namedCurve: P-521}, true, [deriveKey])", + "Success: generateKey({name: Ecdh, namedCurve: P-521}, false, [deriveBits, deriveKey])", + "Success: generateKey({name: Ecdh, namedCurve: P-521}, true, [deriveBits, deriveKey])", + "Success: generateKey({name: Ecdh, namedCurve: P-521}, false, [deriveBits])", + "Success: generateKey({name: Ecdh, namedCurve: P-521}, true, [deriveBits])", + "Success: generateKey({name: Ecdh, namedCurve: P-521}, false, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])", + "Success: generateKey({name: Ecdh, namedCurve: P-521}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])" + ], "successes_ECDSA.https.any.html": [ "Success: generateKey({name: ECDSA, namedCurve: P-521}, false, [sign])", "Success: generateKey({name: ECDSA, namedCurve: P-521}, true, [sign])",