unjwt 0.8.4 → 0.8.5

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.
Files changed (53) hide show
  1. package/README.md +3 -9
  2. package/dist/_chunks/{_import-key.mjs → algorithms.mjs} +194 -399
  3. package/dist/_chunks/{_codec-jwe.d.mts → codec-jwe.d.mts} +40 -9
  4. package/dist/_chunks/{_codec-jws.mjs → codec-jws.mjs} +133 -80
  5. package/dist/_chunks/cookie.mjs +50 -0
  6. package/dist/_chunks/digest.mjs +10 -3
  7. package/dist/_chunks/error.d.mts +103 -0
  8. package/dist/_chunks/export.mjs +97 -0
  9. package/dist/_chunks/index.d.mts +5 -103
  10. package/dist/_chunks/index2.d.mts +206 -12
  11. package/dist/_chunks/index3.d.mts +12 -109
  12. package/dist/_chunks/{jwe.d.mts → index4.d.mts} +2 -1
  13. package/dist/_chunks/{jws.d.mts → index5.d.mts} +2 -1
  14. package/dist/_chunks/index6.d.mts +113 -0
  15. package/dist/_chunks/jwe.mjs +205 -72
  16. package/dist/{core → _chunks}/jwk.mjs +210 -495
  17. package/dist/_chunks/jws.mjs +280 -193
  18. package/dist/_chunks/jwt.d.mts +2 -1
  19. package/dist/_chunks/{_jwt-internal.mjs → jwt.mjs} +110 -54
  20. package/dist/_chunks/libs/unsecure.d.mts +35 -25
  21. package/dist/_chunks/libs/unsecure.mjs +101 -268
  22. package/dist/_chunks/{_internal.d.mts → limits.d.mts} +1 -1
  23. package/dist/_chunks/payload.mjs +23 -0
  24. package/dist/_chunks/wrap.mjs +209 -0
  25. package/dist/adapters/elysia/index.d.mts +4 -4
  26. package/dist/adapters/elysia/index.mjs +4 -3
  27. package/dist/adapters/h3/index.d.mts +13 -13
  28. package/dist/adapters/h3/index.mjs +8 -11
  29. package/dist/adapters/h3v1/index.d.mts +5 -5
  30. package/dist/adapters/h3v1/index.mjs +6 -9
  31. package/dist/core/internal.mjs +1 -1
  32. package/dist/core/{jwe.d.mts → jwe/index.d.mts} +5 -4
  33. package/dist/core/jwe/index.mjs +5 -0
  34. package/dist/core/{jwk.d.mts → jwk/index.d.mts} +5 -4
  35. package/dist/core/jwk/index.mjs +7 -0
  36. package/dist/core/{jws.d.mts → jws/index.d.mts} +5 -4
  37. package/dist/core/jws/index.mjs +5 -0
  38. package/dist/dpop/index.d.mts +73 -0
  39. package/dist/dpop/index.mjs +296 -0
  40. package/dist/error.d.mts +3 -0
  41. package/dist/error.mjs +20 -0
  42. package/dist/index.d.mts +10 -9
  43. package/dist/index.mjs +7 -4
  44. package/dist/session/index.d.mts +4 -4
  45. package/dist/session/index.mjs +6 -47
  46. package/dist/utils/index.d.mts +7 -0
  47. package/dist/{core/utils → utils}/index.mjs +4 -3
  48. package/package.json +21 -10
  49. package/dist/_chunks/jwk.d.mts +0 -205
  50. package/dist/core/jwe.mjs +0 -5
  51. package/dist/core/jws.mjs +0 -5
  52. package/dist/core/utils/index.d.mts +0 -6
  53. /package/dist/_chunks/{_cookie-attributes.d.mts → cookie-attributes.d.mts} +0 -0
