unjwt 0.5.15 → 0.5.17

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.
@@ -1,4 +1,4 @@
1
- import { m as isCryptoKey, k as concatUint8Arrays, d as base64UrlEncode, q as base64Decode, u as base64Encode, s as sanitizeObject, t as textEncoder, r as randomBytes, a as isJWK, f as base64UrlDecode, g as isJWKSet } from './unjwt.CRHfsi7v.mjs';
1
+ import { k as isCryptoKey, p as concatUint8Arrays, d as base64UrlEncode, q as base64Decode, u as base64Encode, t as textEncoder, s as sanitizeObject, w as assertCryptoKey, a as isJWK, e as base64UrlDecode, x as isAsymmetricJWK, r as randomBytes, m as isJWKSet } from './unjwt.tM5bsBSH.mjs';
2
2
 
3
3
  /**
4
4
  * This is a fork of Jose library's utility functions.
@@ -762,6 +762,65 @@ const fromX509 = (pem, alg, options) => {
762
762
  return fromSPKI(spki, alg, options);
763
763
  };
764
764
 
765
+ function lengthAndInput(input) {
766
+ return concatUint8Arrays(uint32be(input.length), input);
767
+ }
768
+ async function concatKdf(secret, bits, value) {
769
+ const iterations = Math.ceil((bits >> 3) / 32);
770
+ const res = new Uint8Array(iterations * 32);
771
+ for (let iter = 0; iter < iterations; iter++) {
772
+ const buf = new Uint8Array(4 + secret.length + value.length);
773
+ buf.set(uint32be(iter + 1));
774
+ buf.set(secret, 4);
775
+ buf.set(value, 4 + secret.length);
776
+ res.set(await digest("sha256", buf), iter * 32);
777
+ }
778
+ return res.slice(0, bits >> 3);
779
+ }
780
+ async function deriveECDHESKey(publicKey, privateKey, algorithm, keyLength, apu = new Uint8Array(0), apv = new Uint8Array(0)) {
781
+ checkEncCryptoKey(publicKey, "ECDH");
782
+ checkEncCryptoKey(privateKey, "ECDH", "deriveBits");
783
+ const value = concatUint8Arrays(
784
+ lengthAndInput(textEncoder.encode(algorithm)),
785
+ lengthAndInput(apu),
786
+ lengthAndInput(apv),
787
+ uint32be(keyLength)
788
+ );
789
+ const length = publicKey.algorithm.name === "X25519" ? 256 : Math.ceil(
790
+ Number.parseInt(
791
+ publicKey.algorithm.namedCurve.slice(-3),
792
+ 10
793
+ ) / 8
794
+ ) << 3;
795
+ const sharedSecret = new Uint8Array(
796
+ await crypto.subtle.deriveBits(
797
+ {
798
+ name: publicKey.algorithm.name,
799
+ public: publicKey
800
+ },
801
+ privateKey,
802
+ length
803
+ )
804
+ );
805
+ return concatKdf(sharedSecret, keyLength, value);
806
+ }
807
+ function allowed(key) {
808
+ switch (key.algorithm.namedCurve) {
809
+ case "P-256":
810
+ case "P-384":
811
+ case "P-521": {
812
+ return true;
813
+ }
814
+ default: {
815
+ return key.algorithm.name === "X25519";
816
+ }
817
+ }
818
+ }
819
+ async function digest(algorithm, data) {
820
+ const subtleDigest = `SHA-${algorithm.slice(-3)}`;
821
+ return new Uint8Array(await crypto.subtle.digest(subtleDigest, data));
822
+ }
823
+
765
824
  /**
766
825
  * This is a fork of Jose library's utility functions.
767
826
  * @source https://github.com/panva/jose/tree/69b7960c67e05be55fa2ec31c74b987696c20c60/src/lib/jwt_to_key.ts
@@ -923,6 +982,134 @@ async function keyToJWK(key) {
923
982
  return jwk;
924
983
  }
925
984
 
985
+ /**
986
+ * This is a fork of Jose library's utility functions.
987
+ * @source https://github.com/panva/jose/tree/69b7960c67e05be55fa2ec31c74b987696c20c60/src/lib/sign.ts
988
+ * @source https://github.com/panva/jose/tree/69b7960c67e05be55fa2ec31c74b987696c20c60/src/lib/verify.ts
989
+ * @license MIT https://github.com/panva/jose/blob/69b7960c67e05be55fa2ec31c74b987696c20c60/LICENSE.md
990
+ */
991
+ async function sign(alg, key, data) {
992
+ const cryptoKey = await getSignVerifyKey(alg, key, "sign");
993
+ checkKeyLength(alg, cryptoKey);
994
+ const signature = await crypto.subtle.sign(
995
+ subtleAlgorithm$1(alg, cryptoKey.algorithm),
996
+ cryptoKey,
997
+ data
998
+ );
999
+ return new Uint8Array(signature);
1000
+ }
1001
+ async function verify(alg, key, signature, data) {
1002
+ const cryptoKey = await getSignVerifyKey(alg, key, "verify");
1003
+ checkKeyLength(alg, cryptoKey);
1004
+ const algorithm = subtleAlgorithm$1(alg, cryptoKey.algorithm);
1005
+ try {
1006
+ return await crypto.subtle.verify(algorithm, cryptoKey, signature, data);
1007
+ } catch {
1008
+ return false;
1009
+ }
1010
+ }
1011
+ function checkKeyLength(alg, key) {
1012
+ if (alg.startsWith("RS") || alg.startsWith("PS")) {
1013
+ const { modulusLength } = key.algorithm;
1014
+ if (typeof modulusLength !== "number" || modulusLength < 2048) {
1015
+ throw new TypeError(
1016
+ `${alg} requires key modulusLength to be 2048 bits or larger`
1017
+ );
1018
+ }
1019
+ }
1020
+ }
1021
+ async function getSignVerifyKey(alg, key, usage) {
1022
+ if (key instanceof Uint8Array) {
1023
+ if (!alg.startsWith("HS")) {
1024
+ throw new TypeError(
1025
+ `Key must be ${key} of type: CryptoKey or JSON Web Key`
1026
+ );
1027
+ }
1028
+ return crypto.subtle.importKey(
1029
+ "raw",
1030
+ key,
1031
+ { hash: `SHA-${alg.slice(-3)}`, name: "HMAC" },
1032
+ false,
1033
+ [usage]
1034
+ );
1035
+ }
1036
+ checkSigCryptoKey(key, alg, usage);
1037
+ return key;
1038
+ }
1039
+ function subtleAlgorithm$1(alg, algorithm) {
1040
+ const hash = `SHA-${alg.slice(-3)}`;
1041
+ switch (alg) {
1042
+ case "HS256":
1043
+ case "HS384":
1044
+ case "HS512": {
1045
+ return { hash, name: "HMAC" };
1046
+ }
1047
+ case "PS256":
1048
+ case "PS384":
1049
+ case "PS512": {
1050
+ return {
1051
+ hash,
1052
+ name: "RSA-PSS",
1053
+ saltLength: Number.parseInt(alg.slice(-3), 10) >> 3
1054
+ };
1055
+ }
1056
+ case "RS256":
1057
+ case "RS384":
1058
+ case "RS512": {
1059
+ return { hash, name: "RSASSA-PKCS1-v1_5" };
1060
+ }
1061
+ case "ES256":
1062
+ case "ES384":
1063
+ case "ES512": {
1064
+ return {
1065
+ hash,
1066
+ name: "ECDSA",
1067
+ namedCurve: algorithm.namedCurve
1068
+ };
1069
+ }
1070
+ case "Ed25519":
1071
+ // Fall through
1072
+ case "EdDSA": {
1073
+ return { name: "Ed25519" };
1074
+ }
1075
+ default: {
1076
+ throw new Error(
1077
+ `alg ${alg} is not supported either by JOSE or your javascript runtime`
1078
+ );
1079
+ }
1080
+ }
1081
+ }
1082
+
1083
+ const subtleAlgorithm = (alg) => {
1084
+ switch (alg) {
1085
+ case "RSA-OAEP":
1086
+ case "RSA-OAEP-256":
1087
+ case "RSA-OAEP-384":
1088
+ case "RSA-OAEP-512": {
1089
+ return "RSA-OAEP";
1090
+ }
1091
+ default: {
1092
+ throw new Error(
1093
+ `alg ${alg} is not supported either by JOSE or your javascript runtime`
1094
+ );
1095
+ }
1096
+ }
1097
+ };
1098
+ async function encryptRSAES(alg, key, cek) {
1099
+ checkEncCryptoKey(key, alg, "encrypt");
1100
+ checkKeyLength(alg, key);
1101
+ return new Uint8Array(
1102
+ await crypto.subtle.encrypt(subtleAlgorithm(alg), key, cek)
1103
+ );
1104
+ }
1105
+ async function decryptRSAES(alg, key, encryptedKey) {
1106
+ checkEncCryptoKey(key, alg, "decrypt");
1107
+ checkKeyLength(alg, key);
1108
+ return new Uint8Array(
1109
+ await crypto.subtle.decrypt(subtleAlgorithm(alg), key, encryptedKey)
1110
+ );
1111
+ }
1112
+
926
1113
  /**
927
1114
  * This is a fork of Jose library's utility functions.
928
1115
  * @source https://github.com/panva/jose/tree/69b7960c67e05be55fa2ec31c74b987696c20c60/src/lib/pbes2kw.ts
@@ -1026,6 +1213,224 @@ async function _unwrap(alg, key, encryptedKey) {
1026
1213
  return new Uint8Array(await crypto.subtle.exportKey("raw", cryptoKeyCek));
1027
1214
  }
1028
1215
 
1216
+ /**
1217
+ * This is a fork of Jose library's utility functions.
1218
+ * @source https://github.com/panva/jose/tree/69b7960c67e05be55fa2ec31c74b987696c20c60/src/lib/encrypt_key_management.ts
1219
+ * @license MIT https://github.com/panva/jose/blob/69b7960c67e05be55fa2ec31c74b987696c20c60/LICENSE.md
1220
+ */
1221
+ const PUBLIC_EPK_FIELDS = /* @__PURE__ */ new Set([
1222
+ "kty",
1223
+ "crv",
1224
+ "x",
1225
+ "y",
1226
+ "kid",
1227
+ "use",
1228
+ "key_ops",
1229
+ "alg",
1230
+ "x5c",
1231
+ "x5t",
1232
+ "x5t#S256",
1233
+ "x5u"
1234
+ ]);
1235
+ function toPublicEpkJwk(jwk) {
1236
+ const filtered = {};
1237
+ for (const [key, value] of Object.entries(jwk)) {
1238
+ if (value !== void 0 && PUBLIC_EPK_FIELDS.has(key)) {
1239
+ filtered[key] = value;
1240
+ }
1241
+ }
1242
+ const { kty, crv, x, y } = filtered;
1243
+ if (typeof kty !== "string") {
1244
+ throw new TypeError(
1245
+ 'ECDH-ES ephemeral key JWK must include the "kty" parameter.'
1246
+ );
1247
+ }
1248
+ if (typeof crv !== "string") {
1249
+ throw new TypeError(
1250
+ 'ECDH-ES ephemeral key JWK must include the "crv" parameter.'
1251
+ );
1252
+ }
1253
+ if (typeof x !== "string") {
1254
+ throw new TypeError(
1255
+ 'ECDH-ES ephemeral key JWK must include the "x" coordinate.'
1256
+ );
1257
+ }
1258
+ if (kty === "EC" && typeof y !== "string") {
1259
+ throw new TypeError(
1260
+ 'ECDH-ES EC ephemeral key JWK must include both "x" and "y" coordinates.'
1261
+ );
1262
+ }
1263
+ const publicJwk = {
1264
+ ...filtered,
1265
+ kty,
1266
+ crv,
1267
+ x
1268
+ };
1269
+ if (typeof y === "string") {
1270
+ publicJwk.y = y;
1271
+ } else {
1272
+ delete publicJwk.y;
1273
+ }
1274
+ return sanitizeObject(publicJwk);
1275
+ }
1276
+ async function ensurePrivateKey(alg, value) {
1277
+ const normalized = await normalizeKey(value, alg);
1278
+ if (!(normalized instanceof CryptoKey)) {
1279
+ throw new TypeError(
1280
+ "ECDH-ES ephemeral private key must be a CryptoKey or convertible JWK."
1281
+ );
1282
+ }
1283
+ if (normalized.type !== "private") {
1284
+ throw new TypeError(
1285
+ 'ECDH-ES ephemeral private key must have type "private".'
1286
+ );
1287
+ }
1288
+ return normalized;
1289
+ }
1290
+ async function exportPublicJwkFrom(alg, value) {
1291
+ if (isCryptoKey(value)) {
1292
+ try {
1293
+ return toPublicEpkJwk(await keyToJWK(value));
1294
+ } catch (error_) {
1295
+ throw new TypeError(
1296
+ "ECDH-ES ephemeral CryptoKey must be extractable to export as JWK.",
1297
+ { cause: error_ instanceof Error ? error_ : void 0 }
1298
+ );
1299
+ }
1300
+ }
1301
+ if (isJWK(value) && isAsymmetricJWK(value) && value.kty === "EC") {
1302
+ return toPublicEpkJwk(value);
1303
+ }
1304
+ const normalized = await normalizeKey(value, alg);
1305
+ if (!(normalized instanceof CryptoKey)) {
1306
+ throw new TypeError(
1307
+ "ECDH-ES ephemeral public key must be a CryptoKey or convertible JWK."
1308
+ );
1309
+ }
1310
+ return exportPublicJwkFrom(alg, normalized);
1311
+ }
1312
+ async function encryptKey(alg, enc, key, providedCek, providedParameters = {}) {
1313
+ let encryptedKey;
1314
+ let parameters = {};
1315
+ let cek;
1316
+ switch (alg) {
1317
+ case "dir": {
1318
+ cek = key;
1319
+ break;
1320
+ }
1321
+ case "ECDH-ES":
1322
+ case "ECDH-ES+A128KW":
1323
+ case "ECDH-ES+A192KW":
1324
+ case "ECDH-ES+A256KW": {
1325
+ assertCryptoKey(key);
1326
+ if (!allowed(key)) {
1327
+ throw new Error(
1328
+ "ECDH with the provided key is not allowed or not supported by your javascript runtime"
1329
+ );
1330
+ }
1331
+ const { apu, apv, epk: providedEpk, epkPrivateKey } = providedParameters;
1332
+ if (providedEpk && !epkPrivateKey) {
1333
+ throw new TypeError(
1334
+ "ECDH-ES custom ephemeral key material must include the matching private key."
1335
+ );
1336
+ }
1337
+ let ephemeralPrivateKey;
1338
+ let epkHeader;
1339
+ if (epkPrivateKey) {
1340
+ ephemeralPrivateKey = await ensurePrivateKey(alg, epkPrivateKey);
1341
+ const publicSource = providedEpk ?? epkPrivateKey;
1342
+ epkHeader = await exportPublicJwkFrom(alg, publicSource);
1343
+ } else {
1344
+ if (providedEpk) {
1345
+ throw new TypeError(
1346
+ "ECDH-ES custom ephemeral public key requires a matching private key."
1347
+ );
1348
+ }
1349
+ const generated = await crypto.subtle.generateKey(
1350
+ key.algorithm,
1351
+ true,
1352
+ ["deriveBits"]
1353
+ );
1354
+ ephemeralPrivateKey = generated.privateKey;
1355
+ epkHeader = await exportPublicJwkFrom(alg, generated.publicKey);
1356
+ }
1357
+ const sharedSecret = await deriveECDHESKey(
1358
+ key,
1359
+ ephemeralPrivateKey,
1360
+ alg === "ECDH-ES" ? enc : alg,
1361
+ alg === "ECDH-ES" ? bitLengthCEK(enc) : Number.parseInt(alg.slice(-5, -2), 10),
1362
+ apu,
1363
+ apv
1364
+ );
1365
+ parameters = { epk: epkHeader };
1366
+ if (apu) parameters.apu = base64UrlEncode(apu);
1367
+ if (apv) parameters.apv = base64UrlEncode(apv);
1368
+ if (alg === "ECDH-ES") {
1369
+ cek = sharedSecret;
1370
+ break;
1371
+ }
1372
+ cek = providedCek || generateCEK(enc);
1373
+ const kwAlg = alg.slice(-6);
1374
+ encryptedKey = (await wrap(kwAlg, sharedSecret, cek)).encryptedKey;
1375
+ break;
1376
+ }
1377
+ case "RSA-OAEP":
1378
+ case "RSA-OAEP-256":
1379
+ case "RSA-OAEP-384":
1380
+ case "RSA-OAEP-512": {
1381
+ cek = providedCek || generateCEK(enc);
1382
+ assertCryptoKey(key);
1383
+ encryptedKey = await encryptRSAES(alg, key, cek);
1384
+ break;
1385
+ }
1386
+ case "PBES2-HS256+A128KW":
1387
+ case "PBES2-HS384+A192KW":
1388
+ case "PBES2-HS512+A256KW": {
1389
+ cek = providedCek || generateCEK(enc);
1390
+ const { p2c, p2s } = providedParameters;
1391
+ ({ encryptedKey, ...parameters } = await wrap(alg, key, cek, p2c, p2s));
1392
+ break;
1393
+ }
1394
+ case "A128KW":
1395
+ case "A192KW":
1396
+ case "A256KW": {
1397
+ cek = providedCek || generateCEK(enc);
1398
+ encryptedKey = (await wrap(alg, key, cek)).encryptedKey;
1399
+ break;
1400
+ }
1401
+ case "A128GCMKW":
1402
+ case "A192GCMKW":
1403
+ case "A256GCMKW": {
1404
+ cek = providedCek || generateCEK(enc);
1405
+ const { iv } = providedParameters;
1406
+ ({ encryptedKey, ...parameters } = await encryptIV(alg, key, cek, iv));
1407
+ break;
1408
+ }
1409
+ default: {
1410
+ throw new Error(
1411
+ 'Invalid or unsupported "alg" (JWE Algorithm) header value'
1412
+ );
1413
+ }
1414
+ }
1415
+ return { cek, encryptedKey, parameters };
1416
+ }
1417
+ async function normalizeKey(key, alg) {
1418
+ if (key instanceof Uint8Array) {
1419
+ return key;
1420
+ }
1421
+ if (isCryptoKey(key)) {
1422
+ return key;
1423
+ }
1424
+ if (isJWK(key)) {
1425
+ const safeJwk = sanitizeObject(key);
1426
+ if ("k" in safeJwk && safeJwk.k) {
1427
+ return base64UrlDecode(safeJwk.k, false);
1428
+ }
1429
+ return jwkTokey({ ...safeJwk, alg });
1430
+ }
1431
+ throw new Error("unreachable");
1432
+ }
1433
+
1029
1434
  async function generateKey(alg, options = {}) {
1030
1435
  const exportToJWK = options.toJWK !== void 0 && options.toJWK !== false;
1031
1436
  const defaultExtractable = options.extractable !== false;
@@ -1052,17 +1457,36 @@ async function generateKey(alg, options = {}) {
1052
1457
  ...additionalKeyParams
1053
1458
  } = typeof options.toJWK === "object" ? options.toJWK : {};
1054
1459
  if (key instanceof CryptoKey) {
1055
- return exportKey(key, { ...additionalKeyParams, alg });
1460
+ return exportKey(key, {
1461
+ ...additionalKeyParams,
1462
+ key_ops: keyUsages,
1463
+ alg
1464
+ });
1056
1465
  } else {
1057
1466
  const [publicKey, privateKey] = await Promise.all([
1058
1467
  exportKey(key.publicKey, { ...additionalKeyParams, alg }),
1059
- exportKey(key.privateKey, { ...additionalKeyParams, alg })
1468
+ exportKey(key.privateKey, {
1469
+ ...additionalKeyParams,
1470
+ key_ops: keyUsages,
1471
+ alg
1472
+ })
1060
1473
  ]);
1061
1474
  return { privateKey, publicKey };
1062
1475
  }
1063
1476
  }
