jose 5.9.6 → 6.0.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.
Files changed (291) hide show
  1. package/README.md +21 -19
  2. package/dist/types/index.d.ts +5 -5
  3. package/dist/types/jwe/compact/decrypt.d.ts +4 -4
  4. package/dist/types/jwe/compact/encrypt.d.ts +4 -4
  5. package/dist/types/jwe/flattened/decrypt.d.ts +4 -4
  6. package/dist/types/jwe/flattened/encrypt.d.ts +6 -6
  7. package/dist/types/jwe/general/decrypt.d.ts +4 -4
  8. package/dist/types/jwe/general/encrypt.d.ts +7 -7
  9. package/dist/types/jwk/embedded.d.ts +2 -2
  10. package/dist/types/jwk/thumbprint.d.ts +5 -5
  11. package/dist/types/jwks/local.d.ts +2 -2
  12. package/dist/types/jwks/remote.d.ts +104 -25
  13. package/dist/types/jws/compact/sign.d.ts +4 -4
  14. package/dist/types/jws/compact/verify.d.ts +4 -4
  15. package/dist/types/jws/flattened/sign.d.ts +4 -4
  16. package/dist/types/jws/flattened/verify.d.ts +4 -4
  17. package/dist/types/jws/general/sign.d.ts +6 -6
  18. package/dist/types/jws/general/verify.d.ts +4 -4
  19. package/dist/types/jwt/decrypt.d.ts +5 -5
  20. package/dist/types/jwt/encrypt.d.ts +4 -4
  21. package/dist/types/jwt/produce.d.ts +3 -3
  22. package/dist/types/jwt/sign.d.ts +3 -3
  23. package/dist/types/jwt/unsecured.d.ts +5 -5
  24. package/dist/types/jwt/verify.d.ts +5 -5
  25. package/dist/types/key/export.d.ts +10 -12
  26. package/dist/types/key/generate_key_pair.d.ts +10 -11
  27. package/dist/types/key/generate_secret.d.ts +6 -9
  28. package/dist/types/key/import.d.ts +20 -27
  29. package/dist/types/types.d.ts +38 -59
  30. package/dist/types/util/decode_jwt.d.ts +2 -2
  31. package/dist/types/util/decode_protected_header.d.ts +2 -2
  32. package/dist/types/util/errors.d.ts +6 -6
  33. package/dist/{browser → webapi}/index.js +2 -2
  34. package/dist/{node/esm → webapi}/jwe/flattened/decrypt.js +8 -4
  35. package/dist/{node/esm → webapi}/jwe/flattened/encrypt.js +7 -3
  36. package/dist/{node/esm → webapi}/jwe/general/encrypt.js +8 -3
  37. package/dist/{node/esm → webapi}/jwk/thumbprint.js +18 -8
  38. package/dist/{node/esm → webapi}/jwks/local.js +4 -6
  39. package/dist/{node/esm → webapi}/jwks/remote.js +34 -6
  40. package/dist/{node/esm → webapi}/jws/flattened/sign.js +7 -5
  41. package/dist/{browser → webapi}/jws/flattened/verify.js +8 -14
  42. package/dist/{browser → webapi}/jwt/unsecured.js +1 -1
  43. package/dist/{node/esm → webapi}/key/export.js +2 -3
  44. package/dist/{browser/runtime/generate.js → webapi/key/generate_key_pair.js} +5 -54
  45. package/dist/webapi/key/generate_secret.js +40 -0
  46. package/dist/{browser → webapi}/key/import.js +9 -7
  47. package/dist/{node/esm → webapi}/lib/aesgcmkw.js +3 -3
  48. package/dist/{browser/runtime → webapi/lib}/aeskw.js +9 -16
  49. package/dist/{browser/runtime → webapi/lib}/asn1.js +25 -17
  50. package/dist/{browser/runtime → webapi/lib}/base64url.js +17 -9
  51. package/dist/{browser → webapi}/lib/buffer_utils.js +4 -19
  52. package/dist/{browser → webapi}/lib/cek.js +1 -2
  53. package/dist/{browser/runtime → webapi/lib}/check_cek_length.js +1 -2
  54. package/dist/{browser → webapi}/lib/check_iv_length.js +1 -2
  55. package/dist/webapi/lib/check_key_type.js +126 -0
  56. package/dist/{node/esm → webapi}/lib/crypto_key.js +11 -23
  57. package/dist/{browser/runtime → webapi/lib}/decrypt.js +26 -10
  58. package/dist/{node/esm → webapi}/lib/decrypt_key_management.js +22 -24
  59. package/dist/{browser/runtime → webapi/lib}/digest.js +1 -3
  60. package/dist/webapi/lib/ecdhes.js +46 -0
  61. package/dist/{browser/runtime → webapi/lib}/encrypt.js +8 -10
  62. package/dist/{node/esm → webapi}/lib/encrypt_key_management.js +26 -23
  63. package/dist/webapi/lib/get_sign_verify_key.js +12 -0
  64. package/dist/{node/esm → webapi}/lib/is_disjoint.js +1 -2
  65. package/dist/{browser → webapi}/lib/is_jwk.js +1 -1
  66. package/dist/webapi/lib/is_key_like.js +14 -0
  67. package/dist/{browser → webapi}/lib/is_object.js +2 -2
  68. package/dist/{node/esm → webapi}/lib/iv.js +1 -2
  69. package/dist/{browser/runtime → webapi/lib}/jwk_to_key.js +4 -10
  70. package/dist/webapi/lib/key_to_jwk.js +27 -0
  71. package/dist/webapi/lib/normalize_key.js +164 -0
  72. package/dist/webapi/lib/pbes2kw.js +37 -0
  73. package/dist/webapi/lib/rsaes.js +24 -0
  74. package/dist/{browser/runtime → webapi/lib}/sign.js +1 -3
  75. package/dist/{browser/runtime → webapi/lib}/subtle_dsa.js +5 -4
  76. package/dist/{browser → webapi}/lib/validate_algorithms.js +1 -2
  77. package/dist/{node/esm → webapi}/lib/validate_crit.js +3 -4
  78. package/dist/{browser/runtime → webapi/lib}/verify.js +1 -3
  79. package/dist/{node/esm → webapi}/util/base64url.js +1 -1
  80. package/package.json +36 -219
  81. package/dist/browser/jwe/compact/encrypt.js +0 -26
  82. package/dist/browser/jwe/flattened/decrypt.js +0 -161
  83. package/dist/browser/jwe/flattened/encrypt.js +0 -153
  84. package/dist/browser/jwe/general/encrypt.js +0 -174
  85. package/dist/browser/jwk/thumbprint.js +0 -53
  86. package/dist/browser/jwks/local.js +0 -121
  87. package/dist/browser/jwks/remote.js +0 -139
  88. package/dist/browser/jws/compact/sign.js +0 -17
  89. package/dist/browser/jws/flattened/sign.js +0 -81
  90. package/dist/browser/jws/general/sign.js +0 -67
  91. package/dist/browser/jwt/encrypt.js +0 -68
  92. package/dist/browser/jwt/produce.js +0 -75
  93. package/dist/browser/jwt/sign.js +0 -20
  94. package/dist/browser/key/export.js +0 -12
  95. package/dist/browser/key/generate_key_pair.js +0 -4
  96. package/dist/browser/key/generate_secret.js +0 -4
  97. package/dist/browser/lib/aesgcmkw.js +0 -16
  98. package/dist/browser/lib/check_key_type.js +0 -77
  99. package/dist/browser/lib/check_p2s.js +0 -6
  100. package/dist/browser/lib/crypto_key.js +0 -152
  101. package/dist/browser/lib/decrypt_key_management.js +0 -129
  102. package/dist/browser/lib/encrypt_key_management.js +0 -89
  103. package/dist/browser/lib/format_pem.js +0 -4
  104. package/dist/browser/lib/is_disjoint.js +0 -22
  105. package/dist/browser/lib/iv.js +0 -20
  106. package/dist/browser/lib/validate_crit.js +0 -34
  107. package/dist/browser/package.json +0 -1
  108. package/dist/browser/runtime/bogus.js +0 -6
  109. package/dist/browser/runtime/ecdhes.js +0 -47
  110. package/dist/browser/runtime/fetch_jwks.js +0 -34
  111. package/dist/browser/runtime/get_sign_verify_key.js +0 -24
  112. package/dist/browser/runtime/is_key_like.js +0 -8
  113. package/dist/browser/runtime/key_to_jwk.js +0 -21
  114. package/dist/browser/runtime/normalize_key.js +0 -68
  115. package/dist/browser/runtime/pbes2kw.js +0 -51
  116. package/dist/browser/runtime/random.js +0 -2
  117. package/dist/browser/runtime/rsaes.js +0 -37
  118. package/dist/browser/runtime/runtime.js +0 -1
  119. package/dist/browser/runtime/subtle_rsaes.js +0 -12
  120. package/dist/browser/runtime/timing_safe_equal.js +0 -19
  121. package/dist/browser/runtime/webcrypto.js +0 -2
  122. package/dist/browser/util/base64url.js +0 -3
  123. package/dist/browser/util/errors.js +0 -114
  124. package/dist/browser/util/runtime.js +0 -2
  125. package/dist/node/cjs/index.js +0 -69
  126. package/dist/node/cjs/jwe/compact/decrypt.js +0 -30
  127. package/dist/node/cjs/jwe/compact/encrypt.js +0 -31
  128. package/dist/node/cjs/jwe/flattened/decrypt.js +0 -164
  129. package/dist/node/cjs/jwe/flattened/encrypt.js +0 -165
  130. package/dist/node/cjs/jwe/general/decrypt.js +0 -34
  131. package/dist/node/cjs/jwe/general/encrypt.js +0 -186
  132. package/dist/node/cjs/jwk/embedded.js +0 -20
  133. package/dist/node/cjs/jwk/thumbprint.js +0 -57
  134. package/dist/node/cjs/jwks/local.js +0 -125
  135. package/dist/node/cjs/jwks/remote.js +0 -152
  136. package/dist/node/cjs/jws/compact/sign.js +0 -22
  137. package/dist/node/cjs/jws/compact/verify.js +0 -24
  138. package/dist/node/cjs/jws/flattened/sign.js +0 -88
  139. package/dist/node/cjs/jws/flattened/verify.js +0 -125
  140. package/dist/node/cjs/jws/general/sign.js +0 -77
  141. package/dist/node/cjs/jws/general/verify.js +0 -27
  142. package/dist/node/cjs/jwt/decrypt.js +0 -26
  143. package/dist/node/cjs/jwt/encrypt.js +0 -79
  144. package/dist/node/cjs/jwt/produce.js +0 -80
  145. package/dist/node/cjs/jwt/sign.js +0 -25
  146. package/dist/node/cjs/jwt/unsecured.js +0 -36
  147. package/dist/node/cjs/jwt/verify.js +0 -18
  148. package/dist/node/cjs/key/export.js +0 -17
  149. package/dist/node/cjs/key/generate_key_pair.js +0 -7
  150. package/dist/node/cjs/key/generate_secret.js +0 -7
  151. package/dist/node/cjs/key/import.js +0 -51
  152. package/dist/node/cjs/lib/aesgcmkw.js +0 -20
  153. package/dist/node/cjs/lib/buffer_utils.js +0 -60
  154. package/dist/node/cjs/lib/cek.js +0 -23
  155. package/dist/node/cjs/lib/check_iv_length.js +0 -10
  156. package/dist/node/cjs/lib/check_key_type.js +0 -80
  157. package/dist/node/cjs/lib/check_p2s.js +0 -9
  158. package/dist/node/cjs/lib/crypto_key.js +0 -156
  159. package/dist/node/cjs/lib/decrypt_key_management.js +0 -131
  160. package/dist/node/cjs/lib/encrypt_key_management.js +0 -91
  161. package/dist/node/cjs/lib/epoch.js +0 -3
  162. package/dist/node/cjs/lib/invalid_key_input.js +0 -34
  163. package/dist/node/cjs/lib/is_disjoint.js +0 -24
  164. package/dist/node/cjs/lib/is_jwk.js +0 -19
  165. package/dist/node/cjs/lib/is_object.js +0 -19
  166. package/dist/node/cjs/lib/iv.js +0 -23
  167. package/dist/node/cjs/lib/jwt_claims_set.js +0 -106
  168. package/dist/node/cjs/lib/private_symbols.js +0 -4
  169. package/dist/node/cjs/lib/secs.js +0 -57
  170. package/dist/node/cjs/lib/validate_algorithms.js +0 -13
  171. package/dist/node/cjs/lib/validate_crit.js +0 -36
  172. package/dist/node/cjs/runtime/aeskw.js +0 -55
  173. package/dist/node/cjs/runtime/asn1.js +0 -54
  174. package/dist/node/cjs/runtime/base64url.js +0 -20
  175. package/dist/node/cjs/runtime/cbc_tag.js +0 -11
  176. package/dist/node/cjs/runtime/check_cek_length.js +0 -37
  177. package/dist/node/cjs/runtime/check_key_length.js +0 -18
  178. package/dist/node/cjs/runtime/ciphers.js +0 -8
  179. package/dist/node/cjs/runtime/decrypt.js +0 -103
  180. package/dist/node/cjs/runtime/digest.js +0 -5
  181. package/dist/node/cjs/runtime/dsa_digest.js +0 -25
  182. package/dist/node/cjs/runtime/ecdhes.js +0 -70
  183. package/dist/node/cjs/runtime/encrypt.js +0 -80
  184. package/dist/node/cjs/runtime/fetch_jwks.js +0 -45
  185. package/dist/node/cjs/runtime/generate.js +0 -101
  186. package/dist/node/cjs/runtime/get_named_curve.js +0 -61
  187. package/dist/node/cjs/runtime/get_sign_verify_key.js +0 -31
  188. package/dist/node/cjs/runtime/hmac_digest.js +0 -16
  189. package/dist/node/cjs/runtime/is_key_like.js +0 -11
  190. package/dist/node/cjs/runtime/is_key_object.js +0 -4
  191. package/dist/node/cjs/runtime/jwk_to_key.js +0 -10
  192. package/dist/node/cjs/runtime/key_to_jwk.js +0 -36
  193. package/dist/node/cjs/runtime/node_key.js +0 -106
  194. package/dist/node/cjs/runtime/normalize_key.js +0 -3
  195. package/dist/node/cjs/runtime/pbes2kw.js +0 -48
  196. package/dist/node/cjs/runtime/random.js +0 -5
  197. package/dist/node/cjs/runtime/rsaes.js +0 -71
  198. package/dist/node/cjs/runtime/runtime.js +0 -3
  199. package/dist/node/cjs/runtime/sign.js +0 -19
  200. package/dist/node/cjs/runtime/timing_safe_equal.js +0 -5
  201. package/dist/node/cjs/runtime/verify.js +0 -31
  202. package/dist/node/cjs/runtime/webcrypto.js +0 -9
  203. package/dist/node/cjs/util/base64url.js +0 -6
  204. package/dist/node/cjs/util/decode_jwt.js +0 -35
  205. package/dist/node/cjs/util/decode_protected_header.js +0 -37
  206. package/dist/node/cjs/util/errors.js +0 -117
  207. package/dist/node/cjs/util/runtime.js +0 -4
  208. package/dist/node/esm/index.js +0 -30
  209. package/dist/node/esm/jwe/compact/decrypt.js +0 -27
  210. package/dist/node/esm/jwe/general/decrypt.js +0 -31
  211. package/dist/node/esm/jwk/embedded.js +0 -17
  212. package/dist/node/esm/jws/compact/verify.js +0 -21
  213. package/dist/node/esm/jws/flattened/verify.js +0 -122
  214. package/dist/node/esm/jws/general/verify.js +0 -24
  215. package/dist/node/esm/jwt/decrypt.js +0 -23
  216. package/dist/node/esm/jwt/unsecured.js +0 -32
  217. package/dist/node/esm/jwt/verify.js +0 -15
  218. package/dist/node/esm/key/generate_key_pair.js +0 -4
  219. package/dist/node/esm/key/generate_secret.js +0 -4
  220. package/dist/node/esm/key/import.js +0 -45
  221. package/dist/node/esm/lib/buffer_utils.js +0 -51
  222. package/dist/node/esm/lib/cek.js +0 -20
  223. package/dist/node/esm/lib/check_iv_length.js +0 -8
  224. package/dist/node/esm/lib/check_key_type.js +0 -77
  225. package/dist/node/esm/lib/check_p2s.js +0 -6
  226. package/dist/node/esm/lib/epoch.js +0 -1
  227. package/dist/node/esm/lib/invalid_key_input.js +0 -31
  228. package/dist/node/esm/lib/is_jwk.js +0 -13
  229. package/dist/node/esm/lib/is_object.js +0 -16
  230. package/dist/node/esm/lib/jwt_claims_set.js +0 -104
  231. package/dist/node/esm/lib/private_symbols.js +0 -1
  232. package/dist/node/esm/lib/secs.js +0 -55
  233. package/dist/node/esm/lib/validate_algorithms.js +0 -11
  234. package/dist/node/esm/package.json +0 -1
  235. package/dist/node/esm/runtime/aeskw.js +0 -50
  236. package/dist/node/esm/runtime/asn1.js +0 -46
  237. package/dist/node/esm/runtime/base64url.js +0 -14
  238. package/dist/node/esm/runtime/cbc_tag.js +0 -8
  239. package/dist/node/esm/runtime/check_cek_length.js +0 -35
  240. package/dist/node/esm/runtime/check_key_length.js +0 -16
  241. package/dist/node/esm/runtime/ciphers.js +0 -6
  242. package/dist/node/esm/runtime/decrypt.js +0 -101
  243. package/dist/node/esm/runtime/digest.js +0 -3
  244. package/dist/node/esm/runtime/dsa_digest.js +0 -22
  245. package/dist/node/esm/runtime/ecdhes.js +0 -64
  246. package/dist/node/esm/runtime/encrypt.js +0 -78
  247. package/dist/node/esm/runtime/fetch_jwks.js +0 -43
  248. package/dist/node/esm/runtime/generate.js +0 -97
  249. package/dist/node/esm/runtime/get_named_curve.js +0 -58
  250. package/dist/node/esm/runtime/get_sign_verify_key.js +0 -28
  251. package/dist/node/esm/runtime/hmac_digest.js +0 -13
  252. package/dist/node/esm/runtime/is_key_like.js +0 -8
  253. package/dist/node/esm/runtime/is_key_object.js +0 -2
  254. package/dist/node/esm/runtime/jwk_to_key.js +0 -8
  255. package/dist/node/esm/runtime/key_to_jwk.js +0 -34
  256. package/dist/node/esm/runtime/node_key.js +0 -103
  257. package/dist/node/esm/runtime/normalize_key.js +0 -1
  258. package/dist/node/esm/runtime/pbes2kw.js +0 -43
  259. package/dist/node/esm/runtime/random.js +0 -1
  260. package/dist/node/esm/runtime/rsaes.js +0 -66
  261. package/dist/node/esm/runtime/runtime.js +0 -1
  262. package/dist/node/esm/runtime/sign.js +0 -17
  263. package/dist/node/esm/runtime/timing_safe_equal.js +0 -3
  264. package/dist/node/esm/runtime/verify.js +0 -29
  265. package/dist/node/esm/runtime/webcrypto.js +0 -5
  266. package/dist/node/esm/util/decode_jwt.js +0 -32
  267. package/dist/node/esm/util/decode_protected_header.js +0 -34
  268. package/dist/node/esm/util/runtime.js +0 -2
  269. package/dist/types/util/runtime.d.ts +0 -3
  270. /package/dist/{browser → webapi}/jwe/compact/decrypt.js +0 -0
  271. /package/dist/{node/esm → webapi}/jwe/compact/encrypt.js +0 -0
  272. /package/dist/{browser → webapi}/jwe/general/decrypt.js +0 -0
  273. /package/dist/{browser → webapi}/jwk/embedded.js +0 -0
  274. /package/dist/{node/esm → webapi}/jws/compact/sign.js +0 -0
  275. /package/dist/{browser → webapi}/jws/compact/verify.js +0 -0
  276. /package/dist/{node/esm → webapi}/jws/general/sign.js +0 -0
  277. /package/dist/{browser → webapi}/jws/general/verify.js +0 -0
  278. /package/dist/{browser → webapi}/jwt/decrypt.js +0 -0
  279. /package/dist/{node/esm → webapi}/jwt/encrypt.js +0 -0
  280. /package/dist/{node/esm → webapi}/jwt/produce.js +0 -0
  281. /package/dist/{node/esm → webapi}/jwt/sign.js +0 -0
  282. /package/dist/{browser → webapi}/jwt/verify.js +0 -0
  283. /package/dist/{browser/runtime → webapi/lib}/check_key_length.js +0 -0
  284. /package/dist/{browser → webapi}/lib/epoch.js +0 -0
  285. /package/dist/{browser → webapi}/lib/invalid_key_input.js +0 -0
  286. /package/dist/{browser → webapi}/lib/jwt_claims_set.js +0 -0
  287. /package/dist/{browser → webapi}/lib/private_symbols.js +0 -0
  288. /package/dist/{browser → webapi}/lib/secs.js +0 -0
  289. /package/dist/{browser → webapi}/util/decode_jwt.js +0 -0
  290. /package/dist/{browser → webapi}/util/decode_protected_header.js +0 -0
  291. /package/dist/{node/esm → webapi}/util/errors.js +0 -0
