unjwt 0.8.3 → 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.
- package/README.md +3 -9
- package/dist/_chunks/algorithms.mjs +1541 -0
- package/dist/_chunks/{_codec-jwe.d.mts → codec-jwe.d.mts} +40 -9
- package/dist/_chunks/{_codec-jws.mjs → codec-jws.mjs} +148 -95
- package/dist/_chunks/cookie.mjs +50 -0
- package/dist/_chunks/digest.mjs +10 -3
- package/dist/_chunks/error.d.mts +103 -0
- package/dist/_chunks/export.mjs +97 -0
- package/dist/_chunks/index.d.mts +5 -103
- package/dist/_chunks/index2.d.mts +206 -12
- package/dist/_chunks/index3.d.mts +12 -109
- package/dist/_chunks/{jwe.d.mts → index4.d.mts} +3 -1
- package/dist/_chunks/{jws.d.mts → index5.d.mts} +6 -2
- package/dist/_chunks/index6.d.mts +113 -0
- package/dist/_chunks/jwe.mjs +208 -74
- package/dist/_chunks/jwk.mjs +214 -2237
- package/dist/_chunks/jws.mjs +289 -202
- package/dist/_chunks/jwt.d.mts +2 -1
- package/dist/_chunks/{_jwt-internal.mjs → jwt.mjs} +124 -68
- package/dist/_chunks/libs/unsecure.d.mts +35 -25
- package/dist/_chunks/libs/unsecure.mjs +148 -302
- package/dist/_chunks/{_internal.d.mts → limits.d.mts} +1 -1
- package/dist/_chunks/payload.mjs +23 -0
- package/dist/_chunks/wrap.mjs +209 -0
- package/dist/adapters/elysia/index.d.mts +4 -4
- package/dist/adapters/elysia/index.mjs +5 -3
- package/dist/adapters/h3/index.d.mts +13 -13
- package/dist/adapters/h3/index.mjs +8 -10
- package/dist/adapters/h3v1/index.d.mts +5 -5
- package/dist/adapters/h3v1/index.mjs +6 -8
- package/dist/core/internal.mjs +1 -1
- package/dist/core/{jwe.d.mts → jwe/index.d.mts} +5 -4
- package/dist/core/jwe/index.mjs +5 -0
- package/dist/core/jwk/index.d.mts +6 -0
- package/dist/core/jwk/index.mjs +7 -0
- package/dist/core/{jws.d.mts → jws/index.d.mts} +5 -4
- package/dist/core/jws/index.mjs +5 -0
- package/dist/dpop/index.d.mts +73 -0
- package/dist/dpop/index.mjs +296 -0
- package/dist/error.d.mts +3 -0
- package/dist/error.mjs +20 -0
- package/dist/index.d.mts +10 -9
- package/dist/index.mjs +7 -3
- package/dist/session/index.d.mts +4 -4
- package/dist/session/index.mjs +6 -46
- package/dist/utils/index.d.mts +7 -0
- package/dist/{core/utils → utils}/index.mjs +4 -3
- package/package.json +22 -10
- package/dist/core/jwe.mjs +0 -5
- package/dist/core/jwk.d.mts +0 -207
- package/dist/core/jwk.mjs +0 -4
- package/dist/core/jws.mjs +0 -5
- package/dist/core/utils/index.d.mts +0 -6
- /package/dist/_chunks/{_cookie-attributes.d.mts → cookie-attributes.d.mts} +0 -0
package/dist/_chunks/digest.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { textEncoder } from "./libs/unsecure.mjs";
|
|
2
|
-
import { JWTError
|
|
2
|
+
import { JWTError } from "../error.mjs";
|
|
3
|
+
import { base64UrlStringify, hasSymmetricSecret, isCryptoKey, isCryptoKeyPair, isJWK, isJWKSet } from "./jwt.mjs";
|
|
3
4
|
const ECDSA_CURVES = /* @__PURE__ */ Object.freeze({
|
|
4
5
|
ES256: "P-256",
|
|
5
6
|
ES384: "P-384",
|
|
@@ -149,7 +150,7 @@ function unionFromJWKSet(keys, mapper, options) {
|
|
|
149
150
|
const algs = /* @__PURE__ */ new Set();
|
|
150
151
|
for (const k of keys) {
|
|
151
152
|
if (!isJWK(k)) continue;
|
|
152
|
-
if (
|
|
153
|
+
if (!options?.allowSymmetric && hasSymmetricSecret(k)) continue;
|
|
153
154
|
const mapped = mapper(k);
|
|
154
155
|
if (!mapped) continue;
|
|
155
156
|
for (const a of mapped) algs.add(a);
|
|
@@ -159,6 +160,12 @@ function unionFromJWKSet(keys, mapper, options) {
|
|
|
159
160
|
function isEd25519Signature(alg) {
|
|
160
161
|
return alg === "EdDSA" || alg === "Ed25519";
|
|
161
162
|
}
|
|
163
|
+
function isSameAlgorithm(a, b) {
|
|
164
|
+
return a === b || isEd25519Signature(a) && isEd25519Signature(b);
|
|
165
|
+
}
|
|
166
|
+
function jwkAlgServes(jwk, alg) {
|
|
167
|
+
return isSameAlgorithm(jwk.alg, alg) || jwk.kty === "oct" && alg === "dir" && isContentEncryptionAlgorithm(jwk.alg);
|
|
168
|
+
}
|
|
162
169
|
function jwsAlgsFromJWK(jwk) {
|
|
163
170
|
if (jwk.alg && isEd25519Signature(jwk.alg)) return ["EdDSA", "Ed25519"];
|
|
164
171
|
if (jwk.alg) return isJWSAlgorithm(jwk.alg) ? [jwk.alg] : void 0;
|
|
@@ -253,4 +260,4 @@ async function digestUrl(data, hash = "SHA-256") {
|
|
|
253
260
|
const bytes = typeof data === "string" ? textEncoder.encode(data) : data;
|
|
254
261
|
return base64UrlStringify(new Uint8Array(await crypto.subtle.digest(hash, bytes)));
|
|
255
262
|
}
|
|
256
|
-
export { ECDSA_CURVES, PBES2_ALGORITHMS, aesBitsOf, checkKeyUsage, cryptoKeyCurve, digestUrl, hashBitsOf, inferJWEAllowedAlgorithms, inferJWSAllowedAlgorithms, innerKeyWrapAlg, isAlgorithm, isContentEncryptionAlgorithm, isECDHESAlgorithm,
|
|
263
|
+
export { ECDSA_CURVES, PBES2_ALGORITHMS, aesBitsOf, checkKeyUsage, cryptoKeyCurve, digestUrl, hashBitsOf, inferJWEAllowedAlgorithms, inferJWSAllowedAlgorithms, innerKeyWrapAlg, isAlgorithm, isContentEncryptionAlgorithm, isECDHESAlgorithm, isJWSAlgorithm, isKeyManagementAlgorithm, isPBES2Algorithm, isSameAlgorithm, jwkAlgServes, jwsHashOf, lengthOf, modulusLengthOf, namedCurveOf, pbes2HashOf, rsaOaepHashOf, shaBitsOf, unusableKey };
|
|
@@ -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 };
|
package/dist/_chunks/index.d.mts
CHANGED
|
@@ -1,105 +1,4 @@
|
|
|
1
|
-
import {
|
|
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
|
-
/**
|
|
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
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
*
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
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>>;
|