1064
1477
  return key;
1065
1478
  }
1479
+ async function generateJWK(alg, jwkParams, options = {}) {
1480
+ const {
1481
+ // @ts-expect-error destructuring just to avoid passing it down
1482
+ toJWK: _,
1483
+ ...opts
1484
+ } = options;
1485
+ return generateKey(alg, {
1486
+ ...opts,
1487
+ toJWK: jwkParams || true
1488
+ });
1489
+ }
1066
1490
  async function deriveKeyFromPassword(password, alg, options) {
1067
1491
  const { salt, iterations, toJWK, extractable, keyUsage } = options;
1068
1492
  if (!(salt instanceof Uint8Array) || salt.length < 8) {
@@ -1287,22 +1711,33 @@ async function unwrapKey(alg, wrappedKey, unwrappingKey, options = {}) {
1287
1711
  case "RSA-OAEP-256":
1288
1712
  case "RSA-OAEP-384":
1289
1713
  case "RSA-OAEP-512": {
1290
- const unwrappedKey = await crypto.subtle.unwrapKey(
1291
- "raw",
1292
- wrappedKey,
1714
+ if (!(importedUnwrappingKey instanceof CryptoKey)) {
1715
+ throw new TypeError(
1716
+ "RSA-OAEP requires the unwrapping key to be provided as a CryptoKey"
1717
+ );
1718
+ }
1719
+ unwrappedCekBytes = await decryptRSAES(
1720
+ alg,
1293
1721
  importedUnwrappingKey,
1294
- { name: "RSA-OAEP" },
1295
- options.unwrappedKeyAlgorithm || { name: "AES-GCM" },
1296
- // Fallback
1297
- defaultExtractable,
1298
- options.keyUsage || ["encrypt", "decrypt"]
1299
- // Default usages
1722
+ wrappedKey
1300
1723
  );
1301
- if (returnAs) return unwrappedKey;
1302
- unwrappedCekBytes = new Uint8Array(
1303
- await crypto.subtle.exportKey("raw", unwrappedKey)
1724
+ if (!returnAs) {
1725
+ break;
1726
+ }
1727
+ const inferredAlgorithm = options.unwrappedKeyAlgorithm || inferAesImportAlgorithm(options.enc, unwrappedCekBytes.length);
1728
+ if (!inferredAlgorithm) {
1729
+ throw new Error(
1730
+ 'Unable to infer algorithm for RSA-OAEP unwrapped key. Provide "unwrappedKeyAlgorithm" in options.'
1731
+ );
1732
+ }
1733
+ const keyUsages = options.keyUsage || ["encrypt", "decrypt"];
1734
+ return await crypto.subtle.importKey(
1735
+ "raw",
1736
+ unwrappedCekBytes,
1737
+ inferredAlgorithm,
1738
+ defaultExtractable,
1739
+ keyUsages
1304
1740
  );
1305
- break;
1306
1741
  }
1307
1742
  case "ECDH-ES":
1308
1743
  case "ECDH-ES+A128KW":
@@ -1311,7 +1746,49 @@ async function unwrapKey(alg, wrappedKey, unwrappingKey, options = {}) {
1311
1746
  if (!options.epk) {
1312
1747
  throw new Error("ECDH-ES requires 'epk' (Ephemeral Public Key) option");
1313
1748
  }
1314
- throw new Error(`Algorithm ${alg} not yet implemented in unwrapKey`);
1749
+ if (!(importedUnwrappingKey instanceof CryptoKey)) {
1750
+ throw new TypeError(
1751
+ "ECDH-ES requires the unwrapping key to be a CryptoKey"
1752
+ );
1753
+ }
1754
+ if (!allowed(importedUnwrappingKey)) {
1755
+ throw new Error(
1756
+ "ECDH with the provided key is not allowed or not supported"
1757
+ );
1758
+ }
1759
+ const epkCandidate = options.epk instanceof CryptoKey ? options.epk : await normalizeKey(options.epk, alg);
1760
+ if (!(epkCandidate instanceof CryptoKey)) {
1761
+ throw new TypeError("Failed to normalize ECDH ephemeral public key");
1762
+ }
1763
+ const apuBytes = typeof options.apu === "string" ? base64UrlDecode(options.apu, false) : options.apu ?? new Uint8Array(0);
1764
+ const apvBytes = typeof options.apv === "string" ? base64UrlDecode(options.apv, false) : options.apv ?? new Uint8Array(0);
1765
+ const infoAlg = alg === "ECDH-ES" ? options.enc : alg;
1766
+ if (!infoAlg) {
1767
+ throw new Error(
1768
+ "ECDH-ES requires content encryption algorithm ('enc') to derive the shared secret"
1769
+ );
1770
+ }
1771
+ const keyLength = alg === "ECDH-ES" ? bitLengthCEK(infoAlg) : Number.parseInt(alg.slice(-5, -2), 10);
1772
+ const sharedSecret = await deriveECDHESKey(
1773
+ epkCandidate,
1774
+ importedUnwrappingKey,
1775
+ infoAlg,
1776
+ keyLength,
1777
+ apuBytes,
1778
+ apvBytes
1779
+ );
1780
+ if (alg === "ECDH-ES") {
1781
+ unwrappedCekBytes = sharedSecret;
1782
+ } else {
1783
+ const kwAlg = alg.slice(-6);
1784
+ if (!(wrappedKey instanceof Uint8Array) || wrappedKey.length === 0) {
1785
+ throw new Error(
1786
+ "ECDH-ES key agreement with key wrapping requires an encrypted key"
1787
+ );
1788
+ }
1789
+ unwrappedCekBytes = await unwrap(kwAlg, sharedSecret, wrappedKey);
1790
+ }
1791
+ break;
1315
1792
  }
1316
1793
  default: {
1317
1794
  throw new Error(`Unsupported key unwrapping algorithm: ${alg}`);
@@ -1483,28 +1960,6 @@ function getGenerateKeyParams(alg, options) {
1483
1960
  keyUsages = defaultKeyUsage ?? ["sign", "verify"];
1484
1961
  break;
1485
1962
  }
1486
- // ECDSA Signatures
1487
- case "ES256": {
1488
- algorithm = { name: "ECDSA", namedCurve: "P-256" };
1489
- keyUsages = defaultKeyUsage ?? ["sign", "verify"];
1490
- break;
1491
- }
1492
- case "ES384": {
1493
- algorithm = { name: "ECDSA", namedCurve: "P-384" };
1494
- keyUsages = defaultKeyUsage ?? ["sign", "verify"];
1495
- break;
1496
- }
1497
- case "ES512": {
1498
- algorithm = { name: "ECDSA", namedCurve: "P-521" };
1499
- keyUsages = defaultKeyUsage ?? ["sign", "verify"];
1500
- break;
1501
- }
1502
- case "Ed25519":
1503
- case "EdDSA": {
1504
- algorithm = { name: "Ed25519" };
1505
- keyUsages = defaultKeyUsage ?? ["sign", "verify"];
1506
- break;
1507
- }
1508
1963
  // RSA Encryption
1509
1964
  case "RSA-OAEP":
1510
1965
  case "RSA-OAEP-256":
@@ -1542,10 +1997,70 @@ function getGenerateKeyParams(alg, options) {
1542
1997
  keyUsages = defaultKeyUsage ?? ["encrypt", "decrypt"];
1543
1998
  break;
1544
1999
  }
1545
- // ECDH Key Agreement (requires specific curve in JWK for import, generation is simpler)
1546
- // For generation, typically generate the EC key pair first (e.g., P-256, P-384, P-521, X25519)
1547
- // then use deriveBits/deriveKey. Direct generation for "ECDH-ES*" alg isn't standard.
1548
- // Handle EC key pair generation under ES256/ES384/ES512.
2000
+ // ECDSA Signatures
2001
+ case "ES256": {
2002
+ algorithm = { name: "ECDSA", namedCurve: "P-256" };
2003
+ keyUsages = defaultKeyUsage ?? ["sign", "verify"];
2004
+ break;
2005
+ }
2006
+ case "ES384": {
2007
+ algorithm = { name: "ECDSA", namedCurve: "P-384" };
2008
+ keyUsages = defaultKeyUsage ?? ["sign", "verify"];
2009
+ break;
2010
+ }
2011
+ case "ES512": {
2012
+ algorithm = { name: "ECDSA", namedCurve: "P-521" };
2013
+ keyUsages = defaultKeyUsage ?? ["sign", "verify"];
2014
+ break;
2015
+ }
2016
+ case "Ed25519": {
2017
+ keyUsages = defaultKeyUsage ?? ["sign", "verify"];
2018
+ algorithm = { name: "Ed25519" };
2019
+ break;
2020
+ }
2021
+ case "EdDSA": {
2022
+ keyUsages = defaultKeyUsage ?? ["sign", "verify"];
2023
+ const namedCurve = options?.namedCurve ?? "Ed25519";
2024
+ switch (namedCurve) {
2025
+ case "Ed25519":
2026
+ case "Ed448": {
2027
+ algorithm = { name: namedCurve };
2028
+ break;
2029
+ }
2030
+ default: {
2031
+ throw new Error(
2032
+ "Unsupported namedCurve provided. Supported values are: Ed25519 and Ed448"
2033
+ );
2034
+ }
2035
+ }
2036
+ break;
2037
+ }
2038
+ // ECDSA Signatures
2039
+ case "ECDH-ES":
2040
+ case "ECDH-ES+A128KW":
2041
+ case "ECDH-ES+A192KW":
2042
+ case "ECDH-ES+A256KW": {
2043
+ keyUsages = ["deriveBits"];
2044
+ const namedCurve = options?.namedCurve ?? "P-256";
2045
+ switch (namedCurve) {
2046
+ case "P-256":
2047
+ case "P-384":
2048
+ case "P-521": {
2049
+ algorithm = { name: "ECDH", namedCurve };
2050
+ break;
2051
+ }
2052
+ case "X25519": {
2053
+ algorithm = { name: "X25519" };
2054
+ break;
2055
+ }
2056
+ default: {
2057
+ throw new Error(
2058
+ "Unsupported namedCurve provided. Supported values are: P-256, P-384, P-521 and X25519"
2059
+ );
2060
+ }
2061
+ }
2062
+ break;
2063
+ }
1549
2064
  default: {
1550
2065
  throw new Error(
1551
2066
  `Unsupported or invalid algorithm for key generation: ${alg}`
@@ -1554,12 +2069,31 @@ function getGenerateKeyParams(alg, options) {
1554
2069
  }
1555
2070
  return { algorithm, keyUsages };
1556
2071
  }
2072
+ function inferAesImportAlgorithm(enc, cekLengthBytes) {
2073
+ const bitLength = cekLengthBytes << 3;
2074
+ if (enc) {
2075
+ if (enc.includes("GCM")) {
2076
+ return {
2077
+ name: "AES-GCM",
2078
+ length: Number.parseInt(enc.slice(1, 4), 10)
2079
+ };
2080
+ }
2081
+ if (enc.includes("CBC-HS")) {
2082
+ return void 0;
2083
+ }
2084
+ }
2085
+ if (bitLength === 128 || bitLength === 192 || bitLength === 256) {
2086
+ return { name: "AES-GCM", length: bitLength };
2087
+ }
2088
+ return void 0;
2089
+ }
1557
2090
 
1558
2091
  const jwk = {
1559
2092
  __proto__: null,
1560
2093
  deriveKeyFromPassword: deriveKeyFromPassword,
1561
2094
  exportJWKToPEM: exportJWKToPEM,
1562
2095
  exportKey: exportKey,
2096
+ generateJWK: generateJWK,
1563
2097
  generateKey: generateKey,
1564
2098
  getJWKFromSet: getJWKFromSet,
1565
2099
  importJWKFromPEM: importJWKFromPEM,
@@ -1568,4 +2102,4 @@ const jwk = {
1568
2102
  wrapKey: wrapKey
1569
2103
  };
1570
2104
 
1571
- export { checkEncCryptoKey as a, generateCEK as b, checkSigCryptoKey as c, bitLengthCEK as d, encryptIV as e, jwkTokey as f, getJWKFromSet as g, generateIV as h, importKey as i, jwk as j, keyToJWK as k, encrypt as l, unwrapKey as m, decrypt as n, generateKey as o, deriveKeyFromPassword as p, exportKey as q, wrapKey as r, importJWKFromPEM as s, exportJWKToPEM as t, uint32be as u, wrap as w };
2105
+ export { encrypt as a, getJWKFromSet as b, generateKey as c, decrypt as d, encryptKey as e, generateJWK as f, generateIV as g, deriveKeyFromPassword as h, importKey as i, jwk as j, exportKey as k, importJWKFromPEM as l, exportJWKToPEM as m, sign as s, unwrapKey as u, verify as v, wrapKey as w };