@atcute/oauth-crypto 0.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.
Files changed (118) hide show
  1. package/LICENSE +14 -0
  2. package/README.md +7 -0
  3. package/dist/client-assertion/create-client-assertion.d.ts +19 -0
  4. package/dist/client-assertion/create-client-assertion.d.ts.map +1 -0
  5. package/dist/client-assertion/create-client-assertion.js +34 -0
  6. package/dist/client-assertion/create-client-assertion.js.map +1 -0
  7. package/dist/client-assertion/generate-key.d.ts +11 -0
  8. package/dist/client-assertion/generate-key.d.ts.map +1 -0
  9. package/dist/client-assertion/generate-key.js +18 -0
  10. package/dist/client-assertion/generate-key.js.map +1 -0
  11. package/dist/client-assertion/index.d.ts +5 -0
  12. package/dist/client-assertion/index.d.ts.map +1 -0
  13. package/dist/client-assertion/index.js +4 -0
  14. package/dist/client-assertion/index.js.map +1 -0
  15. package/dist/client-assertion/keys.d.ts +14 -0
  16. package/dist/client-assertion/keys.d.ts.map +1 -0
  17. package/dist/client-assertion/keys.js +18 -0
  18. package/dist/client-assertion/keys.js.map +1 -0
  19. package/dist/client-assertion/types.d.ts +9 -0
  20. package/dist/client-assertion/types.d.ts.map +1 -0
  21. package/dist/client-assertion/types.js +2 -0
  22. package/dist/client-assertion/types.js.map +1 -0
  23. package/dist/dpop/fetch.d.ts +24 -0
  24. package/dist/dpop/fetch.d.ts.map +1 -0
  25. package/dist/dpop/fetch.js +102 -0
  26. package/dist/dpop/fetch.js.map +1 -0
  27. package/dist/dpop/generate-key.d.ts +9 -0
  28. package/dist/dpop/generate-key.d.ts.map +1 -0
  29. package/dist/dpop/generate-key.js +61 -0
  30. package/dist/dpop/generate-key.js.map +1 -0
  31. package/dist/dpop/index.d.ts +6 -0
  32. package/dist/dpop/index.d.ts.map +1 -0
  33. package/dist/dpop/index.js +5 -0
  34. package/dist/dpop/index.js.map +1 -0
  35. package/dist/dpop/proof.d.ts +9 -0
  36. package/dist/dpop/proof.d.ts.map +1 -0
  37. package/dist/dpop/proof.js +36 -0
  38. package/dist/dpop/proof.js.map +1 -0
  39. package/dist/dpop/types.d.ts +17 -0
  40. package/dist/dpop/types.d.ts.map +1 -0
  41. package/dist/dpop/types.js +2 -0
  42. package/dist/dpop/types.js.map +1 -0
  43. package/dist/dpop/verify.d.ts +42 -0
  44. package/dist/dpop/verify.d.ts.map +1 -0
  45. package/dist/dpop/verify.js +124 -0
  46. package/dist/dpop/verify.js.map +1 -0
  47. package/dist/hash/index.d.ts +3 -0
  48. package/dist/hash/index.d.ts.map +1 -0
  49. package/dist/hash/index.js +3 -0
  50. package/dist/hash/index.js.map +1 -0
  51. package/dist/hash/pkce.d.ts +12 -0
  52. package/dist/hash/pkce.d.ts.map +1 -0
  53. package/dist/hash/pkce.js +14 -0
  54. package/dist/hash/pkce.js.map +1 -0
  55. package/dist/hash/sha256.d.ts +8 -0
  56. package/dist/hash/sha256.d.ts.map +1 -0
  57. package/dist/hash/sha256.js +14 -0
  58. package/dist/hash/sha256.js.map +1 -0
  59. package/dist/index.d.ts +6 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +6 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/internal/crypto.d.ts +7 -0
  64. package/dist/internal/crypto.d.ts.map +1 -0
  65. package/dist/internal/crypto.js +78 -0
  66. package/dist/internal/crypto.js.map +1 -0
  67. package/dist/internal/jwk.d.ts +10 -0
  68. package/dist/internal/jwk.d.ts.map +1 -0
  69. package/dist/internal/jwk.js +121 -0
  70. package/dist/internal/jwk.js.map +1 -0
  71. package/dist/internal/key-cache.d.ts +24 -0
  72. package/dist/internal/key-cache.d.ts.map +1 -0
  73. package/dist/internal/key-cache.js +36 -0
  74. package/dist/internal/key-cache.js.map +1 -0
  75. package/dist/jwk/compute-jkt.d.ts +9 -0
  76. package/dist/jwk/compute-jkt.d.ts.map +1 -0
  77. package/dist/jwk/compute-jkt.js +23 -0
  78. package/dist/jwk/compute-jkt.js.map +1 -0
  79. package/dist/jwk/index.d.ts +5 -0
  80. package/dist/jwk/index.d.ts.map +1 -0
  81. package/dist/jwk/index.js +4 -0
  82. package/dist/jwk/index.js.map +1 -0
  83. package/dist/jwk/keys.d.ts +9 -0
  84. package/dist/jwk/keys.d.ts.map +1 -0
  85. package/dist/jwk/keys.js +13 -0
  86. package/dist/jwk/keys.js.map +1 -0
  87. package/dist/jwk/types.d.ts +37 -0
  88. package/dist/jwk/types.d.ts.map +1 -0
  89. package/dist/jwk/types.js +2 -0
  90. package/dist/jwk/types.js.map +1 -0
  91. package/dist/jwt/index.d.ts +26 -0
  92. package/dist/jwt/index.d.ts.map +1 -0
  93. package/dist/jwt/index.js +56 -0
  94. package/dist/jwt/index.js.map +1 -0
  95. package/lib/client-assertion/create-client-assertion.ts +50 -0
  96. package/lib/client-assertion/generate-key.ts +26 -0
  97. package/lib/client-assertion/index.ts +4 -0
  98. package/lib/client-assertion/keys.ts +26 -0
  99. package/lib/client-assertion/types.ts +9 -0
  100. package/lib/dpop/fetch.ts +140 -0
  101. package/lib/dpop/generate-key.ts +72 -0
  102. package/lib/dpop/index.ts +11 -0
  103. package/lib/dpop/proof.ts +46 -0
  104. package/lib/dpop/types.ts +19 -0
  105. package/lib/dpop/verify.ts +169 -0
  106. package/lib/hash/index.ts +2 -0
  107. package/lib/hash/pkce.ts +18 -0
  108. package/lib/hash/sha256.ts +14 -0
  109. package/lib/index.ts +5 -0
  110. package/lib/internal/crypto.ts +92 -0
  111. package/lib/internal/jwk.ts +157 -0
  112. package/lib/internal/key-cache.ts +51 -0
  113. package/lib/jwk/compute-jkt.ts +27 -0
  114. package/lib/jwk/index.ts +12 -0
  115. package/lib/jwk/keys.ts +15 -0
  116. package/lib/jwk/types.ts +51 -0
  117. package/lib/jwt/index.ts +86 -0
  118. package/package.json +38 -0