@@ -1,12 +1,20 @@
1
- import crypto, { isCryptoKey } from './webcrypto.js';
2
- import invalidKeyInput from '../lib/invalid_key_input.js';
1
+ import invalidKeyInput from './invalid_key_input.js';
3
2
  import { encodeBase64, decodeBase64 } from './base64url.js';
4
- import formatPEM from '../lib/format_pem.js';
5
3
  import { JOSENotSupported } from '../util/errors.js';
6
- import { types } from './is_key_like.js';
4
+ import { isCryptoKey, isKeyObject } from './is_key_like.js';
5
+ const formatPEM = (b64, descriptor) => {
6
+ const newlined = (b64.match(/.{1,64}/g) || []).join('\n');
7
+ return `-----BEGIN ${descriptor}-----\n${newlined}\n-----END ${descriptor}-----`;
8
+ };
7
9
  const genericExport = async (keyType, keyFormat, key) => {
10
+ if (isKeyObject(key)) {
11
+ if (key.type !== keyType) {
12
+ throw new TypeError(`key is not a ${keyType} key`);
13
+ }
14
+ return key.export({ format: 'pem', type: keyFormat });
15
+ }
8
16
  if (!isCryptoKey(key)) {
9
- throw new TypeError(invalidKeyInput(key, ...types));
17
+ throw new TypeError(invalidKeyInput(key, 'CryptoKey', 'KeyObject'));
10
18
  }
11
19
  if (!key.extractable) {
12
20
  throw new TypeError('CryptoKey is not extractable');
@@ -43,16 +51,8 @@ const getNamedCurve = (keyData) => {
43
51
  return 'P-384';
44
52
  case findOid(keyData, [0x2b, 0x81, 0x04, 0x00, 0x23]):
45
53
  return 'P-521';
46
- case findOid(keyData, [0x2b, 0x65, 0x6e]):
47
- return 'X25519';
48
- case findOid(keyData, [0x2b, 0x65, 0x6f]):
49
- return 'X448';
50
- case findOid(keyData, [0x2b, 0x65, 0x70]):
51
- return 'Ed25519';
52
- case findOid(keyData, [0x2b, 0x65, 0x71]):
53
- return 'Ed448';
54
54
  default:
55
- throw new JOSENotSupported('Invalid or unsupported EC Key Curve or OKP Key Sub Type');
55
+ return undefined;
56
56
  }
57
57
  };
58
58
  const genericImport = async (replace, keyFormat, pem, alg, options) => {
@@ -102,18 +102,19 @@ const genericImport = async (replace, keyFormat, pem, alg, options) => {
102
102
  case 'ECDH-ES+A192KW':
103
103
  case 'ECDH-ES+A256KW': {
104
104
  const namedCurve = getNamedCurve(keyData);
105
- algorithm = namedCurve.startsWith('P-') ? { name: 'ECDH', namedCurve } : { name: namedCurve };
105
+ algorithm = namedCurve?.startsWith('P-') ? { name: 'ECDH', namedCurve } : { name: 'X25519' };
106
106
  keyUsages = isPublic ? [] : ['deriveBits'];
107
107
  break;
108
108
  }
109
+ case 'Ed25519':
109
110
  case 'EdDSA':
110
- algorithm = { name: getNamedCurve(keyData) };
111
+ algorithm = { name: 'Ed25519' };
111
112
  keyUsages = isPublic ? ['verify'] : ['sign'];
112
113
  break;
113
114
  default:
114
115
  throw new JOSENotSupported('Invalid or unsupported "alg" (Algorithm) value');
115
116
  }
116
- return crypto.subtle.importKey(keyFormat, keyData, algorithm, options?.extractable ?? false, keyUsages);
117
+ return crypto.subtle.importKey(keyFormat, keyData, algorithm, options?.extractable ?? (isPublic ? true : false), keyUsages);
117
118
  };
118
119
  export const fromPKCS8 = (pem, alg, options) => {
119
120
  return genericImport(/(?:-----(?:BEGIN|END) PRIVATE KEY-----|\s)/g, 'pkcs8', pem, alg, options);
@@ -184,7 +185,14 @@ function spkiFromX509(buf) {
184
185
  const tbsCertificate = getElement(getElement(parseElement(buf).contents)[0].contents);
185
186
  return encodeBase64(tbsCertificate[tbsCertificate[0].raw[0] === 0xa0 ? 6 : 5].raw);
186
187
  }
188
+ let X509Certificate;
187
189
  function getSPKI(x509) {
190
+ if ((X509Certificate ||= globalThis.process?.getBuiltinModule?.('node:crypto')?.X509Certificate)) {
191
+ try {
192
+ return new X509Certificate(x509).publicKey.export({ format: 'pem', type: 'spki' });
193
+ }
194
+ catch { }
195
+ }
188
196
  const pem = x509.replace(/(?:-----(?:BEGIN|END) CERTIFICATE-----|\s)/g, '');
189
197
  const raw = decodeBase64(pem);
190
198
  return formatPEM(spkiFromX509(raw), 'PUBLIC KEY');
@@ -1,5 +1,7 @@
1
- import { encoder, decoder } from '../lib/buffer_utils.js';
2
- export const encodeBase64 = (input) => {
1
+ import { encoder, decoder, Buffer } from '../lib/buffer_utils.js';
2
+ export function encodeBase64(input) {
3
+ if (Buffer)
4
+ return Buffer.from(input).toString('base64');
3
5
  let unencoded = input;
4
6
  if (typeof unencoded === 'string') {
5
7
  unencoded = encoder.encode(unencoded);
@@ -10,23 +12,29 @@ export const encodeBase64 = (input) => {
10
12
  arr.push(String.fromCharCode.apply(null, unencoded.subarray(i, i + CHUNK_SIZE)));
11
13
  }
12
14
  return btoa(arr.join(''));
13
- };
14
- export const encode = (input) => {
15
+ }
16
+ export function encode(input) {
17
+ if (Buffer)
18
+ return Buffer.from(input).toString('base64url');
15
19
  return encodeBase64(input).replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
16
- };
17
- export const decodeBase64 = (encoded) => {
20
+ }
21
+ export function decodeBase64(encoded) {
22
+ if (Buffer)
23
+ return Buffer.from(encoded, 'base64');
18
24
  const binary = atob(encoded);
19
25
  const bytes = new Uint8Array(binary.length);
20
26
  for (let i = 0; i < binary.length; i++) {
21
27
  bytes[i] = binary.charCodeAt(i);
22
28
  }
23
29
  return bytes;
24
- };
25
- export const decode = (input) => {
30
+ }
31
+ export function decode(input) {
26
32
  let encoded = input;
27
33
  if (encoded instanceof Uint8Array) {
28
34
  encoded = decoder.decode(encoded);
29
35
  }
36
+ if (Buffer)
37
+ return Buffer.from(encoded, 'base64url');
30
38
  encoded = encoded.replace(/-/g, '+').replace(/_/g, '/').replace(/\s/g, '');
31
39
  try {
32
40
  return decodeBase64(encoded);
@@ -34,4 +42,4 @@ export const decode = (input) => {
34
42
  catch {
35
43
  throw new TypeError('The input to be decoded is not correctly encoded.');
36
44
  }
37
- };
45
+ }
@@ -1,8 +1,11 @@
1
- import digest from '../runtime/digest.js';
2
1
  export const encoder = new TextEncoder();
3
2
  export const decoder = new TextDecoder();
4
3
  const MAX_INT32 = 2 ** 32;
4
+ const Buffer = globalThis.process?.getBuiltinModule?.('node:buffer')?.Buffer;
5
+ export { Buffer };
5
6
  export function concat(...buffers) {
7
+ if (Buffer)
8
+ return Buffer.concat(buffers);
6
9
  const size = buffers.reduce((acc, { length }) => acc + length, 0);
7
10
  const buf = new Uint8Array(size);
8
11
  let i = 0;
@@ -12,9 +15,6 @@ export function concat(...buffers) {
12
15
  }
13
16
  return buf;
14
17
  }
15
- export function p2s(alg, p2sInput) {
16
- return concat(encoder.encode(alg), new Uint8Array([0]), p2sInput);
17
- }
18
18
  function writeUInt32BE(buf, value, offset) {
19
19
  if (value < 0 || value >= MAX_INT32) {
20
20
  throw new RangeError(`value must be >= 0 and <= ${MAX_INT32 - 1}. Received ${value}`);
@@ -34,18 +34,3 @@ export function uint32be(value) {
34
34
  writeUInt32BE(buf, value);
35
35
  return buf;
36
36
  }
37
- export function lengthAndInput(input) {
38
- return concat(uint32be(input.length), input);
39
- }
40
- export async function concatKdf(secret, bits, value) {
41
- const iterations = Math.ceil((bits >> 3) / 32);
42
- const res = new Uint8Array(iterations * 32);
43
- for (let iter = 0; iter < iterations; iter++) {
44
- const buf = new Uint8Array(4 + secret.length + value.length);
45
- buf.set(uint32be(iter + 1));
46
- buf.set(secret, 4);
47
- buf.set(value, 4 + secret.length);
48
- res.set(await digest('sha256', buf), iter * 32);
49
- }
50
- return res.slice(0, bits >> 3);
51
- }
@@ -1,5 +1,4 @@
1
1
  import { JOSENotSupported } from '../util/errors.js';
2
- import random from '../runtime/random.js';
3
2
  export function bitLength(alg) {
4
3
  switch (alg) {
5
4
  case 'A128GCM':
@@ -17,4 +16,4 @@ export function bitLength(alg) {
17
16
  throw new JOSENotSupported(`Unsupported JWE Algorithm: ${alg}`);
18
17
  }
19
18
  }
20
- export default (alg) => random(new Uint8Array(bitLength(alg) >> 3));
19
+ export default (alg) => crypto.getRandomValues(new Uint8Array(bitLength(alg) >> 3));
@@ -1,8 +1,7 @@
1
1
  import { JWEInvalid } from '../util/errors.js';
2
- const checkCekLength = (cek, expected) => {
2
+ export default (cek, expected) => {
3
3
  const actual = cek.byteLength << 3;
4
4
  if (actual !== expected) {
5
5
  throw new JWEInvalid(`Invalid Content Encryption Key length. Expected ${expected} bits, got ${actual} bits`);
6
6
  }
7
7
  };
8
- export default checkCekLength;
@@ -1,8 +1,7 @@
1
1
  import { JWEInvalid } from '../util/errors.js';
2
2
  import { bitLength } from './iv.js';
3
- const checkIvLength = (enc, iv) => {
3
+ export default (enc, iv) => {
4
4
  if (iv.length << 3 !== bitLength(enc)) {
5
5
  throw new JWEInvalid('Invalid Initialization Vector length');
6
6
  }
7
7
  };
8
- export default checkIvLength;
@@ -0,0 +1,126 @@
1
+ import { withAlg as invalidKeyInput } from './invalid_key_input.js';
2
+ import isKeyLike from './is_key_like.js';
3
+ import * as jwk from './is_jwk.js';
4
+ const tag = (key) => key?.[Symbol.toStringTag];
5
+ const jwkMatchesOp = (alg, key, usage) => {
6
+ if (key.use !== undefined) {
7
+ let expected;
8
+ switch (usage) {
9
+ case 'sign':
10
+ case 'verify':
11
+ expected = 'sig';
12
+ break;
13
+ case 'encrypt':
14
+ case 'decrypt':
15
+ expected = 'enc';
16
+ break;
17
+ }
18
+ if (key.use !== expected) {
19
+ throw new TypeError(`Invalid key for this operation, its "use" must be "${expected}" when present`);
20
+ }
21
+ }
22
+ if (key.alg !== undefined && key.alg !== alg) {
23
+ throw new TypeError(`Invalid key for this operation, its "alg" must be "${alg}" when present`);
24
+ }
25
+ if (Array.isArray(key.key_ops)) {
26
+ let expectedKeyOp;
27
+ switch (true) {
28
+ case usage === 'sign' || usage === 'verify':
29
+ case alg === 'dir':
30
+ case alg.includes('CBC-HS'):
31
+ expectedKeyOp = usage;
32
+ break;
33
+ case alg.startsWith('PBES2'):
34
+ expectedKeyOp = 'deriveBits';
35
+ break;
36
+ case /^A\d{3}(?:GCM)?(?:KW)?$/.test(alg):
37
+ if (!alg.includes('GCM') && alg.endsWith('KW')) {
38
+ expectedKeyOp = usage === 'encrypt' ? 'wrapKey' : 'unwrapKey';
39
+ }
40
+ else {
41
+ expectedKeyOp = usage;
42
+ }
43
+ break;
44
+ case usage === 'encrypt' && alg.startsWith('RSA'):
45
+ expectedKeyOp = 'wrapKey';
46
+ break;
47
+ case usage === 'decrypt':
48
+ expectedKeyOp = alg.startsWith('RSA') ? 'unwrapKey' : 'deriveBits';
49
+ break;
50
+ }
51
+ if (expectedKeyOp && key.key_ops?.includes?.(expectedKeyOp) === false) {
52
+ throw new TypeError(`Invalid key for this operation, its "key_ops" must include "${expectedKeyOp}" when present`);
53
+ }
54
+ }
55
+ return true;
56
+ };
57
+ const symmetricTypeCheck = (alg, key, usage) => {
58
+ if (key instanceof Uint8Array)
59
+ return;
60
+ if (jwk.isJWK(key)) {
61
+ if (jwk.isSecretJWK(key) && jwkMatchesOp(alg, key, usage))
62
+ return;
63
+ throw new TypeError(`JSON Web Key for symmetric algorithms must have JWK "kty" (Key Type) equal to "oct" and the JWK "k" (Key Value) present`);
64
+ }
65
+ if (!isKeyLike(key)) {
66
+ throw new TypeError(invalidKeyInput(alg, key, 'CryptoKey', 'KeyObject', 'JSON Web Key', 'Uint8Array'));
67
+ }
68
+ if (key.type !== 'secret') {
69
+ throw new TypeError(`${tag(key)} instances for symmetric algorithms must be of type "secret"`);
70
+ }
71
+ };
72
+ const asymmetricTypeCheck = (alg, key, usage) => {
73
+ if (jwk.isJWK(key)) {
74
+ switch (usage) {
75
+ case 'decrypt':
76
+ case 'sign':
77
+ if (jwk.isPrivateJWK(key) && jwkMatchesOp(alg, key, usage))
78
+ return;
79
+ throw new TypeError(`JSON Web Key for this operation be a private JWK`);
80
+ case 'encrypt':
81
+ case 'verify':
82
+ if (jwk.isPublicJWK(key) && jwkMatchesOp(alg, key, usage))
83
+ return;
84
+ throw new TypeError(`JSON Web Key for this operation be a public JWK`);
85
+ }
86
+ }
87
+ if (!isKeyLike(key)) {
88
+ throw new TypeError(invalidKeyInput(alg, key, 'CryptoKey', 'KeyObject', 'JSON Web Key'));
89
+ }
90
+ if (key.type === 'secret') {
91
+ throw new TypeError(`${tag(key)} instances for asymmetric algorithms must not be of type "secret"`);
92
+ }
93
+ if (key.type === 'public') {
94
+ switch (usage) {
95
+ case 'sign':
96
+ throw new TypeError(`${tag(key)} instances for asymmetric algorithm signing must be of type "private"`);
97
+ case 'decrypt':
98
+ throw new TypeError(`${tag(key)} instances for asymmetric algorithm decryption must be of type "private"`);
99
+ default:
100
+ break;
101
+ }
102
+ }
103
+ if (key.type === 'private') {
104
+ switch (usage) {
105
+ case 'verify':
106
+ throw new TypeError(`${tag(key)} instances for asymmetric algorithm verifying must be of type "public"`);
107
+ case 'encrypt':
108
+ throw new TypeError(`${tag(key)} instances for asymmetric algorithm encryption must be of type "public"`);
109
+ default:
110
+ break;
111
+ }
112
+ }
113
+ };
114
+ export default (alg, key, usage) => {
115
+ const symmetric = alg.startsWith('HS') ||
116
+ alg === 'dir' ||
117
+ alg.startsWith('PBES2') ||
118
+ /^A(?:128|192|256)(?:GCM)?(?:KW)?$/.test(alg) ||
119
+ /^A(?:128|192|256)CBC-HS(?:256|384|512)$/.test(alg);
120
+ if (symmetric) {
121
+ symmetricTypeCheck(alg, key, usage);
122
+ }
123
+ else {
124
+ asymmetricTypeCheck(alg, key, usage);
125
+ }
126
+ };
@@ -19,23 +19,12 @@ function getNamedCurve(alg) {
19
19
  throw new Error('unreachable');
20
20
  }
21
21
  }
22
- function checkUsage(key, usages) {
23
- if (usages.length && !usages.some((expected) => key.usages.includes(expected))) {
24
- let msg = 'CryptoKey does not support this operation, its usages must include ';
25
- if (usages.length > 2) {
26
- const last = usages.pop();
27
- msg += `one of ${usages.join(', ')}, or ${last}.`;
28
- }
29
- else if (usages.length === 2) {
30
- msg += `one of ${usages[0]} or ${usages[1]}.`;
31
- }
32
- else {
33
- msg += `${usages[0]}.`;
34
- }
35
- throw new TypeError(msg);
22
+ function checkUsage(key, usage) {
23
+ if (usage && !key.usages.includes(usage)) {
24
+ throw new TypeError(`CryptoKey does not support this operation, its usages must include ${usage}.`);
36
25
  }
37
26
  }
38
- export function checkSigCryptoKey(key, alg, ...usages) {
27
+ export function checkSigCryptoKey(key, alg, usage) {
39
28
  switch (alg) {
40
29
  case 'HS256':
41
30
  case 'HS384':
@@ -70,10 +59,10 @@ export function checkSigCryptoKey(key, alg, ...usages) {
70
59
  throw unusable(`SHA-${expected}`, 'algorithm.hash');
71
60
  break;
72
61
  }
62
+ case 'Ed25519':
73
63
  case 'EdDSA': {
74
- if (key.algorithm.name !== 'Ed25519' && key.algorithm.name !== 'Ed448') {
75
- throw unusable('Ed25519 or Ed448');
76
- }
64
+ if (!isAlgorithm(key.algorithm, 'Ed25519'))
65
+ throw unusable('Ed25519');
77
66
  break;
78
67
  }
79
68
  case 'ES256':
@@ -90,9 +79,9 @@ export function checkSigCryptoKey(key, alg, ...usages) {
90
79
  default:
91
80
  throw new TypeError('CryptoKey does not support this operation');
92
81
  }
93
- checkUsage(key, usages);
82
+ checkUsage(key, usage);
94
83
  }
95
- export function checkEncCryptoKey(key, alg, ...usages) {
84
+ export function checkEncCryptoKey(key, alg, usage) {
96
85
  switch (alg) {
97
86
  case 'A128GCM':
98
87
  case 'A192GCM':
@@ -120,10 +109,9 @@ export function checkEncCryptoKey(key, alg, ...usages) {
120
109
  switch (key.algorithm.name) {
121
110
  case 'ECDH':
122
111
  case 'X25519':
123
- case 'X448':
124
112
  break;
125
113
  default:
126
- throw unusable('ECDH, X25519, or X448');
114
+ throw unusable('ECDH or X25519');
127
115
  }
128
116
  break;
129
117
  }
@@ -148,5 +136,5 @@ export function checkEncCryptoKey(key, alg, ...usages) {
148
136
  default:
149
137
  throw new TypeError('CryptoKey does not support this operation');
150
138
  }
151
- checkUsage(key, usages);
139
+ checkUsage(key, usage);
152
140
  }
@@ -1,12 +1,29 @@
1
- import { concat, uint64be } from '../lib/buffer_utils.js';
2
- import checkIvLength from '../lib/check_iv_length.js';
1
+ import { concat, uint64be } from './buffer_utils.js';
2
+ import checkIvLength from './check_iv_length.js';
3
3
  import checkCekLength from './check_cek_length.js';
4
- import timingSafeEqual from './timing_safe_equal.js';
5
4
  import { JOSENotSupported, JWEDecryptionFailed, JWEInvalid } from '../util/errors.js';
6
- import crypto, { isCryptoKey } from './webcrypto.js';
7
- import { checkEncCryptoKey } from '../lib/crypto_key.js';
8
- import invalidKeyInput from '../lib/invalid_key_input.js';
9
- import { types } from './is_key_like.js';
5
+ import { checkEncCryptoKey } from './crypto_key.js';
6
+ import invalidKeyInput from './invalid_key_input.js';
7
+ import { isCryptoKey } from './is_key_like.js';
8
+ let timingSafeEqual = globalThis.process?.getBuiltinModule?.('node:crypto')?.timingSafeEqual;
9
+ timingSafeEqual ||= (a, b) => {
10
+ if (!(a instanceof Uint8Array)) {
11
+ throw new TypeError('First argument must be a buffer');
12
+ }
13
+ if (!(b instanceof Uint8Array)) {
14
+ throw new TypeError('Second argument must be a buffer');
15
+ }
16
+ if (a.length !== b.length) {
17
+ throw new TypeError('Input buffers must have the same length');
18
+ }
19
+ const len = a.length;
20
+ let out = 0;
21
+ let i = -1;
22
+ while (++i < len) {
23
+ out |= a[i] ^ b[i];
24
+ }
25
+ return out === 0;
26
+ };
10
27
  async function cbcDecrypt(enc, cek, ciphertext, iv, tag, aad) {
11
28
  if (!(cek instanceof Uint8Array)) {
12
29
  throw new TypeError(invalidKeyInput(cek, 'Uint8Array'));
@@ -60,9 +77,9 @@ async function gcmDecrypt(enc, cek, ciphertext, iv, tag, aad) {
60
77
  throw new JWEDecryptionFailed();
61
78
  }
62
79
  }
63
- const decrypt = async (enc, cek, ciphertext, iv, tag, aad) => {
80
+ export default async (enc, cek, ciphertext, iv, tag, aad) => {
64
81
  if (!isCryptoKey(cek) && !(cek instanceof Uint8Array)) {
65
- throw new TypeError(invalidKeyInput(cek, ...types, 'Uint8Array'));
82
+ throw new TypeError(invalidKeyInput(cek, 'CryptoKey', 'KeyObject', 'Uint8Array', 'JSON Web Key'));
66
83
  }
67
84
  if (!iv) {
68
85
  throw new JWEInvalid('JWE Initialization Vector missing');
@@ -88,4 +105,3 @@ const decrypt = async (enc, cek, ciphertext, iv, tag, aad) => {
88
105
  throw new JOSENotSupported('Unsupported JWE Content Encryption Algorithm');
89
106
  }
90
107
  };
91
- export default decrypt;
@@ -1,18 +1,15 @@
1
- import { unwrap as aesKw } from '../runtime/aeskw.js';
2
- import * as ECDH from '../runtime/ecdhes.js';
3
- import { decrypt as pbes2Kw } from '../runtime/pbes2kw.js';
4
- import { decrypt as rsaEs } from '../runtime/rsaes.js';
5
- import { decode as base64url } from '../runtime/base64url.js';
6
- import normalize from '../runtime/normalize_key.js';
1
+ import * as aeskw from './aeskw.js';
2
+ import * as ecdhes from './ecdhes.js';
3
+ import * as pbes2kw from './pbes2kw.js';
4
+ import * as rsaes from './rsaes.js';
5
+ import * as base64url from '../lib/base64url.js';
7
6
  import { JOSENotSupported, JWEInvalid } from '../util/errors.js';
8
7
  import { bitLength as cekLength } from '../lib/cek.js';
9
8
  import { importJWK } from '../key/import.js';
10
- import checkKeyType from './check_key_type.js';
11
9
  import isObject from './is_object.js';
12
10
  import { unwrap as aesGcmKw } from './aesgcmkw.js';
13
- async function decryptKeyManagement(alg, key, encryptedKey, joseHeader, options) {
14
- checkKeyType(alg, key, 'decrypt');
15
- key = (await normalize.normalizePrivateKey?.(key, alg)) || key;
11
+ import { assertCryptoKey } from './is_key_like.js';
12
+ export default async (alg, key, encryptedKey, joseHeader, options) => {
16
13
  switch (alg) {
17
14
  case 'dir': {
18
15
  if (encryptedKey !== undefined)
@@ -27,16 +24,18 @@ async function decryptKeyManagement(alg, key, encryptedKey, joseHeader, options)
27
24
  case 'ECDH-ES+A256KW': {
28
25
  if (!isObject(joseHeader.epk))
29
26
  throw new JWEInvalid(`JOSE Header "epk" (Ephemeral Public Key) missing or invalid`);
30
- if (!ECDH.ecdhAllowed(key))
27
+ assertCryptoKey(key);
28
+ if (!ecdhes.allowed(key))
31
29
  throw new JOSENotSupported('ECDH with the provided key is not allowed or not supported by your javascript runtime');
32
30
  const epk = await importJWK(joseHeader.epk, alg);
31
+ assertCryptoKey(epk);
33
32
  let partyUInfo;
34
33
  let partyVInfo;
35
34
  if (joseHeader.apu !== undefined) {
36
35
  if (typeof joseHeader.apu !== 'string')
37
36
  throw new JWEInvalid(`JOSE Header "apu" (Agreement PartyUInfo) invalid`);
38
37
  try {
39
- partyUInfo = base64url(joseHeader.apu);
38
+ partyUInfo = base64url.decode(joseHeader.apu);
40
39
  }
41
40
  catch {
42
41
  throw new JWEInvalid('Failed to base64url decode the apu');
@@ -46,27 +45,27 @@ async function decryptKeyManagement(alg, key, encryptedKey, joseHeader, options)
46
45
  if (typeof joseHeader.apv !== 'string')
47
46
  throw new JWEInvalid(`JOSE Header "apv" (Agreement PartyVInfo) invalid`);
48
47
  try {
49
- partyVInfo = base64url(joseHeader.apv);
48
+ partyVInfo = base64url.decode(joseHeader.apv);
50
49
  }
51
50
  catch {
52
51
  throw new JWEInvalid('Failed to base64url decode the apv');
53
52
  }
54
53
  }
55
- const sharedSecret = await ECDH.deriveKey(epk, key, alg === 'ECDH-ES' ? joseHeader.enc : alg, alg === 'ECDH-ES' ? cekLength(joseHeader.enc) : parseInt(alg.slice(-5, -2), 10), partyUInfo, partyVInfo);
54
+ const sharedSecret = await ecdhes.deriveKey(epk, key, alg === 'ECDH-ES' ? joseHeader.enc : alg, alg === 'ECDH-ES' ? cekLength(joseHeader.enc) : parseInt(alg.slice(-5, -2), 10), partyUInfo, partyVInfo);
56
55
  if (alg === 'ECDH-ES')
57
56
  return sharedSecret;
58
57
  if (encryptedKey === undefined)
59
58
  throw new JWEInvalid('JWE Encrypted Key missing');
60
- return aesKw(alg.slice(-6), sharedSecret, encryptedKey);
59
+ return aeskw.unwrap(alg.slice(-6), sharedSecret, encryptedKey);
61
60
  }
62
- case 'RSA1_5':
63
61
  case 'RSA-OAEP':
64
62
  case 'RSA-OAEP-256':
65
63
  case 'RSA-OAEP-384':
66
64
  case 'RSA-OAEP-512': {
67
65
  if (encryptedKey === undefined)
68
66
  throw new JWEInvalid('JWE Encrypted Key missing');
69
- return rsaEs(alg, key, encryptedKey);
67
+ assertCryptoKey(key);
68
+ return rsaes.decrypt(alg, key, encryptedKey);
70
69
  }
71
70
  case 'PBES2-HS256+A128KW':
72
71
  case 'PBES2-HS384+A192KW':
@@ -82,19 +81,19 @@ async function decryptKeyManagement(alg, key, encryptedKey, joseHeader, options)
82
81
  throw new JWEInvalid(`JOSE Header "p2s" (PBES2 Salt) missing or invalid`);
83
82
  let p2s;
84
83
  try {
85
- p2s = base64url(joseHeader.p2s);
84
+ p2s = base64url.decode(joseHeader.p2s);
86
85
  }
87
86
  catch {
88
87
  throw new JWEInvalid('Failed to base64url decode the p2s');
89
88
  }
90
- return pbes2Kw(alg, key, encryptedKey, joseHeader.p2c, p2s);
89
+ return pbes2kw.unwrap(alg, key, encryptedKey, joseHeader.p2c, p2s);
91
90
  }
92
91
  case 'A128KW':
93
92
  case 'A192KW':
94
93
  case 'A256KW': {
95
94
  if (encryptedKey === undefined)
96
95
  throw new JWEInvalid('JWE Encrypted Key missing');
97
- return aesKw(alg, key, encryptedKey);
96
+ return aeskw.unwrap(alg, key, encryptedKey);
98
97
  }
99
98
  case 'A128GCMKW':
100
99
  case 'A192GCMKW':
@@ -107,14 +106,14 @@ async function decryptKeyManagement(alg, key, encryptedKey, joseHeader, options)
107
106
  throw new JWEInvalid(`JOSE Header "tag" (Authentication Tag) missing or invalid`);
108
107
  let iv;
109
108
  try {
110
- iv = base64url(joseHeader.iv);
109
+ iv = base64url.decode(joseHeader.iv);
111
110
  }
112
111
  catch {
113
112
  throw new JWEInvalid('Failed to base64url decode the iv');
114
113
  }
115
114
  let tag;
116
115
  try {
117
- tag = base64url(joseHeader.tag);
116
+ tag = base64url.decode(joseHeader.tag);
118
117
  }
119
118
  catch {
120
119
  throw new JWEInvalid('Failed to base64url decode the tag');
@@ -125,5 +124,4 @@ async function decryptKeyManagement(alg, key, encryptedKey, joseHeader, options)
125
124
  throw new JOSENotSupported('Invalid or unsupported "alg" (JWE Algorithm) header value');
126
125
  }
127
126
  }
128
- }
129
- export default decryptKeyManagement;
127
+ };
@@ -1,6 +1,4 @@
1
- import crypto from './webcrypto.js';
2
- const digest = async (algorithm, data) => {
1
+ export default async (algorithm, data) => {
3
2
  const subtleDigest = `SHA-${algorithm.slice(-3)}`;
4
3
  return new Uint8Array(await crypto.subtle.digest(subtleDigest, data));
5
4
  };
6
- export default digest;
@@ -0,0 +1,46 @@
1
+ import { encoder, concat, uint32be } from './buffer_utils.js';
2
+ import { checkEncCryptoKey } from './crypto_key.js';
3
+ import digest from './digest.js';
4
+ function lengthAndInput(input) {
5
+ return concat(uint32be(input.length), input);
6
+ }
7
+ async function concatKdf(secret, bits, value) {
8
+ const iterations = Math.ceil((bits >> 3) / 32);
9
+ const res = new Uint8Array(iterations * 32);
10
+ for (let iter = 0; iter < iterations; iter++) {
11
+ const buf = new Uint8Array(4 + secret.length + value.length);
12
+ buf.set(uint32be(iter + 1));
13
+ buf.set(secret, 4);
14
+ buf.set(value, 4 + secret.length);
15
+ res.set(await digest('sha256', buf), iter * 32);
16
+ }
17
+ return res.slice(0, bits >> 3);
18
+ }
19
+ export async function deriveKey(publicKey, privateKey, algorithm, keyLength, apu = new Uint8Array(0), apv = new Uint8Array(0)) {
20
+ checkEncCryptoKey(publicKey, 'ECDH');
21
+ checkEncCryptoKey(privateKey, 'ECDH', 'deriveBits');
22
+ const value = concat(lengthAndInput(encoder.encode(algorithm)), lengthAndInput(apu), lengthAndInput(apv), uint32be(keyLength));
23
+ let length;
24
+ if (publicKey.algorithm.name === 'X25519') {
25
+ length = 256;
26
+ }
27
+ else {
28
+ length =
29
+ Math.ceil(parseInt(publicKey.algorithm.namedCurve.slice(-3), 10) / 8) << 3;
30
+ }
31
+ const sharedSecret = new Uint8Array(await crypto.subtle.deriveBits({
32
+ name: publicKey.algorithm.name,
33
+ public: publicKey,
34
+ }, privateKey, length));
35
+ return concatKdf(sharedSecret, keyLength, value);
36
+ }
37
+ export function allowed(key) {
38
+ switch (key.algorithm.namedCurve) {
39
+ case 'P-256':
40
+ case 'P-384':
41
+ case 'P-521':
42
+ return true;
43
+ default:
44
+ return key.algorithm.name === 'X25519';
45
+ }
46
+ }