jose 6.0.13 → 6.1.0

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.
@@ -35,11 +35,25 @@ export interface JWK_OKP_Public extends JWKParameters {
35
35
  }
36
36
 
37
37
  /** Convenience interface for Private OKP JSON Web Keys */
38
- export interface JWK_OKP_Private extends JWK_OKP_Public, JWKParameters {
38
+ export interface JWK_OKP_Private extends JWK_OKP_Public {
39
39
  /** OKP JWK "d" (The Private Key) Parameter */
40
40
  d: string
41
41
  }
42
42
 
43
+ /** Convenience interface for Public AKP JSON Web Keys */
44
+ export interface JWK_AKP_Public extends JWKParameters {
45
+ /** JWK "alg" (Algorithm) Parameter */
46
+ alg: string
47
+ /** AKP JWK "pub" (The Public key) Parameter */
48
+ pub: string
49
+ }
50
+
51
+ /** Convenience interface for Private AKP JSON Web Keys */
52
+ export interface JWK_AKP_Private extends JWK_AKP_Public {
53
+ /** AKP JWK "priv" (The Private Key) Parameter */
54
+ priv: string
55
+ }
56
+
43
57
  /** Convenience interface for Public EC JSON Web Keys */
44
58
  export interface JWK_EC_Public extends JWKParameters {
45
59
  /** EC JWK "crv" (Curve) Parameter */
@@ -51,7 +65,7 @@ export interface JWK_EC_Public extends JWKParameters {
51
65
  }
52
66
 
53
67
  /** Convenience interface for Private EC JSON Web Keys */
54
- export interface JWK_EC_Private extends JWK_EC_Public, JWKParameters {
68
+ export interface JWK_EC_Private extends JWK_EC_Public {
55
69
  /** EC JWK "d" (ECC Private Key) Parameter */
56
70
  d: string
57
71
  }
@@ -65,7 +79,7 @@ export interface JWK_RSA_Public extends JWKParameters {
65
79
  }
66
80
 
67
81
  /** Convenience interface for Private RSA JSON Web Keys */
68
- export interface JWK_RSA_Private extends JWK_RSA_Public, JWKParameters {
82
+ export interface JWK_RSA_Private extends JWK_RSA_Public {
69
83
  /** RSA JWK "d" (Private Exponent) Parameter */
70
84
  d: string
71
85
  /** RSA JWK "dp" (First Factor CRT Exponent) Parameter */
@@ -87,9 +101,11 @@ export interface JWK_oct extends JWKParameters {
87
101
  }
88
102
 
89
103
  /**
90
- * JSON Web Key ({@link https://www.rfc-editor.org/rfc/rfc7517 JWK}). "RSA", "EC", "OKP", and "oct"
91
- * key types are supported.
104
+ * JSON Web Key ({@link https://www.rfc-editor.org/rfc/rfc7517 JWK}). "RSA", "EC", "OKP", "AKP", and
105
+ * "oct" key types are supported.
92
106
  *
107
+ * @see {@link JWK_AKP_Public}
108
+ * @see {@link JWK_AKP_Private}
93
109
  * @see {@link JWK_OKP_Public}
94
110
  * @see {@link JWK_OKP_Private}
95
111
  * @see {@link JWK_EC_Public}
@@ -133,6 +149,10 @@ export interface JWK extends JWKParameters {
133
149
  x?: string
134
150
  /** EC JWK "y" (Y Coordinate) Parameter */
135
151
  y?: string
152
+ /** AKP JWK "pub" (Public Key) Parameter */
153
+ pub?: string
154
+ /** AKP JWK "priv" (Private key) Parameter */
155
+ priv?: string
136
156
  }
137
157
 
138
158
  /**
@@ -251,7 +271,7 @@ export interface JoseHeaderParameters {
251
271
  jku?: string
252
272
 
253
273
  /** "jwk" (JSON Web Key) Header Parameter */
254
- jwk?: Pick<JWK, 'kty' | 'crv' | 'x' | 'y' | 'e' | 'n'>
274
+ jwk?: Pick<JWK, 'kty' | 'crv' | 'x' | 'y' | 'e' | 'n' | 'alg' | 'pub'>
255
275
 
256
276
  /** "typ" (Type) Header Parameter */
257
277
  typ?: string
@@ -30,6 +30,11 @@ export async function calculateJwkThumbprint(key, digestAlgorithm) {
30
30
  }
31
31
  let components;
32
32
  switch (jwk.kty) {
33
+ case 'AKP':
34
+ check(jwk.alg, '"alg" (Algorithm) Parameter');
35
+ check(jwk.pub, '"pub" (Public key) Parameter');
36
+ components = { alg: jwk.alg, kty: jwk.kty, pub: jwk.pub };
37
+ break;
33
38
  case 'EC':
34
39
  check(jwk.crv, '"crv" (Curve) Parameter');
35
40
  check(jwk.x, '"x" (X Coordinate) Parameter');
@@ -10,6 +10,8 @@ function getKtyFromAlg(alg) {
10
10
  return 'EC';
11
11
  case 'Ed':
12
12
  return 'OKP';
13
+ case 'ML':
14
+ return 'AKP';
13
15
  default:
14
16
  throw new JOSENotSupported('Unsupported "alg" value for a JSON Web Key Set');
15
17
  }
@@ -43,7 +45,7 @@ class LocalJWKSet {
43
45
  if (candidate && typeof kid === 'string') {
44
46
  candidate = kid === jwk.kid;
45
47
  }
46
- if (candidate && typeof jwk.alg === 'string') {
48
+ if (candidate && (typeof jwk.alg === 'string' || kty === 'AKP')) {
47
49
  candidate = alg === jwk.alg;
48
50
  }
49
51
  if (candidate && typeof jwk.use === 'string') {
@@ -9,7 +9,7 @@ function isCloudflareWorkers() {
9
9
  let USER_AGENT;
10
10
  if (typeof navigator === 'undefined' || !navigator.userAgent?.startsWith?.('Mozilla/5.0 ')) {
11
11
  const NAME = 'jose';
12
- const VERSION = 'v6.0.13';
12
+ const VERSION = 'v6.1.0';
13
13
  USER_AGENT = `${NAME}/${VERSION}`;
14
14
  }
15
15
  export const customFetch = Symbol();
@@ -62,6 +62,13 @@ export async function generateKeyPair(alg, options) {
62
62
  algorithm = { name: 'Ed25519' };
63
63
  break;
64
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
+ }
65
72
  case 'ECDH-ES':
66
73
  case 'ECDH-ES+A128KW':
67
74
  case 'ECDH-ES+A192KW':
@@ -38,6 +38,16 @@ export async function importJWK(jwk, alg, options) {
38
38
  if ('oth' in jwk && jwk.oth !== undefined) {
39
39
  throw new JOSENotSupported('RSA JWK "oth" (Other Primes Info) Parameter value is not supported');
40
40
  }
41
+ return toCryptoKey({ ...jwk, alg, ext });
42
+ case 'AKP': {
43
+ if (typeof jwk.alg !== 'string' || !jwk.alg) {
44
+ throw new TypeError('missing "alg" (Algorithm) Parameter value');
45
+ }
46
+ if (alg !== undefined && alg !== jwk.alg) {
47
+ throw new TypeError('JWK alg and alg option value mismatch');
48
+ }
49
+ return toCryptoKey({ ...jwk, ext });
50
+ }
41
51
  case 'EC':
42
52
  case 'OKP':
43
53
  return toCryptoKey({ ...jwk, alg, ext });
@@ -174,6 +174,12 @@ const genericImport = async (keyFormat, keyData, alg, options) => {
174
174
  algorithm = { name: 'Ed25519' };
175
175
  keyUsages = getSigUsages();
176
176
  break;
177
+ case 'ML-DSA-44':
178
+ case 'ML-DSA-65':
179
+ case 'ML-DSA-87':
180
+ algorithm = { name: alg };
181
+ keyUsages = getSigUsages();
182
+ break;
177
183
  default:
178
184
  throw new JOSENotSupported('Invalid or unsupported "alg" (Algorithm) value');
179
185
  }
@@ -65,6 +65,13 @@ export function checkSigCryptoKey(key, alg, usage) {
65
65
  throw unusable('Ed25519');
66
66
  break;
67
67
  }
68
+ case 'ML-DSA-44':
69
+ case 'ML-DSA-65':
70
+ case 'ML-DSA-87': {
71
+ if (!isAlgorithm(key.algorithm, alg))
72
+ throw unusable(alg);
73
+ break;
74
+ }
68
75
  case 'ES256':
69
76
  case 'ES384':
70
77
  case 'ES512': {
@@ -3,10 +3,11 @@ export function isJWK(key) {
3
3
  return isObject(key) && typeof key.kty === 'string';
4
4
  }
5
5
  export function isPrivateJWK(key) {
6
- return key.kty !== 'oct' && typeof key.d === 'string';
6
+ return (key.kty !== 'oct' &&
7
+ ((key.kty === 'AKP' && typeof key.priv === 'string') || typeof key.d === 'string'));
7
8
  }
8
9
  export function isPublicJWK(key) {
9
- return key.kty !== 'oct' && typeof key.d === 'undefined';
10
+ return key.kty !== 'oct' && typeof key.d === 'undefined' && typeof key.priv === 'undefined';
10
11
  }
11
12
  export function isSecretJWK(key) {
12
13
  return key.kty === 'oct' && typeof key.k === 'string';
@@ -3,6 +3,19 @@ function subtleMapping(jwk) {
3
3
  let algorithm;
4
4
  let keyUsages;
5
5
  switch (jwk.kty) {
6
+ case 'AKP': {
7
+ switch (jwk.alg) {
8
+ case 'ML-DSA-44':
9
+ case 'ML-DSA-65':
10
+ case 'ML-DSA-87':
11
+ algorithm = { name: jwk.alg };
12
+ keyUsages = jwk.priv ? ['sign'] : ['verify'];
13
+ break;
14
+ default:
15
+ throw new JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
16
+ }
17
+ break;
18
+ }
6
19
  case 'RSA': {
7
20
  switch (jwk.alg) {
8
21
  case 'PS256':
@@ -88,7 +101,9 @@ export default async (jwk) => {
88
101
  }
89
102
  const { algorithm, keyUsages } = subtleMapping(jwk);
90
103
  const keyData = { ...jwk };
91
- delete keyData.alg;
104
+ if (keyData.kty !== 'AKP') {
105
+ delete keyData.alg;
106
+ }
92
107
  delete keyData.use;
93
- return crypto.subtle.importKey('jwk', keyData, algorithm, jwk.ext ?? (jwk.d ? false : true), jwk.key_ops ?? keyUsages);
108
+ return crypto.subtle.importKey('jwk', keyData, algorithm, jwk.ext ?? (jwk.d || jwk.priv ? false : true), jwk.key_ops ?? keyUsages);
94
109
  };
@@ -23,5 +23,9 @@ export default async function keyToJWK(key) {
23
23
  throw new TypeError('non-extractable CryptoKey cannot be exported as a JWK');
24
24
  }
25
25
  const { ext, key_ops, alg, use, ...jwk } = await crypto.subtle.exportKey('jwk', key);
26
+ if (jwk.kty === 'AKP') {
27
+ ;
28
+ jwk.alg = alg;
29
+ }
26
30
  return jwk;
27
31
  }
@@ -49,6 +49,18 @@ const handleKeyObject = (keyObject, alg) => {
49
49
  isPublic ? 'verify' : 'sign',
50
50
  ]);
51
51
  }
52
+ switch (keyObject.asymmetricKeyType) {
53
+ case 'ml-dsa-44':
54
+ case 'ml-dsa-65':
55
+ case 'ml-dsa-87': {
56
+ if (alg !== keyObject.asymmetricKeyType.toUpperCase()) {
57
+ throw new TypeError('given KeyObject instance cannot be used for this algorithm');
58
+ }
59
+ cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, [
60
+ isPublic ? 'verify' : 'sign',
61
+ ]);
62
+ }
63
+ }
52
64
  if (keyObject.asymmetricKeyType === 'rsa') {
53
65
  let hash;
54
66
  switch (alg) {
@@ -21,6 +21,10 @@ export default (alg, algorithm) => {
21
21
  case 'Ed25519':
22
22
  case 'EdDSA':
23
23
  return { name: 'Ed25519' };
24
+ case 'ML-DSA-44':
25
+ case 'ML-DSA-65':
26
+ case 'ML-DSA-87':
27
+ return { name: alg };
24
28
  default:
25
29
  throw new JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`);
26
30
  }
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "jose",
3
- "version": "6.0.13",
3
+ "version": "6.1.0",
4
4
  "description": "JWA, JWS, JWE, JWT, JWK, JWKS for Node.js, Browser, Cloudflare Workers, Deno, Bun, and other Web-interoperable runtimes",
5
5
  "keywords": [
6
+ "akp",
6
7
  "browser",
7
8
  "bun",
8
9
  "cloudflare",
@@ -29,8 +30,9 @@
29
30
  "jwk",
30
31
  "jwks",
31
32
  "jws",
32
- "jwt",
33
33
  "jwt-decode",
34
+ "jwt",
35
+ "ml-dsa",
34
36
  "netlify",
35
37
  "next",
36
38
  "nextjs",