@@ -0,0 +1,124 @@
1
+ import { fromBase64Url } from '@atcute/multibase';
2
+ import { decodeUtf8From } from '@atcute/uint8array';
3
+ import * as v from '@badrap/valita';
4
+ import { getImportAlgorithm } from '../internal/crypto.js';
5
+ import { computeJktFromJwk } from '../jwk/compute-jkt.js';
6
+ import { verifyJwt } from '../jwt/index.js';
7
+ const dpopJwkSchema = v.union(v.object({
8
+ kty: v.literal('EC'),
9
+ crv: v.union(v.literal('P-256'), v.literal('P-384'), v.literal('P-521')),
10
+ x: v.string(),
11
+ y: v.string(),
12
+ }), v.object({
13
+ kty: v.literal('RSA'),
14
+ e: v.string(),
15
+ n: v.string(),
16
+ }));
17
+ const dpopHeaderSchema = v.object({
18
+ typ: v.literal('dpop+jwt'),
19
+ alg: v.string().assert((alg) => alg !== 'none', 'alg must not be "none"'),
20
+ jwk: dpopJwkSchema,
21
+ });
22
+ const dpopPayloadSchema = v.object({
23
+ htm: v.string(),
24
+ htu: v.string(),
25
+ iat: v.number(),
26
+ jti: v.string(),
27
+ nonce: v.string().optional(),
28
+ });
29
+ /**
30
+ * error thrown when dpop verification fails.
31
+ */
32
+ export class DpopVerifyError extends Error {
33
+ code;
34
+ constructor(message, code) {
35
+ super(message);
36
+ this.code = code;
37
+ this.name = 'DpopVerifyError';
38
+ }
39
+ }
40
+ /**
41
+ * verifies a dpop proof from a request header.
42
+ *
43
+ * @param dpopHeader dpop header value
44
+ * @param options verification options
45
+ * @returns verification result with claims and jwk thumbprint
46
+ * @throws {DpopVerifyError} if verification fails
47
+ */
48
+ export const verifyDpopProof = async (dpopHeader, options) => {
49
+ if (!dpopHeader) {
50
+ throw new DpopVerifyError(`missing dpop header`, 'missing');
51
+ }
52
+ const { method, url, nonce: dpopNonce, maxClockSkew = 60 } = options;
53
+ const parts = dpopHeader.split('.');
54
+ if (parts.length !== 3) {
55
+ throw new DpopVerifyError(`invalid dpop proof format`, 'invalid');
56
+ }
57
+ let header;
58
+ try {
59
+ header = dpopHeaderSchema.parse(decodeSegment(parts[0]), { mode: 'passthrough' });
60
+ }
61
+ catch {
62
+ throw new DpopVerifyError(`invalid dpop header`, 'invalid');
63
+ }
64
+ const { jwk, alg } = header;
65
+ if (!isSigningAlgorithm(alg)) {
66
+ throw new DpopVerifyError(`unsupported dpop alg`, 'invalid');
67
+ }
68
+ let payload;
69
+ try {
70
+ const key = await importPublicKey(jwk, alg);
71
+ const raw = await verifyJwt(dpopHeader, { key, alg, typ: 'dpop+jwt' });
72
+ payload = dpopPayloadSchema.parse(raw, { mode: 'passthrough' });
73
+ }
74
+ catch (err) {
75
+ if (err instanceof v.ValitaError) {
76
+ throw new DpopVerifyError(`invalid dpop payload`, 'invalid');
77
+ }
78
+ throw new DpopVerifyError(`dpop signature verification failed`, 'invalid');
79
+ }
80
+ if (payload.htm !== method) {
81
+ throw new DpopVerifyError(`dpop htm mismatch: expected ${method}, got ${payload.htm}`, 'invalid');
82
+ }
83
+ if (payload.htu !== url) {
84
+ throw new DpopVerifyError(`dpop htu mismatch: expected ${url}, got ${payload.htu}`, 'invalid');
85
+ }
86
+ const now = Math.floor(Date.now() / 1000);
87
+ if (payload.iat > now + maxClockSkew) {
88
+ throw new DpopVerifyError(`dpop proof issued in the future`, 'invalid');
89
+ }
90
+ if (payload.iat < now - maxClockSkew) {
91
+ throw new DpopVerifyError(`dpop proof expired`, 'expired');
92
+ }
93
+ if (dpopNonce) {
94
+ if (!payload.nonce || !(await dpopNonce.check(payload.nonce))) {
95
+ throw new DpopVerifyError(`invalid or missing dpop nonce`, 'nonce_required');
96
+ }
97
+ }
98
+ const jkt = await computeJktFromJwk(jwk);
99
+ return { claims: payload, jwk: jwk, jkt };
100
+ };
101
+ const importPublicKey = async (jwk, alg) => {
102
+ const algorithm = getImportAlgorithm(alg, jwk.kty === 'EC' ? jwk.crv : undefined);
103
+ const key = await crypto.subtle.importKey('jwk', jwk, algorithm, true, ['verify']);
104
+ if (!(key instanceof CryptoKey)) {
105
+ throw new Error(`expected asymmetric key, got symmetric`);
106
+ }
107
+ return key;
108
+ };
109
+ const isSigningAlgorithm = (alg) => {
110
+ return (alg === 'ES256' ||
111
+ alg === 'ES384' ||
112
+ alg === 'ES512' ||
113
+ alg === 'PS256' ||
114
+ alg === 'PS384' ||
115
+ alg === 'PS512' ||
116
+ alg === 'RS256' ||
117
+ alg === 'RS384' ||
118
+ alg === 'RS512');
119
+ };
120
+ const decodeSegment = (segment) => {
121
+ const bytes = fromBase64Url(segment);
122
+ return JSON.parse(decodeUtf8From(bytes));
123
+ };
124
+ //# sourceMappingURL=verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../lib/dpop/verify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAEpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAC5B,CAAC,CAAC,MAAM,CAAC;IACR,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;IACpB,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACxE,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;IACb,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;CACb,CAAC,EACF,CAAC,CAAC,MAAM,CAAC;IACR,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IACrB,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;IACb,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;CACb,CAAC,CACF,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;IAC1B,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,MAAM,EAAE,wBAAwB,CAAC;IACzE,GAAG,EAAE,aAAa;CAClB,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC5B,CAAC,CAAC;AAkBH;;GAEG;AACH,MAAM,OAAO,eAAgB,SAAQ,KAAK;IAGjC,IAAI;IAFZ,YACC,OAAe,EACR,IAA0D,EAChE;QACD,KAAK,CAAC,OAAO,CAAC,CAAC;oBAFR,IAAI;QAGX,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAAA,CAC9B;CACD;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EACnC,UAAqC,EACrC,OAA0B,EACE,EAAE,CAAC;IAC/B,IAAI,CAAC,UAAU,EAAE,CAAC;QACjB,MAAM,IAAI,eAAe,CAAC,qBAAqB,EAAE,SAAS,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC;IACrE,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,eAAe,CAAC,2BAA2B,EAAE,SAAS,CAAC,CAAC;IACnE,CAAC;IAED,IAAI,MAAwC,CAAC;IAC7C,IAAI,CAAC;QACJ,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;IACnF,CAAC;IAAC,MAAM,CAAC;QACR,MAAM,IAAI,eAAe,CAAC,qBAAqB,EAAE,SAAS,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC;IAC5B,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,eAAe,CAAC,sBAAsB,EAAE,SAAS,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI,OAAmB,CAAC;IACxB,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC5C,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,UAAU,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,CAAC;QACvE,OAAO,GAAG,iBAAiB,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;IACjE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,IAAI,GAAG,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;YAClC,MAAM,IAAI,eAAe,CAAC,sBAAsB,EAAE,SAAS,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,IAAI,eAAe,CAAC,oCAAoC,EAAE,SAAS,CAAC,CAAC;IAC5E,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,KAAK,MAAM,EAAE,CAAC;QAC5B,MAAM,IAAI,eAAe,CAAC,+BAA+B,MAAM,SAAS,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC;IACnG,CAAC;IACD,IAAI,OAAO,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;QACzB,MAAM,IAAI,eAAe,CAAC,+BAA+B,GAAG,SAAS,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC;IAChG,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1C,IAAI,OAAO,CAAC,GAAG,GAAG,GAAG,GAAG,YAAY,EAAE,CAAC;QACtC,MAAM,IAAI,eAAe,CAAC,iCAAiC,EAAE,SAAS,CAAC,CAAC;IACzE,CAAC;IACD,IAAI,OAAO,CAAC,GAAG,GAAG,GAAG,GAAG,YAAY,EAAE,CAAC;QACtC,MAAM,IAAI,eAAe,CAAC,oBAAoB,EAAE,SAAS,CAAC,CAAC;IAC5D,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACf,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YAC/D,MAAM,IAAI,eAAe,CAAC,+BAA+B,EAAE,gBAAgB,CAAC,CAAC;QAC9E,CAAC;IACF,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,GAAgB,CAAC,CAAC;IAEtD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAc,EAAE,GAAG,EAAE,CAAC;AAAA,CACrD,CAAC;AAEF,MAAM,eAAe,GAAG,KAAK,EAAE,GAAc,EAAE,GAAqB,EAAsB,EAAE,CAAC;IAC5F,MAAM,SAAS,GAAG,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAClF,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IACnF,IAAI,CAAC,CAAC,GAAG,YAAY,SAAS,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO,GAAG,CAAC;AAAA,CACX,CAAC;AAEF,MAAM,kBAAkB,GAAG,CAAC,GAAW,EAA2B,EAAE,CAAC;IACpE,OAAO,CACN,GAAG,KAAK,OAAO;QACf,GAAG,KAAK,OAAO;QACf,GAAG,KAAK,OAAO;QACf,GAAG,KAAK,OAAO;QACf,GAAG,KAAK,OAAO;QACf,GAAG,KAAK,OAAO;QACf,GAAG,KAAK,OAAO;QACf,GAAG,KAAK,OAAO;QACf,GAAG,KAAK,OAAO,CACf,CAAC;AAAA,CACF,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,OAAe,EAAW,EAAE,CAAC;IACnD,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;AAAA,CACzC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { generatePkce } from './pkce.js';
2
+ export { sha256Base64Url } from './sha256.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/hash/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { generatePkce } from './pkce.js';
2
+ export { sha256Base64Url } from './sha256.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/hash/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * generates pkce verifier and challenge (s256).
3
+ *
4
+ * @param length verifier length (43-128 per rfc 7636)
5
+ * @returns pkce values
6
+ */
7
+ export declare const generatePkce: (length?: number) => Promise<{
8
+ verifier: string;
9
+ challenge: string;
10
+ method: "S256";
11
+ }>;
12
+ //# sourceMappingURL=pkce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkce.d.ts","sourceRoot":"","sources":["../../lib/hash/pkce.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,eAAO,MAAM,YAAY;;;;EAOxB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { nanoid } from 'nanoid';
2
+ import { sha256Base64Url } from './sha256.js';
3
+ /**
4
+ * generates pkce verifier and challenge (s256).
5
+ *
6
+ * @param length verifier length (43-128 per rfc 7636)
7
+ * @returns pkce values
8
+ */
9
+ export const generatePkce = async (length = 64) => {
10
+ const verifier = nanoid(length);
11
+ const challenge = await sha256Base64Url(verifier);
12
+ return { verifier, challenge, method: 'S256' };
13
+ };
14
+ //# sourceMappingURL=pkce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkce.js","sourceRoot":"","sources":["../../lib/hash/pkce.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAChC,MAAM,GAAG,EAAE,EACwD,EAAE,CAAC;IACtE,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAChC,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,QAAQ,CAAC,CAAC;IAElD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAAA,CAC/C,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * computes sha-256 hash and returns base64url-encoded result.
3
+ *
4
+ * @param input string to hash
5
+ * @returns base64url-encoded sha-256 hash
6
+ */
7
+ export declare const sha256Base64Url: (input: string) => Promise<string>;
8
+ //# sourceMappingURL=sha256.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sha256.d.ts","sourceRoot":"","sources":["../../lib/hash/sha256.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,eAAO,MAAM,eAAe,oCAI3B,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { toBase64Url } from '@atcute/multibase';
2
+ import { encodeUtf8, toSha256 } from '@atcute/uint8array';
3
+ /**
4
+ * computes sha-256 hash and returns base64url-encoded result.
5
+ *
6
+ * @param input string to hash
7
+ * @returns base64url-encoded sha-256 hash
8
+ */
9
+ export const sha256Base64Url = async (input) => {
10
+ const bytes = encodeUtf8(input);
11
+ const digest = await toSha256(bytes);
12
+ return toBase64Url(digest);
13
+ };
14
+ //# sourceMappingURL=sha256.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sha256.js","sourceRoot":"","sources":["../../lib/hash/sha256.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAAE,KAAa,EAAmB,EAAE,CAAC;IACxE,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;IACrC,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC;AAAA,CAC3B,CAAC"}
@@ -0,0 +1,6 @@
1
+ export * from './client-assertion/index.js';
2
+ export * from './dpop/index.js';
3
+ export * from './hash/index.js';
4
+ export * from './jwk/index.js';
5
+ export * from './jwt/index.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ export * from './client-assertion/index.js';
2
+ export * from './dpop/index.js';
3
+ export * from './hash/index.js';
4
+ export * from './jwk/index.js';
5
+ export * from './jwt/index.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { SigningAlgorithm } from '../jwk/types.js';
2
+ export declare const getHashName: (alg: SigningAlgorithm) => "SHA-256" | "SHA-384" | "SHA-512";
3
+ export declare const getNamedCurve: (alg: SigningAlgorithm) => "P-256" | "P-384" | "P-521" | null;
4
+ export declare const getSignAlgorithm: (alg: SigningAlgorithm) => EcdsaParams | RsaPssParams | AlgorithmIdentifier;
5
+ export declare const getImportAlgorithm: (alg: SigningAlgorithm, curve?: "P-256" | "P-384" | "P-521" | undefined) => EcKeyImportParams | RsaHashedImportParams;
6
+ export declare const getGenerateAlgorithm: (alg: SigningAlgorithm) => EcKeyGenParams | RsaHashedKeyGenParams;
7
+ //# sourceMappingURL=crypto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../lib/internal/crypto.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AA0BxD,eAAO,MAAM,WAAW,8DAEvB,CAAC;AAEF,eAAO,MAAM,aAAa,+DAEzB,CAAC;AAEF,eAAO,MAAM,gBAAgB,6EAY5B,CAAC;AAEF,eAAO,MAAM,kBAAkB,uHAiB9B,CAAC;AAEF,eAAO,MAAM,oBAAoB,mEAahC,CAAC"}
@@ -0,0 +1,78 @@
1
+ const HASH_BY_ALG = {
2
+ ES256: 'SHA-256',
3
+ ES384: 'SHA-384',
4
+ ES512: 'SHA-512',
5
+ PS256: 'SHA-256',
6
+ PS384: 'SHA-384',
7
+ PS512: 'SHA-512',
8
+ RS256: 'SHA-256',
9
+ RS384: 'SHA-384',
10
+ RS512: 'SHA-512',
11
+ };
12
+ const CURVE_BY_ALG = {
13
+ ES256: 'P-256',
14
+ ES384: 'P-384',
15
+ ES512: 'P-521',
16
+ PS256: null,
17
+ PS384: null,
18
+ PS512: null,
19
+ RS256: null,
20
+ RS384: null,
21
+ RS512: null,
22
+ };
23
+ export const getHashName = (alg) => {
24
+ return HASH_BY_ALG[alg];
25
+ };
26
+ export const getNamedCurve = (alg) => {
27
+ return CURVE_BY_ALG[alg];
28
+ };
29
+ export const getSignAlgorithm = (alg) => {
30
+ if (alg.startsWith('ES')) {
31
+ return { name: 'ECDSA', hash: { name: getHashName(alg) } };
32
+ }
33
+ if (alg.startsWith('PS')) {
34
+ return {
35
+ name: 'RSA-PSS',
36
+ hash: { name: getHashName(alg) },
37
+ saltLength: getHashLength(getHashName(alg)),
38
+ };
39
+ }
40
+ return { name: 'RSASSA-PKCS1-v1_5' };
41
+ };
42
+ export const getImportAlgorithm = (alg, curve) => {
43
+ if (alg.startsWith('ES')) {
44
+ const namedCurve = curve ?? getNamedCurve(alg);
45
+ if (!namedCurve) {
46
+ throw new Error(`unable to determine curve for ${alg}`);
47
+ }
48
+ return { name: 'ECDSA', namedCurve };
49
+ }
50
+ if (alg.startsWith('PS')) {
51
+ return { name: 'RSA-PSS', hash: { name: getHashName(alg) } };
52
+ }
53
+ return { name: 'RSASSA-PKCS1-v1_5', hash: { name: getHashName(alg) } };
54
+ };
55
+ export const getGenerateAlgorithm = (alg) => {
56
+ const curve = getNamedCurve(alg);
57
+ if (curve) {
58
+ return { name: 'ECDSA', namedCurve: curve };
59
+ }
60
+ const hash = { name: getHashName(alg) };
61
+ return {
62
+ name: alg.startsWith('PS') ? 'RSA-PSS' : 'RSASSA-PKCS1-v1_5',
63
+ hash,
64
+ modulusLength: 2048,
65
+ publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
66
+ };
67
+ };
68
+ const getHashLength = (hash) => {
69
+ switch (hash) {
70
+ case 'SHA-256':
71
+ return 32;
72
+ case 'SHA-384':
73
+ return 48;
74
+ case 'SHA-512':
75
+ return 64;
76
+ }
77
+ };
78
+ //# sourceMappingURL=crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../lib/internal/crypto.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,GAAgE;IAChF,KAAK,EAAE,SAAS;IAChB,KAAK,EAAE,SAAS;IAChB,KAAK,EAAE,SAAS;IAChB,KAAK,EAAE,SAAS;IAChB,KAAK,EAAE,SAAS;IAChB,KAAK,EAAE,SAAS;IAChB,KAAK,EAAE,SAAS;IAChB,KAAK,EAAE,SAAS;IAChB,KAAK,EAAE,SAAS;CAChB,CAAC;AAEF,MAAM,YAAY,GAAiE;IAClF,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,IAAI;CACX,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAqB,EAAqC,EAAE,CAAC;IACxF,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;AAAA,CACxB,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,GAAqB,EAAsC,EAAE,CAAC;IAC3F,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;AAAA,CACzB,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,GAAqB,EAAoD,EAAE,CAAC;IAC5G,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;IAC5D,CAAC;IACD,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,OAAO;YACN,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE;YAChC,UAAU,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;SAC3C,CAAC;IACH,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC;AAAA,CACrC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CACjC,GAAqB,EACrB,KAAmC,EACS,EAAE,CAAC;IAC/C,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,MAAM,UAAU,GAAG,KAAK,IAAI,aAAa,CAAC,GAAG,CAAC,CAAC;QAC/C,IAAI,CAAC,UAAU,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,iCAAiC,GAAG,EAAE,CAAC,CAAC;QACzD,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;IACtC,CAAC;IAED,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;IAC9D,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;AAAA,CACvE,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,GAAqB,EAA0C,EAAE,CAAC;IACtG,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IAC7C,CAAC;IAED,MAAM,IAAI,GAAG,EAAE,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;IACxC,OAAO;QACN,IAAI,EAAE,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,mBAAmB;QAC5D,IAAI;QACJ,aAAa,EAAE,IAAI;QACnB,cAAc,EAAE,IAAI,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;KAClD,CAAC;AAAA,CACF,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,IAAuC,EAAU,EAAE,CAAC;IAC1E,QAAQ,IAAI,EAAE,CAAC;QACd,KAAK,SAAS;YACb,OAAO,EAAE,CAAC;QACX,KAAK,SAAS;YACb,OAAO,EAAE,CAAC;QACX,KAAK,SAAS;YACb,OAAO,EAAE,CAAC;IACZ,CAAC;AAAA,CACD,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { PrivateJwk, PublicJwk, SigningAlgorithm } from '../jwk/types.js';
2
+ export declare const isSigningAlgorithm: (alg: string) => alg is SigningAlgorithm;
3
+ export declare const parsePrivateJwkInput: (input: string | PrivateJwk) => PrivateJwk;
4
+ export declare const resolveSigningAlgorithm: (jwk: PrivateJwk, override?: SigningAlgorithm | undefined) => SigningAlgorithm | undefined;
5
+ export declare const derivePublicJwk: (privateJwk: PrivateJwk, kid?: string | undefined, alg?: SigningAlgorithm | undefined) => PublicJwk;
6
+ export declare const importPrivateKeyFromJwk: (jwk: PrivateJwk, alg: SigningAlgorithm) => Promise<CryptoKey>;
7
+ export declare const exportPrivateJwkFromKey: (key: CryptoKey, alg: SigningAlgorithm, kid?: string | undefined) => Promise<PrivateJwk>;
8
+ export declare const importPkcs8PrivateKey: (pem: string, alg: SigningAlgorithm) => Promise<CryptoKey>;
9
+ export declare const exportPkcs8PrivateKey: (key: CryptoKey) => Promise<string>;
10
+ //# sourceMappingURL=jwk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwk.d.ts","sourceRoot":"","sources":["../../lib/internal/jwk.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAsB/E,eAAO,MAAM,kBAAkB,0CAE9B,CAAC;AAEF,eAAO,MAAM,oBAAoB,4CAehC,CAAC;AAEF,eAAO,MAAM,uBAAuB,4FAqBnC,CAAC;AAEF,eAAO,MAAM,eAAe,qGAY3B,CAAC;AAEF,eAAO,MAAM,uBAAuB,gEAoBnC,CAAC;AAEF,eAAO,MAAM,uBAAuB,0FAWnC,CAAC;AAEF,eAAO,MAAM,qBAAqB,4DAWjC,CAAC;AAEF,eAAO,MAAM,qBAAqB,qCAMjC,CAAC"}
@@ -0,0 +1,121 @@
1
+ import { fromBase64Pad, toBase64Pad } from '@atcute/multibase';
2
+ import { getImportAlgorithm } from './crypto.js';
3
+ const SIGNING_ALGORITHMS = [
4
+ 'ES256',
5
+ 'ES384',
6
+ 'ES512',
7
+ 'PS256',
8
+ 'PS384',
9
+ 'PS512',
10
+ 'RS256',
11
+ 'RS384',
12
+ 'RS512',
13
+ ];
14
+ const CURVE_TO_ALG = {
15
+ 'P-256': 'ES256',
16
+ 'P-384': 'ES384',
17
+ 'P-521': 'ES512',
18
+ };
19
+ export const isSigningAlgorithm = (alg) => {
20
+ return SIGNING_ALGORITHMS.includes(alg);
21
+ };
22
+ export const parsePrivateJwkInput = (input) => {
23
+ if (typeof input === 'string') {
24
+ try {
25
+ const jwk = JSON.parse(input);
26
+ return jwk;
27
+ }
28
+ catch {
29
+ throw new Error(`invalid JSON string`);
30
+ }
31
+ }
32
+ if (typeof input === 'object' && input !== null && 'kty' in input) {
33
+ return input;
34
+ }
35
+ throw new Error(`invalid input: expected JWK object or JSON string`);
36
+ };
37
+ export const resolveSigningAlgorithm = (jwk, override) => {
38
+ if (override) {
39
+ return override;
40
+ }
41
+ const alg = jwk.alg;
42
+ if (alg && isSigningAlgorithm(alg)) {
43
+ return alg;
44
+ }
45
+ if (jwk.kty === 'EC') {
46
+ const inferred = CURVE_TO_ALG[jwk.crv];
47
+ if (inferred) {
48
+ return inferred;
49
+ }
50
+ }
51
+ return undefined;
52
+ };
53
+ export const derivePublicJwk = (privateJwk, kid, alg) => {
54
+ if (privateJwk.kty === 'EC') {
55
+ const { crv, x, y } = privateJwk;
56
+ return { kty: 'EC', crv, x, y, kid, alg, use: 'sig' };
57
+ }
58
+ if (privateJwk.kty === 'RSA') {
59
+ const { n, e } = privateJwk;
60
+ return { kty: 'RSA', n, e, kid, alg, use: 'sig' };
61
+ }
62
+ throw new Error(`unsupported key type`);
63
+ };
64
+ export const importPrivateKeyFromJwk = async (jwk, alg) => {
65
+ if (!('d' in jwk) || !jwk.d) {
66
+ throw new Error(`expected a private key (missing 'd' parameter)`);
67
+ }
68
+ if (jwk.kty === 'EC' && !alg.startsWith('ES')) {
69
+ throw new Error(`algorithm ${alg} does not match ec key`);
70
+ }
71
+ if (jwk.kty === 'RSA' && alg.startsWith('ES')) {
72
+ throw new Error(`algorithm ${alg} does not match rsa key`);
73
+ }
74
+ const algorithm = getImportAlgorithm(alg, jwk.kty === 'EC' ? jwk.crv : undefined);
75
+ const key = await crypto.subtle.importKey('jwk', jwk, algorithm, true, ['sign']);
76
+ if (!(key instanceof CryptoKey)) {
77
+ throw new Error(`expected asymmetric key, got symmetric`);
78
+ }
79
+ return key;
80
+ };
81
+ export const exportPrivateJwkFromKey = async (key, alg, kid) => {
82
+ const jwk = (await crypto.subtle.exportKey('jwk', key));
83
+ jwk.alg = alg;
84
+ if (kid) {
85
+ jwk.kid = kid;
86
+ }
87
+ return jwk;
88
+ };
89
+ export const importPkcs8PrivateKey = async (pem, alg) => {
90
+ const bytes = parsePkcs8Pem(pem);
91
+ const algorithm = getImportAlgorithm(alg);
92
+ const key = await crypto.subtle.importKey('pkcs8', bytes, algorithm, true, ['sign']);
93
+ if (!(key instanceof CryptoKey)) {
94
+ throw new Error(`expected asymmetric key, got symmetric`);
95
+ }
96
+ return key;
97
+ };
98
+ export const exportPkcs8PrivateKey = async (key) => {
99
+ const pkcs8 = await crypto.subtle.exportKey('pkcs8', key);
100
+ const bytes = new Uint8Array(pkcs8);
101
+ const base64 = toBase64Pad(bytes);
102
+ return ['-----BEGIN PRIVATE KEY-----', ...chunk64(base64), '-----END PRIVATE KEY-----', ''].join('\n');
103
+ };
104
+ const parsePkcs8Pem = (pem) => {
105
+ const match = pem.match(/-----BEGIN PRIVATE KEY-----([\s\S]*?)-----END PRIVATE KEY-----/);
106
+ if (!match) {
107
+ throw new Error(`invalid pkcs8 pem`);
108
+ }
109
+ const base64 = match[1].replace(/\s+/g, '');
110
+ const bytes = fromBase64Pad(base64);
111
+ const buffer = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
112
+ return buffer;
113
+ };
114
+ const chunk64 = (input) => {
115
+ const chunks = [];
116
+ for (let i = 0; i < input.length; i += 64) {
117
+ chunks.push(input.slice(i, i + 64));
118
+ }
119
+ return chunks;
120
+ };
121
+ //# sourceMappingURL=jwk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwk.js","sourceRoot":"","sources":["../../lib/internal/jwk.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { PrivateJwk, PublicJwk } from '../jwk/types.js';
2
+ /**
3
+ * cached key material for a JWK.
4
+ */
5
+ export interface CachedKeyMaterial {
6
+ cryptoKey: CryptoKey;
7
+ publicJwk: PublicJwk;
8
+ }
9
+ /**
10
+ * retrieves or creates cached key material for a JWK.
11
+ *
12
+ * @param jwk private JWK to get material for
13
+ * @returns cached key material (CryptoKey and derived public JWK)
14
+ */
15
+ export declare const getCachedKeyMaterial: (jwk: PrivateJwk) => Promise<CachedKeyMaterial>;
16
+ /**
17
+ * pre-populates the cache with already-imported key material.
18
+ * useful for PKCS8 imports where we already have the CryptoKey.
19
+ *
20
+ * @param jwk private JWK to cache for
21
+ * @param cryptoKey already-imported CryptoKey
22
+ */
23
+ export declare const setCachedKeyMaterial: (jwk: PrivateJwk, cryptoKey: CryptoKey) => void;
24
+ //# sourceMappingURL=key-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-cache.d.ts","sourceRoot":"","sources":["../../lib/internal/key-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI7D;;GAEG;AACH,MAAM,WAAW,iBAAiB;IACjC,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,EAAE,SAAS,CAAC;CACrB;AAQD;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,iDAchC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,iDAGhC,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { derivePublicJwk, importPrivateKeyFromJwk } from './jwk.js';
2
+ /**
3
+ * cache for imported keys.
4
+ * uses WeakMap so entries are garbage collected when JWK objects are no longer referenced.
5
+ */
6
+ const keyCache = new WeakMap();
7
+ /**
8
+ * retrieves or creates cached key material for a JWK.
9
+ *
10
+ * @param jwk private JWK to get material for
11
+ * @returns cached key material (CryptoKey and derived public JWK)
12
+ */
13
+ export const getCachedKeyMaterial = async (jwk) => {
14
+ const cached = keyCache.get(jwk);
15
+ if (cached) {
16
+ return cached;
17
+ }
18
+ const { alg } = jwk;
19
+ const cryptoKey = await importPrivateKeyFromJwk(jwk, alg);
20
+ const publicJwk = derivePublicJwk(jwk, jwk.kid, alg);
21
+ const material = { cryptoKey, publicJwk };
22
+ keyCache.set(jwk, material);
23
+ return material;
24
+ };
25
+ /**
26
+ * pre-populates the cache with already-imported key material.
27
+ * useful for PKCS8 imports where we already have the CryptoKey.
28
+ *
29
+ * @param jwk private JWK to cache for
30
+ * @param cryptoKey already-imported CryptoKey
31
+ */
32
+ export const setCachedKeyMaterial = (jwk, cryptoKey) => {
33
+ const publicJwk = derivePublicJwk(jwk, jwk.kid, jwk.alg);
34
+ keyCache.set(jwk, { cryptoKey, publicJwk });
35
+ };
36
+ //# sourceMappingURL=key-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-cache.js","sourceRoot":"","sources":["../../lib/internal/key-cache.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAUpE;;;GAGG;AACH,MAAM,QAAQ,GAAG,IAAI,OAAO,EAAiC,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EAAE,GAAe,EAA8B,EAAE,CAAC;IAC1F,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,MAAM,EAAE,CAAC;QACZ,OAAO,MAAM,CAAC;IACf,CAAC;IAED,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IACpB,MAAM,SAAS,GAAG,MAAM,uBAAuB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC1D,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAsB,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;IAE7D,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAE5B,OAAO,QAAQ,CAAC;AAAA,CAChB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,GAAe,EAAE,SAAoB,EAAQ,EAAE,CAAC;IACpF,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IACzD,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;AAAA,CAC5C,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { PublicJwk } from './types.js';
2
+ /**
3
+ * computes the jwk thumbprint (rfc 7638) for a public key.
4
+ *
5
+ * @param jwk public jwk
6
+ * @returns base64url-encoded sha-256 thumbprint
7
+ */
8
+ export declare const computeJktFromJwk: (jwk: PublicJwk) => Promise<string>;
9
+ //# sourceMappingURL=compute-jkt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compute-jkt.d.ts","sourceRoot":"","sources":["../../lib/jwk/compute-jkt.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,qCAe7B,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { toBase64Url } from '@atcute/multibase';
2
+ import { encodeUtf8, toSha256 } from '@atcute/uint8array';
3
+ /**
4
+ * computes the jwk thumbprint (rfc 7638) for a public key.
5
+ *
6
+ * @param jwk public jwk
7
+ * @returns base64url-encoded sha-256 thumbprint
8
+ */
9
+ export const computeJktFromJwk = async (jwk) => {
10
+ let canonical;
11
+ if (jwk.kty === 'EC') {
12
+ const { crv, x, y } = jwk;
13
+ canonical = { crv, kty: jwk.kty, x, y };
14
+ }
15
+ else {
16
+ const { e, n } = jwk;
17
+ canonical = { e, kty: jwk.kty, n };
18
+ }
19
+ const serialized = JSON.stringify(canonical);
20
+ const hash = await toSha256(encodeUtf8(serialized));
21
+ return toBase64Url(hash);
22
+ };
23
+ //# sourceMappingURL=compute-jkt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compute-jkt.js","sourceRoot":"","sources":["../../lib/jwk/compute-jkt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAI1D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EAAE,GAAc,EAAmB,EAAE,CAAC;IAC3E,IAAI,SAAiC,CAAC;IAEtC,IAAI,GAAG,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC;QACtB,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,GAAG,CAAC;QAC1B,SAAS,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;IACzC,CAAC;SAAM,CAAC;QACP,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,GAAG,CAAC;QACrB,SAAS,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC;IACpC,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;IAEpD,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC;AAAA,CACzB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { computeJktFromJwk } from './compute-jkt.js';
2
+ export { derivePublicJwk } from '../internal/jwk.js';
3
+ export { exportPkcs8PrivateKey } from './keys.js';
4
+ export type { EcPrivateJwk, EcPublicJwk, PrivateJwk, PublicJwk, RsaPrivateJwk, RsaPublicJwk, SigningAlgorithm, } from './types.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/jwk/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAClD,YAAY,EACX,YAAY,EACZ,WAAW,EACX,UAAU,EACV,SAAS,EACT,aAAa,EACb,YAAY,EACZ,gBAAgB,GAChB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { computeJktFromJwk } from './compute-jkt.js';
2
+ export { derivePublicJwk } from '../internal/jwk.js';
3
+ export { exportPkcs8PrivateKey } from './keys.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/jwk/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { PrivateJwk } from './types.js';
2
+ /**
3
+ * exports a private JWK to PKCS8 PEM format.
4
+ *
5
+ * @param jwk private JWK to export
6
+ * @returns PKCS8 PEM string
7
+ */
8
+ export declare const exportPkcs8PrivateKey: (jwk: PrivateJwk) => Promise<string>;
9
+ //# sourceMappingURL=keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../lib/jwk/keys.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,sCAGjC,CAAC"}