Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit 539b33c

Browse files
committed
Assorted WebCrypto API fixes
- Accept `Ed25519` algorithm (supported as of cloudflare/workerd#500) - Return `Ed25519` as the algorithm for `NODE-ED25519` keys - Mark `X448` and `Ed448` algorithms as unsupported This passes Miniflare's test suite on Node 16.13.0 and 20.1.0. It also passes `panva/jose`'s `workerd` tap tests on Node 16.17.0 and 20.1.0. Some of those tests fail on 16.13.0 as support for the `X25519` algorithm was only added in 16.17.0. See https://nodejs.org/api/webcrypto.html#web-crypto-api for details.
1 parent b5c58ef commit 539b33c

File tree

2 files changed

+22
-8
lines changed

2 files changed

+22
-8
lines changed

packages/core/src/standards/crypto.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,20 @@ const usesModernEd25519 = (async () => {
7070
async function ensureValidNodeAlgorithm(
7171
algorithm: webcrypto.AlgorithmIdentifier | webcrypto.EcKeyAlgorithm
7272
): Promise<webcrypto.AlgorithmIdentifier | webcrypto.EcKeyAlgorithm> {
73+
// "X448" and "Ed448" are not supported by Workers
74+
if (
75+
typeof algorithm === "object" &&
76+
(algorithm.name === "X448" || algorithm.name === "Ed448")
77+
) {
78+
throw new DOMException("Unrecognized name.", "NotSupportedError");
79+
}
80+
if (
81+
typeof algorithm === "object" &&
82+
algorithm.name === "Ed25519" &&
83+
!(await usesModernEd25519)
84+
) {
85+
return { name: "NODE-ED25519", namedCurve: "NODE-ED25519" };
86+
}
7387
if (
7488
typeof algorithm === "object" &&
7589
algorithm.name === "NODE-ED25519" &&
@@ -83,19 +97,19 @@ async function ensureValidNodeAlgorithm(
8397
}
8498

8599
function ensureValidWorkerKey(key: webcrypto.CryptoKey): webcrypto.CryptoKey {
86-
// Users' workers will expect to see the `NODE-ED25519` algorithm, even if
87-
// we're using "Ed25519" internally (https://github.com/panva/jose/issues/446)
88-
if (key.algorithm.name === "Ed25519") key.algorithm.name = "NODE-ED25519";
100+
// Users' workers will expect to see the `Ed25519` algorithm, even if we're
101+
// using on an old Node version and using "Ed25519" internally
102+
if (key.algorithm.name === "NODE-ED25519") key.algorithm.name = "Ed25519";
89103
return key;
90104
}
91105

92106
async function ensureValidNodeKey(
93107
key: webcrypto.CryptoKey
94108
): Promise<webcrypto.CryptoKey> {
95-
if (key.algorithm.name === "NODE-ED25519" && (await usesModernEd25519)) {
109+
if (key.algorithm.name === "Ed25519" && !(await usesModernEd25519)) {
96110
return new Proxy(key, {
97111
get(target, property, receiver) {
98-
if (property === "algorithm") return { name: "Ed25519" };
112+
if (property === "algorithm") return { name: "NODE-ED25519" };
99113
return Reflect.get(target, property, receiver);
100114
},
101115
});

packages/core/test/standards/crypto.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ test("crypto: generateKey/exportKey: supports NODE-ED25519 algorithm", async (t)
100100
true,
101101
["sign", "verify"]
102102
);
103-
t.is(keyPair.publicKey.algorithm.name, "NODE-ED25519");
104-
t.is(keyPair.privateKey.algorithm.name, "NODE-ED25519");
103+
t.is(keyPair.publicKey.algorithm.name, "Ed25519");
104+
t.is(keyPair.privateKey.algorithm.name, "Ed25519");
105105
const exported = await crypto.subtle.exportKey("raw", keyPair.publicKey);
106106
t.is(exported.byteLength, 32);
107107
});
@@ -126,7 +126,7 @@ test("crypto: importKey/exportKey: supports NODE-ED25519 public keys", async (t)
126126
true,
127127
["verify"]
128128
);
129-
t.is(publicKey.algorithm.name, "NODE-ED25519");
129+
t.is(publicKey.algorithm.name, "Ed25519");
130130
const exported = await crypto.subtle.exportKey("raw", publicKey);
131131
t.is(Buffer.from(exported).toString("hex"), keyData);
132132
});

0 commit comments

Comments
 (0)