unjwt 0.8.3 → 0.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/_codec-jws.mjs +17 -17
- package/dist/_chunks/{jwk.mjs → _import-key.mjs} +36 -741
- package/dist/_chunks/_jwt-internal.mjs +19 -19
- package/dist/_chunks/jwe.d.mts +1 -0
- package/dist/_chunks/jwe.mjs +8 -7
- package/dist/_chunks/jwk.d.mts +205 -0
- package/dist/_chunks/jws.d.mts +4 -1
- package/dist/_chunks/jws.mjs +10 -10
- package/dist/_chunks/libs/unsecure.mjs +143 -130
- package/dist/adapters/elysia/index.d.mts +1 -1
- package/dist/adapters/elysia/index.mjs +3 -2
- package/dist/adapters/h3/index.d.mts +1 -1
- package/dist/adapters/h3/index.mjs +2 -1
- package/dist/adapters/h3v1/index.d.mts +1 -1
- package/dist/adapters/h3v1/index.mjs +2 -1
- package/dist/core/jwe.mjs +1 -1
- package/dist/core/jwk.d.mts +2 -204
- package/dist/core/jwk.mjs +712 -3
- package/dist/core/jws.mjs +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +2 -1
- package/dist/session/index.d.mts +1 -1
- package/dist/session/index.mjs +2 -1
- package/package.json +3 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { safeJsonParse,
|
|
2
|
-
import { JWTError, assertClaimValidationOptions, assertCritShape, assertCryptoKey, assertPlainObject, assertStringList, base64Parse, base64Stringify, base64UrlParse, base64UrlStringify, concatUint8Arrays,
|
|
3
|
-
import { ECDSA_CURVES,
|
|
1
|
+
import { safeJsonParse, textEncoder } from "./libs/unsecure.mjs";
|
|
2
|
+
import { JWTError, assertClaimValidationOptions, assertCritShape, assertCryptoKey, assertPlainObject, assertStringList, base64Parse, base64Stringify, base64UrlParse, base64UrlStringify, concatUint8Arrays, isCryptoKey, isCryptoKeyPair, isJWK, isJWKSet, isPlainObject, isPublicJWK, parsePayloadBytes, parsePayloadSegment, uint32be, validateJwtClaims } from "./_jwt-internal.mjs";
|
|
3
|
+
import { ECDSA_CURVES, aesBitsOf, checkKeyUsage, cryptoKeyCurve, digestUrl, hashBitsOf, inferJWEAllowedAlgorithms, inferJWSAllowedAlgorithms, innerKeyWrapAlg, isAlgorithm, isContentEncryptionAlgorithm, isECDHESAlgorithm, isEd25519Signature, isJWSAlgorithm, isKeyManagementAlgorithm, isPBES2Algorithm, jwsHashOf, lengthOf, modulusLengthOf, namedCurveOf, pbes2HashOf, rsaOaepHashOf, shaBitsOf, unusableKey } from "./digest.mjs";
|
|
4
4
|
const MAX_QUOTED_VALUE = 64;
|
|
5
5
|
function quoteTokenValue(value) {
|
|
6
6
|
const text = String(value);
|
|
@@ -154,7 +154,7 @@ function generateCEK(alg) {
|
|
|
154
154
|
}
|
|
155
155
|
function checkCEKLength(cek, expected) {
|
|
156
156
|
const actual = cek.byteLength << 3;
|
|
157
|
-
if (actual !== expected) throw new JWTError(`Invalid Content Encryption Key length
|
|
157
|
+
if (actual !== expected) throw new JWTError(`Invalid Content Encryption Key length, expected ${expected} bits (got ${actual})`, "ERR_INVALID_OPTION");
|
|
158
158
|
}
|
|
159
159
|
function assertOctKeyLength(bytes, alg) {
|
|
160
160
|
if (!alg) return;
|
|
@@ -446,7 +446,7 @@ function subtleMapping(jwk, alg) {
|
|
|
446
446
|
};
|
|
447
447
|
keyUsages = hasPrivateMember(jwk) ? ["decrypt", "unwrapKey"] : ["encrypt", "wrapKey"];
|
|
448
448
|
break;
|
|
449
|
-
default: throw new JWTError(`Invalid
|
|
449
|
+
default: throw new JWTError(`Invalid JWK "alg" ${quoteTokenValue(alg)}.`, "ERR_JWK_INVALID");
|
|
450
450
|
}
|
|
451
451
|
break;
|
|
452
452
|
case "EC":
|
|
@@ -474,7 +474,7 @@ function subtleMapping(jwk, alg) {
|
|
|
474
474
|
};
|
|
475
475
|
keyUsages = hasPrivateMember(jwk) ? ["deriveBits"] : [];
|
|
476
476
|
break;
|
|
477
|
-
default: throw new JWTError(`Invalid
|
|
477
|
+
default: throw new JWTError(`Invalid JWK "alg" ${quoteTokenValue(alg)}.`, "ERR_JWK_INVALID");
|
|
478
478
|
}
|
|
479
479
|
break;
|
|
480
480
|
case "OKP":
|
|
@@ -491,10 +491,10 @@ function subtleMapping(jwk, alg) {
|
|
|
491
491
|
algorithm = { name: requireCurve(jwk, ["X25519"]) };
|
|
492
492
|
keyUsages = hasPrivateMember(jwk) ? ["deriveBits"] : [];
|
|
493
493
|
break;
|
|
494
|
-
default: throw new JWTError(`Invalid
|
|
494
|
+
default: throw new JWTError(`Invalid JWK "alg" ${quoteTokenValue(alg)}.`, "ERR_JWK_INVALID");
|
|
495
495
|
}
|
|
496
496
|
break;
|
|
497
|
-
default: throw new JWTError(`Invalid
|
|
497
|
+
default: throw new JWTError(`Invalid JWK "kty" ${quoteTokenValue(jwk.kty)}.`, "ERR_JWK_INVALID");
|
|
498
498
|
}
|
|
499
499
|
return {
|
|
500
500
|
algorithm,
|
|
@@ -503,7 +503,7 @@ function subtleMapping(jwk, alg) {
|
|
|
503
503
|
}
|
|
504
504
|
function requireCurve(jwk, allowed) {
|
|
505
505
|
const crv = "crv" in jwk ? jwk.crv : void 0;
|
|
506
|
-
if (typeof crv !== "string" || !allowed.includes(crv)) throw new JWTError(`Invalid
|
|
506
|
+
if (typeof crv !== "string" || !allowed.includes(crv)) throw new JWTError(`Invalid JWK "crv" ${quoteTokenValue(crv)}, expected ${allowed.join(", ")}.`, "ERR_JWK_INVALID");
|
|
507
507
|
return crv;
|
|
508
508
|
}
|
|
509
509
|
function hasPrivateMember(jwk) {
|
|
@@ -542,7 +542,7 @@ async function deriveECDHESKey(publicKey, privateKey, algorithm, keyLength, apu
|
|
|
542
542
|
function ecdhDerivedBits(alg, enc) {
|
|
543
543
|
if (alg !== "ECDH-ES") return aesBitsOf(innerKeyWrapAlg(alg));
|
|
544
544
|
if (enc) return bitLengthCEK(enc);
|
|
545
|
-
throw new JWTError("ECDH-ES requires \"enc\"
|
|
545
|
+
throw new JWTError("ECDH-ES requires \"enc\" to derive the key.", "ERR_JWE_INVALID");
|
|
546
546
|
}
|
|
547
547
|
function generateEphemeralKeyPair(recipientKey) {
|
|
548
548
|
return crypto.subtle.generateKey(recipientKey.algorithm, true, ["deriveBits"]);
|
|
@@ -594,7 +594,7 @@ function assertPBES2Params(params) {
|
|
|
594
594
|
}
|
|
595
595
|
function assertPBES2Salt(salt, name) {
|
|
596
596
|
if (salt instanceof Uint8Array && salt.length >= 8) return;
|
|
597
|
-
throw new JWTError(`${name} must be 8 or more octets
|
|
597
|
+
throw new JWTError(`${name} must be 8 or more octets.`, "ERR_INVALID_OPTION");
|
|
598
598
|
}
|
|
599
599
|
function assertPBES2Count(count, name) {
|
|
600
600
|
if (typeof count !== "number" || !Number.isInteger(count) || count < 1) throw new JWTError(`${name} must be a positive integer.`, "ERR_INVALID_OPTION");
|
|
@@ -696,7 +696,7 @@ async function encryptKey(alg, enc, key, providedCek, providedParameters = {}) {
|
|
|
696
696
|
({encryptedKey, ...parameters} = await gcmkwEncrypt(alg, key, cek, iv));
|
|
697
697
|
break;
|
|
698
698
|
}
|
|
699
|
-
default: throw new JWTError(`
|
|
699
|
+
default: throw new JWTError(`Unsupported JWE "alg" ${quoteTokenValue(alg)}`, "ERR_JWE_ALG_NOT_ALLOWED");
|
|
700
700
|
}
|
|
701
701
|
return {
|
|
702
702
|
cek,
|
|
@@ -774,21 +774,21 @@ const EC_ECDH_CURVES = /* @__PURE__ */ new Set([
|
|
|
774
774
|
const OKP_ECDH_CURVES = /* @__PURE__ */ new Set(["X25519"]);
|
|
775
775
|
function contentAlgorithm(enc) {
|
|
776
776
|
if (enc) return enc;
|
|
777
|
-
throw new JWTError("ECDH-ES requires \"enc\"
|
|
777
|
+
throw new JWTError("ECDH-ES requires \"enc\" to derive the key.", "ERR_JWE_INVALID");
|
|
778
778
|
}
|
|
779
779
|
function assertEphemeralCurve(ephemeralKey, recipientKey) {
|
|
780
780
|
assertECDHKeyAllowed(ephemeralKey);
|
|
781
781
|
const ephemeralCurve = cryptoKeyCurve(ephemeralKey);
|
|
782
782
|
const recipientCurve = cryptoKeyCurve(recipientKey);
|
|
783
783
|
if (ephemeralCurve === recipientCurve) return;
|
|
784
|
-
throw new JWTError(`ECDH-ES ephemeral key curve ${quoteTokenValue(ephemeralCurve)} does not match
|
|
784
|
+
throw new JWTError(`ECDH-ES ephemeral key curve ${quoteTokenValue(ephemeralCurve)} does not match recipient curve ${quoteTokenValue(recipientCurve)}.`, "ERR_JWK_INVALID");
|
|
785
785
|
}
|
|
786
786
|
function invalidEpk(detail) {
|
|
787
787
|
return new JWTError(`Invalid JWE: "epk" ${detail}`, "ERR_JWE_INVALID");
|
|
788
788
|
}
|
|
789
789
|
function assertEpkCurve(epkCurve, recipientCurve) {
|
|
790
790
|
if (!recipientCurve || !epkCurve || epkCurve === recipientCurve) return;
|
|
791
|
-
throw invalidEpk(`curve "${epkCurve}" does not match
|
|
791
|
+
throw invalidEpk(`curve "${epkCurve}" does not match recipient curve "${recipientCurve}".`);
|
|
792
792
|
}
|
|
793
793
|
function toPublicEpkJwk(jwk) {
|
|
794
794
|
const { kty } = jwk;
|
|
@@ -863,7 +863,7 @@ const pemBody = (pem, descriptor) => {
|
|
|
863
863
|
return pem.slice(bodyStart, bodyEnd).replaceAll(/\s/g, "");
|
|
864
864
|
};
|
|
865
865
|
const genericExport = async (keyType, keyFormat, key) => {
|
|
866
|
-
if (!isCryptoKey(key)) throw new JWTError(
|
|
866
|
+
if (!isCryptoKey(key)) throw new JWTError("Key must be of type CryptoKey", "ERR_INVALID_OPTION");
|
|
867
867
|
if (!key.extractable) throw new JWTError("CryptoKey is not extractable", "ERR_JWK_INVALID");
|
|
868
868
|
if (key.type !== keyType) throw new JWTError(`key is not a ${keyType} key`, "ERR_JWK_INVALID");
|
|
869
869
|
return formatPEM(base64Stringify(new Uint8Array(await crypto.subtle.exportKey(keyFormat, key))), `${keyType.toUpperCase()} KEY`);
|
|
@@ -935,7 +935,7 @@ const genericImport = async (descriptor, keyFormat, pem, alg, options) => {
|
|
|
935
935
|
algorithm = { name: requireOKPCurve(keyData, "Ed25519") };
|
|
936
936
|
keyUsages = isPublic ? ["verify"] : ["sign"];
|
|
937
937
|
break;
|
|
938
|
-
default: throw new JWTError("Invalid or unsupported \"alg\"
|
|
938
|
+
default: throw new JWTError("Invalid or unsupported \"alg\" value", "ERR_JWK_UNSUPPORTED");
|
|
939
939
|
}
|
|
940
940
|
try {
|
|
941
941
|
return await crypto.subtle.importKey(keyFormat, keyData, algorithm, options?.extractable ?? isPublic, keyUsages);
|
|
@@ -1151,7 +1151,7 @@ function assertEntryLimit(count, limit, options) {
|
|
|
1151
1151
|
}
|
|
1152
1152
|
function assertCandidateLimit(count, limit) {
|
|
1153
1153
|
if (count <= limit) return;
|
|
1154
|
-
throw new JWTError(`${count} candidate keys exceed the limit of ${limit}
|
|
1154
|
+
throw new JWTError(`${count} candidate keys exceed the limit of ${limit}, narrow them with a "kid".`, "ERR_JWK_KEY_NOT_FOUND");
|
|
1155
1155
|
}
|
|
1156
1156
|
function assertJWKSetCandidates(candidates, options) {
|
|
1157
1157
|
if (candidates.length === 0) {
|
|
@@ -1199,20 +1199,20 @@ function assertProtectedOnlyOption(header, options) {
|
|
|
1199
1199
|
const { tier, family } = options;
|
|
1200
1200
|
for (const param of PROTECTED_ONLY_PARAMS[family]) {
|
|
1201
1201
|
if (!Object.hasOwn(header, param)) continue;
|
|
1202
|
-
throw new JWTError(`${family} "${param}" must be
|
|
1202
|
+
throw new JWTError(`${family} "${param}" must be in the protected header, not the ${tier} header.`, "ERR_INVALID_OPTION");
|
|
1203
1203
|
}
|
|
1204
1204
|
}
|
|
1205
1205
|
function assertProducerKeyHeaders(header, options) {
|
|
1206
1206
|
if (!header) return;
|
|
1207
1207
|
const { tier, family } = options;
|
|
1208
|
-
if (Object.hasOwn(header, "jwk") && !isPublicJWK(Reflect.get(header, "jwk"))) throw new JWTError(`${family} "jwk" in the ${tier} header must be a public JWK
|
|
1209
|
-
if (Object.hasOwn(header, "epk")) throw new JWTError(`${family} "epk" is
|
|
1208
|
+
if (Object.hasOwn(header, "jwk") && !isPublicJWK(Reflect.get(header, "jwk"))) throw new JWTError(`${family} "jwk" in the ${tier} header must be a public JWK.`, "ERR_INVALID_OPTION");
|
|
1209
|
+
if (Object.hasOwn(header, "epk")) throw new JWTError(`${family} "epk" is not a header option, use "ecdh.ephemeralKey".`, "ERR_INVALID_OPTION");
|
|
1210
1210
|
}
|
|
1211
1211
|
function assertProducerConfirmation(payload) {
|
|
1212
1212
|
if (typeof payload !== "object" || payload === null) return;
|
|
1213
1213
|
const cnf = Reflect.get(payload, "cnf");
|
|
1214
1214
|
if (typeof cnf !== "object" || cnf === null || !Object.hasOwn(cnf, "jwk")) return;
|
|
1215
|
-
if (!isPublicJWK(Reflect.get(cnf, "jwk"))) throw new JWTError("Invalid JWT \"cnf\"
|
|
1215
|
+
if (!isPublicJWK(Reflect.get(cnf, "jwk"))) throw new JWTError("Invalid JWT \"cnf\": \"jwk\" must be a public JWK.", "ERR_JWT_CLAIM_INVALID");
|
|
1216
1216
|
}
|
|
1217
1217
|
function assertOptionEntry(entry, options) {
|
|
1218
1218
|
const { label, objects } = options;
|
|
@@ -1226,12 +1226,12 @@ function assertProducerPartyInfo(name, value) {
|
|
|
1226
1226
|
function assertProducerCEK(cek, enc) {
|
|
1227
1227
|
if (cek === void 0) return;
|
|
1228
1228
|
const expected = bitLengthCEK(enc) >> 3;
|
|
1229
|
-
if (!(cek instanceof Uint8Array) || cek.length !== expected) throw new JWTError(`"cek" must be ${expected} bytes for ${enc}
|
|
1229
|
+
if (!(cek instanceof Uint8Array) || cek.length !== expected) throw new JWTError(`"cek" must be ${expected} bytes for ${enc}.`, "ERR_INVALID_OPTION");
|
|
1230
1230
|
}
|
|
1231
1231
|
function assertProducerIV(iv, enc) {
|
|
1232
1232
|
if (iv === void 0) return;
|
|
1233
1233
|
const expected = bitLengthIV(enc) >> 3;
|
|
1234
|
-
if (!(iv instanceof Uint8Array) || iv.length !== expected) throw new JWTError(`"contentEncryptionIV" must be ${expected} bytes for ${enc}
|
|
1234
|
+
if (!(iv instanceof Uint8Array) || iv.length !== expected) throw new JWTError(`"contentEncryptionIV" must be ${expected} bytes for ${enc}.`, "ERR_INVALID_OPTION");
|
|
1235
1235
|
}
|
|
1236
1236
|
function assertConsumerOptions(options) {
|
|
1237
1237
|
assertOptionEntry(options, {
|
|
@@ -1320,7 +1320,7 @@ function buildECDHAgreementParams(ecdh) {
|
|
|
1320
1320
|
}
|
|
1321
1321
|
async function resolveSigningKey(alg, key, usage) {
|
|
1322
1322
|
if (key instanceof Uint8Array) {
|
|
1323
|
-
if (alg !== "HS256" && alg !== "HS384" && alg !== "HS512") throw new JWTError(
|
|
1323
|
+
if (alg !== "HS256" && alg !== "HS384" && alg !== "HS512") throw new JWTError(`${alg} needs an asymmetric key, not raw bytes.`, "ERR_JWK_INVALID");
|
|
1324
1324
|
assertOctKeyLength(key, alg);
|
|
1325
1325
|
return crypto.subtle.importKey("raw", key, {
|
|
1326
1326
|
name: "HMAC",
|
|
@@ -1348,13 +1348,13 @@ function resolvePayloadMode(options) {
|
|
|
1348
1348
|
let mode = payload ?? "json";
|
|
1349
1349
|
if (forceUint8Array !== void 0) {
|
|
1350
1350
|
if (payload === void 0) mode = forceUint8Array ? "bytes" : "json";
|
|
1351
|
-
else if (forceUint8Array !== (payload === "bytes")) throw new JWTError("\"forceUint8Array\" contradicts \"payload\"
|
|
1351
|
+
else if (forceUint8Array !== (payload === "bytes")) throw new JWTError("\"forceUint8Array\" contradicts \"payload\", pass \"payload\" alone.", "ERR_INVALID_OPTION");
|
|
1352
1352
|
}
|
|
1353
1353
|
if (validateClaims === true && mode !== "json") throw new JWTError("\"validateClaims\" requires payload: \"json\".", "ERR_INVALID_OPTION");
|
|
1354
1354
|
return mode;
|
|
1355
1355
|
}
|
|
1356
1356
|
function stringKeyError() {
|
|
1357
|
-
return new JWTError("
|
|
1357
|
+
return new JWTError("Key must be a JWK, CryptoKey or Uint8Array, not a string.", "ERR_JWK_INVALID");
|
|
1358
1358
|
}
|
|
1359
1359
|
function assertNotStringKey(key) {
|
|
1360
1360
|
if (typeof key === "string") throw stringKeyError();
|
|
@@ -1383,7 +1383,7 @@ function checkAlgAllowed(alg, key, options) {
|
|
|
1383
1383
|
if (algorithms !== void 0) return algorithms.includes(alg) ? void 0 : notAllowed(alg, ctx);
|
|
1384
1384
|
if (isJWK(key) && typeof key.alg === "string" && (!ctx.octRoles || key.kty !== "oct")) return key.alg === alg || isEd25519Signature(key.alg) && isEd25519Signature(alg) ? void 0 : notAllowed(alg, ctx);
|
|
1385
1385
|
const inferred = ctx.infer(key, { allowSymmetric });
|
|
1386
|
-
if (!inferred) return new JWTError(
|
|
1386
|
+
if (!inferred) return new JWTError("Cannot infer allowed algorithms from this key, pass \"algorithms\".", ctx.errorCode);
|
|
1387
1387
|
return inferred.includes(alg) ? void 0 : notAllowed(alg, ctx);
|
|
1388
1388
|
}
|
|
1389
1389
|
function notAllowed(alg, ctx) {
|
|
@@ -1415,14 +1415,14 @@ function checkJWSAlgSupported(alg) {
|
|
|
1415
1415
|
});
|
|
1416
1416
|
}
|
|
1417
1417
|
function checkJWSB64(header) {
|
|
1418
|
-
if (Object.hasOwn(header, "b64") && typeof header.b64 !== "boolean") return new JWTError("Invalid JWS: \"b64\" must be a boolean
|
|
1418
|
+
if (Object.hasOwn(header, "b64") && typeof header.b64 !== "boolean") return new JWTError("Invalid JWS: \"b64\" must be a boolean.", "ERR_JWS_INVALID");
|
|
1419
1419
|
if (header.b64 !== false) return void 0;
|
|
1420
1420
|
if (Array.isArray(header.crit) && header.crit.includes("b64")) return void 0;
|
|
1421
|
-
return new JWTError("Invalid JWS: \"b64\" must be listed in \"crit\"
|
|
1421
|
+
return new JWTError("Invalid JWS: \"b64\" must be listed in \"crit\".", "ERR_JWS_INVALID");
|
|
1422
1422
|
}
|
|
1423
1423
|
function assertB64Option(header) {
|
|
1424
1424
|
if (!header || !Object.hasOwn(header, "b64") || typeof header.b64 === "boolean") return;
|
|
1425
|
-
throw new JWTError("\"b64\" must be a boolean
|
|
1425
|
+
throw new JWTError("\"b64\" must be a boolean.", "ERR_INVALID_OPTION");
|
|
1426
1426
|
}
|
|
1427
1427
|
function applyB64Header(header) {
|
|
1428
1428
|
assertB64Option(header);
|
|
@@ -1493,7 +1493,7 @@ const JWE_ENC_CEK_FORMAT = /* @__PURE__ */ Object.freeze({
|
|
|
1493
1493
|
function assertDirectKeyRole(key, enc) {
|
|
1494
1494
|
if (!isJWK(key) || typeof key.alg !== "string" || key.alg === "dir") return;
|
|
1495
1495
|
if (enc !== void 0 && key.alg === enc) return;
|
|
1496
|
-
throw new JWTError(`JWK "alg" is "${key.alg}" but "dir" requires
|
|
1496
|
+
throw new JWTError(`JWK "alg" is "${key.alg}" but "dir" requires "dir" or the token's "enc".`, "ERR_JWK_INVALID");
|
|
1497
1497
|
}
|
|
1498
1498
|
const JWE_DIRECT_ALGS = /* @__PURE__ */ new Set(["dir", "ECDH-ES"]);
|
|
1499
1499
|
function checkJWEAlgSupported(alg) {
|
|
@@ -1568,11 +1568,11 @@ function checkJWEZip(header) {
|
|
|
1568
1568
|
}
|
|
1569
1569
|
function assertNoZipOption(header, tier) {
|
|
1570
1570
|
if (!header || !Object.hasOwn(header, "zip")) return;
|
|
1571
|
-
throw new JWTError(`JWE compression ("zip")
|
|
1571
|
+
throw new JWTError(`JWE compression ("zip") in the ${tier} header is not supported.`, "ERR_INVALID_OPTION");
|
|
1572
1572
|
}
|
|
1573
1573
|
function checkJWEUnprotectedCrit(header) {
|
|
1574
1574
|
if (!header || !Object.hasOwn(header, "crit")) return void 0;
|
|
1575
|
-
return new JWTError("Invalid JWE: \"crit\" must be integrity protected
|
|
1575
|
+
return new JWTError("Invalid JWE: \"crit\" must be integrity protected.", "ERR_JWE_INVALID");
|
|
1576
1576
|
}
|
|
1577
1577
|
function typMatches(expected, actual) {
|
|
1578
1578
|
if (typeof actual !== "string") return false;
|
|
@@ -1584,7 +1584,7 @@ function checkProtectedTyp(expected, protectedHeader, options) {
|
|
|
1584
1584
|
if (typMatches(expected, actual)) return void 0;
|
|
1585
1585
|
const { family, label } = options;
|
|
1586
1586
|
const where = label ? ` on ${label}` : "";
|
|
1587
|
-
const message = actual === void 0 ? `Invalid ${family}: the protected header${where} carries no "typ"
|
|
1587
|
+
const message = actual === void 0 ? `Invalid ${family}: the protected header${where} carries no "typ", expected "${expected}".` : `Invalid ${family}: "typ" mismatch${where}, expected "${expected}".`;
|
|
1588
1588
|
return new JWTError(message, `ERR_${family}_INVALID`);
|
|
1589
1589
|
}
|
|
1590
1590
|
function normalizeTyp(typ) {
|
|
@@ -1654,111 +1654,6 @@ const RSA_SIGNATURE_ALGORITHMS = /* @__PURE__ */ new Set([
|
|
|
1654
1654
|
"PS384",
|
|
1655
1655
|
"PS512"
|
|
1656
1656
|
]);
|
|
1657
|
-
async function generateKey(alg, options = {}) {
|
|
1658
|
-
const exportToJWK = options.toJWK !== void 0 && options.toJWK;
|
|
1659
|
-
const defaultExtractable = exportToJWK || options.extractable !== false;
|
|
1660
|
-
const kid = exportToJWK ? assertKidOption(options.kid) : void 0;
|
|
1661
|
-
if (alg === "A128CBC-HS256" || alg === "A192CBC-HS384" || alg === "A256CBC-HS512") {
|
|
1662
|
-
const keyLength = bitLengthCEK(alg);
|
|
1663
|
-
const keyBytes = secureRandomBytes(keyLength >> 3);
|
|
1664
|
-
if (exportToJWK) {
|
|
1665
|
-
const jwk = await keyToJWK(keyBytes);
|
|
1666
|
-
const keyOps = options.keyUsage === void 0 ? void 0 : resolveKeyUsage(options.keyUsage, {
|
|
1667
|
-
allowed: CONTENT_ENCRYPTION_USAGES,
|
|
1668
|
-
fallback: ["encrypt", "decrypt"],
|
|
1669
|
-
alg
|
|
1670
|
-
});
|
|
1671
|
-
return withGeneratedKid(kid, withKeyOps({
|
|
1672
|
-
...jwk,
|
|
1673
|
-
alg
|
|
1674
|
-
}, keyOps));
|
|
1675
|
-
}
|
|
1676
|
-
return keyBytes;
|
|
1677
|
-
}
|
|
1678
|
-
const { algorithm, keyUsages } = getGenerateKeyParams(alg, options);
|
|
1679
|
-
const key = await crypto.subtle.generateKey(algorithm, defaultExtractable, keyUsages);
|
|
1680
|
-
if (exportToJWK) {
|
|
1681
|
-
if (isCryptoKeyPair(key)) {
|
|
1682
|
-
const pairAlg = generatedPairAlgorithm(alg);
|
|
1683
|
-
const [pub, priv] = await Promise.all([exportJWK(key.publicKey), exportJWK(key.privateKey)]);
|
|
1684
|
-
const publicKey = await withGeneratedKid(kid, withKeyOps(withAlg(pub, pairAlg), requestedKeyOps(options, key.publicKey)));
|
|
1685
|
-
const named = publicKey.kid === void 0 ? void 0 : { kid: publicKey.kid };
|
|
1686
|
-
return {
|
|
1687
|
-
privateKey: {
|
|
1688
|
-
...withKeyOps(withAlg(priv, pairAlg), requestedKeyOps(options, key.privateKey)),
|
|
1689
|
-
...named
|
|
1690
|
-
},
|
|
1691
|
-
publicKey
|
|
1692
|
-
};
|
|
1693
|
-
}
|
|
1694
|
-
return withGeneratedKid(kid, withKeyOps(withAlg(await exportJWK(key), generatedSecretAlgorithm(alg)), requestedKeyOps(options, key)));
|
|
1695
|
-
}
|
|
1696
|
-
return key;
|
|
1697
|
-
}
|
|
1698
|
-
async function generateJWK(alg, options) {
|
|
1699
|
-
const { keyUsage, modulusLength, publicExponent, namedCurve, kid, extractable: _extractable, toJWK: _toJWK, ...jwkParams } = options ?? {};
|
|
1700
|
-
assertNoReservedJWKParams(jwkParams);
|
|
1701
|
-
const result = await generateKey(alg, {
|
|
1702
|
-
keyUsage,
|
|
1703
|
-
modulusLength,
|
|
1704
|
-
publicExponent,
|
|
1705
|
-
namedCurve,
|
|
1706
|
-
kid,
|
|
1707
|
-
toJWK: true
|
|
1708
|
-
});
|
|
1709
|
-
if (result && typeof result === "object" && "privateKey" in result && "publicKey" in result) return {
|
|
1710
|
-
privateKey: {
|
|
1711
|
-
...jwkParams,
|
|
1712
|
-
...result.privateKey
|
|
1713
|
-
},
|
|
1714
|
-
publicKey: {
|
|
1715
|
-
...jwkParams,
|
|
1716
|
-
...result.publicKey
|
|
1717
|
-
}
|
|
1718
|
-
};
|
|
1719
|
-
return {
|
|
1720
|
-
...jwkParams,
|
|
1721
|
-
...result
|
|
1722
|
-
};
|
|
1723
|
-
}
|
|
1724
|
-
async function deriveKeyFromPassword(password, options) {
|
|
1725
|
-
assertPlainObject(options, "options");
|
|
1726
|
-
if (typeof password !== "string" && !(password instanceof Uint8Array)) throw new JWTError("\"password\" must be a string or a Uint8Array.", "ERR_INVALID_OPTION");
|
|
1727
|
-
const { alg, salt, iterations, extractable, keyUsage } = options;
|
|
1728
|
-
assertPBES2Algorithm(alg);
|
|
1729
|
-
const exportToJWK = options.toJWK !== void 0 && options.toJWK;
|
|
1730
|
-
const saltBytes = typeof salt === "string" ? textEncoder.encode(salt) : salt;
|
|
1731
|
-
assertPBES2Salt(saltBytes, "\"salt\"");
|
|
1732
|
-
assertPBES2Count(iterations, "\"iterations\"");
|
|
1733
|
-
const derivedBytes = await deriveKey(saltBytes, alg, iterations, typeof password === "string" ? textEncoder.encode(password) : password);
|
|
1734
|
-
const wrappingAlg = innerKeyWrapAlg(alg);
|
|
1735
|
-
const finalUsages = keyUsage ?? ["wrapKey", "unwrapKey"];
|
|
1736
|
-
const finalExtractable = exportToJWK ? true : extractable === true;
|
|
1737
|
-
const derivedKey = await crypto.subtle.importKey("raw", derivedBytes, { name: "AES-KW" }, finalExtractable, finalUsages);
|
|
1738
|
-
if (exportToJWK) return withKeyOps({
|
|
1739
|
-
...await keyToJWK(derivedKey),
|
|
1740
|
-
alg: wrappingAlg,
|
|
1741
|
-
kty: "oct"
|
|
1742
|
-
}, requestedKeyOps(options, derivedKey));
|
|
1743
|
-
return derivedKey;
|
|
1744
|
-
}
|
|
1745
|
-
async function deriveJWKFromPassword(password, options) {
|
|
1746
|
-
assertPlainObject(options, "options");
|
|
1747
|
-
const { alg, salt, iterations, keyUsage, kid: kidOption, extractable: _extractable, toJWK: _toJWK, ...jwkParams } = options;
|
|
1748
|
-
assertNoReservedJWKParams(jwkParams);
|
|
1749
|
-
const kid = assertKidOption(kidOption);
|
|
1750
|
-
const result = await deriveKeyFromPassword(password, {
|
|
1751
|
-
alg,
|
|
1752
|
-
salt,
|
|
1753
|
-
iterations,
|
|
1754
|
-
keyUsage,
|
|
1755
|
-
toJWK: true
|
|
1756
|
-
});
|
|
1757
|
-
return {
|
|
1758
|
-
...jwkParams,
|
|
1759
|
-
...await withGeneratedKid(kid, result)
|
|
1760
|
-
};
|
|
1761
|
-
}
|
|
1762
1657
|
var WeakMapJWKCache = class {
|
|
1763
1658
|
_map = /* @__PURE__ */ new WeakMap();
|
|
1764
1659
|
get(jwk, alg) {
|
|
@@ -1843,609 +1738,9 @@ function assertIntentOnCryptoKey(key, expect) {
|
|
|
1843
1738
|
if (expect === "public" && key.type === "private") throw new JWTError("Private CryptoKey passed where a public key is expected.", "ERR_JWK_INVALID");
|
|
1844
1739
|
if (expect === "private" && key.type === "public") throw new JWTError("Public CryptoKey passed where a private key is expected.", "ERR_JWK_INVALID");
|
|
1845
1740
|
}
|
|
1846
|
-
async function exportJWK(key, jwkParams) {
|
|
1847
|
-
if (!isCryptoKey(key)) throw new JWTError(`exportJWK expects a CryptoKey, got ${key === null ? "null" : typeof key}.`, "ERR_INVALID_OPTION");
|
|
1848
|
-
if (!key.extractable) throw new JWTError("A non-extractable CryptoKey cannot be exported as a JWK.", "ERR_JWK_INVALID");
|
|
1849
|
-
const exportedJwk = await keyToJWK(key);
|
|
1850
|
-
if (jwkParams) {
|
|
1851
|
-
const extraParams = sanitizeObjectCopy(jwkParams);
|
|
1852
|
-
assertNoReservedJWKParams(extraParams);
|
|
1853
|
-
return {
|
|
1854
|
-
...exportedJwk,
|
|
1855
|
-
...extraParams
|
|
1856
|
-
};
|
|
1857
|
-
}
|
|
1858
|
-
return exportedJwk;
|
|
1859
|
-
}
|
|
1860
|
-
async function exportKey(key, jwkParams) {
|
|
1861
|
-
return exportJWK(key, jwkParams);
|
|
1862
|
-
}
|
|
1863
|
-
function toPublicJWK(jwk) {
|
|
1864
|
-
if (!isAsymmetricJWK(jwk)) throw new JWTError(isJWK(jwk) ? "An oct JWK has no public half." : "toPublicJWK expects an asymmetric JWK.", "ERR_JWK_INVALID");
|
|
1865
|
-
const { d: _d, p: _p, q: _q, dp: _dp, dq: _dq, qi: _qi, oth: _oth, key_ops, ...publicMembers } = sanitizeObjectCopy({ ...jwk });
|
|
1866
|
-
const publicKey = key_ops === void 0 ? publicMembers : {
|
|
1867
|
-
...publicMembers,
|
|
1868
|
-
key_ops: publicKeyOps(key_ops)
|
|
1869
|
-
};
|
|
1870
|
-
if (!isPublicJWK(publicKey)) throw new JWTError(`${jwk.kty} JWK lacks the public members of its key type.`, "ERR_JWK_INVALID");
|
|
1871
|
-
return publicKey;
|
|
1872
|
-
}
|
|
1873
|
-
async function wrapKey(keyToWrap, wrappingKey, options) {
|
|
1874
|
-
assertPlainObject(options, "options");
|
|
1875
|
-
assertKeyBytesArg(keyToWrap, "keyToWrap");
|
|
1876
|
-
const { alg } = options;
|
|
1877
|
-
const cekBytes = keyToWrap instanceof Uint8Array ? keyToWrap : new Uint8Array(await crypto.subtle.exportKey("raw", keyToWrap));
|
|
1878
|
-
if (alg.endsWith("KW")) assertWrappableCEK(cekBytes, alg);
|
|
1879
|
-
if (alg.startsWith("PBES2")) assertPBES2Params({
|
|
1880
|
-
p2s: options.p2s,
|
|
1881
|
-
p2c: options.p2c
|
|
1882
|
-
});
|
|
1883
|
-
const importedWrappingKey = await importKey(resolvePasswordKey(alg, wrappingKey), {
|
|
1884
|
-
alg,
|
|
1885
|
-
expect: "public"
|
|
1886
|
-
});
|
|
1887
|
-
switch (alg) {
|
|
1888
|
-
case "dir": return { encryptedKey: /* @__PURE__ */ new Uint8Array(0) };
|
|
1889
|
-
case "A128KW":
|
|
1890
|
-
case "A192KW":
|
|
1891
|
-
case "A256KW": return { encryptedKey: await aesKwWrap(alg, importedWrappingKey, cekBytes) };
|
|
1892
|
-
case "PBES2-HS256+A128KW":
|
|
1893
|
-
case "PBES2-HS384+A192KW":
|
|
1894
|
-
case "PBES2-HS512+A256KW": {
|
|
1895
|
-
const { p2s, p2c } = options;
|
|
1896
|
-
if (!p2s || typeof p2c !== "number") throw new JWTError("PBES2 requires 'p2s' (salt) and 'p2c' (count) options", "ERR_JWE_INVALID");
|
|
1897
|
-
return pbes2Wrap(alg, importedWrappingKey, cekBytes, p2c, p2s);
|
|
1898
|
-
}
|
|
1899
|
-
case "A128GCMKW":
|
|
1900
|
-
case "A192GCMKW":
|
|
1901
|
-
case "A256GCMKW": {
|
|
1902
|
-
const { encryptedKey, iv, tag } = await gcmkwEncrypt(alg, importedWrappingKey, cekBytes, options.iv);
|
|
1903
|
-
return {
|
|
1904
|
-
encryptedKey,
|
|
1905
|
-
iv,
|
|
1906
|
-
tag
|
|
1907
|
-
};
|
|
1908
|
-
}
|
|
1909
|
-
case "RSA-OAEP":
|
|
1910
|
-
case "RSA-OAEP-256":
|
|
1911
|
-
case "RSA-OAEP-384":
|
|
1912
|
-
case "RSA-OAEP-512":
|
|
1913
|
-
assertCryptoKeyFor(alg, importedWrappingKey, "wrapping");
|
|
1914
|
-
return { encryptedKey: await encryptRSAES(alg, importedWrappingKey, cekBytes) };
|
|
1915
|
-
case "ECDH-ES":
|
|
1916
|
-
case "ECDH-ES+A128KW":
|
|
1917
|
-
case "ECDH-ES+A192KW":
|
|
1918
|
-
case "ECDH-ES+A256KW": {
|
|
1919
|
-
assertCryptoKeyFor(alg, importedWrappingKey, "wrapping");
|
|
1920
|
-
const enc = options.ecdh?.enc;
|
|
1921
|
-
if (enc !== void 0) assertJWEEncSupported(enc);
|
|
1922
|
-
if (alg === "ECDH-ES" && !enc) throw new JWTError("ECDH-ES direct key agreement requires options.ecdh.enc (the target content encryption algorithm)", "ERR_JWK_INVALID");
|
|
1923
|
-
const { encryptedKey, parameters } = await ecdhesWrap(alg, {
|
|
1924
|
-
enc,
|
|
1925
|
-
recipientKey: importedWrappingKey,
|
|
1926
|
-
cek: cekBytes,
|
|
1927
|
-
parameters: buildECDHAgreementParams(options.ecdh)
|
|
1928
|
-
});
|
|
1929
|
-
const wrapResult = {
|
|
1930
|
-
encryptedKey: encryptedKey ?? /* @__PURE__ */ new Uint8Array(0),
|
|
1931
|
-
epk: parameters.epk
|
|
1932
|
-
};
|
|
1933
|
-
if (parameters.apu) wrapResult.apu = parameters.apu;
|
|
1934
|
-
if (parameters.apv) wrapResult.apv = parameters.apv;
|
|
1935
|
-
return wrapResult;
|
|
1936
|
-
}
|
|
1937
|
-
default: throw new JWTError(`Unsupported key wrapping algorithm: ${alg}`, "ERR_JWK_UNSUPPORTED");
|
|
1938
|
-
}
|
|
1939
|
-
}
|
|
1940
|
-
async function unwrapKey(wrappedKey, unwrappingKey, options) {
|
|
1941
|
-
assertPlainObject(options, "options");
|
|
1942
|
-
if (!(wrappedKey instanceof Uint8Array)) throw new JWTError("\"wrappedKey\" must be a Uint8Array.", "ERR_INVALID_OPTION");
|
|
1943
|
-
const { alg } = options;
|
|
1944
|
-
const returnRaw = options.format === "raw";
|
|
1945
|
-
const defaultExtractable = options.extractable !== false;
|
|
1946
|
-
const importedUnwrappingKey = await importKey(resolvePasswordKey(alg, unwrappingKey), {
|
|
1947
|
-
alg,
|
|
1948
|
-
expect: "private"
|
|
1949
|
-
});
|
|
1950
|
-
let unwrappedCekBytes;
|
|
1951
|
-
switch (alg) {
|
|
1952
|
-
case "dir":
|
|
1953
|
-
assertDirectKeyRole(unwrappingKey, options.enc);
|
|
1954
|
-
if (importedUnwrappingKey instanceof Uint8Array) {
|
|
1955
|
-
assertOctKeyLength(importedUnwrappingKey, options.enc);
|
|
1956
|
-
unwrappedCekBytes = importedUnwrappingKey;
|
|
1957
|
-
} else {
|
|
1958
|
-
if (!returnRaw) return importedUnwrappingKey;
|
|
1959
|
-
unwrappedCekBytes = new Uint8Array(await crypto.subtle.exportKey("raw", importedUnwrappingKey));
|
|
1960
|
-
}
|
|
1961
|
-
break;
|
|
1962
|
-
case "A128KW":
|
|
1963
|
-
case "A192KW":
|
|
1964
|
-
case "A256KW":
|
|
1965
|
-
unwrappedCekBytes = await unwrapping(aesKwUnwrap(alg, importedUnwrappingKey, wrappedKey));
|
|
1966
|
-
break;
|
|
1967
|
-
case "PBES2-HS256+A128KW":
|
|
1968
|
-
case "PBES2-HS384+A192KW":
|
|
1969
|
-
case "PBES2-HS512+A256KW": {
|
|
1970
|
-
const { p2s, p2c, minIterations, maxIterations } = options;
|
|
1971
|
-
if (!p2s || typeof p2c !== "number") throw new JWTError("PBES2 requires 'p2s' (salt) and 'p2c' (count) options", "ERR_JWE_INVALID");
|
|
1972
|
-
unwrappedCekBytes = await unwrapping(pbes2Unwrap(alg, importedUnwrappingKey, wrappedKey, p2c, segmentBytes(p2s, "p2s"), minIterations, maxIterations));
|
|
1973
|
-
break;
|
|
1974
|
-
}
|
|
1975
|
-
case "A128GCMKW":
|
|
1976
|
-
case "A192GCMKW":
|
|
1977
|
-
case "A256GCMKW": {
|
|
1978
|
-
if (!options.iv || !options.tag) throw new JWTError("AES-GCMKW requires 'iv' and 'tag' options for unwrapping", "ERR_JWE_INVALID");
|
|
1979
|
-
const ivBytes = segmentBytes(options.iv, "iv");
|
|
1980
|
-
const tagBytes = segmentBytes(options.tag, "tag");
|
|
1981
|
-
assertKeyWrapSegmentLength("iv", ivBytes, bitLengthIV(alg) >> 3, alg);
|
|
1982
|
-
assertKeyWrapSegmentLength("tag", tagBytes, bitLengthTag(alg) >> 3, alg);
|
|
1983
|
-
unwrappedCekBytes = await unwrapping(gcmkwDecrypt(alg, importedUnwrappingKey, wrappedKey, ivBytes, tagBytes));
|
|
1984
|
-
break;
|
|
1985
|
-
}
|
|
1986
|
-
case "RSA-OAEP":
|
|
1987
|
-
case "RSA-OAEP-256":
|
|
1988
|
-
case "RSA-OAEP-384":
|
|
1989
|
-
case "RSA-OAEP-512": {
|
|
1990
|
-
assertCryptoKeyFor(alg, importedUnwrappingKey, "unwrapping");
|
|
1991
|
-
unwrappedCekBytes = await unwrapping(decryptRSAES(alg, importedUnwrappingKey, wrappedKey));
|
|
1992
|
-
if (returnRaw) break;
|
|
1993
|
-
const inferredAlgorithm = options.unwrappedKeyAlgorithm || inferAesImportAlgorithm(options.enc, unwrappedCekBytes.length);
|
|
1994
|
-
if (!inferredAlgorithm) throw new JWTError("Unable to infer algorithm for RSA-OAEP unwrapped key. Provide \"unwrappedKeyAlgorithm\" in options.", "ERR_JWE_INVALID");
|
|
1995
|
-
const keyUsages = options.keyUsage || ["encrypt", "decrypt"];
|
|
1996
|
-
return await crypto.subtle.importKey("raw", unwrappedCekBytes, inferredAlgorithm, defaultExtractable, keyUsages);
|
|
1997
|
-
}
|
|
1998
|
-
case "ECDH-ES":
|
|
1999
|
-
case "ECDH-ES+A128KW":
|
|
2000
|
-
case "ECDH-ES+A192KW":
|
|
2001
|
-
case "ECDH-ES+A256KW": {
|
|
2002
|
-
if (!options.epk) throw new JWTError("ECDH-ES requires 'epk' (Ephemeral Public Key) option", "ERR_JWE_INVALID");
|
|
2003
|
-
assertCryptoKeyFor(alg, importedUnwrappingKey, "unwrapping");
|
|
2004
|
-
assertECDHKeyAllowed(importedUnwrappingKey);
|
|
2005
|
-
const epkCandidate = await normalizeEpk(options.epk, {
|
|
2006
|
-
alg,
|
|
2007
|
-
recipientKey: importedUnwrappingKey
|
|
2008
|
-
});
|
|
2009
|
-
const apuBytes = segmentBytes(options.apu ?? /* @__PURE__ */ new Uint8Array(0), "apu");
|
|
2010
|
-
const apvBytes = segmentBytes(options.apv ?? /* @__PURE__ */ new Uint8Array(0), "apv");
|
|
2011
|
-
assertPartyInfoLength("apu", apuBytes);
|
|
2012
|
-
assertPartyInfoLength("apv", apvBytes);
|
|
2013
|
-
if (options.enc !== void 0) assertJWEEncSupported(options.enc);
|
|
2014
|
-
const infoAlg = alg === "ECDH-ES" ? options.enc : alg;
|
|
2015
|
-
if (!infoAlg) throw new JWTError("ECDH-ES requires content encryption algorithm ('enc') to derive the shared secret", "ERR_JWE_INVALID");
|
|
2016
|
-
const sharedSecret = await unwrapping(deriveECDHESKey(epkCandidate, importedUnwrappingKey, infoAlg, ecdhDerivedBits(alg, options.enc), apuBytes, apvBytes));
|
|
2017
|
-
if (alg === "ECDH-ES") unwrappedCekBytes = sharedSecret;
|
|
2018
|
-
else {
|
|
2019
|
-
const kwAlg = innerKeyWrapAlg(alg);
|
|
2020
|
-
if (!(wrappedKey instanceof Uint8Array) || wrappedKey.length === 0) throw new JWTError("ECDH-ES key agreement with key wrapping requires an encrypted key", "ERR_JWE_INVALID");
|
|
2021
|
-
unwrappedCekBytes = await unwrapping(aesKwUnwrap(kwAlg, sharedSecret, wrappedKey));
|
|
2022
|
-
}
|
|
2023
|
-
break;
|
|
2024
|
-
}
|
|
2025
|
-
default: throw new JWTError(`Unsupported key unwrapping algorithm: ${alg}`, "ERR_JWK_UNSUPPORTED");
|
|
2026
|
-
}
|
|
2027
|
-
if (returnRaw) return unwrappedCekBytes;
|
|
2028
|
-
return await crypto.subtle.importKey("raw", unwrappedCekBytes, options.unwrappedKeyAlgorithm || { name: "AES-GCM" }, defaultExtractable, options.keyUsage || ["encrypt", "decrypt"]);
|
|
2029
|
-
}
|
|
2030
|
-
async function importPEM(pem, alg, options) {
|
|
2031
|
-
if (typeof pem !== "string") throw new JWTError(`"pem" must be a PEM-encoded string, got ${pem === null ? "null" : typeof pem}.`, "ERR_INVALID_OPTION");
|
|
2032
|
-
if (options !== void 0) assertPlainObject(options, "options");
|
|
2033
|
-
const extractable = true;
|
|
2034
|
-
const pemType = options?.pemType ?? inferPEMType(pem);
|
|
2035
|
-
if (!pemType) throw new JWTError("Cannot infer PEM type from the input; pass \"options.pemType\" explicitly.", "ERR_JWK_INVALID");
|
|
2036
|
-
let cryptoKey;
|
|
2037
|
-
switch (pemType) {
|
|
2038
|
-
case "pkcs8":
|
|
2039
|
-
cryptoKey = await fromPKCS8(pem, alg, { extractable });
|
|
2040
|
-
break;
|
|
2041
|
-
case "spki":
|
|
2042
|
-
cryptoKey = await fromSPKI(pem, alg, { extractable });
|
|
2043
|
-
break;
|
|
2044
|
-
case "x509":
|
|
2045
|
-
cryptoKey = await fromX509(pem, alg, { extractable });
|
|
2046
|
-
break;
|
|
2047
|
-
default: throw new JWTError(`Unsupported PEM type: ${String(pemType)}`, "ERR_JWK_UNSUPPORTED");
|
|
2048
|
-
}
|
|
2049
|
-
return {
|
|
2050
|
-
...await exportJWK(cryptoKey, options?.jwkParams),
|
|
2051
|
-
alg
|
|
2052
|
-
};
|
|
2053
|
-
}
|
|
2054
|
-
async function exportPEM(jwk, options) {
|
|
2055
|
-
assertPlainObject(jwk, "jwk");
|
|
2056
|
-
if (options !== void 0) assertPlainObject(options, "options");
|
|
2057
|
-
if (jwk.kty === "oct") throw new JWTError("Octet (symmetric) JWKs (kty: 'oct') cannot be exported to PKCS8 or SPKI PEM formats.", "ERR_JWK_UNSUPPORTED");
|
|
2058
|
-
const effectiveAlg = jwk.alg || options?.alg;
|
|
2059
|
-
if (!effectiveAlg && (jwk.kty === "RSA" || jwk.kty === "EC" || jwk.kty === "OKP")) throw new JWTError("Algorithm (alg) must be provided in the JWK or via options for converting this JWK type to a CryptoKey.", "ERR_JWK_INVALID");
|
|
2060
|
-
if (effectiveAlg !== void 0 && !PEM_ALGORITHMS.has(effectiveAlg)) throw new JWTError(`Unsupported PEM algorithm: ${effectiveAlg}`, "ERR_JWK_UNSUPPORTED");
|
|
2061
|
-
const pemFormat = options?.pemFormat ?? ("d" in jwk ? "pkcs8" : "spki");
|
|
2062
|
-
const cryptoKeyCandidate = await importKey({
|
|
2063
|
-
...jwk,
|
|
2064
|
-
ext: true
|
|
2065
|
-
}, {
|
|
2066
|
-
alg: effectiveAlg,
|
|
2067
|
-
expect: pemFormat === "pkcs8" ? "private" : "public",
|
|
2068
|
-
extractable: true
|
|
2069
|
-
});
|
|
2070
|
-
if (!isCryptoKey(cryptoKeyCandidate)) throw new JWTError("Failed to convert JWK to a CryptoKey instance suitable for PEM export.", "ERR_JWK_INVALID");
|
|
2071
|
-
const cryptoKey = cryptoKeyCandidate;
|
|
2072
|
-
switch (pemFormat) {
|
|
2073
|
-
case "pkcs8":
|
|
2074
|
-
if (cryptoKey.type !== "private") throw new JWTError(`Only 'private' type CryptoKeys can be exported to PKCS8 PEM format. Key type is '${cryptoKey.type}'.`, "ERR_JWK_INVALID");
|
|
2075
|
-
return toPKCS8(cryptoKey);
|
|
2076
|
-
case "spki":
|
|
2077
|
-
if (cryptoKey.type !== "public") throw new JWTError(`Only 'public' type CryptoKeys can be exported to SPKI PEM format. Key type is '${cryptoKey.type}'.`, "ERR_JWK_INVALID");
|
|
2078
|
-
return toSPKI(cryptoKey);
|
|
2079
|
-
default: throw new JWTError(`Unsupported PEM format: ${String(pemFormat)}`, "ERR_JWK_UNSUPPORTED");
|
|
2080
|
-
}
|
|
2081
|
-
}
|
|
2082
|
-
function inferPEMType(pem) {
|
|
2083
|
-
if (pem.includes("-----BEGIN PRIVATE KEY-----")) return "pkcs8";
|
|
2084
|
-
if (pem.includes("-----BEGIN PUBLIC KEY-----")) return "spki";
|
|
2085
|
-
if (pem.includes("-----BEGIN CERTIFICATE-----")) return "x509";
|
|
2086
|
-
}
|
|
2087
|
-
async function deriveSharedSecret(publicKey, privateKey, options) {
|
|
2088
|
-
assertPlainObject(options, "options");
|
|
2089
|
-
const { enc: alg, keyLength: requestedKeyLength, partyUInfo, partyVInfo } = options;
|
|
2090
|
-
if (!isECDHESAlgorithm(alg)) assertJWEEncSupported(alg);
|
|
2091
|
-
if (requestedKeyLength !== void 0) assertDerivedKeyLength(requestedKeyLength);
|
|
2092
|
-
const importAlg = isECDHESAlgorithm(alg) ? alg : "ECDH-ES";
|
|
2093
|
-
const pubCryptoKey = isCryptoKey(publicKey) ? publicKey : await importKey(publicKey, {
|
|
2094
|
-
alg: importAlg,
|
|
2095
|
-
expect: "public"
|
|
2096
|
-
});
|
|
2097
|
-
const privCryptoKey = isCryptoKey(privateKey) ? privateKey : await importKey(privateKey, {
|
|
2098
|
-
alg: importAlg,
|
|
2099
|
-
expect: "private"
|
|
2100
|
-
});
|
|
2101
|
-
let keyLength;
|
|
2102
|
-
if (requestedKeyLength !== void 0) keyLength = requestedKeyLength;
|
|
2103
|
-
else if (alg === "ECDH-ES") throw new JWTError("deriveSharedSecret with enc \"ECDH-ES\" requires an explicit keyLength in options", "ERR_JWK_INVALID");
|
|
2104
|
-
else if (isECDHESAlgorithm(alg)) keyLength = aesBitsOf(innerKeyWrapAlg(alg));
|
|
2105
|
-
else keyLength = bitLengthCEK(alg);
|
|
2106
|
-
return deriveECDHESKey(pubCryptoKey, privCryptoKey, alg, keyLength, partyUInfo ?? /* @__PURE__ */ new Uint8Array(0), partyVInfo ?? /* @__PURE__ */ new Uint8Array(0));
|
|
2107
|
-
}
|
|
2108
1741
|
function getJWKsFromSet(jwkSet, filter) {
|
|
2109
1742
|
if (!jwkSet || !isJWKSet(jwkSet)) throw new JWTError("Invalid JWK Set provided", "ERR_JWK_INVALID");
|
|
2110
1743
|
const keys = jwkSet.keys.filter((key) => isJWK(key));
|
|
2111
1744
|
return filter ? keys.filter(filter) : keys;
|
|
2112
1745
|
}
|
|
2113
|
-
|
|
2114
|
-
let algorithm;
|
|
2115
|
-
let keyUsages;
|
|
2116
|
-
const requested = options?.keyUsage;
|
|
2117
|
-
const usage = (allowed, fallback) => resolveKeyUsage(requested, {
|
|
2118
|
-
allowed,
|
|
2119
|
-
fallback,
|
|
2120
|
-
alg
|
|
2121
|
-
});
|
|
2122
|
-
const pairUsage = (allowed, fallback) => assertPairUsages(usage(allowed, fallback), {
|
|
2123
|
-
fallback,
|
|
2124
|
-
alg
|
|
2125
|
-
});
|
|
2126
|
-
switch (alg) {
|
|
2127
|
-
case "HS256":
|
|
2128
|
-
case "HS384":
|
|
2129
|
-
case "HS512":
|
|
2130
|
-
algorithm = {
|
|
2131
|
-
name: "HMAC",
|
|
2132
|
-
hash: jwsHashOf(alg)
|
|
2133
|
-
};
|
|
2134
|
-
keyUsages = usage(SIGNATURE_USAGES, ["sign", "verify"]);
|
|
2135
|
-
break;
|
|
2136
|
-
case "RS256":
|
|
2137
|
-
case "RS384":
|
|
2138
|
-
case "RS512":
|
|
2139
|
-
algorithm = {
|
|
2140
|
-
name: "RSASSA-PKCS1-v1_5",
|
|
2141
|
-
modulusLength: assertModulusLength(options?.modulusLength),
|
|
2142
|
-
publicExponent: assertPublicExponent(options?.publicExponent),
|
|
2143
|
-
hash: jwsHashOf(alg)
|
|
2144
|
-
};
|
|
2145
|
-
keyUsages = pairUsage(SIGNATURE_USAGES, ["sign", "verify"]);
|
|
2146
|
-
break;
|
|
2147
|
-
case "PS256":
|
|
2148
|
-
case "PS384":
|
|
2149
|
-
case "PS512":
|
|
2150
|
-
algorithm = {
|
|
2151
|
-
name: "RSA-PSS",
|
|
2152
|
-
modulusLength: assertModulusLength(options?.modulusLength),
|
|
2153
|
-
publicExponent: assertPublicExponent(options?.publicExponent),
|
|
2154
|
-
hash: jwsHashOf(alg)
|
|
2155
|
-
};
|
|
2156
|
-
keyUsages = pairUsage(SIGNATURE_USAGES, ["sign", "verify"]);
|
|
2157
|
-
break;
|
|
2158
|
-
case "RSA-OAEP":
|
|
2159
|
-
case "RSA-OAEP-256":
|
|
2160
|
-
case "RSA-OAEP-384":
|
|
2161
|
-
case "RSA-OAEP-512":
|
|
2162
|
-
algorithm = {
|
|
2163
|
-
name: "RSA-OAEP",
|
|
2164
|
-
modulusLength: assertModulusLength(options?.modulusLength),
|
|
2165
|
-
publicExponent: assertPublicExponent(options?.publicExponent),
|
|
2166
|
-
hash: rsaOaepHashOf(alg)
|
|
2167
|
-
};
|
|
2168
|
-
keyUsages = pairUsage(KEY_ENCRYPTION_USAGES, [
|
|
2169
|
-
"encrypt",
|
|
2170
|
-
"decrypt",
|
|
2171
|
-
"wrapKey",
|
|
2172
|
-
"unwrapKey"
|
|
2173
|
-
]);
|
|
2174
|
-
break;
|
|
2175
|
-
case "A128KW":
|
|
2176
|
-
case "A192KW":
|
|
2177
|
-
case "A256KW":
|
|
2178
|
-
algorithm = {
|
|
2179
|
-
name: "AES-KW",
|
|
2180
|
-
length: aesBitsOf(alg)
|
|
2181
|
-
};
|
|
2182
|
-
keyUsages = usage(KEY_WRAPPING_USAGES, ["wrapKey", "unwrapKey"]);
|
|
2183
|
-
break;
|
|
2184
|
-
case "A128GCM":
|
|
2185
|
-
case "A192GCM":
|
|
2186
|
-
case "A256GCM":
|
|
2187
|
-
case "A128GCMKW":
|
|
2188
|
-
case "A192GCMKW":
|
|
2189
|
-
case "A256GCMKW":
|
|
2190
|
-
algorithm = {
|
|
2191
|
-
name: "AES-GCM",
|
|
2192
|
-
length: aesBitsOf(alg)
|
|
2193
|
-
};
|
|
2194
|
-
keyUsages = usage(KEY_ENCRYPTION_USAGES, ["encrypt", "decrypt"]);
|
|
2195
|
-
break;
|
|
2196
|
-
case "ES256":
|
|
2197
|
-
case "ES384":
|
|
2198
|
-
case "ES512": {
|
|
2199
|
-
const namedCurve = ECDSA_CURVES[alg];
|
|
2200
|
-
assertNamedCurve(options?.namedCurve, namedCurve, alg);
|
|
2201
|
-
algorithm = {
|
|
2202
|
-
name: "ECDSA",
|
|
2203
|
-
namedCurve
|
|
2204
|
-
};
|
|
2205
|
-
keyUsages = pairUsage(SIGNATURE_USAGES, ["sign", "verify"]);
|
|
2206
|
-
break;
|
|
2207
|
-
}
|
|
2208
|
-
case "Ed25519":
|
|
2209
|
-
assertNamedCurve(options?.namedCurve, "Ed25519", alg);
|
|
2210
|
-
keyUsages = pairUsage(SIGNATURE_USAGES, ["sign", "verify"]);
|
|
2211
|
-
algorithm = { name: "Ed25519" };
|
|
2212
|
-
break;
|
|
2213
|
-
case "EdDSA": {
|
|
2214
|
-
keyUsages = pairUsage(SIGNATURE_USAGES, ["sign", "verify"]);
|
|
2215
|
-
const namedCurve = options?.namedCurve ?? "Ed25519";
|
|
2216
|
-
if (namedCurve !== "Ed25519") throw new JWTError("Unsupported namedCurve provided. Supported values are: Ed25519", "ERR_JWK_UNSUPPORTED");
|
|
2217
|
-
algorithm = { name: namedCurve };
|
|
2218
|
-
break;
|
|
2219
|
-
}
|
|
2220
|
-
case "ECDH-ES":
|
|
2221
|
-
case "ECDH-ES+A128KW":
|
|
2222
|
-
case "ECDH-ES+A192KW":
|
|
2223
|
-
case "ECDH-ES+A256KW": {
|
|
2224
|
-
keyUsages = pairUsage(DERIVATION_USAGES, ["deriveBits"]);
|
|
2225
|
-
const namedCurve = options?.namedCurve ?? "P-256";
|
|
2226
|
-
switch (namedCurve) {
|
|
2227
|
-
case "P-256":
|
|
2228
|
-
case "P-384":
|
|
2229
|
-
case "P-521":
|
|
2230
|
-
algorithm = {
|
|
2231
|
-
name: "ECDH",
|
|
2232
|
-
namedCurve
|
|
2233
|
-
};
|
|
2234
|
-
break;
|
|
2235
|
-
case "X25519":
|
|
2236
|
-
algorithm = { name: "X25519" };
|
|
2237
|
-
break;
|
|
2238
|
-
default: throw new JWTError("Unsupported namedCurve provided. Supported values are: P-256, P-384, P-521 and X25519", "ERR_JWK_UNSUPPORTED");
|
|
2239
|
-
}
|
|
2240
|
-
break;
|
|
2241
|
-
}
|
|
2242
|
-
default: throw new JWTError(`Unsupported or invalid algorithm for key generation: ${alg}`, "ERR_JWK_UNSUPPORTED");
|
|
2243
|
-
}
|
|
2244
|
-
return {
|
|
2245
|
-
algorithm,
|
|
2246
|
-
keyUsages
|
|
2247
|
-
};
|
|
2248
|
-
}
|
|
2249
|
-
function inferAesImportAlgorithm(enc, cekLengthBytes) {
|
|
2250
|
-
const bitLength = cekLengthBytes << 3;
|
|
2251
|
-
if (enc) {
|
|
2252
|
-
if (enc.includes("GCM")) return {
|
|
2253
|
-
name: "AES-GCM",
|
|
2254
|
-
length: aesBitsOf(enc)
|
|
2255
|
-
};
|
|
2256
|
-
if (enc.includes("CBC-HS")) return;
|
|
2257
|
-
}
|
|
2258
|
-
if (bitLength === 128 || bitLength === 192 || bitLength === 256) return {
|
|
2259
|
-
name: "AES-GCM",
|
|
2260
|
-
length: bitLength
|
|
2261
|
-
};
|
|
2262
|
-
}
|
|
2263
|
-
const RESERVED_JWK_PARAMS = /* @__PURE__ */ new Set([
|
|
2264
|
-
"kty",
|
|
2265
|
-
"alg",
|
|
2266
|
-
"key_ops",
|
|
2267
|
-
"ext",
|
|
2268
|
-
"k",
|
|
2269
|
-
"d",
|
|
2270
|
-
"n",
|
|
2271
|
-
"e",
|
|
2272
|
-
"p",
|
|
2273
|
-
"q",
|
|
2274
|
-
"dp",
|
|
2275
|
-
"dq",
|
|
2276
|
-
"qi",
|
|
2277
|
-
"oth",
|
|
2278
|
-
"x",
|
|
2279
|
-
"y",
|
|
2280
|
-
"crv"
|
|
2281
|
-
]);
|
|
2282
|
-
function assertNoReservedJWKParams(jwkParams) {
|
|
2283
|
-
const reserved = Object.keys(jwkParams).filter((name) => RESERVED_JWK_PARAMS.has(name));
|
|
2284
|
-
if (reserved.length > 0) throw new JWTError(`jwkParams must not set reserved JWK members: ${reserved.join(", ")}`, "ERR_INVALID_OPTION");
|
|
2285
|
-
}
|
|
2286
|
-
function assertNamedCurve(requested, expected, alg) {
|
|
2287
|
-
if (requested === void 0 || requested === expected) return;
|
|
2288
|
-
throw new JWTError(`"namedCurve" ${requested} contradicts ${alg}, which is defined over ${expected}.`, "ERR_INVALID_OPTION");
|
|
2289
|
-
}
|
|
2290
|
-
function assertPublicExponent(publicExponent) {
|
|
2291
|
-
if (publicExponent === void 0) return new Uint8Array([
|
|
2292
|
-
1,
|
|
2293
|
-
0,
|
|
2294
|
-
1
|
|
2295
|
-
]);
|
|
2296
|
-
if (!(publicExponent instanceof Uint8Array) || publicExponent.length === 0) throw new JWTError("\"publicExponent\" must be the exponent's big-endian bytes as a Uint8Array.", "ERR_INVALID_OPTION");
|
|
2297
|
-
return publicExponent;
|
|
2298
|
-
}
|
|
2299
|
-
const SIGNATURE_USAGES = ["sign", "verify"];
|
|
2300
|
-
const KEY_WRAPPING_USAGES = ["wrapKey", "unwrapKey"];
|
|
2301
|
-
const KEY_ENCRYPTION_USAGES = [
|
|
2302
|
-
"encrypt",
|
|
2303
|
-
"decrypt",
|
|
2304
|
-
"wrapKey",
|
|
2305
|
-
"unwrapKey"
|
|
2306
|
-
];
|
|
2307
|
-
const DERIVATION_USAGES = ["deriveBits", "deriveKey"];
|
|
2308
|
-
const CONTENT_ENCRYPTION_USAGES = ["encrypt", "decrypt"];
|
|
2309
|
-
function resolveKeyUsage(requested, options) {
|
|
2310
|
-
const { allowed, fallback, alg } = options;
|
|
2311
|
-
if (requested === void 0) return fallback;
|
|
2312
|
-
if (!Array.isArray(requested) || requested.length === 0) throw new JWTError("\"keyUsage\" must be a non-empty array.", "ERR_INVALID_OPTION");
|
|
2313
|
-
const rejected = requested.filter((entry) => !allowed.includes(entry));
|
|
2314
|
-
if (rejected.length > 0) throw new JWTError(`"keyUsage" ${rejected.join(", ")} cannot be served by ${alg}; it admits ${allowed.join(", ")}.`, "ERR_INVALID_OPTION");
|
|
2315
|
-
return requested;
|
|
2316
|
-
}
|
|
2317
|
-
const PRIVATE_KEY_USAGES = [
|
|
2318
|
-
"sign",
|
|
2319
|
-
"decrypt",
|
|
2320
|
-
"unwrapKey",
|
|
2321
|
-
"deriveBits",
|
|
2322
|
-
"deriveKey"
|
|
2323
|
-
];
|
|
2324
|
-
const PUBLIC_KEY_USAGES = [
|
|
2325
|
-
"verify",
|
|
2326
|
-
"encrypt",
|
|
2327
|
-
"wrapKey"
|
|
2328
|
-
];
|
|
2329
|
-
function assertPairUsages(usages, options) {
|
|
2330
|
-
const { fallback, alg } = options;
|
|
2331
|
-
for (const [half, side] of [[PRIVATE_KEY_USAGES, "private"], [PUBLIC_KEY_USAGES, "public"]]) {
|
|
2332
|
-
const wanted = fallback.filter((entry) => half.includes(entry));
|
|
2333
|
-
if (wanted.length === 0 || usages.some((entry) => half.includes(entry))) continue;
|
|
2334
|
-
throw new JWTError(`"keyUsage" leaves the ${side} half of a ${alg} key pair with no usage; include one of ${wanted.join(", ")}.`, "ERR_INVALID_OPTION");
|
|
2335
|
-
}
|
|
2336
|
-
return usages;
|
|
2337
|
-
}
|
|
2338
|
-
function assertKidOption(kid) {
|
|
2339
|
-
if (kid === void 0 || kid === false || typeof kid === "string") return kid;
|
|
2340
|
-
throw new JWTError("\"kid\" must be a string or false.", "ERR_INVALID_OPTION");
|
|
2341
|
-
}
|
|
2342
|
-
async function withGeneratedKid(kid, jwk) {
|
|
2343
|
-
if (kid === false) return jwk;
|
|
2344
|
-
return {
|
|
2345
|
-
...jwk,
|
|
2346
|
-
kid: kid ?? await thumbprint(jwk)
|
|
2347
|
-
};
|
|
2348
|
-
}
|
|
2349
|
-
const PEM_ALGORITHMS = /* @__PURE__ */ new Set(Object.keys({
|
|
2350
|
-
"PS256": true,
|
|
2351
|
-
"PS384": true,
|
|
2352
|
-
"PS512": true,
|
|
2353
|
-
"RS256": true,
|
|
2354
|
-
"RS384": true,
|
|
2355
|
-
"RS512": true,
|
|
2356
|
-
"RSA-OAEP": true,
|
|
2357
|
-
"RSA-OAEP-256": true,
|
|
2358
|
-
"RSA-OAEP-384": true,
|
|
2359
|
-
"RSA-OAEP-512": true,
|
|
2360
|
-
"ES256": true,
|
|
2361
|
-
"ES384": true,
|
|
2362
|
-
"ES512": true,
|
|
2363
|
-
"ECDH-ES": true,
|
|
2364
|
-
"ECDH-ES+A128KW": true,
|
|
2365
|
-
"ECDH-ES+A192KW": true,
|
|
2366
|
-
"ECDH-ES+A256KW": true,
|
|
2367
|
-
"Ed25519": true,
|
|
2368
|
-
"EdDSA": true
|
|
2369
|
-
}));
|
|
2370
|
-
function assertWrappableCEK(cek, alg) {
|
|
2371
|
-
if (cek.length >= 16 && cek.length % 8 === 0) return;
|
|
2372
|
-
throw new JWTError(`${alg} wraps a key of 16 or more bytes in whole 8-byte blocks (got ${cek.length}).`, "ERR_INVALID_OPTION");
|
|
2373
|
-
}
|
|
2374
|
-
async function unwrapping(operation) {
|
|
2375
|
-
try {
|
|
2376
|
-
return await operation;
|
|
2377
|
-
} catch (error) {
|
|
2378
|
-
throw asDecryptionError(error);
|
|
2379
|
-
}
|
|
2380
|
-
}
|
|
2381
|
-
function assertPBES2Algorithm(alg) {
|
|
2382
|
-
if (typeof alg === "string" && PBES2_ALGORITHMS.includes(alg)) return;
|
|
2383
|
-
throw new JWTError(`Password derivation is defined for ${PBES2_ALGORITHMS.join(", ")}, not ${String(alg)}.`, "ERR_JWK_UNSUPPORTED");
|
|
2384
|
-
}
|
|
2385
|
-
function assertKeyBytesArg(value, name) {
|
|
2386
|
-
if (value instanceof Uint8Array || isCryptoKey(value)) return;
|
|
2387
|
-
throw new JWTError(`"${name}" must be a Uint8Array or a CryptoKey, got ${value === null ? "null" : typeof value}.`, "ERR_INVALID_OPTION");
|
|
2388
|
-
}
|
|
2389
|
-
function assertModulusLength(modulusLength) {
|
|
2390
|
-
const length = modulusLength ?? 2048;
|
|
2391
|
-
if (!Number.isInteger(length) || length < 2048) throw new JWTError("modulusLength must be at least 2048 bits (RFC 7518 §3.3)", "ERR_INVALID_OPTION");
|
|
2392
|
-
return length;
|
|
2393
|
-
}
|
|
2394
|
-
function assertPartyInfoLength(name, bytes) {
|
|
2395
|
-
if (bytes.length > 1024) throw new JWTError(`Invalid JWE: "${name}" must not exceed ${MAX_PARTY_INFO_BYTES} bytes (got ${bytes.length}).`, "ERR_JWE_INVALID");
|
|
2396
|
-
}
|
|
2397
|
-
function assertKeyWrapSegmentLength(name, bytes, expected, alg) {
|
|
2398
|
-
if (bytes.length !== expected) throw new JWTError(`Invalid JWE: "${name}" must be ${expected} bytes for ${alg} (got ${bytes.length}).`, "ERR_JWE_INVALID");
|
|
2399
|
-
}
|
|
2400
|
-
function assertDerivedKeyLength(keyLength) {
|
|
2401
|
-
if (!Number.isInteger(keyLength) || keyLength <= 0 || keyLength % 8 !== 0 || keyLength > 8192) throw new JWTError(`keyLength must be a positive multiple of 8 no greater than 8192 bits, got ${keyLength}`, "ERR_INVALID_OPTION");
|
|
2402
|
-
}
|
|
2403
|
-
function assertCryptoKeyFor(alg, key, role) {
|
|
2404
|
-
if (isCryptoKey(key)) return;
|
|
2405
|
-
throw new JWTError(`${alg.startsWith("RSA") ? "RSA-OAEP" : "ECDH-ES"} requires the ${role} key to be a CryptoKey`, "ERR_JWK_INVALID");
|
|
2406
|
-
}
|
|
2407
|
-
function segmentBytes(value, name) {
|
|
2408
|
-
return typeof value === "string" ? decodeSegment(value, {
|
|
2409
|
-
family: "JWE",
|
|
2410
|
-
what: `"${name}"`
|
|
2411
|
-
}) : value;
|
|
2412
|
-
}
|
|
2413
|
-
function withAlg(jwk, alg) {
|
|
2414
|
-
return {
|
|
2415
|
-
...jwk,
|
|
2416
|
-
alg
|
|
2417
|
-
};
|
|
2418
|
-
}
|
|
2419
|
-
function generatedPairAlgorithm(alg) {
|
|
2420
|
-
return alg;
|
|
2421
|
-
}
|
|
2422
|
-
function generatedSecretAlgorithm(alg) {
|
|
2423
|
-
return alg;
|
|
2424
|
-
}
|
|
2425
|
-
const PUBLIC_KEY_OPS = /* @__PURE__ */ new Map([
|
|
2426
|
-
["sign", "verify"],
|
|
2427
|
-
["verify", "verify"],
|
|
2428
|
-
["decrypt", "encrypt"],
|
|
2429
|
-
["encrypt", "encrypt"],
|
|
2430
|
-
["unwrapKey", "wrapKey"],
|
|
2431
|
-
["wrapKey", "wrapKey"]
|
|
2432
|
-
]);
|
|
2433
|
-
function publicKeyOps(keyOps) {
|
|
2434
|
-
if (!Array.isArray(keyOps)) return [];
|
|
2435
|
-
const ops = [];
|
|
2436
|
-
for (const op of keyOps) {
|
|
2437
|
-
const publicOp = typeof op === "string" ? PUBLIC_KEY_OPS.get(op) : void 0;
|
|
2438
|
-
if (publicOp !== void 0 && !ops.includes(publicOp)) ops.push(publicOp);
|
|
2439
|
-
}
|
|
2440
|
-
return ops;
|
|
2441
|
-
}
|
|
2442
|
-
function requestedKeyOps(options, key) {
|
|
2443
|
-
return options.keyUsage === void 0 ? void 0 : [...key.usages];
|
|
2444
|
-
}
|
|
2445
|
-
function withKeyOps(jwk, keyOps) {
|
|
2446
|
-
return keyOps === void 0 ? jwk : {
|
|
2447
|
-
...jwk,
|
|
2448
|
-
key_ops: keyOps
|
|
2449
|
-
};
|
|
2450
|
-
}
|
|
2451
|
-
export { DEFAULT_JOSE_LIMITS, DEFAULT_PBES2_ITERATIONS, JWE_ALG_CTX, JWE_DIRECT_ALGS, JWS_ALG_CTX, WeakMapJWKCache, applyB64Header, asDecryptionError, asJWTError, asKeyLookupError, asKeyUsageError, assertB64Option, assertCompactToken, assertConsumerOptions, assertDirectKeyRole, assertEntryLimit, assertJWEAlgSupported, assertJWEEncSupported, assertJWKSetCandidates, assertJWSAlgSupported, assertNoZipOption, assertNotStringKey, assertOptionEntry, assertPBES2Params, assertProducerCEK, assertProducerConfirmation, assertProducerCrit, assertProducerIV, assertProducerKeyHeaders, assertProtectedOnlyOption, assertSerializationObject, buildECDHAgreementParams, buildJWKSetFilter, buildUnwrapKeyOptions, checkAlgAllowed, checkJWEAlgSupported, checkJWEContentSegments, checkJWEDirectEncryptedKey, checkJWEEncAllowed, checkJWEEncSupported, checkJWEUnprotectedCrit, checkJWEZip, checkJWSAlgSupported, checkJWSB64, checkProtectedTyp, checkSerializationEntry, clearJWKCache, configureJWKCache, createPBES2Budget, decodeJWEPayload, decodeJWSPayload, decodeProtectedHeader, decodeSegment, decrypt, deriveJWKFromPassword, deriveKeyFromPassword, deriveSharedSecret, encrypt, encryptKey, exportJWK, exportKey, exportPEM, exportReturnedCek, generateCEK, generateIV, generateJWK, generateKey, getJWKsFromSet, importKey, importPEM, isJWEAlgSupported, keyMatchesHeader, quoteTokenValue, resolveKeyInput, resolveLimit, resolvePasswordKey, resolvePayloadMode, resolveSigningKey, serializeProtectedHeader, sign, stringKeyError, thumbprint, toPublicJWK, unwrapKey, validateClaimsIfJson, verify, wrapKey };
|
|
1746
|
+
export { DEFAULT_JOSE_LIMITS, DEFAULT_PBES2_ITERATIONS, JWE_ALG_CTX, JWE_DIRECT_ALGS, JWS_ALG_CTX, MAX_PARTY_INFO_BYTES, WeakMapJWKCache, aesKwUnwrap, aesKwWrap, applyB64Header, asDecryptionError, asJWTError, asKeyLookupError, asKeyUsageError, assertB64Option, assertCompactToken, assertConsumerOptions, assertDirectKeyRole, assertECDHKeyAllowed, assertEntryLimit, assertJWEAlgSupported, assertJWEEncSupported, assertJWKSetCandidates, assertJWSAlgSupported, assertNoZipOption, assertNotStringKey, assertOctKeyLength, assertOptionEntry, assertPBES2Count, assertPBES2Params, assertPBES2Salt, assertProducerCEK, assertProducerConfirmation, assertProducerCrit, assertProducerIV, assertProducerKeyHeaders, assertProtectedOnlyOption, assertSerializationObject, bitLengthCEK, bitLengthIV, bitLengthTag, buildECDHAgreementParams, buildJWKSetFilter, buildUnwrapKeyOptions, checkAlgAllowed, checkJWEAlgSupported, checkJWEContentSegments, checkJWEDirectEncryptedKey, checkJWEEncAllowed, checkJWEEncSupported, checkJWEUnprotectedCrit, checkJWEZip, checkJWSAlgSupported, checkJWSB64, checkProtectedTyp, checkSerializationEntry, clearJWKCache, configureJWKCache, createPBES2Budget, decodeJWEPayload, decodeJWSPayload, decodeProtectedHeader, decodeSegment, decrypt, decryptRSAES, deriveECDHESKey, deriveKey, ecdhDerivedBits, ecdhesWrap, encrypt, encryptKey, encryptRSAES, exportReturnedCek, fromPKCS8, fromSPKI, fromX509, gcmkwDecrypt, gcmkwEncrypt, generateCEK, generateIV, getJWKsFromSet, importKey, isJWEAlgSupported, keyMatchesHeader, keyToJWK, normalizeEpk, pbes2Unwrap, pbes2Wrap, quoteTokenValue, resolveKeyInput, resolveLimit, resolvePasswordKey, resolvePayloadMode, resolveSigningKey, serializeProtectedHeader, sign, stringKeyError, thumbprint, toPKCS8, toSPKI, validateClaimsIfJson, verify };
|