@sd-jwt/core 0.19.1-next.5 → 0.19.1-next.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -7
- package/dist/index.d.mts +343 -16
- package/dist/index.d.ts +343 -16
- package/dist/index.js +644 -142
- package/dist/index.mjs +585 -127
- package/package.json +4 -7
- package/src/decode/decode.ts +366 -0
- package/src/decode/index.ts +1 -0
- package/src/decoy.ts +2 -2
- package/src/flattenJSON.ts +3 -3
- package/src/generalJSON.ts +3 -3
- package/src/index.ts +39 -25
- package/src/jwt.ts +10 -15
- package/src/kbjwt.ts +5 -6
- package/src/present/index.ts +1 -0
- package/src/present/present.ts +210 -0
- package/src/sdjwt.ts +11 -10
- package/src/test/decode/decode.spec.ts +202 -0
- package/src/test/decoy.spec.ts +2 -2
- package/src/test/generalJSON.spec.ts +1 -1
- package/src/test/index.spec.ts +2 -2
- package/src/test/jwt.spec.ts +7 -13
- package/src/test/kbjwt.spec.ts +5 -5
- package/src/test/present/present.spec.ts +305 -0
- package/src/test/sdjwt.spec.ts +4 -4
- package/src/test/types/type.spec.ts +88 -0
- package/src/test/utils/base64url.spec.ts +33 -0
- package/src/test/utils/disclosure.spec.ts +170 -0
- package/src/test/utils/error.spec.ts +15 -0
- package/src/types/index.ts +2 -0
- package/src/types/type.ts +249 -0
- package/src/types/verification-error.ts +55 -0
- package/src/utils/base64url.ts +6 -0
- package/src/utils/disclosure.ts +98 -0
- package/src/utils/error.ts +25 -0
- package/src/utils/index.ts +3 -0
- package/test/app-e2e.spec.ts +8 -8
- package/test/rfc9901-validation.spec.ts +150 -0
- package/CHANGELOG.md +0 -240
package/dist/index.js
CHANGED
|
@@ -20,6 +20,18 @@ var __spreadValues = (a, b) => {
|
|
|
20
20
|
return a;
|
|
21
21
|
};
|
|
22
22
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
23
|
+
var __objRest = (source, exclude) => {
|
|
24
|
+
var target = {};
|
|
25
|
+
for (var prop in source)
|
|
26
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
27
|
+
target[prop] = source[prop];
|
|
28
|
+
if (source != null && __getOwnPropSymbols)
|
|
29
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
30
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
31
|
+
target[prop] = source[prop];
|
|
32
|
+
}
|
|
33
|
+
return target;
|
|
34
|
+
};
|
|
23
35
|
var __export = (target, all) => {
|
|
24
36
|
for (var name in all)
|
|
25
37
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -57,26 +69,384 @@ var __async = (__this, __arguments, generator) => {
|
|
|
57
69
|
// src/index.ts
|
|
58
70
|
var index_exports = {};
|
|
59
71
|
__export(index_exports, {
|
|
72
|
+
Disclosure: () => Disclosure,
|
|
60
73
|
FlattenJSON: () => FlattenJSON,
|
|
61
74
|
GeneralJSON: () => GeneralJSON,
|
|
75
|
+
IANA_HASH_ALGORITHMS: () => IANA_HASH_ALGORITHMS,
|
|
62
76
|
Jwt: () => Jwt,
|
|
63
77
|
KBJwt: () => KBJwt,
|
|
78
|
+
KB_JWT_TYP: () => KB_JWT_TYP,
|
|
79
|
+
SDJWTException: () => SDJWTException,
|
|
64
80
|
SDJwt: () => SDJwt,
|
|
65
81
|
SDJwtGeneralJSONInstance: () => SDJwtGeneralJSONInstance,
|
|
66
82
|
SDJwtInstance: () => SDJwtInstance,
|
|
83
|
+
SD_DECOY: () => SD_DECOY,
|
|
84
|
+
SD_DIGEST: () => SD_DIGEST,
|
|
85
|
+
SD_LIST_KEY: () => SD_LIST_KEY,
|
|
86
|
+
SD_SEPARATOR: () => SD_SEPARATOR,
|
|
87
|
+
base64UrlToUint8Array: () => import_identity_common.base64UrlToUint8Array,
|
|
88
|
+
base64urlDecode: () => import_identity_common.base64urlDecode,
|
|
89
|
+
base64urlEncode: () => import_identity_common.base64urlEncode,
|
|
67
90
|
createDecoy: () => createDecoy,
|
|
91
|
+
createHashMapping: () => createHashMapping,
|
|
92
|
+
createHashMappingForSerializedDisclosure: () => createHashMappingForSerializedDisclosure,
|
|
93
|
+
createHashMappingSync: () => createHashMappingSync,
|
|
94
|
+
decodeJwt: () => decodeJwt,
|
|
95
|
+
decodeSdJwt: () => decodeSdJwt,
|
|
96
|
+
decodeSdJwtSync: () => decodeSdJwtSync,
|
|
97
|
+
ensureError: () => ensureError,
|
|
98
|
+
getClaims: () => getClaims,
|
|
99
|
+
getClaimsSync: () => getClaimsSync,
|
|
100
|
+
getSDAlgAndPayload: () => getSDAlgAndPayload,
|
|
68
101
|
listKeys: () => listKeys,
|
|
69
|
-
pack: () => pack
|
|
102
|
+
pack: () => pack,
|
|
103
|
+
present: () => present,
|
|
104
|
+
presentSync: () => presentSync,
|
|
105
|
+
presentableKeys: () => presentableKeys,
|
|
106
|
+
presentableKeysSync: () => presentableKeysSync,
|
|
107
|
+
selectDisclosures: () => selectDisclosures,
|
|
108
|
+
splitSdJwt: () => splitSdJwt,
|
|
109
|
+
transformPresentationFrame: () => transformPresentationFrame,
|
|
110
|
+
uint8ArrayToBase64Url: () => import_identity_common.uint8ArrayToBase64Url,
|
|
111
|
+
unpack: () => unpack,
|
|
112
|
+
unpackObj: () => unpackObj,
|
|
113
|
+
unpackSync: () => unpackSync
|
|
70
114
|
});
|
|
71
115
|
module.exports = __toCommonJS(index_exports);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
var
|
|
116
|
+
|
|
117
|
+
// src/types/type.ts
|
|
118
|
+
var SD_SEPARATOR = "~";
|
|
119
|
+
var SD_LIST_KEY = "...";
|
|
120
|
+
var SD_DIGEST = "_sd";
|
|
121
|
+
var SD_DECOY = "_sd_decoy";
|
|
122
|
+
var KB_JWT_TYP = "kb+jwt";
|
|
123
|
+
var IANA_HASH_ALGORITHMS = [
|
|
124
|
+
"sha-256",
|
|
125
|
+
"sha-256-128",
|
|
126
|
+
"sha-256-120",
|
|
127
|
+
"sha-256-96",
|
|
128
|
+
"sha-256-64",
|
|
129
|
+
"sha-256-32",
|
|
130
|
+
"sha-384",
|
|
131
|
+
"sha-512",
|
|
132
|
+
"sha3-224",
|
|
133
|
+
"sha3-256",
|
|
134
|
+
"sha3-384",
|
|
135
|
+
"sha3-512",
|
|
136
|
+
"blake2s-256",
|
|
137
|
+
"blake2b-256",
|
|
138
|
+
"blake2b-512",
|
|
139
|
+
"k12-256",
|
|
140
|
+
"k12-512"
|
|
141
|
+
];
|
|
142
|
+
|
|
143
|
+
// src/utils/base64url.ts
|
|
144
|
+
var import_identity_common = require("@owf/identity-common");
|
|
145
|
+
|
|
146
|
+
// src/utils/error.ts
|
|
147
|
+
var SDJWTException = class _SDJWTException extends Error {
|
|
148
|
+
constructor(message, details) {
|
|
149
|
+
super(message);
|
|
150
|
+
Object.setPrototypeOf(this, _SDJWTException.prototype);
|
|
151
|
+
this.name = "SDJWTException";
|
|
152
|
+
this.details = details;
|
|
153
|
+
}
|
|
154
|
+
getFullMessage() {
|
|
155
|
+
return `${this.name}: ${this.message} ${this.details ? `- ${JSON.stringify(this.details)}` : ""}`;
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
function ensureError(value) {
|
|
159
|
+
if (value instanceof Error) return value;
|
|
160
|
+
if (typeof value === "string") return new Error(value);
|
|
161
|
+
return new Error(String(value));
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// src/utils/disclosure.ts
|
|
165
|
+
var Disclosure = class _Disclosure {
|
|
166
|
+
constructor(data, _meta) {
|
|
167
|
+
this._digest = _meta == null ? void 0 : _meta.digest;
|
|
168
|
+
this._encoded = _meta == null ? void 0 : _meta.encoded;
|
|
169
|
+
if (data.length === 2) {
|
|
170
|
+
this.salt = data[0];
|
|
171
|
+
this.value = data[1];
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (data.length === 3) {
|
|
175
|
+
this.salt = data[0];
|
|
176
|
+
this.key = data[1];
|
|
177
|
+
this.value = data[2];
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
throw new SDJWTException("Invalid disclosure data");
|
|
181
|
+
}
|
|
182
|
+
// We need to digest of the original encoded data.
|
|
183
|
+
// After decode process, we use JSON.stringify to encode the data.
|
|
184
|
+
// This can be different from the original encoded data.
|
|
185
|
+
static fromEncode(s, hash) {
|
|
186
|
+
return __async(this, null, function* () {
|
|
187
|
+
const { hasher, alg } = hash;
|
|
188
|
+
const digest = yield hasher(s, alg);
|
|
189
|
+
const digestStr = (0, import_identity_common.uint8ArrayToBase64Url)(digest);
|
|
190
|
+
const item = JSON.parse((0, import_identity_common.base64urlDecode)(s));
|
|
191
|
+
return _Disclosure.fromArray(item, { digest: digestStr, encoded: s });
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
static fromEncodeSync(s, hash) {
|
|
195
|
+
const { hasher, alg } = hash;
|
|
196
|
+
const digest = hasher(s, alg);
|
|
197
|
+
const digestStr = (0, import_identity_common.uint8ArrayToBase64Url)(digest);
|
|
198
|
+
const item = JSON.parse((0, import_identity_common.base64urlDecode)(s));
|
|
199
|
+
return _Disclosure.fromArray(item, { digest: digestStr, encoded: s });
|
|
200
|
+
}
|
|
201
|
+
static fromArray(item, _meta) {
|
|
202
|
+
return new _Disclosure(item, _meta);
|
|
203
|
+
}
|
|
204
|
+
encode() {
|
|
205
|
+
if (!this._encoded) {
|
|
206
|
+
this._encoded = (0, import_identity_common.base64urlEncode)(JSON.stringify(this.decode()));
|
|
207
|
+
}
|
|
208
|
+
return this._encoded;
|
|
209
|
+
}
|
|
210
|
+
decode() {
|
|
211
|
+
return this.key ? [this.salt, this.key, this.value] : [this.salt, this.value];
|
|
212
|
+
}
|
|
213
|
+
digest(hash) {
|
|
214
|
+
return __async(this, null, function* () {
|
|
215
|
+
const { hasher, alg } = hash;
|
|
216
|
+
if (!this._digest) {
|
|
217
|
+
const hash2 = yield hasher(this.encode(), alg);
|
|
218
|
+
this._digest = (0, import_identity_common.uint8ArrayToBase64Url)(hash2);
|
|
219
|
+
}
|
|
220
|
+
return this._digest;
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
digestSync(hash) {
|
|
224
|
+
const { hasher, alg } = hash;
|
|
225
|
+
if (!this._digest) {
|
|
226
|
+
const hash2 = hasher(this.encode(), alg);
|
|
227
|
+
this._digest = (0, import_identity_common.uint8ArrayToBase64Url)(hash2);
|
|
228
|
+
}
|
|
229
|
+
return this._digest;
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
// src/decode/decode.ts
|
|
234
|
+
var decodeJwt = (jwt) => {
|
|
235
|
+
const { 0: header, 1: payload, 2: signature, length } = jwt.split(".");
|
|
236
|
+
if (length !== 3) {
|
|
237
|
+
throw new SDJWTException("Invalid JWT as input");
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
header: JSON.parse((0, import_identity_common.base64urlDecode)(header)),
|
|
241
|
+
payload: JSON.parse((0, import_identity_common.base64urlDecode)(payload)),
|
|
242
|
+
signature
|
|
243
|
+
};
|
|
244
|
+
};
|
|
245
|
+
var splitSdJwt = (sdjwt) => {
|
|
246
|
+
const [encodedJwt, ...encodedDisclosures] = sdjwt.split(SD_SEPARATOR);
|
|
247
|
+
if (encodedDisclosures.length === 0) {
|
|
248
|
+
return {
|
|
249
|
+
jwt: encodedJwt,
|
|
250
|
+
disclosures: []
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
const encodedKeyBindingJwt = encodedDisclosures.pop();
|
|
254
|
+
return {
|
|
255
|
+
jwt: encodedJwt,
|
|
256
|
+
disclosures: encodedDisclosures,
|
|
257
|
+
kbJwt: encodedKeyBindingJwt || void 0
|
|
258
|
+
};
|
|
259
|
+
};
|
|
260
|
+
var decodeSdJwt = (sdjwt, hasher) => __async(null, null, function* () {
|
|
261
|
+
const [encodedJwt, ...encodedDisclosures] = sdjwt.split(SD_SEPARATOR);
|
|
262
|
+
const jwt = decodeJwt(encodedJwt);
|
|
263
|
+
if (encodedDisclosures.length === 0) {
|
|
264
|
+
return {
|
|
265
|
+
jwt,
|
|
266
|
+
disclosures: []
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
const encodedKeyBindingJwt = encodedDisclosures.pop();
|
|
270
|
+
const kbJwt = encodedKeyBindingJwt ? decodeJwt(encodedKeyBindingJwt) : void 0;
|
|
271
|
+
const { _sd_alg } = getSDAlgAndPayload(jwt.payload);
|
|
272
|
+
const disclosures = yield Promise.all(
|
|
273
|
+
encodedDisclosures.map(
|
|
274
|
+
(ed) => Disclosure.fromEncode(ed, { alg: _sd_alg, hasher })
|
|
275
|
+
)
|
|
276
|
+
);
|
|
277
|
+
return {
|
|
278
|
+
jwt,
|
|
279
|
+
disclosures,
|
|
280
|
+
kbJwt
|
|
281
|
+
};
|
|
282
|
+
});
|
|
283
|
+
var decodeSdJwtSync = (sdjwt, hasher) => {
|
|
284
|
+
const [encodedJwt, ...encodedDisclosures] = sdjwt.split(SD_SEPARATOR);
|
|
285
|
+
const jwt = decodeJwt(encodedJwt);
|
|
286
|
+
if (encodedDisclosures.length === 0) {
|
|
287
|
+
return {
|
|
288
|
+
jwt,
|
|
289
|
+
disclosures: []
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
const encodedKeyBindingJwt = encodedDisclosures.pop();
|
|
293
|
+
const kbJwt = encodedKeyBindingJwt ? decodeJwt(encodedKeyBindingJwt) : void 0;
|
|
294
|
+
const { _sd_alg } = getSDAlgAndPayload(jwt.payload);
|
|
295
|
+
const disclosures = encodedDisclosures.map(
|
|
296
|
+
(ed) => Disclosure.fromEncodeSync(ed, { alg: _sd_alg, hasher })
|
|
297
|
+
);
|
|
298
|
+
return {
|
|
299
|
+
jwt,
|
|
300
|
+
disclosures,
|
|
301
|
+
kbJwt
|
|
302
|
+
};
|
|
303
|
+
};
|
|
304
|
+
var getClaims = (rawPayload, disclosures, hasher) => __async(null, null, function* () {
|
|
305
|
+
const { unpackedObj } = yield unpack(rawPayload, disclosures, hasher);
|
|
306
|
+
return unpackedObj;
|
|
307
|
+
});
|
|
308
|
+
var getClaimsSync = (rawPayload, disclosures, hasher) => {
|
|
309
|
+
const { unpackedObj } = unpackSync(rawPayload, disclosures, hasher);
|
|
310
|
+
return unpackedObj;
|
|
311
|
+
};
|
|
312
|
+
var isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
313
|
+
var unpackArray = (arr, map, prefix = "", seenDigests) => {
|
|
314
|
+
const keys = {};
|
|
315
|
+
const unpackedArray = [];
|
|
316
|
+
arr.forEach((item, idx) => {
|
|
317
|
+
if (isRecord(item)) {
|
|
318
|
+
const hash = item[SD_LIST_KEY];
|
|
319
|
+
if (typeof hash === "string") {
|
|
320
|
+
if (seenDigests) {
|
|
321
|
+
if (seenDigests.has(hash)) {
|
|
322
|
+
throw new SDJWTException(
|
|
323
|
+
"Duplicate digest found in SD-JWT payload"
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
seenDigests.add(hash);
|
|
327
|
+
}
|
|
328
|
+
const disclosed = map[hash];
|
|
329
|
+
if (disclosed) {
|
|
330
|
+
const presentKey = prefix ? `${prefix}.${idx}` : `${idx}`;
|
|
331
|
+
keys[presentKey] = hash;
|
|
332
|
+
const { unpackedObj, disclosureKeymap: disclosureKeys } = unpackObjInternal(disclosed.value, map, presentKey, seenDigests);
|
|
333
|
+
unpackedArray.push(unpackedObj);
|
|
334
|
+
Object.assign(keys, disclosureKeys);
|
|
335
|
+
}
|
|
336
|
+
} else {
|
|
337
|
+
const newKey = prefix ? `${prefix}.${idx}` : `${idx}`;
|
|
338
|
+
const { unpackedObj, disclosureKeymap: disclosureKeys } = unpackObjInternal(item, map, newKey, seenDigests);
|
|
339
|
+
unpackedArray.push(unpackedObj);
|
|
340
|
+
Object.assign(keys, disclosureKeys);
|
|
341
|
+
}
|
|
342
|
+
} else if (Array.isArray(item)) {
|
|
343
|
+
const newKey = prefix ? `${prefix}.${idx}` : `${idx}`;
|
|
344
|
+
const { unpackedObj, disclosureKeymap: disclosureKeys } = unpackObjInternal(item, map, newKey, seenDigests);
|
|
345
|
+
unpackedArray.push(unpackedObj);
|
|
346
|
+
Object.assign(keys, disclosureKeys);
|
|
347
|
+
} else {
|
|
348
|
+
unpackedArray.push(item);
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
return { unpackedObj: unpackedArray, disclosureKeymap: keys };
|
|
352
|
+
};
|
|
353
|
+
var unpackObj = (obj, map) => {
|
|
354
|
+
const copiedObj = JSON.parse(JSON.stringify(obj));
|
|
355
|
+
const seenDigests = /* @__PURE__ */ new Set();
|
|
356
|
+
const result = unpackObjInternal(copiedObj, map, "", seenDigests);
|
|
357
|
+
const mapDigests = Object.keys(map);
|
|
358
|
+
const unusedDigests = mapDigests.filter((d) => !seenDigests.has(d));
|
|
359
|
+
if (unusedDigests.length > 0) {
|
|
360
|
+
throw new SDJWTException("Unreferenced disclosure(s) detected in SD-JWT");
|
|
361
|
+
}
|
|
362
|
+
return result;
|
|
363
|
+
};
|
|
364
|
+
var unpackObjInternal = (obj, map, prefix = "", seenDigests) => {
|
|
365
|
+
const keys = {};
|
|
366
|
+
if (typeof obj === "object" && obj !== null) {
|
|
367
|
+
if (Array.isArray(obj)) {
|
|
368
|
+
return unpackArray(obj, map, prefix, seenDigests);
|
|
369
|
+
}
|
|
370
|
+
const record = obj;
|
|
371
|
+
for (const key in record) {
|
|
372
|
+
if (key !== SD_DIGEST && key !== SD_LIST_KEY && typeof record[key] === "object") {
|
|
373
|
+
const newKey = prefix ? `${prefix}.${key}` : key;
|
|
374
|
+
const { unpackedObj: unpackedObj2, disclosureKeymap: disclosureKeys } = unpackObjInternal(record[key], map, newKey, seenDigests);
|
|
375
|
+
record[key] = unpackedObj2;
|
|
376
|
+
Object.assign(keys, disclosureKeys);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
const _a = record, { _sd } = _a, payload = __objRest(_a, ["_sd"]);
|
|
380
|
+
const claims = {};
|
|
381
|
+
if (_sd) {
|
|
382
|
+
for (const hash of _sd) {
|
|
383
|
+
if (seenDigests) {
|
|
384
|
+
if (seenDigests.has(hash)) {
|
|
385
|
+
throw new SDJWTException(
|
|
386
|
+
"Duplicate digest found in SD-JWT payload"
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
seenDigests.add(hash);
|
|
390
|
+
}
|
|
391
|
+
const disclosed = map[hash];
|
|
392
|
+
if (disclosed == null ? void 0 : disclosed.key) {
|
|
393
|
+
if (disclosed.key in payload) {
|
|
394
|
+
throw new SDJWTException(
|
|
395
|
+
`Disclosed claim name "${disclosed.key}" conflicts with existing payload key`
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
const presentKey = prefix ? `${prefix}.${disclosed.key}` : disclosed.key;
|
|
399
|
+
keys[presentKey] = hash;
|
|
400
|
+
const { unpackedObj: unpackedObj2, disclosureKeymap: disclosureKeys } = unpackObjInternal(disclosed.value, map, presentKey, seenDigests);
|
|
401
|
+
claims[disclosed.key] = unpackedObj2;
|
|
402
|
+
Object.assign(keys, disclosureKeys);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
const unpackedObj = Object.assign(payload, claims);
|
|
407
|
+
return { unpackedObj, disclosureKeymap: keys };
|
|
408
|
+
}
|
|
409
|
+
return { unpackedObj: obj, disclosureKeymap: keys };
|
|
410
|
+
};
|
|
411
|
+
var createHashMapping = (disclosures, hash) => __async(null, null, function* () {
|
|
412
|
+
const map = {};
|
|
413
|
+
for (let i = 0; i < disclosures.length; i++) {
|
|
414
|
+
const disclosure = disclosures[i];
|
|
415
|
+
const digest = yield disclosure.digest(hash);
|
|
416
|
+
map[digest] = disclosure;
|
|
417
|
+
}
|
|
418
|
+
return map;
|
|
419
|
+
});
|
|
420
|
+
var createHashMappingSync = (disclosures, hash) => {
|
|
421
|
+
const map = {};
|
|
422
|
+
for (let i = 0; i < disclosures.length; i++) {
|
|
423
|
+
const disclosure = disclosures[i];
|
|
424
|
+
const digest = disclosure.digestSync(hash);
|
|
425
|
+
map[digest] = disclosure;
|
|
426
|
+
}
|
|
427
|
+
return map;
|
|
428
|
+
};
|
|
429
|
+
var getSDAlgAndPayload = (SdJwtPayload) => {
|
|
430
|
+
const _a = SdJwtPayload, { _sd_alg } = _a, payload = __objRest(_a, ["_sd_alg"]);
|
|
431
|
+
if (typeof _sd_alg !== "string") {
|
|
432
|
+
return { _sd_alg: "sha-256", payload };
|
|
433
|
+
}
|
|
434
|
+
return { _sd_alg, payload };
|
|
435
|
+
};
|
|
436
|
+
var unpack = (SdJwtPayload, disclosures, hasher) => __async(null, null, function* () {
|
|
437
|
+
const { _sd_alg, payload } = getSDAlgAndPayload(SdJwtPayload);
|
|
438
|
+
const hash = { hasher, alg: _sd_alg };
|
|
439
|
+
const map = yield createHashMapping(disclosures, hash);
|
|
440
|
+
return unpackObj(payload, map);
|
|
441
|
+
});
|
|
442
|
+
var unpackSync = (SdJwtPayload, disclosures, hasher) => {
|
|
443
|
+
const { _sd_alg, payload } = getSDAlgAndPayload(SdJwtPayload);
|
|
444
|
+
const hash = { hasher, alg: _sd_alg };
|
|
445
|
+
const map = createHashMappingSync(disclosures, hash);
|
|
446
|
+
return unpackObj(payload, map);
|
|
447
|
+
};
|
|
75
448
|
|
|
76
449
|
// src/flattenJSON.ts
|
|
77
|
-
var import_decode = require("@sd-jwt/decode");
|
|
78
|
-
var import_types = require("@sd-jwt/types");
|
|
79
|
-
var import_utils = require("@sd-jwt/utils");
|
|
80
450
|
var FlattenJSON = class _FlattenJSON {
|
|
81
451
|
constructor(data) {
|
|
82
452
|
this.disclosures = data.disclosures;
|
|
@@ -86,10 +456,10 @@ var FlattenJSON = class _FlattenJSON {
|
|
|
86
456
|
this.protected = data.jwtData.protected;
|
|
87
457
|
}
|
|
88
458
|
static fromEncode(encodedSdJwt) {
|
|
89
|
-
const { jwt, disclosures, kbJwt } =
|
|
459
|
+
const { jwt, disclosures, kbJwt } = splitSdJwt(encodedSdJwt);
|
|
90
460
|
const { 0: protectedHeader, 1: payload, 2: signature } = jwt.split(".");
|
|
91
461
|
if (!protectedHeader || !payload || !signature) {
|
|
92
|
-
throw new
|
|
462
|
+
throw new SDJWTException("Invalid JWT");
|
|
93
463
|
}
|
|
94
464
|
return new _FlattenJSON({
|
|
95
465
|
jwtData: {
|
|
@@ -129,19 +499,16 @@ var FlattenJSON = class _FlattenJSON {
|
|
|
129
499
|
const jwt = `${this.protected}.${this.payload}.${this.signature}`;
|
|
130
500
|
data.push(jwt);
|
|
131
501
|
if (this.disclosures && this.disclosures.length > 0) {
|
|
132
|
-
const disclosures = this.disclosures.join(
|
|
502
|
+
const disclosures = this.disclosures.join(SD_SEPARATOR);
|
|
133
503
|
data.push(disclosures);
|
|
134
504
|
}
|
|
135
505
|
const kb_jwt = (_a = this.kb_jwt) != null ? _a : "";
|
|
136
506
|
data.push(kb_jwt);
|
|
137
|
-
return data.join(
|
|
507
|
+
return data.join(SD_SEPARATOR);
|
|
138
508
|
}
|
|
139
509
|
};
|
|
140
510
|
|
|
141
511
|
// src/generalJSON.ts
|
|
142
|
-
var import_decode2 = require("@sd-jwt/decode");
|
|
143
|
-
var import_types2 = require("@sd-jwt/types");
|
|
144
|
-
var import_utils2 = require("@sd-jwt/utils");
|
|
145
512
|
var GeneralJSON = class _GeneralJSON {
|
|
146
513
|
constructor(data) {
|
|
147
514
|
this.payload = data.payload;
|
|
@@ -150,10 +517,10 @@ var GeneralJSON = class _GeneralJSON {
|
|
|
150
517
|
this.signatures = data.signatures;
|
|
151
518
|
}
|
|
152
519
|
static fromEncode(encodedSdJwt) {
|
|
153
|
-
const { jwt, disclosures, kbJwt } =
|
|
520
|
+
const { jwt, disclosures, kbJwt } = splitSdJwt(encodedSdJwt);
|
|
154
521
|
const { 0: protectedHeader, 1: payload, 2: signature } = jwt.split(".");
|
|
155
522
|
if (!protectedHeader || !payload || !signature) {
|
|
156
|
-
throw new
|
|
523
|
+
throw new SDJWTException("Invalid JWT");
|
|
157
524
|
}
|
|
158
525
|
return new _GeneralJSON({
|
|
159
526
|
payload,
|
|
@@ -170,7 +537,7 @@ var GeneralJSON = class _GeneralJSON {
|
|
|
170
537
|
static fromSerialized(json) {
|
|
171
538
|
var _a, _b, _c;
|
|
172
539
|
if (!json.signatures[0]) {
|
|
173
|
-
throw new
|
|
540
|
+
throw new SDJWTException("Invalid JSON");
|
|
174
541
|
}
|
|
175
542
|
const disclosures = (_b = (_a = json.signatures[0].header) == null ? void 0 : _a.disclosures) != null ? _b : [];
|
|
176
543
|
const kb_jwt = (_c = json.signatures[0].header) == null ? void 0 : _c.kb_jwt;
|
|
@@ -216,23 +583,23 @@ var GeneralJSON = class _GeneralJSON {
|
|
|
216
583
|
toEncoded(index) {
|
|
217
584
|
var _a;
|
|
218
585
|
if (index < 0 || index >= this.signatures.length) {
|
|
219
|
-
throw new
|
|
586
|
+
throw new SDJWTException("Index out of bounds");
|
|
220
587
|
}
|
|
221
588
|
const data = [];
|
|
222
589
|
const { protected: protectedHeader, signature } = this.signatures[index];
|
|
223
590
|
const jwt = `${protectedHeader}.${this.payload}.${signature}`;
|
|
224
591
|
data.push(jwt);
|
|
225
592
|
if (this.disclosures && this.disclosures.length > 0) {
|
|
226
|
-
const disclosures = this.disclosures.join(
|
|
593
|
+
const disclosures = this.disclosures.join(SD_SEPARATOR);
|
|
227
594
|
data.push(disclosures);
|
|
228
595
|
}
|
|
229
596
|
const kb = (_a = this.kb_jwt) != null ? _a : "";
|
|
230
597
|
data.push(kb);
|
|
231
|
-
return data.join(
|
|
598
|
+
return data.join(SD_SEPARATOR);
|
|
232
599
|
}
|
|
233
600
|
addSignature(protectedHeader, signer, kid) {
|
|
234
601
|
return __async(this, null, function* () {
|
|
235
|
-
const header = (0,
|
|
602
|
+
const header = (0, import_identity_common.base64urlEncode)(JSON.stringify(protectedHeader));
|
|
236
603
|
const signature = yield signer(`${header}.${this.payload}`);
|
|
237
604
|
this.signatures.push({
|
|
238
605
|
protected: header,
|
|
@@ -244,8 +611,6 @@ var GeneralJSON = class _GeneralJSON {
|
|
|
244
611
|
};
|
|
245
612
|
|
|
246
613
|
// src/jwt.ts
|
|
247
|
-
var import_decode3 = require("@sd-jwt/decode");
|
|
248
|
-
var import_utils3 = require("@sd-jwt/utils");
|
|
249
614
|
var Jwt = class _Jwt {
|
|
250
615
|
constructor(data) {
|
|
251
616
|
this.header = data == null ? void 0 : data.header;
|
|
@@ -254,7 +619,7 @@ var Jwt = class _Jwt {
|
|
|
254
619
|
this.encoded = data == null ? void 0 : data.encoded;
|
|
255
620
|
}
|
|
256
621
|
static decodeJWT(jwt) {
|
|
257
|
-
return
|
|
622
|
+
return decodeJwt(jwt);
|
|
258
623
|
}
|
|
259
624
|
static fromEncode(encodedJwt) {
|
|
260
625
|
const { header, payload, signature } = _Jwt.decodeJWT(
|
|
@@ -280,18 +645,18 @@ var Jwt = class _Jwt {
|
|
|
280
645
|
}
|
|
281
646
|
getUnsignedToken() {
|
|
282
647
|
if (!this.header || !this.payload) {
|
|
283
|
-
throw new
|
|
648
|
+
throw new SDJWTException("Serialize Error: Invalid JWT");
|
|
284
649
|
}
|
|
285
650
|
if (this.encoded) {
|
|
286
651
|
const parts = this.encoded.split(".");
|
|
287
652
|
if (parts.length !== 3) {
|
|
288
|
-
throw new
|
|
653
|
+
throw new SDJWTException(`Invalid JWT format: ${this.encoded}`);
|
|
289
654
|
}
|
|
290
655
|
const unsignedToken = parts.slice(0, 2).join(".");
|
|
291
656
|
return unsignedToken;
|
|
292
657
|
}
|
|
293
|
-
const header = (0,
|
|
294
|
-
const payload = (0,
|
|
658
|
+
const header = (0, import_identity_common.base64urlEncode)(JSON.stringify(this.header));
|
|
659
|
+
const payload = (0, import_identity_common.base64urlEncode)(JSON.stringify(this.payload));
|
|
295
660
|
return `${header}.${payload}`;
|
|
296
661
|
}
|
|
297
662
|
sign(signer) {
|
|
@@ -306,10 +671,10 @@ var Jwt = class _Jwt {
|
|
|
306
671
|
return this.encoded;
|
|
307
672
|
}
|
|
308
673
|
if (!this.header || !this.payload || !this.signature) {
|
|
309
|
-
throw new
|
|
674
|
+
throw new SDJWTException("Serialize Error: Invalid JWT");
|
|
310
675
|
}
|
|
311
|
-
const header = (0,
|
|
312
|
-
const payload = (0,
|
|
676
|
+
const header = (0, import_identity_common.base64urlEncode)(JSON.stringify(this.header));
|
|
677
|
+
const payload = (0, import_identity_common.base64urlEncode)(JSON.stringify(this.payload));
|
|
313
678
|
const signature = this.signature;
|
|
314
679
|
const compact = `${header}.${payload}.${signature}`;
|
|
315
680
|
this.encoded = compact;
|
|
@@ -327,22 +692,25 @@ var Jwt = class _Jwt {
|
|
|
327
692
|
var _a, _b, _c, _d;
|
|
328
693
|
const skew = (options == null ? void 0 : options.skewSeconds) ? options.skewSeconds : 0;
|
|
329
694
|
const currentDate = (_a = options == null ? void 0 : options.currentDate) != null ? _a : Math.floor(Date.now() / 1e3);
|
|
330
|
-
|
|
331
|
-
|
|
695
|
+
const iat = (_b = this.payload) == null ? void 0 : _b.iat;
|
|
696
|
+
const nbf = (_c = this.payload) == null ? void 0 : _c.nbf;
|
|
697
|
+
const exp = (_d = this.payload) == null ? void 0 : _d.exp;
|
|
698
|
+
if (typeof iat === "number" && iat - skew > currentDate) {
|
|
699
|
+
throw new SDJWTException("Verify Error: JWT is not yet valid");
|
|
332
700
|
}
|
|
333
|
-
if (
|
|
334
|
-
throw new
|
|
701
|
+
if (typeof nbf === "number" && nbf - skew > currentDate) {
|
|
702
|
+
throw new SDJWTException("Verify Error: JWT is not yet valid");
|
|
335
703
|
}
|
|
336
|
-
if (
|
|
337
|
-
throw new
|
|
704
|
+
if (typeof exp === "number" && exp + skew < currentDate) {
|
|
705
|
+
throw new SDJWTException("Verify Error: JWT is expired");
|
|
338
706
|
}
|
|
339
707
|
if (!this.signature) {
|
|
340
|
-
throw new
|
|
708
|
+
throw new SDJWTException("Verify Error: no signature in JWT");
|
|
341
709
|
}
|
|
342
710
|
const data = this.getUnsignedToken();
|
|
343
711
|
const verified = yield verifier(data, this.signature, options);
|
|
344
712
|
if (!verified) {
|
|
345
|
-
throw new
|
|
713
|
+
throw new SDJWTException("Verify Error: Invalid JWT Signature");
|
|
346
714
|
}
|
|
347
715
|
return { payload: this.payload, header: this.header };
|
|
348
716
|
});
|
|
@@ -350,20 +718,17 @@ var Jwt = class _Jwt {
|
|
|
350
718
|
};
|
|
351
719
|
|
|
352
720
|
// src/kbjwt.ts
|
|
353
|
-
var import_types3 = require("@sd-jwt/types");
|
|
354
|
-
var import_utils4 = require("@sd-jwt/utils");
|
|
355
721
|
var KBJwt = class _KBJwt extends Jwt {
|
|
356
722
|
// Checking the validity of the key binding jwt
|
|
357
723
|
// the type unknown is not good, but we don't know at this point how to get the public key of the signer, this is defined in the kbVerifier
|
|
358
724
|
verifyKB(values) {
|
|
359
725
|
return __async(this, null, function* () {
|
|
360
|
-
var _a;
|
|
361
726
|
if (!this.header || !this.payload || !this.signature) {
|
|
362
|
-
throw new
|
|
727
|
+
throw new SDJWTException("Verify Error: Invalid JWT");
|
|
363
728
|
}
|
|
364
|
-
if (!this.header.alg || this.header.alg === "none" || !this.header.typ || this.header.typ !==
|
|
365
|
-
!(this.payload.sd_hash ||
|
|
366
|
-
throw new
|
|
729
|
+
if (!this.header.alg || this.header.alg === "none" || !this.header.typ || this.header.typ !== KB_JWT_TYP || !this.payload.iat || !this.payload.aud || !this.payload.nonce || // this is for backward compatibility with version 06
|
|
730
|
+
!(this.payload.sd_hash || "_sd_hash" in this.payload && this.payload._sd_hash)) {
|
|
731
|
+
throw new SDJWTException("Invalid Key Binding Jwt");
|
|
367
732
|
}
|
|
368
733
|
const data = this.getUnsignedToken();
|
|
369
734
|
const verified = yield values.verifier(
|
|
@@ -372,10 +737,10 @@ var KBJwt = class _KBJwt extends Jwt {
|
|
|
372
737
|
values.payload
|
|
373
738
|
);
|
|
374
739
|
if (!verified) {
|
|
375
|
-
throw new
|
|
740
|
+
throw new SDJWTException("Verify Error: Invalid JWT Signature");
|
|
376
741
|
}
|
|
377
742
|
if (this.payload.nonce !== values.nonce) {
|
|
378
|
-
throw new
|
|
743
|
+
throw new SDJWTException("Verify Error: Invalid Nonce");
|
|
379
744
|
}
|
|
380
745
|
return { payload: this.payload, header: this.header };
|
|
381
746
|
});
|
|
@@ -395,20 +760,117 @@ var KBJwt = class _KBJwt extends Jwt {
|
|
|
395
760
|
}
|
|
396
761
|
};
|
|
397
762
|
|
|
398
|
-
// src/sdjwt.ts
|
|
399
|
-
var import_decode4 = require("@sd-jwt/decode");
|
|
400
|
-
var import_present = require("@sd-jwt/present");
|
|
401
|
-
var import_types4 = require("@sd-jwt/types");
|
|
402
|
-
var import_utils6 = require("@sd-jwt/utils");
|
|
403
|
-
|
|
404
763
|
// src/decoy.ts
|
|
405
|
-
var import_utils5 = require("@sd-jwt/utils");
|
|
406
764
|
var createDecoy = (hash, saltGenerator) => __async(null, null, function* () {
|
|
407
765
|
const { hasher, alg } = hash;
|
|
408
766
|
const salt = yield saltGenerator(16);
|
|
409
767
|
const decoy = yield hasher(salt, alg);
|
|
410
|
-
return (0,
|
|
768
|
+
return (0, import_identity_common.uint8ArrayToBase64Url)(decoy);
|
|
769
|
+
});
|
|
770
|
+
|
|
771
|
+
// src/present/present.ts
|
|
772
|
+
var presentableKeys = (rawPayload, disclosures, hasher) => __async(null, null, function* () {
|
|
773
|
+
const { disclosureKeymap } = yield unpack(rawPayload, disclosures, hasher);
|
|
774
|
+
return Object.keys(disclosureKeymap).sort();
|
|
775
|
+
});
|
|
776
|
+
var presentableKeysSync = (rawPayload, disclosures, hasher) => {
|
|
777
|
+
const { disclosureKeymap } = unpackSync(rawPayload, disclosures, hasher);
|
|
778
|
+
return Object.keys(disclosureKeymap).sort();
|
|
779
|
+
};
|
|
780
|
+
var present = (sdJwt, presentFrame, hasher) => __async(null, null, function* () {
|
|
781
|
+
const { jwt, kbJwt } = splitSdJwt(sdJwt);
|
|
782
|
+
const {
|
|
783
|
+
jwt: { payload },
|
|
784
|
+
disclosures
|
|
785
|
+
} = yield decodeSdJwt(sdJwt, hasher);
|
|
786
|
+
const { _sd_alg: alg } = getSDAlgAndPayload(payload);
|
|
787
|
+
const hash = { alg, hasher };
|
|
788
|
+
const keys = transformPresentationFrame(presentFrame);
|
|
789
|
+
const hashmap = yield createHashMapping(disclosures, hash);
|
|
790
|
+
const { disclosureKeymap } = yield unpack(payload, disclosures, hasher);
|
|
791
|
+
const presentedDisclosures = keys.map((k) => hashmap[disclosureKeymap[k]]).filter((d) => d !== void 0);
|
|
792
|
+
return [
|
|
793
|
+
jwt,
|
|
794
|
+
...presentedDisclosures.map((d) => d.encode()),
|
|
795
|
+
kbJwt != null ? kbJwt : ""
|
|
796
|
+
].join(SD_SEPARATOR);
|
|
411
797
|
});
|
|
798
|
+
var presentSync = (sdJwt, presentFrame, hasher) => {
|
|
799
|
+
const { jwt, kbJwt } = splitSdJwt(sdJwt);
|
|
800
|
+
const {
|
|
801
|
+
jwt: { payload },
|
|
802
|
+
disclosures
|
|
803
|
+
} = decodeSdJwtSync(sdJwt, hasher);
|
|
804
|
+
const { _sd_alg: alg } = getSDAlgAndPayload(payload);
|
|
805
|
+
const hash = { alg, hasher };
|
|
806
|
+
const keys = transformPresentationFrame(presentFrame);
|
|
807
|
+
const hashmap = createHashMappingSync(disclosures, hash);
|
|
808
|
+
const { disclosureKeymap } = unpackSync(payload, disclosures, hasher);
|
|
809
|
+
const presentedDisclosures = keys.map((k) => hashmap[disclosureKeymap[k]]).filter((d) => d !== void 0);
|
|
810
|
+
return [
|
|
811
|
+
jwt,
|
|
812
|
+
...presentedDisclosures.map((d) => d.encode()),
|
|
813
|
+
kbJwt != null ? kbJwt : ""
|
|
814
|
+
].join(SD_SEPARATOR);
|
|
815
|
+
};
|
|
816
|
+
var transformPresentationFrame = (obj, prefix = "") => {
|
|
817
|
+
return Object.entries(obj).reduce((acc, [key, value]) => {
|
|
818
|
+
const newPrefix = prefix ? `${prefix}.${key}` : key;
|
|
819
|
+
if (typeof value === "boolean") {
|
|
820
|
+
if (value) {
|
|
821
|
+
acc.push(newPrefix);
|
|
822
|
+
}
|
|
823
|
+
} else if (typeof value === "object" && value !== null) {
|
|
824
|
+
acc.push(
|
|
825
|
+
newPrefix,
|
|
826
|
+
...transformPresentationFrame(
|
|
827
|
+
value,
|
|
828
|
+
newPrefix
|
|
829
|
+
)
|
|
830
|
+
);
|
|
831
|
+
}
|
|
832
|
+
return acc;
|
|
833
|
+
}, []);
|
|
834
|
+
};
|
|
835
|
+
var createHashMappingForSerializedDisclosure = (disclosures) => {
|
|
836
|
+
const map = {};
|
|
837
|
+
for (let i = 0; i < disclosures.length; i++) {
|
|
838
|
+
const disclosure = disclosures[i];
|
|
839
|
+
const { digest, encoded, key, salt, value } = disclosure;
|
|
840
|
+
map[digest] = Disclosure.fromArray(
|
|
841
|
+
key ? [salt, key, value] : [salt, value],
|
|
842
|
+
{ digest, encoded }
|
|
843
|
+
);
|
|
844
|
+
}
|
|
845
|
+
return map;
|
|
846
|
+
};
|
|
847
|
+
var selectDisclosures = (payload, disclosures, presentationFrame) => {
|
|
848
|
+
if (disclosures.length === 0) {
|
|
849
|
+
return [];
|
|
850
|
+
}
|
|
851
|
+
const hashmap = createHashMappingForSerializedDisclosure(disclosures);
|
|
852
|
+
const { disclosureKeymap } = unpackObj(payload, hashmap);
|
|
853
|
+
const keys = transformPresentationFrame(presentationFrame);
|
|
854
|
+
const presentedDisclosures = keys.map((k) => hashmap[disclosureKeymap[k]]).filter((d) => d !== void 0);
|
|
855
|
+
const selectedDisclosures = presentedDisclosures.map(
|
|
856
|
+
(d) => {
|
|
857
|
+
const { salt, key, value, _digest } = d;
|
|
858
|
+
if (!_digest) {
|
|
859
|
+
throw new SDJWTException(
|
|
860
|
+
"Implementation error: _digest is not defined"
|
|
861
|
+
);
|
|
862
|
+
}
|
|
863
|
+
return {
|
|
864
|
+
digest: _digest,
|
|
865
|
+
encoded: d.encode(),
|
|
866
|
+
salt,
|
|
867
|
+
key,
|
|
868
|
+
value
|
|
869
|
+
};
|
|
870
|
+
}
|
|
871
|
+
);
|
|
872
|
+
return selectedDisclosures;
|
|
873
|
+
};
|
|
412
874
|
|
|
413
875
|
// src/sdjwt.ts
|
|
414
876
|
var SDJwt = class _SDJwt {
|
|
@@ -419,7 +881,7 @@ var SDJwt = class _SDJwt {
|
|
|
419
881
|
}
|
|
420
882
|
static decodeSDJwt(sdjwt, hasher) {
|
|
421
883
|
return __async(this, null, function* () {
|
|
422
|
-
const [encodedJwt, ...encodedDisclosures] = sdjwt.split(
|
|
884
|
+
const [encodedJwt, ...encodedDisclosures] = sdjwt.split(SD_SEPARATOR);
|
|
423
885
|
const jwt = Jwt.fromEncode(encodedJwt);
|
|
424
886
|
if (!jwt.payload) {
|
|
425
887
|
throw new Error("Payload is undefined on the JWT. Invalid state reached");
|
|
@@ -432,10 +894,10 @@ var SDJwt = class _SDJwt {
|
|
|
432
894
|
}
|
|
433
895
|
const encodedKeyBindingJwt = encodedDisclosures.pop();
|
|
434
896
|
const kbJwt = encodedKeyBindingJwt ? KBJwt.fromKBEncode(encodedKeyBindingJwt) : void 0;
|
|
435
|
-
const { _sd_alg } =
|
|
897
|
+
const { _sd_alg } = getSDAlgAndPayload(jwt.payload);
|
|
436
898
|
const disclosures = yield Promise.all(
|
|
437
899
|
encodedDisclosures.map(
|
|
438
|
-
(ed) =>
|
|
900
|
+
(ed) => Disclosure.fromEncode(ed, { alg: _sd_alg, hasher })
|
|
439
901
|
)
|
|
440
902
|
);
|
|
441
903
|
return {
|
|
@@ -447,7 +909,7 @@ var SDJwt = class _SDJwt {
|
|
|
447
909
|
}
|
|
448
910
|
static extractJwt(encodedSdJwt) {
|
|
449
911
|
return __async(this, null, function* () {
|
|
450
|
-
const [encodedJwt, ..._encodedDisclosures] = encodedSdJwt.split(
|
|
912
|
+
const [encodedJwt, ..._encodedDisclosures] = encodedSdJwt.split(SD_SEPARATOR);
|
|
451
913
|
return Jwt.fromEncode(encodedJwt);
|
|
452
914
|
});
|
|
453
915
|
}
|
|
@@ -476,17 +938,17 @@ var SDJwt = class _SDJwt {
|
|
|
476
938
|
return __async(this, null, function* () {
|
|
477
939
|
var _a;
|
|
478
940
|
if (!((_a = this.jwt) == null ? void 0 : _a.payload) || !this.disclosures) {
|
|
479
|
-
throw new
|
|
941
|
+
throw new SDJWTException("Invalid sd-jwt: jwt or disclosures is missing");
|
|
480
942
|
}
|
|
481
|
-
const { _sd_alg: alg } =
|
|
943
|
+
const { _sd_alg: alg } = getSDAlgAndPayload(this.jwt.payload);
|
|
482
944
|
const hash = { alg, hasher };
|
|
483
|
-
const hashmap = yield
|
|
484
|
-
const { disclosureKeymap } = yield
|
|
945
|
+
const hashmap = yield createHashMapping(this.disclosures, hash);
|
|
946
|
+
const { disclosureKeymap } = yield unpack(
|
|
485
947
|
this.jwt.payload,
|
|
486
948
|
this.disclosures,
|
|
487
949
|
hasher
|
|
488
950
|
);
|
|
489
|
-
const keys = presentFrame ?
|
|
951
|
+
const keys = presentFrame ? transformPresentationFrame(presentFrame) : yield this.presentableKeys(hasher);
|
|
490
952
|
const disclosures = keys.map((k) => hashmap[disclosureKeymap[k]]).filter((d) => d !== void 0);
|
|
491
953
|
return disclosures;
|
|
492
954
|
});
|
|
@@ -494,16 +956,16 @@ var SDJwt = class _SDJwt {
|
|
|
494
956
|
encodeSDJwt() {
|
|
495
957
|
const data = [];
|
|
496
958
|
if (!this.jwt) {
|
|
497
|
-
throw new
|
|
959
|
+
throw new SDJWTException("Invalid sd-jwt: jwt is missing");
|
|
498
960
|
}
|
|
499
961
|
const encodedJwt = this.jwt.encodeJwt();
|
|
500
962
|
data.push(encodedJwt);
|
|
501
963
|
if (this.disclosures && this.disclosures.length > 0) {
|
|
502
|
-
const encodeddisclosures = this.disclosures.map((dc) => dc.encode()).join(
|
|
964
|
+
const encodeddisclosures = this.disclosures.map((dc) => dc.encode()).join(SD_SEPARATOR);
|
|
503
965
|
data.push(encodeddisclosures);
|
|
504
966
|
}
|
|
505
967
|
data.push(this.kbJwt ? this.kbJwt.encodeJwt() : "");
|
|
506
|
-
return data.join(
|
|
968
|
+
return data.join(SD_SEPARATOR);
|
|
507
969
|
}
|
|
508
970
|
keys(hasher) {
|
|
509
971
|
return __async(this, null, function* () {
|
|
@@ -514,9 +976,9 @@ var SDJwt = class _SDJwt {
|
|
|
514
976
|
return __async(this, null, function* () {
|
|
515
977
|
var _a, _b;
|
|
516
978
|
if (!((_a = this.jwt) == null ? void 0 : _a.payload) || !this.disclosures) {
|
|
517
|
-
throw new
|
|
979
|
+
throw new SDJWTException("Invalid sd-jwt: jwt or disclosures is missing");
|
|
518
980
|
}
|
|
519
|
-
const { disclosureKeymap } = yield
|
|
981
|
+
const { disclosureKeymap } = yield unpack(
|
|
520
982
|
(_b = this.jwt) == null ? void 0 : _b.payload,
|
|
521
983
|
this.disclosures,
|
|
522
984
|
hasher
|
|
@@ -528,9 +990,9 @@ var SDJwt = class _SDJwt {
|
|
|
528
990
|
return __async(this, null, function* () {
|
|
529
991
|
var _a;
|
|
530
992
|
if (!((_a = this.jwt) == null ? void 0 : _a.payload) || !this.disclosures) {
|
|
531
|
-
throw new
|
|
993
|
+
throw new SDJWTException("Invalid sd-jwt: jwt or disclosures is missing");
|
|
532
994
|
}
|
|
533
|
-
const { unpackedObj } = yield
|
|
995
|
+
const { unpackedObj } = yield unpack(
|
|
534
996
|
this.jwt.payload,
|
|
535
997
|
this.disclosures,
|
|
536
998
|
hasher
|
|
@@ -545,8 +1007,9 @@ var listKeys = (obj, prefix = "") => {
|
|
|
545
1007
|
if (obj[key] === void 0) continue;
|
|
546
1008
|
const newKey = prefix ? `${prefix}.${key}` : key;
|
|
547
1009
|
keys.push(newKey);
|
|
548
|
-
|
|
549
|
-
|
|
1010
|
+
const value = obj[key];
|
|
1011
|
+
if (value && typeof value === "object") {
|
|
1012
|
+
keys.push(...listKeys(value, newKey));
|
|
550
1013
|
}
|
|
551
1014
|
}
|
|
552
1015
|
return keys;
|
|
@@ -559,14 +1022,14 @@ var pack = (claims, disclosureFrame, hash, saltGenerator) => __async(null, null,
|
|
|
559
1022
|
disclosures: []
|
|
560
1023
|
};
|
|
561
1024
|
}
|
|
562
|
-
const sd = (_a = disclosureFrame[
|
|
563
|
-
const decoyCount = (_b = disclosureFrame[
|
|
1025
|
+
const sd = (_a = disclosureFrame[SD_DIGEST]) != null ? _a : [];
|
|
1026
|
+
const decoyCount = (_b = disclosureFrame[SD_DECOY]) != null ? _b : 0;
|
|
564
1027
|
if (Array.isArray(claims)) {
|
|
565
1028
|
const packedClaims2 = [];
|
|
566
1029
|
const disclosures2 = [];
|
|
567
1030
|
const recursivePackedClaims2 = {};
|
|
568
1031
|
for (const key in disclosureFrame) {
|
|
569
|
-
if (key !==
|
|
1032
|
+
if (key !== SD_DIGEST) {
|
|
570
1033
|
const idx = Number.parseInt(key, 10);
|
|
571
1034
|
const packed = yield pack(
|
|
572
1035
|
claims[idx],
|
|
@@ -582,9 +1045,9 @@ var pack = (claims, disclosureFrame, hash, saltGenerator) => __async(null, null,
|
|
|
582
1045
|
const claim = recursivePackedClaims2[i] ? recursivePackedClaims2[i] : claims[i];
|
|
583
1046
|
if (sd.includes(i)) {
|
|
584
1047
|
const salt = yield saltGenerator(16);
|
|
585
|
-
const disclosure = new
|
|
1048
|
+
const disclosure = new Disclosure([salt, claim]);
|
|
586
1049
|
const digest = yield disclosure.digest(hash);
|
|
587
|
-
packedClaims2.push({ [
|
|
1050
|
+
packedClaims2.push({ [SD_LIST_KEY]: digest });
|
|
588
1051
|
disclosures2.push(disclosure);
|
|
589
1052
|
} else {
|
|
590
1053
|
packedClaims2.push(claim);
|
|
@@ -592,7 +1055,7 @@ var pack = (claims, disclosureFrame, hash, saltGenerator) => __async(null, null,
|
|
|
592
1055
|
}
|
|
593
1056
|
for (let j = 0; j < decoyCount; j++) {
|
|
594
1057
|
const decoyDigest = yield createDecoy(hash, saltGenerator);
|
|
595
|
-
packedClaims2.push({ [
|
|
1058
|
+
packedClaims2.push({ [SD_LIST_KEY]: decoyDigest });
|
|
596
1059
|
}
|
|
597
1060
|
return { packedClaims: packedClaims2, disclosures: disclosures2 };
|
|
598
1061
|
}
|
|
@@ -600,7 +1063,7 @@ var pack = (claims, disclosureFrame, hash, saltGenerator) => __async(null, null,
|
|
|
600
1063
|
const disclosures = [];
|
|
601
1064
|
const recursivePackedClaims = {};
|
|
602
1065
|
for (const key in disclosureFrame) {
|
|
603
|
-
if (key !==
|
|
1066
|
+
if (key !== SD_DIGEST) {
|
|
604
1067
|
const packed = yield pack(
|
|
605
1068
|
// @ts-expect-error
|
|
606
1069
|
claims[key],
|
|
@@ -617,7 +1080,7 @@ var pack = (claims, disclosureFrame, hash, saltGenerator) => __async(null, null,
|
|
|
617
1080
|
const claim = recursivePackedClaims[key] ? recursivePackedClaims[key] : claims[key];
|
|
618
1081
|
if (sd.includes(key)) {
|
|
619
1082
|
const salt = yield saltGenerator(16);
|
|
620
|
-
const disclosure = new
|
|
1083
|
+
const disclosure = new Disclosure([salt, key, claim]);
|
|
621
1084
|
const digest = yield disclosure.digest(hash);
|
|
622
1085
|
_sd.push(digest);
|
|
623
1086
|
disclosures.push(disclosure);
|
|
@@ -630,7 +1093,7 @@ var pack = (claims, disclosureFrame, hash, saltGenerator) => __async(null, null,
|
|
|
630
1093
|
_sd.push(decoyDigest);
|
|
631
1094
|
}
|
|
632
1095
|
if (_sd.length > 0) {
|
|
633
|
-
packedClaims[
|
|
1096
|
+
packedClaims[SD_DIGEST] = _sd.sort();
|
|
634
1097
|
}
|
|
635
1098
|
return { packedClaims, disclosures };
|
|
636
1099
|
});
|
|
@@ -640,8 +1103,8 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
640
1103
|
constructor(userConfig) {
|
|
641
1104
|
this.userConfig = {};
|
|
642
1105
|
if (userConfig) {
|
|
643
|
-
if (userConfig.hashAlg && !
|
|
644
|
-
throw new
|
|
1106
|
+
if (userConfig.hashAlg && !IANA_HASH_ALGORITHMS.includes(userConfig.hashAlg)) {
|
|
1107
|
+
throw new SDJWTException(
|
|
645
1108
|
`Invalid hash algorithm: ${userConfig.hashAlg}`
|
|
646
1109
|
);
|
|
647
1110
|
}
|
|
@@ -651,15 +1114,15 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
651
1114
|
createKBJwt(options, sdHash) {
|
|
652
1115
|
return __async(this, null, function* () {
|
|
653
1116
|
if (!this.userConfig.kbSigner) {
|
|
654
|
-
throw new
|
|
1117
|
+
throw new SDJWTException("Key Binding Signer not found");
|
|
655
1118
|
}
|
|
656
1119
|
if (!this.userConfig.kbSignAlg) {
|
|
657
|
-
throw new
|
|
1120
|
+
throw new SDJWTException("Key Binding sign algorithm not specified");
|
|
658
1121
|
}
|
|
659
1122
|
const { payload } = options;
|
|
660
1123
|
const kbJwt = new KBJwt({
|
|
661
1124
|
header: {
|
|
662
|
-
typ:
|
|
1125
|
+
typ: KB_JWT_TYP,
|
|
663
1126
|
alg: this.userConfig.kbSignAlg
|
|
664
1127
|
},
|
|
665
1128
|
payload: __spreadProps(__spreadValues({}, payload), { sd_hash: sdHash })
|
|
@@ -671,7 +1134,7 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
671
1134
|
SignJwt(jwt) {
|
|
672
1135
|
return __async(this, null, function* () {
|
|
673
1136
|
if (!this.userConfig.signer) {
|
|
674
|
-
throw new
|
|
1137
|
+
throw new SDJWTException("Signer not found");
|
|
675
1138
|
}
|
|
676
1139
|
yield jwt.sign(this.userConfig.signer);
|
|
677
1140
|
return jwt;
|
|
@@ -680,7 +1143,7 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
680
1143
|
VerifyJwt(jwt, options) {
|
|
681
1144
|
return __async(this, null, function* () {
|
|
682
1145
|
if (!this.userConfig.verifier) {
|
|
683
|
-
throw new
|
|
1146
|
+
throw new SDJWTException("Verifier not found");
|
|
684
1147
|
}
|
|
685
1148
|
return jwt.verify(this.userConfig.verifier, options);
|
|
686
1149
|
});
|
|
@@ -689,13 +1152,13 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
689
1152
|
return __async(this, null, function* () {
|
|
690
1153
|
var _a, _b;
|
|
691
1154
|
if (!this.userConfig.hasher) {
|
|
692
|
-
throw new
|
|
1155
|
+
throw new SDJWTException("Hasher not found");
|
|
693
1156
|
}
|
|
694
1157
|
if (!this.userConfig.saltGenerator) {
|
|
695
|
-
throw new
|
|
1158
|
+
throw new SDJWTException("SaltGenerator not found");
|
|
696
1159
|
}
|
|
697
1160
|
if (!this.userConfig.signAlg) {
|
|
698
|
-
throw new
|
|
1161
|
+
throw new SDJWTException("sign alogrithm not specified");
|
|
699
1162
|
}
|
|
700
1163
|
if (disclosureFrame) {
|
|
701
1164
|
this.validateReservedFields(disclosureFrame);
|
|
@@ -738,11 +1201,11 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
738
1201
|
return __async(this, null, function* () {
|
|
739
1202
|
var _a;
|
|
740
1203
|
if (!this.userConfig.hasher) {
|
|
741
|
-
throw new
|
|
1204
|
+
throw new SDJWTException("Hasher not found");
|
|
742
1205
|
}
|
|
743
1206
|
const hasher = this.userConfig.hasher;
|
|
744
1207
|
const sdjwt = yield SDJwt.fromEncode(encodedSDJwt, hasher);
|
|
745
|
-
if (!((_a = sdjwt.jwt) == null ? void 0 : _a.payload)) throw new
|
|
1208
|
+
if (!((_a = sdjwt.jwt) == null ? void 0 : _a.payload)) throw new SDJWTException("Payload not found");
|
|
746
1209
|
const presentSdJwtWithoutKb = yield sdjwt.present(
|
|
747
1210
|
presentationFrame,
|
|
748
1211
|
hasher
|
|
@@ -765,12 +1228,12 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
765
1228
|
verify(encodedSDJwt, options) {
|
|
766
1229
|
return __async(this, null, function* () {
|
|
767
1230
|
if (!this.userConfig.hasher) {
|
|
768
|
-
throw new
|
|
1231
|
+
throw new SDJWTException("Hasher not found");
|
|
769
1232
|
}
|
|
770
1233
|
const hasher = this.userConfig.hasher;
|
|
771
1234
|
const sdjwt = yield SDJwt.fromEncode(encodedSDJwt, hasher);
|
|
772
1235
|
if (!sdjwt.jwt || !sdjwt.jwt.payload) {
|
|
773
|
-
throw new
|
|
1236
|
+
throw new SDJWTException("Invalid SD JWT");
|
|
774
1237
|
}
|
|
775
1238
|
const { payload, header } = yield this.validate(encodedSDJwt, options);
|
|
776
1239
|
if (options == null ? void 0 : options.requiredClaimKeys) {
|
|
@@ -779,7 +1242,7 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
779
1242
|
(k) => !keys.includes(k)
|
|
780
1243
|
);
|
|
781
1244
|
if (missingKeys.length > 0) {
|
|
782
|
-
throw new
|
|
1245
|
+
throw new SDJWTException(
|
|
783
1246
|
`Missing required claim keys: ${missingKeys.join(", ")}`
|
|
784
1247
|
);
|
|
785
1248
|
}
|
|
@@ -788,10 +1251,10 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
788
1251
|
return { payload, header };
|
|
789
1252
|
}
|
|
790
1253
|
if (!sdjwt.kbJwt) {
|
|
791
|
-
throw new
|
|
1254
|
+
throw new SDJWTException("Key Binding JWT not exist");
|
|
792
1255
|
}
|
|
793
1256
|
if (!this.userConfig.kbVerifier) {
|
|
794
|
-
throw new
|
|
1257
|
+
throw new SDJWTException("Key Binding Verifier not found");
|
|
795
1258
|
}
|
|
796
1259
|
const kb = yield sdjwt.kbJwt.verifyKB({
|
|
797
1260
|
verifier: this.userConfig.kbVerifier,
|
|
@@ -813,7 +1276,7 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
813
1276
|
hasher
|
|
814
1277
|
);
|
|
815
1278
|
if (sdHashStr !== sdHashfromKb) {
|
|
816
|
-
throw new
|
|
1279
|
+
throw new SDJWTException("Invalid sd_hash in Key Binding JWT");
|
|
817
1280
|
}
|
|
818
1281
|
return { payload, header, kb };
|
|
819
1282
|
});
|
|
@@ -859,6 +1322,9 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
859
1322
|
if (errors.length > 0) {
|
|
860
1323
|
return { success: false, errors };
|
|
861
1324
|
}
|
|
1325
|
+
if (!this.userConfig.hasher) {
|
|
1326
|
+
throw new SDJWTException("Hasher not found");
|
|
1327
|
+
}
|
|
862
1328
|
const hasher = this.userConfig.hasher;
|
|
863
1329
|
let sdjwt;
|
|
864
1330
|
let payload;
|
|
@@ -868,7 +1334,8 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
868
1334
|
if (!sdjwt.jwt || !sdjwt.jwt.payload) {
|
|
869
1335
|
addError("INVALID_SD_JWT", "Invalid SD JWT: missing JWT or payload");
|
|
870
1336
|
}
|
|
871
|
-
} catch (
|
|
1337
|
+
} catch (e) {
|
|
1338
|
+
const error = ensureError(e);
|
|
872
1339
|
addError(
|
|
873
1340
|
"INVALID_SD_JWT",
|
|
874
1341
|
`Failed to decode SD-JWT: ${error.message}`,
|
|
@@ -881,7 +1348,8 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
881
1348
|
header = result.header;
|
|
882
1349
|
const claims = yield sdjwt.getClaims(hasher);
|
|
883
1350
|
payload = claims;
|
|
884
|
-
} catch (
|
|
1351
|
+
} catch (e) {
|
|
1352
|
+
const error = ensureError(e);
|
|
885
1353
|
const code = exceptionToCode(error);
|
|
886
1354
|
addError(code, error.message, error);
|
|
887
1355
|
}
|
|
@@ -899,7 +1367,8 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
899
1367
|
{ missingKeys }
|
|
900
1368
|
);
|
|
901
1369
|
}
|
|
902
|
-
} catch (
|
|
1370
|
+
} catch (e) {
|
|
1371
|
+
const error = ensureError(e);
|
|
903
1372
|
addError(
|
|
904
1373
|
"UNKNOWN_ERROR",
|
|
905
1374
|
`Failed to check required claims: ${error.message}`,
|
|
@@ -951,7 +1420,8 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
951
1420
|
);
|
|
952
1421
|
}
|
|
953
1422
|
}
|
|
954
|
-
} catch (
|
|
1423
|
+
} catch (e) {
|
|
1424
|
+
const error = ensureError(e);
|
|
955
1425
|
addError(
|
|
956
1426
|
"KEY_BINDING_SIGNATURE_INVALID",
|
|
957
1427
|
`Key binding verification failed: ${error.message}`,
|
|
@@ -976,11 +1446,11 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
976
1446
|
calculateSDHash(presentSdJwtWithoutKb, sdjwt, hasher) {
|
|
977
1447
|
return __async(this, null, function* () {
|
|
978
1448
|
if (!sdjwt.jwt || !sdjwt.jwt.payload) {
|
|
979
|
-
throw new
|
|
1449
|
+
throw new SDJWTException("Invalid SD JWT");
|
|
980
1450
|
}
|
|
981
|
-
const { _sd_alg } =
|
|
1451
|
+
const { _sd_alg } = getSDAlgAndPayload(sdjwt.jwt.payload);
|
|
982
1452
|
const sdHash = yield hasher(presentSdJwtWithoutKb, _sd_alg);
|
|
983
|
-
const sdHashStr = (0,
|
|
1453
|
+
const sdHashStr = (0, import_identity_common.uint8ArrayToBase64Url)(sdHash);
|
|
984
1454
|
return sdHashStr;
|
|
985
1455
|
});
|
|
986
1456
|
}
|
|
@@ -994,12 +1464,12 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
994
1464
|
validate(encodedSDJwt, options) {
|
|
995
1465
|
return __async(this, null, function* () {
|
|
996
1466
|
if (!this.userConfig.hasher) {
|
|
997
|
-
throw new
|
|
1467
|
+
throw new SDJWTException("Hasher not found");
|
|
998
1468
|
}
|
|
999
1469
|
const hasher = this.userConfig.hasher;
|
|
1000
1470
|
const sdjwt = yield SDJwt.fromEncode(encodedSDJwt, hasher);
|
|
1001
1471
|
if (!sdjwt.jwt) {
|
|
1002
|
-
throw new
|
|
1472
|
+
throw new SDJWTException("Invalid SD JWT");
|
|
1003
1473
|
}
|
|
1004
1474
|
const verifiedPayloads = yield this.VerifyJwt(sdjwt.jwt, options);
|
|
1005
1475
|
const claims = yield sdjwt.getClaims(hasher);
|
|
@@ -1014,14 +1484,14 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
1014
1484
|
}
|
|
1015
1485
|
decode(endcodedSDJwt) {
|
|
1016
1486
|
if (!this.userConfig.hasher) {
|
|
1017
|
-
throw new
|
|
1487
|
+
throw new SDJWTException("Hasher not found");
|
|
1018
1488
|
}
|
|
1019
1489
|
return SDJwt.fromEncode(endcodedSDJwt, this.userConfig.hasher);
|
|
1020
1490
|
}
|
|
1021
1491
|
keys(endcodedSDJwt) {
|
|
1022
1492
|
return __async(this, null, function* () {
|
|
1023
1493
|
if (!this.userConfig.hasher) {
|
|
1024
|
-
throw new
|
|
1494
|
+
throw new SDJWTException("Hasher not found");
|
|
1025
1495
|
}
|
|
1026
1496
|
const sdjwt = yield SDJwt.fromEncode(endcodedSDJwt, this.userConfig.hasher);
|
|
1027
1497
|
return sdjwt.keys(this.userConfig.hasher);
|
|
@@ -1030,7 +1500,7 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
1030
1500
|
presentableKeys(endcodedSDJwt) {
|
|
1031
1501
|
return __async(this, null, function* () {
|
|
1032
1502
|
if (!this.userConfig.hasher) {
|
|
1033
|
-
throw new
|
|
1503
|
+
throw new SDJWTException("Hasher not found");
|
|
1034
1504
|
}
|
|
1035
1505
|
const sdjwt = yield SDJwt.fromEncode(endcodedSDJwt, this.userConfig.hasher);
|
|
1036
1506
|
return sdjwt.presentableKeys(this.userConfig.hasher);
|
|
@@ -1039,7 +1509,7 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
1039
1509
|
getClaims(endcodedSDJwt) {
|
|
1040
1510
|
return __async(this, null, function* () {
|
|
1041
1511
|
if (!this.userConfig.hasher) {
|
|
1042
|
-
throw new
|
|
1512
|
+
throw new SDJWTException("Hasher not found");
|
|
1043
1513
|
}
|
|
1044
1514
|
const sdjwt = yield SDJwt.fromEncode(endcodedSDJwt, this.userConfig.hasher);
|
|
1045
1515
|
return sdjwt.getClaims(this.userConfig.hasher);
|
|
@@ -1058,8 +1528,8 @@ var SDJwtGeneralJSONInstance = class {
|
|
|
1058
1528
|
constructor(userConfig) {
|
|
1059
1529
|
this.userConfig = {};
|
|
1060
1530
|
if (userConfig) {
|
|
1061
|
-
if (userConfig.hashAlg && !
|
|
1062
|
-
throw new
|
|
1531
|
+
if (userConfig.hashAlg && !IANA_HASH_ALGORITHMS.includes(userConfig.hashAlg)) {
|
|
1532
|
+
throw new SDJWTException(
|
|
1063
1533
|
`Invalid hash algorithm: ${userConfig.hashAlg}`
|
|
1064
1534
|
);
|
|
1065
1535
|
}
|
|
@@ -1069,15 +1539,15 @@ var SDJwtGeneralJSONInstance = class {
|
|
|
1069
1539
|
createKBJwt(options, sdHash) {
|
|
1070
1540
|
return __async(this, null, function* () {
|
|
1071
1541
|
if (!this.userConfig.kbSigner) {
|
|
1072
|
-
throw new
|
|
1542
|
+
throw new SDJWTException("Key Binding Signer not found");
|
|
1073
1543
|
}
|
|
1074
1544
|
if (!this.userConfig.kbSignAlg) {
|
|
1075
|
-
throw new
|
|
1545
|
+
throw new SDJWTException("Key Binding sign algorithm not specified");
|
|
1076
1546
|
}
|
|
1077
1547
|
const { payload } = options;
|
|
1078
1548
|
const kbJwt = new KBJwt({
|
|
1079
1549
|
header: {
|
|
1080
|
-
typ:
|
|
1550
|
+
typ: KB_JWT_TYP,
|
|
1081
1551
|
alg: this.userConfig.kbSignAlg
|
|
1082
1552
|
},
|
|
1083
1553
|
payload: __spreadProps(__spreadValues({}, payload), { sd_hash: sdHash })
|
|
@@ -1087,16 +1557,16 @@ var SDJwtGeneralJSONInstance = class {
|
|
|
1087
1557
|
});
|
|
1088
1558
|
}
|
|
1089
1559
|
encodeObj(obj) {
|
|
1090
|
-
return (0,
|
|
1560
|
+
return (0, import_identity_common.base64urlEncode)(JSON.stringify(obj));
|
|
1091
1561
|
}
|
|
1092
1562
|
issue(payload, disclosureFrame, options) {
|
|
1093
1563
|
return __async(this, null, function* () {
|
|
1094
1564
|
var _a;
|
|
1095
1565
|
if (!this.userConfig.hasher) {
|
|
1096
|
-
throw new
|
|
1566
|
+
throw new SDJWTException("Hasher not found");
|
|
1097
1567
|
}
|
|
1098
1568
|
if (!this.userConfig.saltGenerator) {
|
|
1099
|
-
throw new
|
|
1569
|
+
throw new SDJWTException("SaltGenerator not found");
|
|
1100
1570
|
}
|
|
1101
1571
|
if (disclosureFrame) {
|
|
1102
1572
|
this.validateReservedFields(disclosureFrame);
|
|
@@ -1148,12 +1618,12 @@ var SDJwtGeneralJSONInstance = class {
|
|
|
1148
1618
|
return __async(this, null, function* () {
|
|
1149
1619
|
var _a;
|
|
1150
1620
|
if (!this.userConfig.hasher) {
|
|
1151
|
-
throw new
|
|
1621
|
+
throw new SDJWTException("Hasher not found");
|
|
1152
1622
|
}
|
|
1153
1623
|
const hasher = this.userConfig.hasher;
|
|
1154
1624
|
const encodedSDJwt = generalJSON.toEncoded(0);
|
|
1155
1625
|
const sdjwt = yield SDJwt.fromEncode(encodedSDJwt, hasher);
|
|
1156
|
-
if (!((_a = sdjwt.jwt) == null ? void 0 : _a.payload)) throw new
|
|
1626
|
+
if (!((_a = sdjwt.jwt) == null ? void 0 : _a.payload)) throw new SDJWTException("Payload not found");
|
|
1157
1627
|
const disclosures = yield sdjwt.getPresentDisclosures(
|
|
1158
1628
|
presentationFrame,
|
|
1159
1629
|
hasher
|
|
@@ -1188,14 +1658,14 @@ var SDJwtGeneralJSONInstance = class {
|
|
|
1188
1658
|
verify(generalJSON, options) {
|
|
1189
1659
|
return __async(this, null, function* () {
|
|
1190
1660
|
if (!this.userConfig.hasher) {
|
|
1191
|
-
throw new
|
|
1661
|
+
throw new SDJWTException("Hasher not found");
|
|
1192
1662
|
}
|
|
1193
1663
|
const hasher = this.userConfig.hasher;
|
|
1194
1664
|
const { payload, headers } = yield this.validate(generalJSON);
|
|
1195
1665
|
const encodedSDJwt = generalJSON.toEncoded(0);
|
|
1196
1666
|
const sdjwt = yield SDJwt.fromEncode(encodedSDJwt, hasher);
|
|
1197
1667
|
if (!sdjwt.jwt || !sdjwt.jwt.payload) {
|
|
1198
|
-
throw new
|
|
1668
|
+
throw new SDJWTException("Invalid SD JWT");
|
|
1199
1669
|
}
|
|
1200
1670
|
if (options == null ? void 0 : options.requiredClaimKeys) {
|
|
1201
1671
|
const keys = yield sdjwt.keys(hasher);
|
|
@@ -1203,7 +1673,7 @@ var SDJwtGeneralJSONInstance = class {
|
|
|
1203
1673
|
(k) => !keys.includes(k)
|
|
1204
1674
|
);
|
|
1205
1675
|
if (missingKeys.length > 0) {
|
|
1206
|
-
throw new
|
|
1676
|
+
throw new SDJWTException(
|
|
1207
1677
|
`Missing required claim keys: ${missingKeys.join(", ")}`
|
|
1208
1678
|
);
|
|
1209
1679
|
}
|
|
@@ -1212,10 +1682,10 @@ var SDJwtGeneralJSONInstance = class {
|
|
|
1212
1682
|
return { payload, headers };
|
|
1213
1683
|
}
|
|
1214
1684
|
if (!sdjwt.kbJwt) {
|
|
1215
|
-
throw new
|
|
1685
|
+
throw new SDJWTException("Key Binding JWT not exist");
|
|
1216
1686
|
}
|
|
1217
1687
|
if (!this.userConfig.kbVerifier) {
|
|
1218
|
-
throw new
|
|
1688
|
+
throw new SDJWTException("Key Binding Verifier not found");
|
|
1219
1689
|
}
|
|
1220
1690
|
const kb = yield sdjwt.kbJwt.verifyKB({
|
|
1221
1691
|
verifier: this.userConfig.kbVerifier,
|
|
@@ -1237,7 +1707,7 @@ var SDJwtGeneralJSONInstance = class {
|
|
|
1237
1707
|
hasher
|
|
1238
1708
|
);
|
|
1239
1709
|
if (sdHashStr !== sdHashfromKb) {
|
|
1240
|
-
throw new
|
|
1710
|
+
throw new SDJWTException("Invalid sd_hash in Key Binding JWT");
|
|
1241
1711
|
}
|
|
1242
1712
|
return { payload, headers, kb };
|
|
1243
1713
|
});
|
|
@@ -1245,11 +1715,11 @@ var SDJwtGeneralJSONInstance = class {
|
|
|
1245
1715
|
calculateSDHash(presentSdJwtWithoutKb, sdjwt, hasher) {
|
|
1246
1716
|
return __async(this, null, function* () {
|
|
1247
1717
|
if (!sdjwt.jwt || !sdjwt.jwt.payload) {
|
|
1248
|
-
throw new
|
|
1718
|
+
throw new SDJWTException("Invalid SD JWT");
|
|
1249
1719
|
}
|
|
1250
|
-
const { _sd_alg } =
|
|
1720
|
+
const { _sd_alg } = getSDAlgAndPayload(sdjwt.jwt.payload);
|
|
1251
1721
|
const sdHash = yield hasher(presentSdJwtWithoutKb, _sd_alg);
|
|
1252
|
-
const sdHashStr = (0,
|
|
1722
|
+
const sdHashStr = (0, import_identity_common.uint8ArrayToBase64Url)(sdHash);
|
|
1253
1723
|
return sdHashStr;
|
|
1254
1724
|
});
|
|
1255
1725
|
}
|
|
@@ -1258,10 +1728,10 @@ var SDJwtGeneralJSONInstance = class {
|
|
|
1258
1728
|
validate(generalJSON) {
|
|
1259
1729
|
return __async(this, null, function* () {
|
|
1260
1730
|
if (!this.userConfig.hasher) {
|
|
1261
|
-
throw new
|
|
1731
|
+
throw new SDJWTException("Hasher not found");
|
|
1262
1732
|
}
|
|
1263
1733
|
if (!this.userConfig.verifier) {
|
|
1264
|
-
throw new
|
|
1734
|
+
throw new SDJWTException("Verifier not found");
|
|
1265
1735
|
}
|
|
1266
1736
|
const hasher = this.userConfig.hasher;
|
|
1267
1737
|
const verifier = this.userConfig.verifier;
|
|
@@ -1273,18 +1743,18 @@ var SDJwtGeneralJSONInstance = class {
|
|
|
1273
1743
|
`${encodedHeader}.${payload}`,
|
|
1274
1744
|
signature
|
|
1275
1745
|
);
|
|
1276
|
-
const header = JSON.parse((0,
|
|
1746
|
+
const header = JSON.parse((0, import_identity_common.base64urlDecode)(encodedHeader));
|
|
1277
1747
|
return { verified: verified2, header };
|
|
1278
1748
|
}))
|
|
1279
1749
|
);
|
|
1280
1750
|
const verified = results.every((r) => r.verified);
|
|
1281
1751
|
if (!verified) {
|
|
1282
|
-
throw new
|
|
1752
|
+
throw new SDJWTException("Signature is not valid");
|
|
1283
1753
|
}
|
|
1284
1754
|
const encodedSDJwt = generalJSON.toEncoded(0);
|
|
1285
1755
|
const sdjwt = yield SDJwt.fromEncode(encodedSDJwt, hasher);
|
|
1286
1756
|
if (!sdjwt.jwt) {
|
|
1287
|
-
throw new
|
|
1757
|
+
throw new SDJWTException("Invalid SD JWT");
|
|
1288
1758
|
}
|
|
1289
1759
|
const claims = yield sdjwt.getClaims(hasher);
|
|
1290
1760
|
return { payload: claims, headers: results.map((r) => r.header) };
|
|
@@ -1302,7 +1772,7 @@ var SDJwtGeneralJSONInstance = class {
|
|
|
1302
1772
|
keys(generalSdjwt) {
|
|
1303
1773
|
return __async(this, null, function* () {
|
|
1304
1774
|
if (!this.userConfig.hasher) {
|
|
1305
|
-
throw new
|
|
1775
|
+
throw new SDJWTException("Hasher not found");
|
|
1306
1776
|
}
|
|
1307
1777
|
const endcodedSDJwt = generalSdjwt.toEncoded(0);
|
|
1308
1778
|
const sdjwt = yield SDJwt.fromEncode(endcodedSDJwt, this.userConfig.hasher);
|
|
@@ -1312,7 +1782,7 @@ var SDJwtGeneralJSONInstance = class {
|
|
|
1312
1782
|
presentableKeys(generalSdjwt) {
|
|
1313
1783
|
return __async(this, null, function* () {
|
|
1314
1784
|
if (!this.userConfig.hasher) {
|
|
1315
|
-
throw new
|
|
1785
|
+
throw new SDJWTException("Hasher not found");
|
|
1316
1786
|
}
|
|
1317
1787
|
const endcodedSDJwt = generalSdjwt.toEncoded(0);
|
|
1318
1788
|
const sdjwt = yield SDJwt.fromEncode(endcodedSDJwt, this.userConfig.hasher);
|
|
@@ -1322,7 +1792,7 @@ var SDJwtGeneralJSONInstance = class {
|
|
|
1322
1792
|
getClaims(generalSdjwt) {
|
|
1323
1793
|
return __async(this, null, function* () {
|
|
1324
1794
|
if (!this.userConfig.hasher) {
|
|
1325
|
-
throw new
|
|
1795
|
+
throw new SDJWTException("Hasher not found");
|
|
1326
1796
|
}
|
|
1327
1797
|
const endcodedSDJwt = generalSdjwt.toEncoded(0);
|
|
1328
1798
|
const sdjwt = yield SDJwt.fromEncode(endcodedSDJwt, this.userConfig.hasher);
|
|
@@ -1333,14 +1803,46 @@ var SDJwtGeneralJSONInstance = class {
|
|
|
1333
1803
|
SDJwtGeneralJSONInstance.DEFAULT_hashAlg = "sha-256";
|
|
1334
1804
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1335
1805
|
0 && (module.exports = {
|
|
1806
|
+
Disclosure,
|
|
1336
1807
|
FlattenJSON,
|
|
1337
1808
|
GeneralJSON,
|
|
1809
|
+
IANA_HASH_ALGORITHMS,
|
|
1338
1810
|
Jwt,
|
|
1339
1811
|
KBJwt,
|
|
1812
|
+
KB_JWT_TYP,
|
|
1813
|
+
SDJWTException,
|
|
1340
1814
|
SDJwt,
|
|
1341
1815
|
SDJwtGeneralJSONInstance,
|
|
1342
1816
|
SDJwtInstance,
|
|
1817
|
+
SD_DECOY,
|
|
1818
|
+
SD_DIGEST,
|
|
1819
|
+
SD_LIST_KEY,
|
|
1820
|
+
SD_SEPARATOR,
|
|
1821
|
+
base64UrlToUint8Array,
|
|
1822
|
+
base64urlDecode,
|
|
1823
|
+
base64urlEncode,
|
|
1343
1824
|
createDecoy,
|
|
1825
|
+
createHashMapping,
|
|
1826
|
+
createHashMappingForSerializedDisclosure,
|
|
1827
|
+
createHashMappingSync,
|
|
1828
|
+
decodeJwt,
|
|
1829
|
+
decodeSdJwt,
|
|
1830
|
+
decodeSdJwtSync,
|
|
1831
|
+
ensureError,
|
|
1832
|
+
getClaims,
|
|
1833
|
+
getClaimsSync,
|
|
1834
|
+
getSDAlgAndPayload,
|
|
1344
1835
|
listKeys,
|
|
1345
|
-
pack
|
|
1836
|
+
pack,
|
|
1837
|
+
present,
|
|
1838
|
+
presentSync,
|
|
1839
|
+
presentableKeys,
|
|
1840
|
+
presentableKeysSync,
|
|
1841
|
+
selectDisclosures,
|
|
1842
|
+
splitSdJwt,
|
|
1843
|
+
transformPresentationFrame,
|
|
1844
|
+
uint8ArrayToBase64Url,
|
|
1845
|
+
unpack,
|
|
1846
|
+
unpackObj,
|
|
1847
|
+
unpackSync
|
|
1346
1848
|
});
|