@@ -0,0 +1,103 @@
1
+ import { UnsecureError, UnsecureErrorCode } from "./libs/unsecure.mjs";
2
+ /**
3
+ * The closed union of error codes unjwt itself throws.
4
+ *
5
+ * Code naming follows the JOSE spec hierarchy:
6
+ * ERR_JWT_* — RFC 7519 JSON Web Token claim validation
7
+ * ERR_JWS_* — RFC 7515 JSON Web Signature
8
+ * ERR_JWE_* — RFC 7516 JSON Web Encryption
9
+ * ERR_JWK_* — RFC 7517 JSON Web Key
10
+ * ERR_DPOP_* — RFC 9449 proof validation
11
+ * ERR_SESSION_* — the framework session adapters
12
+ *
13
+ * Use this type where a typo must not compile — {@link isJWTError} takes it,
14
+ * so `isJWTError(err, "ERR_JWS_INVALD")` is a type error rather than a check
15
+ * that silently never matches. Use {@link JWTErrorCode} for values that may
16
+ * legitimately carry a code this version does not know about.
17
+ */
18
+ export type KnownJWTErrorCode = "ERR_JWT_EXPIRED" | "ERR_JWT_NBF" | "ERR_JWT_CLAIM_INVALID" | "ERR_JWT_CLAIM_MISSING" | "ERR_JWS_INVALID" | "ERR_JWS_INVALID_SERIALIZATION" | "ERR_JWS_SIGNATURE_INVALID" | "ERR_JWS_ALG_NOT_ALLOWED" | "ERR_JWS_ALG_MISSING" | "ERR_JWS_SIGNER_ALG_INFERENCE" | "ERR_JWS_NO_MATCHING_SIGNER" | "ERR_JWS_HEADER_PARAMS_NOT_DISJOINT" | "ERR_JWS_B64_INCONSISTENT" | "ERR_JWE_INVALID" | "ERR_JWE_INVALID_SERIALIZATION" | "ERR_JWE_DECRYPTION_FAILED" | "ERR_JWE_ALG_NOT_ALLOWED" | "ERR_JWE_ALG_MISSING" | "ERR_JWE_ALG_FORBIDDEN_IN_MULTI" | "ERR_JWE_ENC_MISSING" | "ERR_JWE_RECIPIENT_ALG_INFERENCE" | "ERR_JWE_NO_MATCHING_RECIPIENT" | "ERR_JWE_HEADER_PARAMS_NOT_DISJOINT" | "ERR_JWK_INVALID" | "ERR_JWK_KEY_NOT_FOUND" | "ERR_JWK_UNSUPPORTED" | "ERR_DPOP_INVALID" | "ERR_DPOP_CLAIM_INVALID" | "ERR_DPOP_NONCE_INVALID" | "ERR_DPOP_REPLAY" | "ERR_SESSION_TOKEN_INVALID" | "ERR_SESSION_READONLY_EVENT" | "ERR_SESSION_KEY_INVALID" | "ERR_SESSION_CONFIG_INVALID" | "ERR_INVALID_OPTION";
19
+ /**
20
+ * A {@link JWTError} `code`: every {@link KnownJWTErrorCode}, plus any other
21
+ * string for forward compatibility — a newer unjwt (or a caller constructing
22
+ * its own `JWTError`) may carry a code this version's union does not list.
23
+ */
24
+ export type JWTErrorCode = KnownJWTErrorCode | (string & {});
25
+ /**
26
+ * Maps known error codes to their structured `cause` shapes.
27
+ * Only codes that carry decoded context beyond the message appear here.
28
+ * Extend this interface when new structured causes are introduced.
29
+ */
30
+ export interface JWTErrorCauseMap {
31
+ /** Decoded claims available at the point the lifetime check failed. */
32
+ ERR_JWT_EXPIRED: {
33
+ jti?: string;
34
+ iat?: number;
35
+ exp?: number;
36
+ };
37
+ }
38
+ /**
39
+ * Base error class for all unjwt errors. Every error thrown by the library is
40
+ * an instance of `JWTError`, so a single `instanceof` check is sufficient to
41
+ * distinguish library errors from other thrown values. Use the `code` property
42
+ * (or the `isJWTError` type guard) to narrow to a specific error condition.
43
+ *
44
+ * @example
45
+ * import { JWTError, isJWTError } from "unjwt/jws";
46
+ *
47
+ * try {
48
+ * await verify(token, key);
49
+ * } catch (err) {
50
+ * if (isJWTError(err, "ERR_JWT_EXPIRED")) {
51
+ * console.log(err.cause.jti); // string | undefined
52
+ * }
53
+ * }
54
+ */
55
+ export declare class JWTError<TCode extends JWTErrorCode = JWTErrorCode> extends Error {
56
+ readonly code: TCode;
57
+ override readonly cause?: unknown;
58
+ constructor(message: string, code: TCode, cause?: unknown);
59
+ }
60
+ /**
61
+ * Type guard that narrows `error` to `JWTError`.
62
+ *
63
+ * When called with a code that is a key of `JWTErrorCauseMap`, the return
64
+ * type is additionally narrowed to include the structured `cause` shape for
65
+ * that code. When called with any other `KnownJWTErrorCode`, `code` is narrowed
66
+ * but `cause` remains `unknown`. When called without a code, narrows only to
67
+ * `JWTError`.
68
+ *
69
+ * `code` is a {@link KnownJWTErrorCode}, so a misspelled code fails to
70
+ * type-check instead of silently never matching.
71
+ *
72
+ * @example
73
+ * if (isJWTError(err, "ERR_JWT_EXPIRED")) {
74
+ * err.cause.jti // string | undefined ✓
75
+ * }
76
+ */
77
+ export declare function isJWTError<T extends keyof JWTErrorCauseMap>(error: unknown, code: T): error is JWTError<T> & {
78
+ cause: JWTErrorCauseMap[T];
79
+ };
80
+ export declare function isJWTError<T extends KnownJWTErrorCode>(error: unknown, code: T): error is JWTError<T>;
81
+ export declare function isJWTError(error: unknown): error is JWTError;
82
+ /**
83
+ * Type guard that narrows `error` to the bundled {@link UnsecureError}, the
84
+ * class thrown by unjwt's codec / JSON / random primitives and carried as the
85
+ * `cause` of a {@link JWTError} when a wire segment or key field fails to
86
+ * decode. Pass a `code` to narrow further.
87
+ *
88
+ * Check against this export rather than a `UnsecureError` imported from a
89
+ * consumer-installed `unsecure`: unjwt bundles its own copy, so the two classes
90
+ * are distinct and `instanceof` against the latter is always `false`.
91
+ *
92
+ * @example
93
+ * import { isJWTError, isUnsecureError } from "unjwt/jws";
94
+ *
95
+ * const error = await verify(token, key).catch((e) => e);
96
+ * if (isJWTError(error, "ERR_JWS_INVALID") && isUnsecureError(error.cause, "MALFORMED")) {
97
+ * // a segment of the token is not canonical base64url
98
+ * }
99
+ */
100
+ export declare function isUnsecureError<T extends UnsecureErrorCode>(error: unknown, code: T): error is UnsecureError & {
101
+ code: T;
102
+ };
103
+ export declare function isUnsecureError(error: unknown): error is UnsecureError;
@@ -0,0 +1,97 @@
1
+ import { JWTError } from "../error.mjs";
2
+ import { isAsymmetricJWK, isCryptoKey, isJWK, isPublicJWK } from "./jwt.mjs";
3
+ import { copyJsonObject, keyToJWK, thumbprint } from "./algorithms.mjs";
4
+ const RESERVED_JWK_PARAMS = /* @__PURE__ */ new Set([
5
+ "kty",
6
+ "alg",
7
+ "key_ops",
8
+ "ext",
9
+ "k",
10
+ "d",
11
+ "n",
12
+ "e",
13
+ "p",
14
+ "q",
15
+ "dp",
16
+ "dq",
17
+ "qi",
18
+ "oth",
19
+ "x",
20
+ "y",
21
+ "crv"
22
+ ]);
23
+ function assertNoReservedJWKParams(jwkParams) {
24
+ const reserved = Object.keys(jwkParams).filter((name) => RESERVED_JWK_PARAMS.has(name));
25
+ if (reserved.length > 0) throw new JWTError(`jwkParams must not set reserved JWK members: ${reserved.join(", ")}`, "ERR_INVALID_OPTION");
26
+ }
27
+ function assertKidOption(kid) {
28
+ if (kid === void 0 || kid === false || typeof kid === "string") return kid;
29
+ throw new JWTError("\"kid\" must be a string or false.", "ERR_INVALID_OPTION");
30
+ }
31
+ async function withGeneratedKid(kid, jwk) {
32
+ if (kid === false) return jwk;
33
+ return {
34
+ ...jwk,
35
+ kid: kid ?? await thumbprint(jwk)
36
+ };
37
+ }
38
+ function requestedKeyOps(options, key) {
39
+ return options.keyUsage === void 0 ? void 0 : [...key.usages];
40
+ }
41
+ function withKeyOps(jwk, keyOps) {
42
+ return keyOps === void 0 ? jwk : {
43
+ ...jwk,
44
+ key_ops: keyOps
45
+ };
46
+ }
47
+ async function exportJWK(key, jwkParams) {
48
+ if (!isCryptoKey(key)) throw new JWTError("exportJWK expects a CryptoKey.", "ERR_INVALID_OPTION");
49
+ if (!key.extractable) throw new JWTError("A non-extractable CryptoKey cannot be exported as a JWK.", "ERR_JWK_INVALID");
50
+ const exportedJwk = await keyToJWK(key);
51
+ if (jwkParams) {
52
+ const extraParams = copyJsonObject(jwkParams, {
53
+ code: "ERR_INVALID_OPTION",
54
+ message: "JWK parameters must hold only JSON values."
55
+ });
56
+ assertNoReservedJWKParams(extraParams);
57
+ return {
58
+ ...exportedJwk,
59
+ ...extraParams
60
+ };
61
+ }
62
+ return exportedJwk;
63
+ }
64
+ async function exportKey(key, jwkParams) {
65
+ return exportJWK(key, jwkParams);
66
+ }
67
+ function toPublicJWK(jwk) {
68
+ if (!isAsymmetricJWK(jwk)) throw new JWTError(isJWK(jwk) ? "An oct JWK has no public half." : "toPublicJWK expects an asymmetric JWK.", "ERR_JWK_INVALID");
69
+ const { d: _d, p: _p, q: _q, dp: _dp, dq: _dq, qi: _qi, oth: _oth, k: _k, key_ops, ...publicMembers } = copyJsonObject({ ...jwk }, {
70
+ code: "ERR_JWK_INVALID",
71
+ message: "A JWK must hold only JSON values."
72
+ });
73
+ const publicKey = key_ops === void 0 ? publicMembers : {
74
+ ...publicMembers,
75
+ key_ops: publicKeyOps(key_ops)
76
+ };
77
+ if (!isPublicJWK(publicKey)) throw new JWTError(`${jwk.kty} JWK lacks the public members of its key type.`, "ERR_JWK_INVALID");
78
+ return publicKey;
79
+ }
80
+ const PUBLIC_KEY_OPS = /* @__PURE__ */ new Map([
81
+ ["sign", "verify"],
82
+ ["verify", "verify"],
83
+ ["decrypt", "encrypt"],
84
+ ["encrypt", "encrypt"],
85
+ ["unwrapKey", "wrapKey"],
86
+ ["wrapKey", "wrapKey"]
87
+ ]);
88
+ function publicKeyOps(keyOps) {
89
+ if (!Array.isArray(keyOps)) return [];
90
+ const ops = [];
91
+ for (const op of keyOps) {
92
+ const publicOp = typeof op === "string" ? PUBLIC_KEY_OPS.get(op) : void 0;
93
+ if (publicOp !== void 0 && !ops.includes(publicOp)) ops.push(publicOp);
94
+ }
95
+ return ops;
96
+ }
97
+ export { assertKidOption, assertNoReservedJWKParams, exportJWK, exportKey, requestedKeyOps, toPublicJWK, withGeneratedKid, withKeyOps };
@@ -1,105 +1,4 @@
1
- import { UnsecureError, UnsecureErrorCode } from "./libs/unsecure.mjs";
2
- /**
3
- * The closed union of error codes unjwt itself throws.
4
- *
5
- * Code naming follows the JOSE spec hierarchy:
6
- * ERR_JWT_* — RFC 7519 JSON Web Token claim validation
7
- * ERR_JWS_* — RFC 7515 JSON Web Signature
8
- * ERR_JWE_* — RFC 7516 JSON Web Encryption
9
- * ERR_JWK_* — RFC 7517 JSON Web Key
10
- * ERR_SESSION_* — the framework session adapters
11
- *
12
- * Use this type where a typo must not compile — {@link isJWTError} takes it,
13
- * so `isJWTError(err, "ERR_JWS_INVALD")` is a type error rather than a check
14
- * that silently never matches. Use {@link JWTErrorCode} for values that may
15
- * legitimately carry a code this version does not know about.
16
- */
17
- export type KnownJWTErrorCode = "ERR_JWT_EXPIRED" | "ERR_JWT_NBF" | "ERR_JWT_CLAIM_INVALID" | "ERR_JWT_CLAIM_MISSING" | "ERR_JWS_INVALID" | "ERR_JWS_INVALID_SERIALIZATION" | "ERR_JWS_SIGNATURE_INVALID" | "ERR_JWS_ALG_NOT_ALLOWED" | "ERR_JWS_ALG_MISSING" | "ERR_JWS_SIGNER_ALG_INFERENCE" | "ERR_JWS_NO_MATCHING_SIGNER" | "ERR_JWS_HEADER_PARAMS_NOT_DISJOINT" | "ERR_JWS_B64_INCONSISTENT" | "ERR_JWE_INVALID" | "ERR_JWE_INVALID_SERIALIZATION" | "ERR_JWE_DECRYPTION_FAILED" | "ERR_JWE_ALG_NOT_ALLOWED" | "ERR_JWE_ALG_MISSING" | "ERR_JWE_ALG_FORBIDDEN_IN_MULTI" | "ERR_JWE_ENC_MISSING" | "ERR_JWE_RECIPIENT_ALG_INFERENCE" | "ERR_JWE_NO_MATCHING_RECIPIENT" | "ERR_JWE_HEADER_PARAMS_NOT_DISJOINT" | "ERR_JWK_INVALID" | "ERR_JWK_KEY_NOT_FOUND" | "ERR_JWK_UNSUPPORTED" | "ERR_SESSION_TOKEN_INVALID" | "ERR_SESSION_READONLY_EVENT" | "ERR_SESSION_KEY_INVALID" | "ERR_SESSION_CONFIG_INVALID" | "ERR_INVALID_OPTION";
18
- /**
19
- * A {@link JWTError} `code`: every {@link KnownJWTErrorCode}, plus any other
20
- * string for forward compatibility — a newer unjwt (or a caller constructing
21
- * its own `JWTError`) may carry a code this version's union does not list.
22
- */
23
- export type JWTErrorCode = KnownJWTErrorCode | (string & {});
24
- /**
25
- * Maps known error codes to their structured `cause` shapes.
26
- * Only codes that carry decoded context beyond the message appear here.
27
- * Extend this interface when new structured causes are introduced.
28
- */
29
- export interface JWTErrorCauseMap {
30
- /** Decoded claims available at the point the lifetime check failed. */
31
- ERR_JWT_EXPIRED: {
32
- jti?: string;
33
- iat?: number;
34
- exp?: number;
35
- };
36
- }
37
- /**
38
- * Base error class for all unjwt errors. Every error thrown by the library is
39
- * an instance of `JWTError`, so a single `instanceof` check is sufficient to
40
- * distinguish library errors from other thrown values. Use the `code` property
41
- * (or the `isJWTError` type guard) to narrow to a specific error condition.
42
- *
43
- * @example
44
- * import { JWTError, isJWTError } from "unjwt/jws";
45
- *
46
- * try {
47
- * await verify(token, key);
48
- * } catch (err) {
49
- * if (isJWTError(err, "ERR_JWT_EXPIRED")) {
50
- * console.log(err.cause.jti); // string | undefined
51
- * }
52
- * }
53
- */
54
- export declare class JWTError<TCode extends JWTErrorCode = JWTErrorCode> extends Error {
55
- readonly code: TCode;
56
- override readonly cause?: unknown;
57
- constructor(message: string, code: TCode, cause?: unknown);
58
- }
59
- /**
60
- * Type guard that narrows `error` to `JWTError`.
61
- *
62
- * When called with a code that is a key of `JWTErrorCauseMap`, the return
63
- * type is additionally narrowed to include the structured `cause` shape for
64
- * that code. When called with any other `KnownJWTErrorCode`, `code` is narrowed
65
- * but `cause` remains `unknown`. When called without a code, narrows only to
66
- * `JWTError`.
67
- *
68
- * `code` is a {@link KnownJWTErrorCode}, so a misspelled code fails to
69
- * type-check instead of silently never matching.
70
- *
71
- * @example
72
- * if (isJWTError(err, "ERR_JWT_EXPIRED")) {
73
- * err.cause.jti // string | undefined ✓
74
- * }
75
- */
76
- export declare function isJWTError<T extends keyof JWTErrorCauseMap>(error: unknown, code: T): error is JWTError<T> & {
77
- cause: JWTErrorCauseMap[T];
78
- };
79
- export declare function isJWTError<T extends KnownJWTErrorCode>(error: unknown, code: T): error is JWTError<T>;
80
- export declare function isJWTError(error: unknown): error is JWTError;
81
- /**
82
- * Type guard that narrows `error` to the bundled {@link UnsecureError}, the
83
- * class thrown by unjwt's codec / JSON / random primitives and carried as the
84
- * `cause` of a {@link JWTError} when a wire segment or key field fails to
85
- * decode. Pass a `code` to narrow further.
86
- *
87
- * Check against this export rather than a `UnsecureError` imported from a
88
- * consumer-installed `unsecure`: unjwt bundles its own copy, so the two classes
89
- * are distinct and `instanceof` against the latter is always `false`.
90
- *
91
- * @example
92
- * import { isJWTError, isUnsecureError } from "unjwt/jws";
93
- *
94
- * const error = await verify(token, key).catch((e) => e);
95
- * if (isJWTError(error, "ERR_JWS_INVALID") && isUnsecureError(error.cause, "MALFORMED")) {
96
- * // a segment of the token is not canonical base64url
97
- * }
98
- */
99
- export declare function isUnsecureError<T extends UnsecureErrorCode>(error: unknown, code: T): error is UnsecureError & {
100
- code: T;
101
- };
102
- export declare function isUnsecureError(error: unknown): error is UnsecureError;
1
+ import { JWTError } from "./error.mjs";
103
2
  /** Header Parameters common to JWE and JWS. */
