toolcraft 0.0.119 → 0.0.121
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/composition.json +17 -2
- package/dist/composition.json +17 -2
- package/dist/http.compile-check.d.ts +1 -0
- package/dist/http.compile-check.js +31 -0
- package/dist/http.d.ts +19 -0
- package/dist/http.js +62 -0
- package/dist/mcp.js +26 -11
- package/node_modules/jose/LICENSE.md +21 -0
- package/node_modules/jose/README.md +153 -0
- package/node_modules/jose/dist/types/index.d.ts +55 -0
- package/node_modules/jose/dist/types/jwe/compact/decrypt.d.ts +31 -0
- package/node_modules/jose/dist/types/jwe/compact/encrypt.d.ts +65 -0
- package/node_modules/jose/dist/types/jwe/flattened/decrypt.d.ts +31 -0
- package/node_modules/jose/dist/types/jwe/flattened/encrypt.d.ts +83 -0
- package/node_modules/jose/dist/types/jwe/general/decrypt.d.ts +38 -0
- package/node_modules/jose/dist/types/jwe/general/encrypt.d.ts +74 -0
- package/node_modules/jose/dist/types/jwk/embedded.d.ts +17 -0
- package/node_modules/jose/dist/types/jwk/thumbprint.d.ts +32 -0
- package/node_modules/jose/dist/types/jwks/local.d.ts +29 -0
- package/node_modules/jose/dist/types/jwks/remote.d.ts +237 -0
- package/node_modules/jose/dist/types/jws/compact/sign.d.ts +36 -0
- package/node_modules/jose/dist/types/jws/compact/verify.d.ts +33 -0
- package/node_modules/jose/dist/types/jws/flattened/sign.d.ts +42 -0
- package/node_modules/jose/dist/types/jws/flattened/verify.d.ts +33 -0
- package/node_modules/jose/dist/types/jws/general/sign.d.ts +53 -0
- package/node_modules/jose/dist/types/jws/general/verify.d.ts +41 -0
- package/node_modules/jose/dist/types/jwt/decrypt.d.ts +35 -0
- package/node_modules/jose/dist/types/jwt/encrypt.d.ts +91 -0
- package/node_modules/jose/dist/types/jwt/sign.d.ts +43 -0
- package/node_modules/jose/dist/types/jwt/unsecured.d.ts +43 -0
- package/node_modules/jose/dist/types/jwt/verify.d.ts +37 -0
- package/node_modules/jose/dist/types/key/export.d.ts +33 -0
- package/node_modules/jose/dist/types/key/generate_key_pair.d.ts +47 -0
- package/node_modules/jose/dist/types/key/generate_secret.d.ts +35 -0
- package/node_modules/jose/dist/types/key/import.d.ts +83 -0
- package/node_modules/jose/dist/types/types.d.ts +852 -0
- package/node_modules/jose/dist/types/util/base64url.d.ts +9 -0
- package/node_modules/jose/dist/types/util/decode_jwt.d.ts +18 -0
- package/node_modules/jose/dist/types/util/decode_protected_header.d.ts +17 -0
- package/node_modules/jose/dist/types/util/errors.d.ts +213 -0
- package/node_modules/jose/dist/webapi/index.js +32 -0
- package/node_modules/jose/dist/webapi/jwe/compact/decrypt.js +27 -0
- package/node_modules/jose/dist/webapi/jwe/compact/encrypt.js +27 -0
- package/node_modules/jose/dist/webapi/jwe/flattened/decrypt.js +159 -0
- package/node_modules/jose/dist/webapi/jwe/flattened/encrypt.js +167 -0
- package/node_modules/jose/dist/webapi/jwe/general/decrypt.js +31 -0
- package/node_modules/jose/dist/webapi/jwe/general/encrypt.js +182 -0
- package/node_modules/jose/dist/webapi/jwk/embedded.js +17 -0
- package/node_modules/jose/dist/webapi/jwk/thumbprint.js +68 -0
- package/node_modules/jose/dist/webapi/jwks/local.js +119 -0
- package/node_modules/jose/dist/webapi/jwks/remote.js +179 -0
- package/node_modules/jose/dist/webapi/jws/compact/sign.js +18 -0
- package/node_modules/jose/dist/webapi/jws/compact/verify.js +21 -0
- package/node_modules/jose/dist/webapi/jws/flattened/sign.js +89 -0
- package/node_modules/jose/dist/webapi/jws/flattened/verify.js +110 -0
- package/node_modules/jose/dist/webapi/jws/general/sign.js +70 -0
- package/node_modules/jose/dist/webapi/jws/general/verify.js +24 -0
- package/node_modules/jose/dist/webapi/jwt/decrypt.js +23 -0
- package/node_modules/jose/dist/webapi/jwt/encrypt.js +101 -0
- package/node_modules/jose/dist/webapi/jwt/sign.js +52 -0
- package/node_modules/jose/dist/webapi/jwt/unsecured.js +63 -0
- package/node_modules/jose/dist/webapi/jwt/verify.js +15 -0
- package/node_modules/jose/dist/webapi/key/export.js +11 -0
- package/node_modules/jose/dist/webapi/key/generate_key_pair.js +97 -0
- package/node_modules/jose/dist/webapi/key/generate_secret.js +40 -0
- package/node_modules/jose/dist/webapi/key/import.js +57 -0
- package/node_modules/jose/dist/webapi/lib/aesgcmkw.js +15 -0
- package/node_modules/jose/dist/webapi/lib/aeskw.js +25 -0
- package/node_modules/jose/dist/webapi/lib/asn1.js +243 -0
- package/node_modules/jose/dist/webapi/lib/base64.js +22 -0
- package/node_modules/jose/dist/webapi/lib/buffer_utils.js +43 -0
- package/node_modules/jose/dist/webapi/lib/check_key_type.js +122 -0
- package/node_modules/jose/dist/webapi/lib/content_encryption.js +217 -0
- package/node_modules/jose/dist/webapi/lib/crypto_key.js +136 -0
- package/node_modules/jose/dist/webapi/lib/deflate.js +44 -0
- package/node_modules/jose/dist/webapi/lib/ecdhes.js +52 -0
- package/node_modules/jose/dist/webapi/lib/helpers.js +19 -0
- package/node_modules/jose/dist/webapi/lib/invalid_key_input.js +27 -0
- package/node_modules/jose/dist/webapi/lib/is_key_like.js +17 -0
- package/node_modules/jose/dist/webapi/lib/jwk_to_key.js +107 -0
- package/node_modules/jose/dist/webapi/lib/jwt_claims_set.js +238 -0
- package/node_modules/jose/dist/webapi/lib/key_management.js +186 -0
- package/node_modules/jose/dist/webapi/lib/key_to_jwk.js +31 -0
- package/node_modules/jose/dist/webapi/lib/normalize_key.js +166 -0
- package/node_modules/jose/dist/webapi/lib/pbes2kw.js +42 -0
- package/node_modules/jose/dist/webapi/lib/rsaes.js +24 -0
- package/node_modules/jose/dist/webapi/lib/signing.js +68 -0
- package/node_modules/jose/dist/webapi/lib/type_checks.js +40 -0
- package/node_modules/jose/dist/webapi/lib/validate_algorithms.js +10 -0
- package/node_modules/jose/dist/webapi/lib/validate_crit.js +33 -0
- package/node_modules/jose/dist/webapi/util/base64url.js +30 -0
- package/node_modules/jose/dist/webapi/util/decode_jwt.js +32 -0
- package/node_modules/jose/dist/webapi/util/decode_protected_header.js +34 -0
- package/node_modules/jose/dist/webapi/util/errors.js +99 -0
- package/node_modules/jose/package.json +200 -0
- package/node_modules/tiny-http-mcp-server/LICENSE +21 -0
- package/node_modules/tiny-http-mcp-server/README.md +778 -0
- package/node_modules/tiny-http-mcp-server/dist/auth.d.ts +69 -0
- package/node_modules/tiny-http-mcp-server/dist/auth.js +261 -0
- package/node_modules/tiny-http-mcp-server/dist/cli.d.ts +20 -0
- package/node_modules/tiny-http-mcp-server/dist/cli.js +465 -0
- package/node_modules/tiny-http-mcp-server/dist/composition.json +30 -0
- package/node_modules/tiny-http-mcp-server/dist/express-middleware.d.ts +18 -0
- package/node_modules/tiny-http-mcp-server/dist/express-middleware.js +90 -0
- package/node_modules/tiny-http-mcp-server/dist/http-server.d.ts +49 -0
- package/node_modules/tiny-http-mcp-server/dist/http-server.js +264 -0
- package/node_modules/tiny-http-mcp-server/dist/http-transport.d.ts +164 -0
- package/node_modules/tiny-http-mcp-server/dist/http-transport.js +897 -0
- package/node_modules/tiny-http-mcp-server/dist/index.d.ts +13 -0
- package/node_modules/tiny-http-mcp-server/dist/index.js +6 -0
- package/node_modules/tiny-http-mcp-server/dist/load-oauth-verifier.d.ts +6 -0
- package/node_modules/tiny-http-mcp-server/dist/load-oauth-verifier.js +43 -0
- package/node_modules/tiny-http-mcp-server/dist/parse-body.d.ts +22 -0
- package/node_modules/tiny-http-mcp-server/dist/parse-body.js +150 -0
- package/node_modules/tiny-http-mcp-server/dist/server.d.ts +9 -0
- package/node_modules/tiny-http-mcp-server/dist/server.js +4 -0
- package/node_modules/tiny-http-mcp-server/dist/session.d.ts +18 -0
- package/node_modules/tiny-http-mcp-server/dist/session.js +37 -0
- package/node_modules/tiny-http-mcp-server/dist/sse.d.ts +11 -0
- package/node_modules/tiny-http-mcp-server/dist/sse.js +22 -0
- package/node_modules/tiny-http-mcp-server/dist/test-support.d.ts +10 -0
- package/node_modules/tiny-http-mcp-server/dist/test-support.js +398 -0
- package/node_modules/tiny-http-mcp-server/dist/testing.d.ts +59 -0
- package/node_modules/tiny-http-mcp-server/dist/testing.js +191 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/LICENSE +21 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/README.md +70 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/auth-store-session-store.d.ts +14 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/auth-store-session-store.js +169 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/authorization-state.d.ts +8 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/authorization-state.js +47 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/default-oauth-client-provider.d.ts +3 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/default-oauth-client-provider.js +627 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/loopback-authorization.d.ts +20 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/loopback-authorization.js +207 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/pkce.d.ts +2 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/pkce.js +7 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/token-endpoint.d.ts +40 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/token-endpoint.js +164 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/types.d.ts +113 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/types.js +1 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/index.d.ts +10 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/index.js +7 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/resource-indicator.d.ts +1 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/resource-indicator.js +11 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/server/jwks-token-verifier.d.ts +32 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/server/jwks-token-verifier.js +388 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/types.compile-check.d.ts +1 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/types.compile-check.js +22 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/package.json +28 -0
- package/node_modules/tiny-http-mcp-server/package.json +59 -0
- package/node_modules/tiny-stdio-mcp-server/dist/composition.json +1 -1
- package/node_modules/toolcraft-schema/package.json +1 -1
- package/package.json +11 -4
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { encode as b64u } from '../../util/base64url.js';
|
|
2
|
+
import { sign } from '../../lib/signing.js';
|
|
3
|
+
import { isDisjoint } from '../../lib/type_checks.js';
|
|
4
|
+
import { JWSInvalid } from '../../util/errors.js';
|
|
5
|
+
import { concat, encode } from '../../lib/buffer_utils.js';
|
|
6
|
+
import { checkKeyType } from '../../lib/check_key_type.js';
|
|
7
|
+
import { validateCrit } from '../../lib/validate_crit.js';
|
|
8
|
+
import { normalizeKey } from '../../lib/normalize_key.js';
|
|
9
|
+
import { assertNotSet } from '../../lib/helpers.js';
|
|
10
|
+
export class FlattenedSign {
|
|
11
|
+
#payload;
|
|
12
|
+
#protectedHeader;
|
|
13
|
+
#unprotectedHeader;
|
|
14
|
+
constructor(payload) {
|
|
15
|
+
if (!(payload instanceof Uint8Array)) {
|
|
16
|
+
throw new TypeError('payload must be an instance of Uint8Array');
|
|
17
|
+
}
|
|
18
|
+
this.#payload = payload;
|
|
19
|
+
}
|
|
20
|
+
setProtectedHeader(protectedHeader) {
|
|
21
|
+
assertNotSet(this.#protectedHeader, 'setProtectedHeader');
|
|
22
|
+
this.#protectedHeader = protectedHeader;
|
|
23
|
+
return this;
|
|
24
|
+
}
|
|
25
|
+
setUnprotectedHeader(unprotectedHeader) {
|
|
26
|
+
assertNotSet(this.#unprotectedHeader, 'setUnprotectedHeader');
|
|
27
|
+
this.#unprotectedHeader = unprotectedHeader;
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
30
|
+
async sign(key, options) {
|
|
31
|
+
if (!this.#protectedHeader && !this.#unprotectedHeader) {
|
|
32
|
+
throw new JWSInvalid('either setProtectedHeader or setUnprotectedHeader must be called before #sign()');
|
|
33
|
+
}
|
|
34
|
+
if (!isDisjoint(this.#protectedHeader, this.#unprotectedHeader)) {
|
|
35
|
+
throw new JWSInvalid('JWS Protected and JWS Unprotected Header Parameter names must be disjoint');
|
|
36
|
+
}
|
|
37
|
+
const joseHeader = {
|
|
38
|
+
...this.#protectedHeader,
|
|
39
|
+
...this.#unprotectedHeader,
|
|
40
|
+
};
|
|
41
|
+
const extensions = validateCrit(JWSInvalid, new Map([['b64', true]]), options?.crit, this.#protectedHeader, joseHeader);
|
|
42
|
+
let b64 = true;
|
|
43
|
+
if (extensions.has('b64')) {
|
|
44
|
+
b64 = this.#protectedHeader.b64;
|
|
45
|
+
if (typeof b64 !== 'boolean') {
|
|
46
|
+
throw new JWSInvalid('The "b64" (base64url-encode payload) Header Parameter must be a boolean');
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const { alg } = joseHeader;
|
|
50
|
+
if (typeof alg !== 'string' || !alg) {
|
|
51
|
+
throw new JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
|
|
52
|
+
}
|
|
53
|
+
checkKeyType(alg, key, 'sign');
|
|
54
|
+
let payloadS;
|
|
55
|
+
let payloadB;
|
|
56
|
+
if (b64) {
|
|
57
|
+
payloadS = b64u(this.#payload);
|
|
58
|
+
payloadB = encode(payloadS);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
payloadB = this.#payload;
|
|
62
|
+
payloadS = '';
|
|
63
|
+
}
|
|
64
|
+
let protectedHeaderString;
|
|
65
|
+
let protectedHeaderBytes;
|
|
66
|
+
if (this.#protectedHeader) {
|
|
67
|
+
protectedHeaderString = b64u(JSON.stringify(this.#protectedHeader));
|
|
68
|
+
protectedHeaderBytes = encode(protectedHeaderString);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
protectedHeaderString = '';
|
|
72
|
+
protectedHeaderBytes = new Uint8Array();
|
|
73
|
+
}
|
|
74
|
+
const data = concat(protectedHeaderBytes, encode('.'), payloadB);
|
|
75
|
+
const k = await normalizeKey(key, alg);
|
|
76
|
+
const signature = await sign(alg, k, data);
|
|
77
|
+
const jws = {
|
|
78
|
+
signature: b64u(signature),
|
|
79
|
+
payload: payloadS,
|
|
80
|
+
};
|
|
81
|
+
if (this.#unprotectedHeader) {
|
|
82
|
+
jws.header = this.#unprotectedHeader;
|
|
83
|
+
}
|
|
84
|
+
if (this.#protectedHeader) {
|
|
85
|
+
jws.protected = protectedHeaderString;
|
|
86
|
+
}
|
|
87
|
+
return jws;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { decode as b64u } from '../../util/base64url.js';
|
|
2
|
+
import { verify } from '../../lib/signing.js';
|
|
3
|
+
import { JOSEAlgNotAllowed, JWSInvalid, JWSSignatureVerificationFailed } from '../../util/errors.js';
|
|
4
|
+
import { concat, encoder, decoder, encode } from '../../lib/buffer_utils.js';
|
|
5
|
+
import { decodeBase64url } from '../../lib/helpers.js';
|
|
6
|
+
import { isDisjoint } from '../../lib/type_checks.js';
|
|
7
|
+
import { isObject } from '../../lib/type_checks.js';
|
|
8
|
+
import { checkKeyType } from '../../lib/check_key_type.js';
|
|
9
|
+
import { validateCrit } from '../../lib/validate_crit.js';
|
|
10
|
+
import { validateAlgorithms } from '../../lib/validate_algorithms.js';
|
|
11
|
+
import { normalizeKey } from '../../lib/normalize_key.js';
|
|
12
|
+
export async function flattenedVerify(jws, key, options) {
|
|
13
|
+
if (!isObject(jws)) {
|
|
14
|
+
throw new JWSInvalid('Flattened JWS must be an object');
|
|
15
|
+
}
|
|
16
|
+
if (jws.protected === undefined && jws.header === undefined) {
|
|
17
|
+
throw new JWSInvalid('Flattened JWS must have either of the "protected" or "header" members');
|
|
18
|
+
}
|
|
19
|
+
if (jws.protected !== undefined && typeof jws.protected !== 'string') {
|
|
20
|
+
throw new JWSInvalid('JWS Protected Header incorrect type');
|
|
21
|
+
}
|
|
22
|
+
if (jws.payload === undefined) {
|
|
23
|
+
throw new JWSInvalid('JWS Payload missing');
|
|
24
|
+
}
|
|
25
|
+
if (typeof jws.signature !== 'string') {
|
|
26
|
+
throw new JWSInvalid('JWS Signature missing or incorrect type');
|
|
27
|
+
}
|
|
28
|
+
if (jws.header !== undefined && !isObject(jws.header)) {
|
|
29
|
+
throw new JWSInvalid('JWS Unprotected Header incorrect type');
|
|
30
|
+
}
|
|
31
|
+
let parsedProt = {};
|
|
32
|
+
if (jws.protected) {
|
|
33
|
+
try {
|
|
34
|
+
const protectedHeader = b64u(jws.protected);
|
|
35
|
+
parsedProt = JSON.parse(decoder.decode(protectedHeader));
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
throw new JWSInvalid('JWS Protected Header is invalid');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (!isDisjoint(parsedProt, jws.header)) {
|
|
42
|
+
throw new JWSInvalid('JWS Protected and JWS Unprotected Header Parameter names must be disjoint');
|
|
43
|
+
}
|
|
44
|
+
const joseHeader = {
|
|
45
|
+
...parsedProt,
|
|
46
|
+
...jws.header,
|
|
47
|
+
};
|
|
48
|
+
const extensions = validateCrit(JWSInvalid, new Map([['b64', true]]), options?.crit, parsedProt, joseHeader);
|
|
49
|
+
let b64 = true;
|
|
50
|
+
if (extensions.has('b64')) {
|
|
51
|
+
b64 = parsedProt.b64;
|
|
52
|
+
if (typeof b64 !== 'boolean') {
|
|
53
|
+
throw new JWSInvalid('The "b64" (base64url-encode payload) Header Parameter must be a boolean');
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const { alg } = joseHeader;
|
|
57
|
+
if (typeof alg !== 'string' || !alg) {
|
|
58
|
+
throw new JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
|
|
59
|
+
}
|
|
60
|
+
const algorithms = options && validateAlgorithms('algorithms', options.algorithms);
|
|
61
|
+
if (algorithms && !algorithms.has(alg)) {
|
|
62
|
+
throw new JOSEAlgNotAllowed('"alg" (Algorithm) Header Parameter value not allowed');
|
|
63
|
+
}
|
|
64
|
+
if (b64) {
|
|
65
|
+
if (typeof jws.payload !== 'string') {
|
|
66
|
+
throw new JWSInvalid('JWS Payload must be a string');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else if (typeof jws.payload !== 'string' && !(jws.payload instanceof Uint8Array)) {
|
|
70
|
+
throw new JWSInvalid('JWS Payload must be a string or an Uint8Array instance');
|
|
71
|
+
}
|
|
72
|
+
let resolvedKey = false;
|
|
73
|
+
if (typeof key === 'function') {
|
|
74
|
+
key = await key(parsedProt, jws);
|
|
75
|
+
resolvedKey = true;
|
|
76
|
+
}
|
|
77
|
+
checkKeyType(alg, key, 'verify');
|
|
78
|
+
const data = concat(jws.protected !== undefined ? encode(jws.protected) : new Uint8Array(), encode('.'), typeof jws.payload === 'string'
|
|
79
|
+
? b64
|
|
80
|
+
? encode(jws.payload)
|
|
81
|
+
: encoder.encode(jws.payload)
|
|
82
|
+
: jws.payload);
|
|
83
|
+
const signature = decodeBase64url(jws.signature, 'signature', JWSInvalid);
|
|
84
|
+
const k = await normalizeKey(key, alg);
|
|
85
|
+
const verified = await verify(alg, k, signature, data);
|
|
86
|
+
if (!verified) {
|
|
87
|
+
throw new JWSSignatureVerificationFailed();
|
|
88
|
+
}
|
|
89
|
+
let payload;
|
|
90
|
+
if (b64) {
|
|
91
|
+
payload = decodeBase64url(jws.payload, 'payload', JWSInvalid);
|
|
92
|
+
}
|
|
93
|
+
else if (typeof jws.payload === 'string') {
|
|
94
|
+
payload = encoder.encode(jws.payload);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
payload = jws.payload;
|
|
98
|
+
}
|
|
99
|
+
const result = { payload };
|
|
100
|
+
if (jws.protected !== undefined) {
|
|
101
|
+
result.protectedHeader = parsedProt;
|
|
102
|
+
}
|
|
103
|
+
if (jws.header !== undefined) {
|
|
104
|
+
result.unprotectedHeader = jws.header;
|
|
105
|
+
}
|
|
106
|
+
if (resolvedKey) {
|
|
107
|
+
return { ...result, key: k };
|
|
108
|
+
}
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { FlattenedSign } from '../flattened/sign.js';
|
|
2
|
+
import { JWSInvalid } from '../../util/errors.js';
|
|
3
|
+
import { assertNotSet } from '../../lib/helpers.js';
|
|
4
|
+
class IndividualSignature {
|
|
5
|
+
#parent;
|
|
6
|
+
protectedHeader;
|
|
7
|
+
unprotectedHeader;
|
|
8
|
+
options;
|
|
9
|
+
key;
|
|
10
|
+
constructor(sig, key, options) {
|
|
11
|
+
this.#parent = sig;
|
|
12
|
+
this.key = key;
|
|
13
|
+
this.options = options;
|
|
14
|
+
}
|
|
15
|
+
setProtectedHeader(protectedHeader) {
|
|
16
|
+
assertNotSet(this.protectedHeader, 'setProtectedHeader');
|
|
17
|
+
this.protectedHeader = protectedHeader;
|
|
18
|
+
return this;
|
|
19
|
+
}
|
|
20
|
+
setUnprotectedHeader(unprotectedHeader) {
|
|
21
|
+
assertNotSet(this.unprotectedHeader, 'setUnprotectedHeader');
|
|
22
|
+
this.unprotectedHeader = unprotectedHeader;
|
|
23
|
+
return this;
|
|
24
|
+
}
|
|
25
|
+
addSignature(...args) {
|
|
26
|
+
return this.#parent.addSignature(...args);
|
|
27
|
+
}
|
|
28
|
+
sign(...args) {
|
|
29
|
+
return this.#parent.sign(...args);
|
|
30
|
+
}
|
|
31
|
+
done() {
|
|
32
|
+
return this.#parent;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export class GeneralSign {
|
|
36
|
+
#payload;
|
|
37
|
+
#signatures = [];
|
|
38
|
+
constructor(payload) {
|
|
39
|
+
this.#payload = payload;
|
|
40
|
+
}
|
|
41
|
+
addSignature(key, options) {
|
|
42
|
+
const signature = new IndividualSignature(this, key, options);
|
|
43
|
+
this.#signatures.push(signature);
|
|
44
|
+
return signature;
|
|
45
|
+
}
|
|
46
|
+
async sign() {
|
|
47
|
+
if (!this.#signatures.length) {
|
|
48
|
+
throw new JWSInvalid('at least one signature must be added');
|
|
49
|
+
}
|
|
50
|
+
const jws = {
|
|
51
|
+
signatures: [],
|
|
52
|
+
payload: '',
|
|
53
|
+
};
|
|
54
|
+
for (let i = 0; i < this.#signatures.length; i++) {
|
|
55
|
+
const signature = this.#signatures[i];
|
|
56
|
+
const flattened = new FlattenedSign(this.#payload);
|
|
57
|
+
flattened.setProtectedHeader(signature.protectedHeader);
|
|
58
|
+
flattened.setUnprotectedHeader(signature.unprotectedHeader);
|
|
59
|
+
const { payload, ...rest } = await flattened.sign(signature.key, signature.options);
|
|
60
|
+
if (i === 0) {
|
|
61
|
+
jws.payload = payload;
|
|
62
|
+
}
|
|
63
|
+
else if (jws.payload !== payload) {
|
|
64
|
+
throw new JWSInvalid('inconsistent use of JWS Unencoded Payload (RFC7797)');
|
|
65
|
+
}
|
|
66
|
+
jws.signatures.push(rest);
|
|
67
|
+
}
|
|
68
|
+
return jws;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { flattenedVerify } from '../flattened/verify.js';
|
|
2
|
+
import { JWSInvalid, JWSSignatureVerificationFailed } from '../../util/errors.js';
|
|
3
|
+
import { isObject } from '../../lib/type_checks.js';
|
|
4
|
+
export async function generalVerify(jws, key, options) {
|
|
5
|
+
if (!isObject(jws)) {
|
|
6
|
+
throw new JWSInvalid('General JWS must be an object');
|
|
7
|
+
}
|
|
8
|
+
if (!Array.isArray(jws.signatures) || !jws.signatures.every(isObject)) {
|
|
9
|
+
throw new JWSInvalid('JWS Signatures missing or incorrect type');
|
|
10
|
+
}
|
|
11
|
+
for (const signature of jws.signatures) {
|
|
12
|
+
try {
|
|
13
|
+
return await flattenedVerify({
|
|
14
|
+
header: signature.header,
|
|
15
|
+
payload: jws.payload,
|
|
16
|
+
protected: signature.protected,
|
|
17
|
+
signature: signature.signature,
|
|
18
|
+
}, key, options);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
throw new JWSSignatureVerificationFailed();
|
|
24
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { compactDecrypt } from '../jwe/compact/decrypt.js';
|
|
2
|
+
import { validateClaimsSet } from '../lib/jwt_claims_set.js';
|
|
3
|
+
import { JWTClaimValidationFailed } from '../util/errors.js';
|
|
4
|
+
export async function jwtDecrypt(jwt, key, options) {
|
|
5
|
+
const decrypted = await compactDecrypt(jwt, key, options);
|
|
6
|
+
const payload = validateClaimsSet(decrypted.protectedHeader, decrypted.plaintext, options);
|
|
7
|
+
const { protectedHeader } = decrypted;
|
|
8
|
+
if (protectedHeader.iss !== undefined && protectedHeader.iss !== payload.iss) {
|
|
9
|
+
throw new JWTClaimValidationFailed('replicated "iss" claim header parameter mismatch', payload, 'iss', 'mismatch');
|
|
10
|
+
}
|
|
11
|
+
if (protectedHeader.sub !== undefined && protectedHeader.sub !== payload.sub) {
|
|
12
|
+
throw new JWTClaimValidationFailed('replicated "sub" claim header parameter mismatch', payload, 'sub', 'mismatch');
|
|
13
|
+
}
|
|
14
|
+
if (protectedHeader.aud !== undefined &&
|
|
15
|
+
JSON.stringify(protectedHeader.aud) !== JSON.stringify(payload.aud)) {
|
|
16
|
+
throw new JWTClaimValidationFailed('replicated "aud" claim header parameter mismatch', payload, 'aud', 'mismatch');
|
|
17
|
+
}
|
|
18
|
+
const result = { payload, protectedHeader };
|
|
19
|
+
if (typeof key === 'function') {
|
|
20
|
+
return { ...result, key: decrypted.key };
|
|
21
|
+
}
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { CompactEncrypt } from '../jwe/compact/encrypt.js';
|
|
2
|
+
import { JWTClaimsBuilder } from '../lib/jwt_claims_set.js';
|
|
3
|
+
import { assertNotSet } from '../lib/helpers.js';
|
|
4
|
+
export class EncryptJWT {
|
|
5
|
+
#cek;
|
|
6
|
+
#iv;
|
|
7
|
+
#keyManagementParameters;
|
|
8
|
+
#protectedHeader;
|
|
9
|
+
#replicateIssuerAsHeader;
|
|
10
|
+
#replicateSubjectAsHeader;
|
|
11
|
+
#replicateAudienceAsHeader;
|
|
12
|
+
#jwt;
|
|
13
|
+
constructor(payload = {}) {
|
|
14
|
+
this.#jwt = new JWTClaimsBuilder(payload);
|
|
15
|
+
}
|
|
16
|
+
setIssuer(issuer) {
|
|
17
|
+
this.#jwt.iss = issuer;
|
|
18
|
+
return this;
|
|
19
|
+
}
|
|
20
|
+
setSubject(subject) {
|
|
21
|
+
this.#jwt.sub = subject;
|
|
22
|
+
return this;
|
|
23
|
+
}
|
|
24
|
+
setAudience(audience) {
|
|
25
|
+
this.#jwt.aud = audience;
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
setJti(jwtId) {
|
|
29
|
+
this.#jwt.jti = jwtId;
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
setNotBefore(input) {
|
|
33
|
+
this.#jwt.nbf = input;
|
|
34
|
+
return this;
|
|
35
|
+
}
|
|
36
|
+
setExpirationTime(input) {
|
|
37
|
+
this.#jwt.exp = input;
|
|
38
|
+
return this;
|
|
39
|
+
}
|
|
40
|
+
setIssuedAt(input) {
|
|
41
|
+
this.#jwt.iat = input;
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
44
|
+
setProtectedHeader(protectedHeader) {
|
|
45
|
+
assertNotSet(this.#protectedHeader, 'setProtectedHeader');
|
|
46
|
+
this.#protectedHeader = protectedHeader;
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
setKeyManagementParameters(parameters) {
|
|
50
|
+
assertNotSet(this.#keyManagementParameters, 'setKeyManagementParameters');
|
|
51
|
+
this.#keyManagementParameters = parameters;
|
|
52
|
+
return this;
|
|
53
|
+
}
|
|
54
|
+
setContentEncryptionKey(cek) {
|
|
55
|
+
assertNotSet(this.#cek, 'setContentEncryptionKey');
|
|
56
|
+
this.#cek = cek;
|
|
57
|
+
return this;
|
|
58
|
+
}
|
|
59
|
+
setInitializationVector(iv) {
|
|
60
|
+
assertNotSet(this.#iv, 'setInitializationVector');
|
|
61
|
+
this.#iv = iv;
|
|
62
|
+
return this;
|
|
63
|
+
}
|
|
64
|
+
replicateIssuerAsHeader() {
|
|
65
|
+
this.#replicateIssuerAsHeader = true;
|
|
66
|
+
return this;
|
|
67
|
+
}
|
|
68
|
+
replicateSubjectAsHeader() {
|
|
69
|
+
this.#replicateSubjectAsHeader = true;
|
|
70
|
+
return this;
|
|
71
|
+
}
|
|
72
|
+
replicateAudienceAsHeader() {
|
|
73
|
+
this.#replicateAudienceAsHeader = true;
|
|
74
|
+
return this;
|
|
75
|
+
}
|
|
76
|
+
async encrypt(key, options) {
|
|
77
|
+
const enc = new CompactEncrypt(this.#jwt.data());
|
|
78
|
+
if (this.#protectedHeader &&
|
|
79
|
+
(this.#replicateIssuerAsHeader ||
|
|
80
|
+
this.#replicateSubjectAsHeader ||
|
|
81
|
+
this.#replicateAudienceAsHeader)) {
|
|
82
|
+
this.#protectedHeader = {
|
|
83
|
+
...this.#protectedHeader,
|
|
84
|
+
iss: this.#replicateIssuerAsHeader ? this.#jwt.iss : undefined,
|
|
85
|
+
sub: this.#replicateSubjectAsHeader ? this.#jwt.sub : undefined,
|
|
86
|
+
aud: this.#replicateAudienceAsHeader ? this.#jwt.aud : undefined,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
enc.setProtectedHeader(this.#protectedHeader);
|
|
90
|
+
if (this.#iv) {
|
|
91
|
+
enc.setInitializationVector(this.#iv);
|
|
92
|
+
}
|
|
93
|
+
if (this.#cek) {
|
|
94
|
+
enc.setContentEncryptionKey(this.#cek);
|
|
95
|
+
}
|
|
96
|
+
if (this.#keyManagementParameters) {
|
|
97
|
+
enc.setKeyManagementParameters(this.#keyManagementParameters);
|
|
98
|
+
}
|
|
99
|
+
return enc.encrypt(key, options);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { CompactSign } from '../jws/compact/sign.js';
|
|
2
|
+
import { JWTInvalid } from '../util/errors.js';
|
|
3
|
+
import { JWTClaimsBuilder } from '../lib/jwt_claims_set.js';
|
|
4
|
+
export class SignJWT {
|
|
5
|
+
#protectedHeader;
|
|
6
|
+
#jwt;
|
|
7
|
+
constructor(payload = {}) {
|
|
8
|
+
this.#jwt = new JWTClaimsBuilder(payload);
|
|
9
|
+
}
|
|
10
|
+
setIssuer(issuer) {
|
|
11
|
+
this.#jwt.iss = issuer;
|
|
12
|
+
return this;
|
|
13
|
+
}
|
|
14
|
+
setSubject(subject) {
|
|
15
|
+
this.#jwt.sub = subject;
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
setAudience(audience) {
|
|
19
|
+
this.#jwt.aud = audience;
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
setJti(jwtId) {
|
|
23
|
+
this.#jwt.jti = jwtId;
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
26
|
+
setNotBefore(input) {
|
|
27
|
+
this.#jwt.nbf = input;
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
30
|
+
setExpirationTime(input) {
|
|
31
|
+
this.#jwt.exp = input;
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
34
|
+
setIssuedAt(input) {
|
|
35
|
+
this.#jwt.iat = input;
|
|
36
|
+
return this;
|
|
37
|
+
}
|
|
38
|
+
setProtectedHeader(protectedHeader) {
|
|
39
|
+
this.#protectedHeader = protectedHeader;
|
|
40
|
+
return this;
|
|
41
|
+
}
|
|
42
|
+
async sign(key, options) {
|
|
43
|
+
const sig = new CompactSign(this.#jwt.data());
|
|
44
|
+
sig.setProtectedHeader(this.#protectedHeader);
|
|
45
|
+
if (Array.isArray(this.#protectedHeader?.crit) &&
|
|
46
|
+
this.#protectedHeader.crit.includes('b64') &&
|
|
47
|
+
this.#protectedHeader.b64 === false) {
|
|
48
|
+
throw new JWTInvalid('JWTs MUST NOT use unencoded payload');
|
|
49
|
+
}
|
|
50
|
+
return sig.sign(key, options);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as b64u from '../util/base64url.js';
|
|
2
|
+
import { decoder } from '../lib/buffer_utils.js';
|
|
3
|
+
import { JWTInvalid } from '../util/errors.js';
|
|
4
|
+
import { validateClaimsSet, JWTClaimsBuilder } from '../lib/jwt_claims_set.js';
|
|
5
|
+
export class UnsecuredJWT {
|
|
6
|
+
#jwt;
|
|
7
|
+
constructor(payload = {}) {
|
|
8
|
+
this.#jwt = new JWTClaimsBuilder(payload);
|
|
9
|
+
}
|
|
10
|
+
encode() {
|
|
11
|
+
const header = b64u.encode(JSON.stringify({ alg: 'none' }));
|
|
12
|
+
const payload = b64u.encode(this.#jwt.data());
|
|
13
|
+
return `${header}.${payload}.`;
|
|
14
|
+
}
|
|
15
|
+
setIssuer(issuer) {
|
|
16
|
+
this.#jwt.iss = issuer;
|
|
17
|
+
return this;
|
|
18
|
+
}
|
|
19
|
+
setSubject(subject) {
|
|
20
|
+
this.#jwt.sub = subject;
|
|
21
|
+
return this;
|
|
22
|
+
}
|
|
23
|
+
setAudience(audience) {
|
|
24
|
+
this.#jwt.aud = audience;
|
|
25
|
+
return this;
|
|
26
|
+
}
|
|
27
|
+
setJti(jwtId) {
|
|
28
|
+
this.#jwt.jti = jwtId;
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
setNotBefore(input) {
|
|
32
|
+
this.#jwt.nbf = input;
|
|
33
|
+
return this;
|
|
34
|
+
}
|
|
35
|
+
setExpirationTime(input) {
|
|
36
|
+
this.#jwt.exp = input;
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
setIssuedAt(input) {
|
|
40
|
+
this.#jwt.iat = input;
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
43
|
+
static decode(jwt, options) {
|
|
44
|
+
if (typeof jwt !== 'string') {
|
|
45
|
+
throw new JWTInvalid('Unsecured JWT must be a string');
|
|
46
|
+
}
|
|
47
|
+
const { 0: encodedHeader, 1: encodedPayload, 2: signature, length } = jwt.split('.');
|
|
48
|
+
if (length !== 3 || signature !== '') {
|
|
49
|
+
throw new JWTInvalid('Invalid Unsecured JWT');
|
|
50
|
+
}
|
|
51
|
+
let header;
|
|
52
|
+
try {
|
|
53
|
+
header = JSON.parse(decoder.decode(b64u.decode(encodedHeader)));
|
|
54
|
+
if (header.alg !== 'none')
|
|
55
|
+
throw new Error();
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
throw new JWTInvalid('Invalid Unsecured JWT');
|
|
59
|
+
}
|
|
60
|
+
const payload = validateClaimsSet(header, b64u.decode(encodedPayload), options);
|
|
61
|
+
return { payload, header };
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { compactVerify } from '../jws/compact/verify.js';
|
|
2
|
+
import { validateClaimsSet } from '../lib/jwt_claims_set.js';
|
|
3
|
+
import { JWTInvalid } from '../util/errors.js';
|
|
4
|
+
export async function jwtVerify(jwt, key, options) {
|
|
5
|
+
const verified = await compactVerify(jwt, key, options);
|
|
6
|
+
if (verified.protectedHeader.crit?.includes('b64') && verified.protectedHeader.b64 === false) {
|
|
7
|
+
throw new JWTInvalid('JWTs MUST NOT use unencoded payload');
|
|
8
|
+
}
|
|
9
|
+
const payload = validateClaimsSet(verified.protectedHeader, verified.payload, options);
|
|
10
|
+
const result = { payload, protectedHeader: verified.protectedHeader };
|
|
11
|
+
if (typeof key === 'function') {
|
|
12
|
+
return { ...result, key: verified.key };
|
|
13
|
+
}
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { toSPKI as exportPublic, toPKCS8 as exportPrivate } from '../lib/asn1.js';
|
|
2
|
+
import { keyToJWK } from '../lib/key_to_jwk.js';
|
|
3
|
+
export async function exportSPKI(key) {
|
|
4
|
+
return exportPublic(key);
|
|
5
|
+
}
|
|
6
|
+
export async function exportPKCS8(key) {
|
|
7
|
+
return exportPrivate(key);
|
|
8
|
+
}
|
|
9
|
+
export async function exportJWK(key) {
|
|
10
|
+
return keyToJWK(key);
|
|
11
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { JOSENotSupported } from '../util/errors.js';
|
|
2
|
+
function getModulusLengthOption(options) {
|
|
3
|
+
const modulusLength = options?.modulusLength ?? 2048;
|
|
4
|
+
if (typeof modulusLength !== 'number' || modulusLength < 2048) {
|
|
5
|
+
throw new JOSENotSupported('Invalid or unsupported modulusLength option provided, 2048 bits or larger keys must be used');
|
|
6
|
+
}
|
|
7
|
+
return modulusLength;
|
|
8
|
+
}
|
|
9
|
+
export async function generateKeyPair(alg, options) {
|
|
10
|
+
let algorithm;
|
|
11
|
+
let keyUsages;
|
|
12
|
+
switch (alg) {
|
|
13
|
+
case 'PS256':
|
|
14
|
+
case 'PS384':
|
|
15
|
+
case 'PS512':
|
|
16
|
+
algorithm = {
|
|
17
|
+
name: 'RSA-PSS',
|
|
18
|
+
hash: `SHA-${alg.slice(-3)}`,
|
|
19
|
+
publicExponent: Uint8Array.of(0x01, 0x00, 0x01),
|
|
20
|
+
modulusLength: getModulusLengthOption(options),
|
|
21
|
+
};
|
|
22
|
+
keyUsages = ['sign', 'verify'];
|
|
23
|
+
break;
|
|
24
|
+
case 'RS256':
|
|
25
|
+
case 'RS384':
|
|
26
|
+
case 'RS512':
|
|
27
|
+
algorithm = {
|
|
28
|
+
name: 'RSASSA-PKCS1-v1_5',
|
|
29
|
+
hash: `SHA-${alg.slice(-3)}`,
|
|
30
|
+
publicExponent: Uint8Array.of(0x01, 0x00, 0x01),
|
|
31
|
+
modulusLength: getModulusLengthOption(options),
|
|
32
|
+
};
|
|
33
|
+
keyUsages = ['sign', 'verify'];
|
|
34
|
+
break;
|
|
35
|
+
case 'RSA-OAEP':
|
|
36
|
+
case 'RSA-OAEP-256':
|
|
37
|
+
case 'RSA-OAEP-384':
|
|
38
|
+
case 'RSA-OAEP-512':
|
|
39
|
+
algorithm = {
|
|
40
|
+
name: 'RSA-OAEP',
|
|
41
|
+
hash: `SHA-${parseInt(alg.slice(-3), 10) || 1}`,
|
|
42
|
+
publicExponent: Uint8Array.of(0x01, 0x00, 0x01),
|
|
43
|
+
modulusLength: getModulusLengthOption(options),
|
|
44
|
+
};
|
|
45
|
+
keyUsages = ['decrypt', 'unwrapKey', 'encrypt', 'wrapKey'];
|
|
46
|
+
break;
|
|
47
|
+
case 'ES256':
|
|
48
|
+
algorithm = { name: 'ECDSA', namedCurve: 'P-256' };
|
|
49
|
+
keyUsages = ['sign', 'verify'];
|
|
50
|
+
break;
|
|
51
|
+
case 'ES384':
|
|
52
|
+
algorithm = { name: 'ECDSA', namedCurve: 'P-384' };
|
|
53
|
+
keyUsages = ['sign', 'verify'];
|
|
54
|
+
break;
|
|
55
|
+
case 'ES512':
|
|
56
|
+
algorithm = { name: 'ECDSA', namedCurve: 'P-521' };
|
|
57
|
+
keyUsages = ['sign', 'verify'];
|
|
58
|
+
break;
|
|
59
|
+
case 'Ed25519':
|
|
60
|
+
case 'EdDSA': {
|
|
61
|
+
keyUsages = ['sign', 'verify'];
|
|
62
|
+
algorithm = { name: 'Ed25519' };
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
case 'ML-DSA-44':
|
|
66
|
+
case 'ML-DSA-65':
|
|
67
|
+
case 'ML-DSA-87': {
|
|
68
|
+
keyUsages = ['sign', 'verify'];
|
|
69
|
+
algorithm = { name: alg };
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
case 'ECDH-ES':
|
|
73
|
+
case 'ECDH-ES+A128KW':
|
|
74
|
+
case 'ECDH-ES+A192KW':
|
|
75
|
+
case 'ECDH-ES+A256KW': {
|
|
76
|
+
keyUsages = ['deriveBits'];
|
|
77
|
+
const crv = options?.crv ?? 'P-256';
|
|
78
|
+
switch (crv) {
|
|
79
|
+
case 'P-256':
|
|
80
|
+
case 'P-384':
|
|
81
|
+
case 'P-521': {
|
|
82
|
+
algorithm = { name: 'ECDH', namedCurve: crv };
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
case 'X25519':
|
|
86
|
+
algorithm = { name: 'X25519' };
|
|
87
|
+
break;
|
|
88
|
+
default:
|
|
89
|
+
throw new JOSENotSupported('Invalid or unsupported crv option provided, supported values are P-256, P-384, P-521, and X25519');
|
|
90
|
+
}
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
default:
|
|
94
|
+
throw new JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
|
|
95
|
+
}
|
|
96
|
+
return crypto.subtle.generateKey(algorithm, options?.extractable ?? false, keyUsages);
|
|
97
|
+
}
|