104
3
  export interface JoseHeaderParameters {
105
4
  /** "kid" (Key ID) Header Parameter */
@@ -225,7 +124,10 @@ export interface JWTTimeClaimOptions {
225
124
  }
226
125
  /** Options shared by `verify` and `decrypt` (compact and multi). */
227
126
  export interface JOSEConsumerOptions<Mode extends JOSEPayloadMode = JOSEPayloadMode> extends JWTClaimValidationOptions {
228
- /** Admit `oct` entries of a JWK Set as key material; only for application-controlled sets. @default false */
127
+ /**
128
+ * Admit `oct` entries of a JWK Set as key material; only for application-controlled sets. @default false
129
+ * @deprecated A JWK Set is key material the caller chose to trust, so its `oct` entries count like any other; the option goes away and symmetric entries are admitted without it.
130
+ */
229
131
  allowSymmetricJWKSet?: boolean;
230
132
  /** Payload decoding mode; a mismatch is `ERR_JWS_INVALID` / `ERR_JWE_INVALID`. @default "json" */
231
133
  payload?: Mode;
@@ -1,12 +1,206 @@
1
- import { JWK } from "./index.mjs";
2
- import { DigestHash } from "./digest.mjs";
3
- /** Hash functions RFC 7638 §3.4 leaves open to the application. */
4
- export type ThumbprintHash = DigestHash;
5
- /**
6
- * The base64url JWK Thumbprint of a key (RFC 7638), over its required members only, so a
7
- * public key and its private counterpart share one. `hash` defaults to `"SHA-256"`
8
- * (RFC 7638 §3.4); a missing required member or unknown `kty` throws `ERR_JWK_INVALID`.
9
- */
10
- export declare function thumbprint(jwk: JWK, options?: {
11
- hash?: ThumbprintHash;
12
- }): Promise<string>;
1
+ import "./error.mjs";
2
+ import { ContentEncryptionAlgorithm, DeriveJWKOptions, DeriveJWKReturn, DeriveKeyOptions, DeriveKeyReturn, GenerateJWKOptions, GenerateJWKReturn, GenerateKeyAlgorithm, GenerateKeyOptions, GenerateKeyReturn, ImportedKey, ImportedPEMJWK, JWK, JWKAlgorithm, JWKCacheAdapter, JWKMetadata, JWKPEMAlgorithm, JWKSet, JWK_Asymmetric, JWK_ECDH_ES, JWK_EC_Private, JWK_EC_Public, JWK_PBES2, JWK_oct, KeyManagementAlgorithm, PEMType, ToPublicJWKReturn, UnwrapKeyOptions, UnwrapKeyResult, UnwrappingKeyFor, WrapKeyOptions, WrapKeyResult, WrappingKeyFor } from "./index.mjs";
3
+ import "./index3.mjs";
4
+ /**
5
+ * Default JWK import cache, keyed by JWK object identity: a copied JWK misses it, and a JWK
6
+ * mutated in place keeps serving the old `CryptoKey`. Rotate by replacing the object.
7
+ */
8
+ export declare class WeakMapJWKCache implements JWKCacheAdapter {
9
+ private readonly _map;
10
+ get(jwk: JWK, alg: JWKAlgorithm): CryptoKey | undefined;
11
+ set(jwk: JWK, alg: JWKAlgorithm, key: CryptoKey): void;
12
+ }
13
+ /**
14
+ * Replaces the JWK import cache used by `importKey`, or disables it with `false`.
15
+ *
16
+ * A cache shared across JWK objects keys on the RFC 7638 thumbprint, the pair half (`d` present)
17
+ * and `alg`: the thumbprint covers public members only, and a `kid` may name different keys.
18
+ * `get` and `set` may return promises.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * const cacheKey = async (jwk: JWK, alg: JWKAlgorithm) =>
23
+ * `${await thumbprint(jwk)}:${"d" in jwk ? "private" : "public"}:${alg}`;
24
+ * const map = new Map<string, CryptoKey>();
25
+ * configureJWKCache({
26
+ * get: async (jwk, alg) => map.get(await cacheKey(jwk, alg)),
27
+ * set: async (jwk, alg, key) => {
28
+ * map.set(await cacheKey(jwk, alg), key);
29
+ * },
30
+ * });
31
+ * ```
32
+ */
33
+ export declare function configureJWKCache(cache: JWKCacheAdapter | false): void;
34
+ /** Resets the JWK import cache to a fresh `WeakMapJWKCache`. */
35
+ export declare function clearJWKCache(): void;
36
+ /** Imports the secret of an `oct` JWK as a `CryptoKey` under `algorithm` and `usage`. */
37
+ export declare function importKey(key: JWK_oct, options: {
38
+ asCryptoKey: true;
39
+ /** Algorithm to import the key as (e.g. `{ name: "AES-GCM", length: 256 }`). */
40
+ algorithm: Parameters<typeof crypto.subtle.importKey>[2];
41
+ usage: KeyUsage[];
42
+ /** Mark the key as extractable. Defaults to `false`. */
43
+ extractable?: boolean;
44
+ }): Promise<CryptoKey>;
45
+ /**
46
+ * Imports key material: a `CryptoKey` or `Uint8Array` is returned as is, an `oct` JWK as its raw
47
+ * bytes, an asymmetric JWK as a `CryptoKey` under its own `alg` or the hint. A string throws
48
+ * `ERR_JWK_INVALID`.
49
+ *
50
+ * `expect` and `extractable` apply to asymmetric keys only; `expect` rejects the other pair half
51
+ * with `ERR_JWK_INVALID`. A JWK's `alg` is authoritative (RFC 7517 §4.4): a different requested
52
+ * `alg` throws `ERR_JWK_INVALID`, except an `oct` JWK declaring a content encryption `alg` under
53
+ * `"dir"`.
54
+ */
55
+ export declare function importKey<K extends CryptoKey | JWK | Uint8Array<ArrayBuffer>>(key: K, options?: JWKAlgorithm | {
56
+ /** Algorithm hint. Required when `key.alg` is absent on an asymmetric JWK. */
57
+ alg?: JWKAlgorithm;
58
+ /** Reject on shape mismatch instead of silently importing. */
59
+ expect?: "public" | "private";
60
+ /** Defaults to `false` for private, `true` for public material; JWK `ext: false` wins. */
61
+ extractable?: boolean;
62
+ }): Promise<ImportedKey<K>>;
63
+ /**
64
+ * Returns the JWKs of a JWK Set, dropping non-JWK entries, optionally narrowed by `filter`.
65
+ * An invalid set throws `ERR_JWK_INVALID`.
66
+ */
67
+ export declare function getJWKsFromSet(jwkSet: JWKSet, filter?: (jwk: JWK) => boolean): JWK[];
68
+ /**
69
+ * Generates a key for a JWA algorithm: a `CryptoKey` for symmetric algorithms, raw bytes for
70
+ * the `A*CBC-HS*` composites, a `CryptoKeyPair` for asymmetric ones; with `toJWK: true`, a JWK
71
+ * (or JWK pair) named by the `kid` option or its RFC 7638 thumbprint. PBES2, `"dir"` and `"none"` are refused.
72
+ *
73
+ * @param options
74
+ * - `extractable?` — defaults to `true`; ignored when `toJWK` is set.
75
+ * - `kid?` — with `toJWK`, a string set verbatim or `false` for no `kid`, either skipping the
76
+ * thumbprint digest; anything else throws `ERR_INVALID_OPTION`.
77
+ * - `keyUsage?` — narrows the usages derived from `alg`; leaving either half of a pair with
78
+ * no usage throws `ERR_INVALID_OPTION`.
79
+ * - `modulusLength?` — RSA only; defaults to `2048`.
80
+ * - `publicExponent?` — RSA only; big-endian bytes, defaults to `0x010001`.
81
+ * - `namedCurve?` — EC/OKP only; defaults to `"P-256"` / `"Ed25519"`. One that contradicts
82
+ * the curve `ES*` or `Ed25519` names throws `ERR_INVALID_OPTION`.
83
+ */
84
+ export declare function generateKey<TAlg extends GenerateKeyAlgorithm, ToJWK extends boolean = false, Kid extends string | false = string>(alg: TAlg, options?: GenerateKeyOptions<ToJWK, Kid>): Promise<GenerateKeyReturn<TAlg, GenerateKeyOptions<ToJWK, Kid>>>;
85
+ /**
86
+ * Generates a JWK (or JWK pair) for a JWA algorithm, its `kid` the caller's, none with
87
+ * `kid: false`, or else its RFC 7638 thumbprint. PBES2, `"dir"` and `"none"` are refused.
88
+ *
89
+ * @param options
90
+ * - `keyUsage?`, `modulusLength?` (default `2048`), `publicExponent?` (default `0x010001`),
91
+ * `namedCurve?` (default `"P-256"` / `"Ed25519"`); a narrowing that empties a pair half or
92
+ * a curve that contradicts `alg` throws `ERR_INVALID_OPTION`.
93
+ * - `kid?` — a string set verbatim or `false` for no `kid`, either skipping the thumbprint
94
+ * digest; anything else throws `ERR_INVALID_OPTION`.
95
+ * - JWK metadata (`use`, `x5c`, `x5t`, `x5t#S256`, `x5u`) is merged onto the result;
96
+ * `alg`, `kty`, `key_ops`, `ext` and key-material members are reserved (`ERR_INVALID_OPTION`).
97
+ */
98
+ export declare function generateJWK<TAlg extends GenerateKeyAlgorithm, Kid extends string | false = string>(alg: TAlg, options?: GenerateJWKOptions<Kid> & Omit<JWKMetadata, "kid">): Promise<GenerateJWKReturn<TAlg, Kid>>;
99
+ /**
100
+ * Derives an AES-KW key from a password with PBKDF2 per PBES2 (RFC 7518 §4.8).
101
+ *
102
+ * @param options
103
+ * - `alg` — a PBES2 algorithm; any other throws `ERR_JWK_UNSUPPORTED`.
104
+ * - `salt` — PBKDF2 salt (`p2s`), at least 8 octets (RFC 7518 §4.8.1.1).
105
+ * - `iterations` — PBKDF2 count (`p2c`), an integer of at least 1000 (RFC 7518 §4.8.1.2);
106
+ * anything else throws `ERR_INVALID_OPTION`.
107
+ * - `keyUsage?` — defaults to `["wrapKey", "unwrapKey"]`.
108
+ * - `extractable?` — defaults to `false`; ignored when `toJWK` is set.
109
+ * - `toJWK?` — return a `JWK_oct` carrying the inner AES-KW `alg` instead of a `CryptoKey`.
110
+ */
111
+ export declare function deriveKeyFromPassword<TOptions extends DeriveKeyOptions>(password: string | Uint8Array<ArrayBuffer>, options: TOptions): Promise<DeriveKeyReturn<TOptions, TOptions["alg"]>>;
112
+ /**
113
+ * Derives a `JWK_oct` from a password per PBES2 (RFC 7518 §4.8); its `alg` is the inner AES-KW
114
+ * variant and its `kid` the caller's, none with `kid: false`, or else its RFC 7638 thumbprint.
115
+ *
116
+ * @param options
117
+ * - `alg` (PBES2 only, else `ERR_JWK_UNSUPPORTED`), `salt` (at least 8 octets), `iterations`
118
+ * (integer of at least 1000, else `ERR_INVALID_OPTION`), `keyUsage?` (default
119
+ * `["wrapKey", "unwrapKey"]`).
120
+ * - `kid?` — a string set verbatim or `false` for no `kid`, either skipping the thumbprint
121
+ * digest; anything else throws `ERR_INVALID_OPTION`.
122
+ * - JWK metadata (`use`, `x5c`, `x5t`, `x5t#S256`, `x5u`) is merged onto the result;
123
+ * `alg`, `kty`, `key_ops`, `ext` and key-material members are reserved (`ERR_INVALID_OPTION`).
124
+ */
125
+ export declare function deriveJWKFromPassword<TAlg extends JWK_PBES2, Kid extends string | false = string>(password: string | Uint8Array<ArrayBuffer>, options: DeriveJWKOptions<TAlg, Kid> & Omit<JWKMetadata, "kid">): Promise<DeriveJWKReturn<TAlg, Kid>>;
126
+ /**
127
+ * Exports an extractable `CryptoKey` as a JWK, merging optional `jwkParams` metadata.
128
+ *
129
+ * The `alg` is WebCrypto's, which knows no JOSE roles: an AES-GCM key minted for `A128GCMKW`
130
+ * exports as `A128GCM`, so key-wrapping keys are minted with `generateJWK` instead.
131
+ *
132
+ * @throws `ERR_INVALID_OPTION` if `key` is not a `CryptoKey` or `jwkParams` sets a reserved member
133
+ * (`alg`, `kty`, `key_ops`, `ext`, key material); `ERR_JWK_INVALID` for a non-extractable key.
134
+ */
135
+ export declare function exportJWK<T extends JWK = JWK>(key: CryptoKey, jwkParams?: JWKMetadata): Promise<T>;
136
+ /** @deprecated Use `exportJWK`; removed in 0.9.0. */
137
+ export declare function exportKey<T extends JWK = JWK>(key: CryptoKey, jwkParams?: JWKMetadata): Promise<T>;
138
+ /**
139
+ * Utility to derive the public half of an asymmetric JWK, or throw if the input is not asymmetric.
140
+ *
141
+ * @param jwk An asymmetric JWK (EC, OKP, RSA) with a private scalar (`d`).
142
+ * @throws `ERR_JWK_INVALID` if the input is not an asymmetric JWK.
143
+ * @returns A JWK with the same public members, without the private scalar or a `k` member.
144
+ */
145
+ export declare function toPublicJWK<T extends JWK_Asymmetric>(jwk: T): ToPublicJWKReturn<T>;
146
+ /**
147
+ * Wraps a CEK under a JWA key management algorithm; the result shape follows `alg`.
148
+ *
149
+ * @param wrappingKey A `CryptoKey`, a JWK, or for PBES2 a password string or bytes.
150
+ * @param options `alg` plus its parameters (`p2s`/`p2c` for PBES2, `ecdh` for ECDH-ES, …).
151
+ */
152
+ export declare function wrapKey<TAlg extends KeyManagementAlgorithm>(keyToWrap: CryptoKey | Uint8Array<ArrayBuffer>, wrappingKey: WrappingKeyFor<TAlg>, options: WrapKeyOptions<TAlg>): Promise<WrapKeyResult<TAlg>>;
153
+ /**
154
+ * Unwraps a CEK under a JWA key management algorithm.
155
+ *
156
+ * @param unwrappingKey A `CryptoKey`, a JWK, or for PBES2 a password string or bytes.
157
+ * @param options `alg`, `format?` (`"cryptokey"` by default, or `"raw"`), plus the algorithm's
158
+ * parameters (`iv`/`tag`, `p2s`/`p2c`, `epk`, …).
159
+ * @throws `ERR_JWE_DECRYPTION_FAILED` for any failed unwrap, its cause undisclosed (RFC 7516
160
+ * §11.5); `ERR_INVALID_OPTION` for a malformed `wrappedKey` or `options`; `ERR_JWE_INVALID` for
161
+ * missing or malformed algorithm parameters.
162
+ */
163
+ export declare function unwrapKey<TOptions extends UnwrapKeyOptions>(wrappedKey: Uint8Array<ArrayBuffer>, unwrappingKey: UnwrappingKeyFor<TOptions["alg"]>, options: TOptions): Promise<UnwrapKeyResult<TOptions>>;
164
+ /**
165
+ * Imports a PEM key as a JWK carrying `alg`. The type follows the label — `PRIVATE KEY`
166
+ * (PKCS#8), `PUBLIC KEY` (SPKI), `CERTIFICATE` (X.509, only its SPKI kept) — unless
167
+ * `options.pemType` overrides it. The JWK holds the key material in plain JavaScript.
168
+ *
169
+ * @throws `ERR_JWK_INVALID` if the type cannot be inferred or does not match the label;
170
+ * `ERR_JWK_UNSUPPORTED` for an unknown `pemType`; `ERR_INVALID_OPTION` if `jwkParams` sets
171
+ * `alg`, `kty`, `key_ops`, `ext` or a key-material member.
172
+ */
173
+ export declare function importPEM<A extends JWKPEMAlgorithm, Type extends PEMType | undefined = undefined>(pem: string, alg: A, options?: {
174
+ /** PEM type. Inferred from the PEM label when omitted, which leaves the result public or private. */
175
+ pemType?: Type;
176
+ /** Additional JWK properties merged into the exported key (e.g. `kid`). */
177
+ jwkParams?: JWKMetadata;
178
+ }): Promise<ImportedPEMJWK<A, Type>>;
179
+ /**
180
+ * Exports an asymmetric JWK as PEM: PKCS#8 when it carries `d`, SPKI otherwise.
181
+ *
182
+ * @throws `ERR_JWK_UNSUPPORTED` for `oct` JWKs or an unknown format or algorithm;
183
+ * `ERR_JWK_INVALID` for a missing `alg` or a `pemFormat` that contradicts the JWK's half.
184
+ */
185
+ export declare function exportPEM(jwk: JWK, options?: {
186
+ /** PEM format. Inferred from the JWK shape when omitted. */
187
+ pemFormat?: "pkcs8" | "spki";
188
+ /** Algorithm hint used when `jwk.alg` is absent. */
189
+ alg?: JWKPEMAlgorithm;
190
+ }): Promise<string>;
191
+ /**
192
+ * Derives ECDH-ES key material (RFC 7518 §4.6): ECDH followed by the Concat KDF.
193
+ *
194
+ * @param publicKey The recipient's static public key (the ephemeral one when decrypting).
195
+ * @param privateKey The ephemeral private key (the recipient's static one when decrypting).
196
+ */
197
+ export declare function deriveSharedSecret(publicKey: CryptoKey | JWK_EC_Public, privateKey: CryptoKey | JWK_EC_Private, options: {
198
+ /** Algorithm identifier fed to the concat KDF as `AlgorithmID`. */
199
+ enc: JWK_ECDH_ES | ContentEncryptionAlgorithm;
200
+ /** Derived length in bits. Defaults to `enc`'s length; required for `"ECDH-ES"`. */
201
+ keyLength?: number;
202
+ /** Agreement PartyUInfo (apu). */
203
+ partyUInfo?: Uint8Array<ArrayBuffer>;
204
+ /** Agreement PartyVInfo (apv). */
205
+ partyVInfo?: Uint8Array<ArrayBuffer>;
206
+ }): Promise<Uint8Array<ArrayBuffer>>;