@owf/mdoc 0.6.0-alpha-20260225221529
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/LICENSE +176 -0
- package/README.md +47 -0
- package/dist/index.d.mts +1928 -0
- package/dist/index.mjs +3499 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +63 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,3499 @@
|
|
|
1
|
+
import { Encoder, addExtension, addExtension as addExtension$1 } from "cbor-x";
|
|
2
|
+
import z$1, { z } from "zod";
|
|
3
|
+
import { createErrorMap, fromError } from "zod-validation-error";
|
|
4
|
+
|
|
5
|
+
//#region src/utils/zod-error.ts
|
|
6
|
+
z$1.config({ customError: createErrorMap() });
|
|
7
|
+
function formatZodError(error) {
|
|
8
|
+
if (!error) return "";
|
|
9
|
+
return fromError(error, {
|
|
10
|
+
prefix: "",
|
|
11
|
+
prefixSeparator: "ā ",
|
|
12
|
+
issueSeparator: "\nā ",
|
|
13
|
+
unionSeparator: "\n OR ā "
|
|
14
|
+
}).toString();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region src/error/ValidationError.ts
|
|
19
|
+
var ValidationError = class extends Error {
|
|
20
|
+
constructor(message, zodError) {
|
|
21
|
+
super(message);
|
|
22
|
+
this.message = `${message}\n${zodError ? formatZodError(zodError) : ""}`;
|
|
23
|
+
Object.defineProperty(this, "zodError", {
|
|
24
|
+
value: zodError,
|
|
25
|
+
writable: false,
|
|
26
|
+
enumerable: false
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/utils/zod.ts
|
|
33
|
+
const zUint8Array = z$1.instanceof(Uint8Array);
|
|
34
|
+
function parseStructureWithErrorHandling(structureName, schema, data, customErrorMessage) {
|
|
35
|
+
const parseResult = z$1.safeParse(schema, data);
|
|
36
|
+
if (!parseResult.success) throw new ValidationError(customErrorMessage ?? `Error decoding ${structureName}`, parseResult.error);
|
|
37
|
+
return parseResult.data;
|
|
38
|
+
}
|
|
39
|
+
function decodeStructureWithErrorHandling(structureName, schema, data, customErrorMessage) {
|
|
40
|
+
const decodeResult = z$1.safeDecode(schema, data);
|
|
41
|
+
if (!decodeResult.success) throw new ValidationError(customErrorMessage ?? `Error decoding ${structureName}`, decodeResult.error);
|
|
42
|
+
return decodeResult.data;
|
|
43
|
+
}
|
|
44
|
+
function encodeStructureWithErrorHandling(structureName, schema, data, customErrorMessage) {
|
|
45
|
+
const encodeResult = z$1.safeEncode(schema, data);
|
|
46
|
+
if (!encodeResult.success) throw new ValidationError(customErrorMessage ?? `Error encoding ${structureName}`, encodeResult.error);
|
|
47
|
+
return encodeResult.data;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
//#endregion
|
|
51
|
+
//#region src/cbor/parser.ts
|
|
52
|
+
const encoderDefaults = {
|
|
53
|
+
tagUint8Array: false,
|
|
54
|
+
useRecords: false,
|
|
55
|
+
mapsAsObjects: false,
|
|
56
|
+
unwrapTopLevelDataItem: true,
|
|
57
|
+
variableMapSize: true
|
|
58
|
+
};
|
|
59
|
+
const cborDecode = (input, options = encoderDefaults) => {
|
|
60
|
+
const params = {
|
|
61
|
+
...encoderDefaults,
|
|
62
|
+
...options
|
|
63
|
+
};
|
|
64
|
+
const decoded = new Encoder(params).decode(input);
|
|
65
|
+
return params.unwrapTopLevelDataItem && typeof decoded === "object" && decoded instanceof DataItem ? decoded.data : decoded;
|
|
66
|
+
};
|
|
67
|
+
const cborEncode = (obj, options = encoderDefaults) => {
|
|
68
|
+
const enc = new Encoder({
|
|
69
|
+
...encoderDefaults,
|
|
70
|
+
...options
|
|
71
|
+
});
|
|
72
|
+
return Uint8Array.from(enc.encode(obj));
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
//#endregion
|
|
76
|
+
//#region src/cbor/data-item.ts
|
|
77
|
+
/**
|
|
78
|
+
* DataItem is an extension defined https://www.rfc-editor.org/rfc/rfc8949.html#name-encoded-cbor-data-item
|
|
79
|
+
* > Sometimes it is beneficial to carry an embedded CBOR data item that is
|
|
80
|
+
* > not meant to be decoded immediately at the time the enclosing data item is being decoded.
|
|
81
|
+
*
|
|
82
|
+
* The idea of this class is to provide lazy encode and decode of cbor data.
|
|
83
|
+
*
|
|
84
|
+
* Due to a bug in the cbor-x library, we are eagerly encoding the data in the constructor.
|
|
85
|
+
* https://github.com/kriszyp/cbor-x/issues/83
|
|
86
|
+
*
|
|
87
|
+
*/
|
|
88
|
+
var DataItem = class DataItem {
|
|
89
|
+
#data;
|
|
90
|
+
#buffer;
|
|
91
|
+
constructor(options) {
|
|
92
|
+
if (!("data" in options) && !("buffer" in options)) throw new Error("DataItem must be initialized with either the data or a buffer");
|
|
93
|
+
if ("data" in options) this.#data = options.data;
|
|
94
|
+
this.#buffer = "buffer" in options ? options.buffer : cborEncode(options.data);
|
|
95
|
+
}
|
|
96
|
+
get data() {
|
|
97
|
+
if (!this.#data) this.#data = cborDecode(this.#buffer);
|
|
98
|
+
return this.#data;
|
|
99
|
+
}
|
|
100
|
+
get buffer() {
|
|
101
|
+
return this.#buffer;
|
|
102
|
+
}
|
|
103
|
+
static fromData(data) {
|
|
104
|
+
return new DataItem({ data });
|
|
105
|
+
}
|
|
106
|
+
static fromBuffer(buffer) {
|
|
107
|
+
return new DataItem({ buffer });
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
addExtension({
|
|
111
|
+
Class: DataItem,
|
|
112
|
+
tag: 24,
|
|
113
|
+
encode: (instance, encode) => {
|
|
114
|
+
return encode(instance.buffer);
|
|
115
|
+
},
|
|
116
|
+
decode: (buffer) => {
|
|
117
|
+
return DataItem.fromBuffer(buffer);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
//#endregion
|
|
122
|
+
//#region src/cbor/cbor-structure.ts
|
|
123
|
+
var CborStructure = class {
|
|
124
|
+
constructor(structure) {
|
|
125
|
+
this.structure = structure;
|
|
126
|
+
}
|
|
127
|
+
get decodedStructure() {
|
|
128
|
+
return this.structure;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Static getter for the Zod codec schema that defines the CBOR structure.
|
|
132
|
+
* Subclasses CAN override this to provide their specific schema for automatic encoding/decoding.
|
|
133
|
+
* The schema should be a Zod schema or codec that handles validation and transformation.
|
|
134
|
+
* If not provided, subclasses must override encode(), decode(), and fromEncodedStructure().
|
|
135
|
+
*/
|
|
136
|
+
static get encodingSchema() {}
|
|
137
|
+
/**
|
|
138
|
+
* Returns the encoded structure that will be serialized to CBOR.
|
|
139
|
+
* By default, returns the protected structure property.
|
|
140
|
+
* Override if custom encoding logic is needed.
|
|
141
|
+
*/
|
|
142
|
+
get encodedStructure() {
|
|
143
|
+
const encodingSchema = this.constructor.encodingSchema;
|
|
144
|
+
if (!encodingSchema) throw new Error("encodedStructure must be implemented when encodingSchema is not provided");
|
|
145
|
+
return encodeStructureWithErrorHandling(this.constructor.name, encodingSchema, this.structure);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Encodes this structure to CBOR bytes.
|
|
149
|
+
*/
|
|
150
|
+
encode(options) {
|
|
151
|
+
return cborEncode(options?.asDataItem ? DataItem.fromData(this.encodedStructure) : this.encodedStructure);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Decodes CBOR bytes into a structure instance.
|
|
155
|
+
* Uses the encodingSchema's decode() method to validate and transform the decoded data.
|
|
156
|
+
*/
|
|
157
|
+
static decode(bytes) {
|
|
158
|
+
const rawStructure = cborDecode(bytes);
|
|
159
|
+
return new this(this.fromEncodedStructure(rawStructure).decodedStructure);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Creates a structure instance from the encoded CBOR structure (after calling cborDecode).
|
|
163
|
+
*
|
|
164
|
+
* Uses the encodingSchema's decode() method to validate and transform the structure if available.
|
|
165
|
+
* Otherwise, subclasses must override this method.
|
|
166
|
+
*/
|
|
167
|
+
static fromEncodedStructure(encodedStructure) {
|
|
168
|
+
if (!this.encodingSchema) throw new Error("fromEncodedStructure must be implemented when encodingSchema is not provided");
|
|
169
|
+
return new this(decodeStructureWithErrorHandling(this.name, this.encodingSchema, encodedStructure));
|
|
170
|
+
}
|
|
171
|
+
static fromDataItem(dataItem) {
|
|
172
|
+
return new this(parseStructureWithErrorHandling(this.name, z.instanceof(DataItem).transform((di) => di.data).transform((d) => this.fromEncodedStructure(d).decodedStructure), dataItem, `Error decoding ${this.name} from DateItem`));
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Creates a structure instance from the decoded structure.
|
|
176
|
+
*
|
|
177
|
+
* Uses the encodingSchema's parse method to validate the structure if available.
|
|
178
|
+
* Otherwise, subclasses must override this method.
|
|
179
|
+
*/
|
|
180
|
+
static fromDecodedStructure(decodedStructure) {
|
|
181
|
+
const encodingSchema = this.encodingSchema;
|
|
182
|
+
if (!encodingSchema) throw new Error("fromDecodedStructure must be implemented when encodingSchema is not provided");
|
|
183
|
+
const decodedSchema = encodingSchema instanceof z.ZodPipe ? encodingSchema.out : encodingSchema;
|
|
184
|
+
return new this(parseStructureWithErrorHandling(this.name, decodedSchema, decodedStructure));
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
//#endregion
|
|
189
|
+
//#region src/cbor/models/date.ts
|
|
190
|
+
addExtension({
|
|
191
|
+
Class: Date,
|
|
192
|
+
tag: 0,
|
|
193
|
+
encode: (date, encode) => encode(`${date.toISOString().split(".")[0]}Z`),
|
|
194
|
+
decode: (isoStringDateTime) => new Date(isoStringDateTime)
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
//#endregion
|
|
198
|
+
//#region src/cbor/models/date-only.ts
|
|
199
|
+
const customInspectSymbol = Symbol.for("nodejs.util.inspect.custom");
|
|
200
|
+
var DateOnly = class DateOnly {
|
|
201
|
+
constructor(date) {
|
|
202
|
+
this.date = date ? new Date(date) : /* @__PURE__ */ new Date();
|
|
203
|
+
}
|
|
204
|
+
get [Symbol.toStringTag]() {
|
|
205
|
+
return DateOnly.name;
|
|
206
|
+
}
|
|
207
|
+
toString() {
|
|
208
|
+
return this.toISOString();
|
|
209
|
+
}
|
|
210
|
+
toJSON() {
|
|
211
|
+
return this.toISOString();
|
|
212
|
+
}
|
|
213
|
+
toISOString() {
|
|
214
|
+
return this.date.toISOString().split("T")[0];
|
|
215
|
+
}
|
|
216
|
+
[customInspectSymbol]() {
|
|
217
|
+
return this.toISOString();
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
addExtension({
|
|
221
|
+
Class: DateOnly,
|
|
222
|
+
tag: 1004,
|
|
223
|
+
encode: (date, encode) => encode(date.toISOString()),
|
|
224
|
+
decode: (isoStringDate) => new DateOnly(isoStringDate)
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
//#endregion
|
|
228
|
+
//#region src/cose/error.ts
|
|
229
|
+
var CoseError = class extends Error {
|
|
230
|
+
constructor(message = new.target.name) {
|
|
231
|
+
super(message);
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
var CoseUnsupportedMacError = class extends CoseError {};
|
|
235
|
+
var CoseInvalidSignatureError = class extends CoseError {};
|
|
236
|
+
var CoseInvalidAlgorithmError = class extends CoseError {};
|
|
237
|
+
var CosePayloadMustBeNullError = class extends CoseError {};
|
|
238
|
+
var CosePayloadMustBeDefinedError = class extends CoseError {};
|
|
239
|
+
var CosePayloadInvalidStructureError = class extends CoseError {};
|
|
240
|
+
var CoseInvalidTypeForKeyError = class extends CoseError {};
|
|
241
|
+
var CoseInvalidValueForKtyError = class extends CoseError {};
|
|
242
|
+
var CoseInvalidKtyForRawError = class extends CoseError {};
|
|
243
|
+
var CoseXNotDefinedError = class extends CoseError {};
|
|
244
|
+
var CoseYNotDefinedError = class extends CoseError {};
|
|
245
|
+
var CoseDNotDefinedError = class extends CoseError {};
|
|
246
|
+
var CoseKNotDefinedError = class extends CoseError {};
|
|
247
|
+
var CoseEphemeralMacKeyIsRequiredError = class extends CoseError {};
|
|
248
|
+
var CoseCertificateNotFoundError = class extends CoseError {};
|
|
249
|
+
var CoseKeyTypeNotSupportedForPrivateKeyExtractionError = class extends CoseError {};
|
|
250
|
+
|
|
251
|
+
//#endregion
|
|
252
|
+
//#region src/cose/headers/defaults.ts
|
|
253
|
+
let Header = /* @__PURE__ */ function(Header) {
|
|
254
|
+
Header[Header["Algorithm"] = 1] = "Algorithm";
|
|
255
|
+
Header[Header["Critical"] = 2] = "Critical";
|
|
256
|
+
Header[Header["ContentType"] = 3] = "ContentType";
|
|
257
|
+
Header[Header["KeyId"] = 4] = "KeyId";
|
|
258
|
+
Header[Header["Iv"] = 5] = "Iv";
|
|
259
|
+
Header[Header["PartialIv"] = 6] = "PartialIv";
|
|
260
|
+
Header[Header["CounterSignature"] = 7] = "CounterSignature";
|
|
261
|
+
Header[Header["CounterSignature0"] = 9] = "CounterSignature0";
|
|
262
|
+
Header[Header["CounterSignatureV2"] = 11] = "CounterSignatureV2";
|
|
263
|
+
Header[Header["CounterSignature0V2"] = 12] = "CounterSignature0V2";
|
|
264
|
+
Header[Header["X5Bag"] = 32] = "X5Bag";
|
|
265
|
+
Header[Header["X5Chain"] = 33] = "X5Chain";
|
|
266
|
+
Header[Header["X5T"] = 34] = "X5T";
|
|
267
|
+
Header[Header["X5U"] = 35] = "X5U";
|
|
268
|
+
return Header;
|
|
269
|
+
}({});
|
|
270
|
+
let SignatureAlgorithm = /* @__PURE__ */ function(SignatureAlgorithm) {
|
|
271
|
+
SignatureAlgorithm[SignatureAlgorithm["EdDSA"] = -8] = "EdDSA";
|
|
272
|
+
SignatureAlgorithm[SignatureAlgorithm["ES256"] = -7] = "ES256";
|
|
273
|
+
SignatureAlgorithm[SignatureAlgorithm["ES384"] = -35] = "ES384";
|
|
274
|
+
SignatureAlgorithm[SignatureAlgorithm["ES512"] = -36] = "ES512";
|
|
275
|
+
SignatureAlgorithm[SignatureAlgorithm["PS256"] = -37] = "PS256";
|
|
276
|
+
SignatureAlgorithm[SignatureAlgorithm["PS384"] = -38] = "PS384";
|
|
277
|
+
SignatureAlgorithm[SignatureAlgorithm["PS512"] = -39] = "PS512";
|
|
278
|
+
SignatureAlgorithm[SignatureAlgorithm["RS256"] = -257] = "RS256";
|
|
279
|
+
SignatureAlgorithm[SignatureAlgorithm["RS384"] = -258] = "RS384";
|
|
280
|
+
SignatureAlgorithm[SignatureAlgorithm["RS512"] = -259] = "RS512";
|
|
281
|
+
return SignatureAlgorithm;
|
|
282
|
+
}({});
|
|
283
|
+
let MacAlgorithm = /* @__PURE__ */ function(MacAlgorithm) {
|
|
284
|
+
MacAlgorithm[MacAlgorithm["HS256"] = 5] = "HS256";
|
|
285
|
+
MacAlgorithm[MacAlgorithm["HS384"] = 6] = "HS384";
|
|
286
|
+
MacAlgorithm[MacAlgorithm["HS512"] = 7] = "HS512";
|
|
287
|
+
return MacAlgorithm;
|
|
288
|
+
}({});
|
|
289
|
+
let EncryptionAlgorithm = /* @__PURE__ */ function(EncryptionAlgorithm) {
|
|
290
|
+
EncryptionAlgorithm[EncryptionAlgorithm["A128GCM"] = 1] = "A128GCM";
|
|
291
|
+
EncryptionAlgorithm[EncryptionAlgorithm["A192GCM"] = 2] = "A192GCM";
|
|
292
|
+
EncryptionAlgorithm[EncryptionAlgorithm["A256GCM"] = 3] = "A256GCM";
|
|
293
|
+
EncryptionAlgorithm[EncryptionAlgorithm["Direct"] = -6] = "Direct";
|
|
294
|
+
return EncryptionAlgorithm;
|
|
295
|
+
}({});
|
|
296
|
+
|
|
297
|
+
//#endregion
|
|
298
|
+
//#region src/cose/headers/protected-headers.ts
|
|
299
|
+
const protectedHeadersEncodedStructure = zUint8Array;
|
|
300
|
+
const protectedHeadersDecodedStructure = z$1.map(z$1.number(), z$1.unknown());
|
|
301
|
+
var ProtectedHeaders = class extends CborStructure {
|
|
302
|
+
static get encodingSchema() {
|
|
303
|
+
return z$1.codec(protectedHeadersEncodedStructure, protectedHeadersDecodedStructure, {
|
|
304
|
+
encode: (decoded) => cborEncode(decoded),
|
|
305
|
+
decode: (encoded) => cborDecode(encoded)
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
get headers() {
|
|
309
|
+
return this.structure;
|
|
310
|
+
}
|
|
311
|
+
static create(options) {
|
|
312
|
+
return this.fromDecodedStructure(options.protectedHeaders ?? /* @__PURE__ */ new Map());
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
//#endregion
|
|
317
|
+
//#region src/cose/headers/unprotected-headers.ts
|
|
318
|
+
const unprotectedHeadersStructure = z$1.map(z$1.number(), z$1.unknown());
|
|
319
|
+
var UnprotectedHeaders = class extends CborStructure {
|
|
320
|
+
static get encodingSchema() {
|
|
321
|
+
return unprotectedHeadersStructure;
|
|
322
|
+
}
|
|
323
|
+
get headers() {
|
|
324
|
+
return this.structure;
|
|
325
|
+
}
|
|
326
|
+
static create(options) {
|
|
327
|
+
return this.fromDecodedStructure(options.unprotectedHeaders ?? /* @__PURE__ */ new Map());
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
//#endregion
|
|
332
|
+
//#region src/cose/key/curve.ts
|
|
333
|
+
let Curve = /* @__PURE__ */ function(Curve) {
|
|
334
|
+
Curve[Curve["P-256"] = 1] = "P-256";
|
|
335
|
+
Curve[Curve["P-384"] = 2] = "P-384";
|
|
336
|
+
Curve[Curve["P-521"] = 3] = "P-521";
|
|
337
|
+
Curve[Curve["X25519"] = 4] = "X25519";
|
|
338
|
+
Curve[Curve["X448"] = 5] = "X448";
|
|
339
|
+
Curve[Curve["Ed25519"] = 6] = "Ed25519";
|
|
340
|
+
Curve[Curve["Ed448"] = 7] = "Ed448";
|
|
341
|
+
return Curve;
|
|
342
|
+
}({});
|
|
343
|
+
|
|
344
|
+
//#endregion
|
|
345
|
+
//#region src/utils/transformers.ts
|
|
346
|
+
const BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
347
|
+
const bytesToBase64 = (bytes) => {
|
|
348
|
+
let result = "";
|
|
349
|
+
let i;
|
|
350
|
+
for (i = 0; i < bytes.length - 2; i += 3) {
|
|
351
|
+
const chunk = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2];
|
|
352
|
+
result += BASE64_CHARS[chunk >> 18 & 63];
|
|
353
|
+
result += BASE64_CHARS[chunk >> 12 & 63];
|
|
354
|
+
result += BASE64_CHARS[chunk >> 6 & 63];
|
|
355
|
+
result += BASE64_CHARS[chunk & 63];
|
|
356
|
+
}
|
|
357
|
+
if (i < bytes.length) {
|
|
358
|
+
const chunk = bytes[i] << 16 | (i + 1 < bytes.length ? bytes[i + 1] << 8 : 0);
|
|
359
|
+
result += BASE64_CHARS[chunk >> 18 & 63];
|
|
360
|
+
result += BASE64_CHARS[chunk >> 12 & 63];
|
|
361
|
+
result += i + 1 < bytes.length ? BASE64_CHARS[chunk >> 6 & 63] : "=";
|
|
362
|
+
result += "=";
|
|
363
|
+
}
|
|
364
|
+
return result;
|
|
365
|
+
};
|
|
366
|
+
const base64ToBytes = (base64) => {
|
|
367
|
+
if (!/^[A-Za-z0-9+/]*={0,2}$/.test(base64)) throw new Error("Invalid base64 string: contains invalid characters");
|
|
368
|
+
const cleanBase64 = base64.replace(/=/g, "");
|
|
369
|
+
const length = cleanBase64.length;
|
|
370
|
+
const bytes = new Uint8Array(length * 3 >> 2);
|
|
371
|
+
let byteIndex = 0;
|
|
372
|
+
for (let i = 0; i < length; i += 4) {
|
|
373
|
+
const a = BASE64_CHARS.indexOf(cleanBase64[i]);
|
|
374
|
+
const b = BASE64_CHARS.indexOf(cleanBase64[i + 1]);
|
|
375
|
+
const c = i + 2 < length ? BASE64_CHARS.indexOf(cleanBase64[i + 2]) : 0;
|
|
376
|
+
const d = i + 3 < length ? BASE64_CHARS.indexOf(cleanBase64[i + 3]) : 0;
|
|
377
|
+
bytes[byteIndex++] = a << 2 | b >> 4;
|
|
378
|
+
if (i + 2 < length) bytes[byteIndex++] = (b & 15) << 4 | c >> 2;
|
|
379
|
+
if (i + 3 < length) bytes[byteIndex++] = (c & 3) << 6 | d;
|
|
380
|
+
}
|
|
381
|
+
return bytes;
|
|
382
|
+
};
|
|
383
|
+
const bytesToBase64Url = (bytes) => {
|
|
384
|
+
return bytesToBase64(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
385
|
+
};
|
|
386
|
+
const base64UrlToBytes = (base64url) => {
|
|
387
|
+
if (!/^[A-Za-z0-9_-]*$/.test(base64url)) throw new Error("Invalid base64url string: contains invalid characters");
|
|
388
|
+
let base64 = base64url.replace(/-/g, "+").replace(/_/g, "/");
|
|
389
|
+
while (base64.length % 4) base64 += "=";
|
|
390
|
+
return base64ToBytes(base64);
|
|
391
|
+
};
|
|
392
|
+
const bytesToHex = (bytes) => {
|
|
393
|
+
let result = "";
|
|
394
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
395
|
+
const hex = bytes[i].toString(16);
|
|
396
|
+
result += hex.length === 1 ? `0${hex}` : hex;
|
|
397
|
+
}
|
|
398
|
+
return result;
|
|
399
|
+
};
|
|
400
|
+
const hexToBytes = (hex) => {
|
|
401
|
+
if (!/^[0-9a-fA-F]*$/.test(hex)) throw new Error("Invalid hex string: contains invalid characters");
|
|
402
|
+
if (hex.length % 2 !== 0) throw new Error("Invalid hex string: length must be even");
|
|
403
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
404
|
+
for (let i = 0; i < hex.length; i += 2) bytes[i / 2] = Number.parseInt(hex.substring(i, i + 2), 16);
|
|
405
|
+
return bytes;
|
|
406
|
+
};
|
|
407
|
+
const base64 = {
|
|
408
|
+
decode: base64ToBytes,
|
|
409
|
+
encode: bytesToBase64
|
|
410
|
+
};
|
|
411
|
+
const base64url = {
|
|
412
|
+
decode: base64UrlToBytes,
|
|
413
|
+
encode: bytesToBase64Url
|
|
414
|
+
};
|
|
415
|
+
const hex = {
|
|
416
|
+
decode: hexToBytes,
|
|
417
|
+
encode: bytesToHex
|
|
418
|
+
};
|
|
419
|
+
const bytesToString = (bytes) => {
|
|
420
|
+
let result = "";
|
|
421
|
+
let i = 0;
|
|
422
|
+
while (i < bytes.length) {
|
|
423
|
+
const byte1 = bytes[i++];
|
|
424
|
+
if (byte1 < 128) result += String.fromCharCode(byte1);
|
|
425
|
+
else if (byte1 < 224) {
|
|
426
|
+
const byte2 = bytes[i++];
|
|
427
|
+
result += String.fromCharCode((byte1 & 31) << 6 | byte2 & 63);
|
|
428
|
+
} else if (byte1 < 240) {
|
|
429
|
+
const byte2 = bytes[i++];
|
|
430
|
+
const byte3 = bytes[i++];
|
|
431
|
+
result += String.fromCharCode((byte1 & 15) << 12 | (byte2 & 63) << 6 | byte3 & 63);
|
|
432
|
+
} else {
|
|
433
|
+
const byte2 = bytes[i++];
|
|
434
|
+
const byte3 = bytes[i++];
|
|
435
|
+
const byte4 = bytes[i++];
|
|
436
|
+
const codePoint = (byte1 & 7) << 18 | (byte2 & 63) << 12 | (byte3 & 63) << 6 | byte4 & 63;
|
|
437
|
+
const surrogate1 = 55296 + (codePoint - 65536 >> 10);
|
|
438
|
+
const surrogate2 = 56320 + (codePoint - 65536 & 1023);
|
|
439
|
+
result += String.fromCharCode(surrogate1, surrogate2);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
return result;
|
|
443
|
+
};
|
|
444
|
+
const stringToBytes = (str) => {
|
|
445
|
+
const bytes = [];
|
|
446
|
+
for (let i = 0; i < str.length; i++) {
|
|
447
|
+
let codePoint = str.charCodeAt(i);
|
|
448
|
+
if (codePoint >= 55296 && codePoint <= 56319 && i + 1 < str.length) {
|
|
449
|
+
const low = str.charCodeAt(i + 1);
|
|
450
|
+
if (low >= 56320 && low <= 57343) {
|
|
451
|
+
codePoint = 65536 + (codePoint - 55296 << 10) + (low - 56320);
|
|
452
|
+
i++;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
if (codePoint < 128) bytes.push(codePoint);
|
|
456
|
+
else if (codePoint < 2048) {
|
|
457
|
+
bytes.push(192 | codePoint >> 6);
|
|
458
|
+
bytes.push(128 | codePoint & 63);
|
|
459
|
+
} else if (codePoint < 65536) {
|
|
460
|
+
bytes.push(224 | codePoint >> 12);
|
|
461
|
+
bytes.push(128 | codePoint >> 6 & 63);
|
|
462
|
+
bytes.push(128 | codePoint & 63);
|
|
463
|
+
} else {
|
|
464
|
+
bytes.push(240 | codePoint >> 18);
|
|
465
|
+
bytes.push(128 | codePoint >> 12 & 63);
|
|
466
|
+
bytes.push(128 | codePoint >> 6 & 63);
|
|
467
|
+
bytes.push(128 | codePoint & 63);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
return new Uint8Array(bytes);
|
|
471
|
+
};
|
|
472
|
+
const concatBytes = (byteArrays) => {
|
|
473
|
+
const totalLength = byteArrays.reduce((sum, arr) => sum + arr.length, 0);
|
|
474
|
+
const result = new Uint8Array(totalLength);
|
|
475
|
+
let offset = 0;
|
|
476
|
+
for (const arr of byteArrays) {
|
|
477
|
+
result.set(arr, offset);
|
|
478
|
+
offset += arr.length;
|
|
479
|
+
}
|
|
480
|
+
return result;
|
|
481
|
+
};
|
|
482
|
+
const compareBytes = (lhs, rhs) => {
|
|
483
|
+
if (lhs === rhs) return true;
|
|
484
|
+
if (lhs.byteLength !== rhs.byteLength) return false;
|
|
485
|
+
return lhs.every((b, i) => b === rhs[i]);
|
|
486
|
+
};
|
|
487
|
+
|
|
488
|
+
//#endregion
|
|
489
|
+
//#region src/utils/typed-map.ts
|
|
490
|
+
/**
|
|
491
|
+
* TypedMap provides compile-time type safety for Maps where each key has its own specific value type.
|
|
492
|
+
* Unlike Map<K, V> which has the same value type V for all keys, TypedMap<Schema, OptionalKeys>
|
|
493
|
+
* allows different value types per key (heterogeneous values).
|
|
494
|
+
*
|
|
495
|
+
* Example:
|
|
496
|
+
* type CoseKeySchema = {
|
|
497
|
+
* [CoseKeyParameter.KeyType]: KeyType // number key ā KeyType value
|
|
498
|
+
* [CoseKeyParameter.Curve]: Curve // number key ā Curve value
|
|
499
|
+
* [CoseKeyParameter.X]: Uint8Array // number key ā Uint8Array value
|
|
500
|
+
* }
|
|
501
|
+
*
|
|
502
|
+
* const map = new TypedMap<CoseKeySchema>()
|
|
503
|
+
* map.get(CoseKeyParameter.KeyType) // TypeScript knows this is KeyType!
|
|
504
|
+
* map.get(CoseKeyParameter.Curve) // TypeScript knows this is Curve!
|
|
505
|
+
* map.get(CoseKeyParameter.X) // TypeScript knows this is Uint8Array!
|
|
506
|
+
*
|
|
507
|
+
* @template Schema - Object type mapping keys to their value types
|
|
508
|
+
* @template OptionalKeys - Union of keys that are optional (can be absent)
|
|
509
|
+
*/
|
|
510
|
+
var TypedMap = class TypedMap {
|
|
511
|
+
constructor(entries) {
|
|
512
|
+
this.map = new Map(entries);
|
|
513
|
+
}
|
|
514
|
+
static fromMap(map) {
|
|
515
|
+
return new TypedMap(Array.from(map.entries()));
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Type-safe get that returns the correct value type for each key.
|
|
519
|
+
* Required keys return T, optional keys return T | undefined.
|
|
520
|
+
*/
|
|
521
|
+
get(key) {
|
|
522
|
+
return this.map.get(key);
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Type-safe set that ensures the value matches the key's type
|
|
526
|
+
*/
|
|
527
|
+
set(key, value) {
|
|
528
|
+
this.map.set(key, value);
|
|
529
|
+
return this;
|
|
530
|
+
}
|
|
531
|
+
has(key) {
|
|
532
|
+
return this.map.has(key);
|
|
533
|
+
}
|
|
534
|
+
delete(key) {
|
|
535
|
+
return this.map.delete(key);
|
|
536
|
+
}
|
|
537
|
+
clear() {
|
|
538
|
+
this.map.clear();
|
|
539
|
+
}
|
|
540
|
+
get size() {
|
|
541
|
+
return this.map.size;
|
|
542
|
+
}
|
|
543
|
+
keys() {
|
|
544
|
+
return this.map.keys();
|
|
545
|
+
}
|
|
546
|
+
values() {
|
|
547
|
+
return this.map.values();
|
|
548
|
+
}
|
|
549
|
+
entries() {
|
|
550
|
+
return this.map.entries();
|
|
551
|
+
}
|
|
552
|
+
forEach(callbackfn, thisArg) {
|
|
553
|
+
this.map.forEach(callbackfn, thisArg);
|
|
554
|
+
}
|
|
555
|
+
[Symbol.iterator]() {
|
|
556
|
+
return this.map[Symbol.iterator]();
|
|
557
|
+
}
|
|
558
|
+
toMap() {
|
|
559
|
+
return new Map(this.map);
|
|
560
|
+
}
|
|
561
|
+
};
|
|
562
|
+
/**
|
|
563
|
+
* This checks whether the property is exact optional. exact optional means that the value cannot be undefined, but if used
|
|
564
|
+
* in an object the key can be omitted. This is important for CBOR structures, as undefined will be encoded, and thus must be
|
|
565
|
+
* omitted in most cases.
|
|
566
|
+
*
|
|
567
|
+
* Zod recommend to check for optionality by just parsing undefined.
|
|
568
|
+
*/
|
|
569
|
+
const isExactOptional = (schema) => !schema.safeParse(void 0).success && z.object({ test: schema }).safeParse({}).success;
|
|
570
|
+
/**
|
|
571
|
+
* Utility function to create a typed map codec.
|
|
572
|
+
* Takes an array of [key, valueSchema] entries to support any key type (including non-string keys for CBOR).
|
|
573
|
+
*
|
|
574
|
+
* Example:
|
|
575
|
+
* const coseKeyMap = typedMap([
|
|
576
|
+
* [CoseKeyParameter.KeyType, z.number()],
|
|
577
|
+
* [CoseKeyParameter.Curve, z.number()],
|
|
578
|
+
* [CoseKeyParameter.X, z.instanceof(Uint8Array)]
|
|
579
|
+
* ] as const)
|
|
580
|
+
*
|
|
581
|
+
* The resulting schema validates a Map and transforms it to TypedMap<Schema, never>.
|
|
582
|
+
*/
|
|
583
|
+
function typedMap(entries, { allowAdditionalKeys = true, encode, decode } = {}) {
|
|
584
|
+
const requiredKeys = entries.filter(([, valueSchema]) => !isExactOptional(valueSchema)).map(([key]) => key);
|
|
585
|
+
const schemaMap = new Map(entries);
|
|
586
|
+
const originalEncode = (decoded) => decoded.toMap();
|
|
587
|
+
const originalDecode = (encoded) => TypedMap.fromMap(encoded);
|
|
588
|
+
return z.codec(z.map(z.unknown(), z.unknown()), z.instanceof(TypedMap).superRefine((map, ctx) => {
|
|
589
|
+
const additionalKeys = Array.from(map.keys()).filter((key) => !schemaMap.has(key));
|
|
590
|
+
if (additionalKeys.length > 0 && !allowAdditionalKeys) for (const additionalKey of additionalKeys) if (typeof additionalKey !== "string" && typeof additionalKey !== "number") ctx.addIssue({
|
|
591
|
+
code: "invalid_key",
|
|
592
|
+
origin: "map",
|
|
593
|
+
continue: true,
|
|
594
|
+
path: [],
|
|
595
|
+
input: map,
|
|
596
|
+
issues: [],
|
|
597
|
+
message: "Key found in map that is not a string or number"
|
|
598
|
+
});
|
|
599
|
+
else ctx.addIssue({
|
|
600
|
+
code: "invalid_key",
|
|
601
|
+
origin: "map",
|
|
602
|
+
continue: true,
|
|
603
|
+
path: [additionalKey],
|
|
604
|
+
input: map,
|
|
605
|
+
issues: [],
|
|
606
|
+
message: `Unexpected key '${additionalKey}' found in map, additional keys are not allowed.`
|
|
607
|
+
});
|
|
608
|
+
for (const [key, valueSchema] of schemaMap.entries()) {
|
|
609
|
+
const hasKey = map.has(key);
|
|
610
|
+
const value = map.get(key);
|
|
611
|
+
if (!hasKey && requiredKeys.includes(key)) {
|
|
612
|
+
ctx.addIssue({
|
|
613
|
+
code: "invalid_value",
|
|
614
|
+
continue: true,
|
|
615
|
+
message: `Expected key '${key}' to be defined.`,
|
|
616
|
+
path: [key],
|
|
617
|
+
values: [],
|
|
618
|
+
input: value
|
|
619
|
+
});
|
|
620
|
+
continue;
|
|
621
|
+
}
|
|
622
|
+
if (!hasKey && !requiredKeys.includes(key)) continue;
|
|
623
|
+
const parseResult = valueSchema.safeParse(value);
|
|
624
|
+
if (!parseResult.success) for (const issue of parseResult.error.issues) ctx.addIssue({
|
|
625
|
+
...issue,
|
|
626
|
+
path: [`${key}`, ...issue.path]
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
}), {
|
|
630
|
+
decode: (input) => decode ? decode(input, originalDecode) : originalDecode(input),
|
|
631
|
+
encode: (output) => encode ? encode(output, originalEncode) : originalEncode(output)
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
//#endregion
|
|
636
|
+
//#region src/cose/key/key-operation.ts
|
|
637
|
+
let KeyOps = /* @__PURE__ */ function(KeyOps) {
|
|
638
|
+
KeyOps[KeyOps["Sign"] = 1] = "Sign";
|
|
639
|
+
KeyOps[KeyOps["Verify"] = 2] = "Verify";
|
|
640
|
+
KeyOps[KeyOps["Encrypt"] = 3] = "Encrypt";
|
|
641
|
+
KeyOps[KeyOps["Decrypt"] = 4] = "Decrypt";
|
|
642
|
+
KeyOps[KeyOps["WrapKey"] = 5] = "WrapKey";
|
|
643
|
+
KeyOps[KeyOps["UnwrapKey"] = 6] = "UnwrapKey";
|
|
644
|
+
KeyOps[KeyOps["DeriveKey"] = 7] = "DeriveKey";
|
|
645
|
+
KeyOps[KeyOps["DeriveBits"] = 8] = "DeriveBits";
|
|
646
|
+
KeyOps[KeyOps["MACCreate"] = 9] = "MACCreate";
|
|
647
|
+
KeyOps[KeyOps["MACVerify"] = 10] = "MACVerify";
|
|
648
|
+
return KeyOps;
|
|
649
|
+
}({});
|
|
650
|
+
|
|
651
|
+
//#endregion
|
|
652
|
+
//#region src/cose/key/key-type.ts
|
|
653
|
+
let KeyType = /* @__PURE__ */ function(KeyType) {
|
|
654
|
+
KeyType[KeyType["Okp"] = 1] = "Okp";
|
|
655
|
+
KeyType[KeyType["Ec"] = 2] = "Ec";
|
|
656
|
+
KeyType[KeyType["Oct"] = 4] = "Oct";
|
|
657
|
+
KeyType[KeyType["Reserved"] = 0] = "Reserved";
|
|
658
|
+
return KeyType;
|
|
659
|
+
}({});
|
|
660
|
+
|
|
661
|
+
//#endregion
|
|
662
|
+
//#region src/cose/key/jwk.ts
|
|
663
|
+
const swapMap = (map) => Object.fromEntries(Object.entries(map).map(([key, value]) => [value, key]));
|
|
664
|
+
const swapNestedMap = (nestedMap) => Object.fromEntries(Object.entries(nestedMap).map(([category, mappings]) => [category, Object.fromEntries(Object.entries(mappings).map(([key, value]) => [value, key]))]));
|
|
665
|
+
const jwkCoseKeyMap = {
|
|
666
|
+
kty: {
|
|
667
|
+
OKP: KeyType.Okp,
|
|
668
|
+
EC: KeyType.Ec,
|
|
669
|
+
OCT: KeyType.Oct
|
|
670
|
+
},
|
|
671
|
+
crv: {
|
|
672
|
+
"P-256": Curve["P-256"],
|
|
673
|
+
"p-384": Curve["P-384"],
|
|
674
|
+
"p-521": Curve["P-521"],
|
|
675
|
+
X25519: Curve.X25519,
|
|
676
|
+
Ed2519: Curve.Ed25519,
|
|
677
|
+
Ed448: Curve.Ed448
|
|
678
|
+
},
|
|
679
|
+
alg: {
|
|
680
|
+
EdDSA: SignatureAlgorithm.EdDSA,
|
|
681
|
+
ES256: SignatureAlgorithm.ES256,
|
|
682
|
+
ES384: SignatureAlgorithm.ES384,
|
|
683
|
+
ES512: SignatureAlgorithm.ES512,
|
|
684
|
+
PS256: SignatureAlgorithm.PS256,
|
|
685
|
+
PS384: SignatureAlgorithm.PS384,
|
|
686
|
+
PS512: SignatureAlgorithm.PS512,
|
|
687
|
+
RS256: SignatureAlgorithm.RS256,
|
|
688
|
+
RS384: SignatureAlgorithm.RS384,
|
|
689
|
+
RS512: SignatureAlgorithm.RS512,
|
|
690
|
+
HS256: MacAlgorithm.HS256,
|
|
691
|
+
HS384: MacAlgorithm.HS384,
|
|
692
|
+
HS512: MacAlgorithm.HS512,
|
|
693
|
+
A128GCM: EncryptionAlgorithm.A128GCM,
|
|
694
|
+
A192GCM: EncryptionAlgorithm.A192GCM,
|
|
695
|
+
A256GCM: EncryptionAlgorithm.A256GCM,
|
|
696
|
+
Direct: EncryptionAlgorithm.Direct
|
|
697
|
+
},
|
|
698
|
+
keyOps: {
|
|
699
|
+
sign: KeyOps.Sign,
|
|
700
|
+
verify: KeyOps.Verify,
|
|
701
|
+
encrypt: KeyOps.Encrypt,
|
|
702
|
+
decrypt: KeyOps.Decrypt,
|
|
703
|
+
wrapKey: KeyOps.WrapKey,
|
|
704
|
+
unwrapKey: KeyOps.UnwrapKey,
|
|
705
|
+
deriveKey: KeyOps.DeriveKey,
|
|
706
|
+
deriveBits: KeyOps.DeriveBits,
|
|
707
|
+
mACCreate: KeyOps.MACCreate,
|
|
708
|
+
mACVerify: KeyOps.MACVerify
|
|
709
|
+
}
|
|
710
|
+
};
|
|
711
|
+
const coseKeyJwkMap = swapNestedMap(jwkCoseKeyMap);
|
|
712
|
+
const jwkCoseOptionsMap = {
|
|
713
|
+
kty: "keyType",
|
|
714
|
+
kid: "keyId",
|
|
715
|
+
alg: "algorithm",
|
|
716
|
+
keyOps: "keyOps",
|
|
717
|
+
baseIv: "baseIv",
|
|
718
|
+
crv: "curve",
|
|
719
|
+
x: "x",
|
|
720
|
+
y: "y",
|
|
721
|
+
d: "d"
|
|
722
|
+
};
|
|
723
|
+
const coseOptionsJwkMap = swapMap(jwkCoseOptionsMap);
|
|
724
|
+
const jwkToCoseKey = {
|
|
725
|
+
kty: (kty) => {
|
|
726
|
+
return jwkCoseKeyMap.kty[kty] ?? kty;
|
|
727
|
+
},
|
|
728
|
+
crv: (crv) => jwkCoseKeyMap.crv[crv] ?? crv,
|
|
729
|
+
alg: (alg) => jwkCoseKeyMap.alg[alg] ?? alg,
|
|
730
|
+
kid: (kid) => kid,
|
|
731
|
+
keyOps: (keyOps) => Array.isArray(keyOps) ? keyOps?.map((ko) => jwkCoseKeyMap.keyOps[ko] ?? ko) : void 0,
|
|
732
|
+
x: (s) => s && typeof s === "string" ? base64url.decode(s) : void 0,
|
|
733
|
+
y: (s) => s && typeof s === "string" ? base64url.decode(s) : void 0,
|
|
734
|
+
d: (s) => s && typeof s === "string" ? base64url.decode(s) : void 0
|
|
735
|
+
};
|
|
736
|
+
const coseKeyToJwk = {
|
|
737
|
+
keyType: (keyType) => coseKeyJwkMap.kty[keyType],
|
|
738
|
+
keyId: (keyId) => keyId,
|
|
739
|
+
algorithm: (algorithm) => algorithm ? coseKeyJwkMap.alg[algorithm] : void 0,
|
|
740
|
+
keyOps: (keyOps) => keyOps && Array.isArray(keyOps) ? keyOps.map((ko) => coseKeyJwkMap.keyOps[ko]) : void 0,
|
|
741
|
+
baseIv: (baseIv) => baseIv,
|
|
742
|
+
curve: (curve) => curve ? coseKeyJwkMap.crv[curve] : void 0,
|
|
743
|
+
x: (x) => x ? base64url.encode(x) : void 0,
|
|
744
|
+
y: (y) => y ? base64url.encode(y) : void 0,
|
|
745
|
+
d: (d) => d ? base64url.encode(d) : void 0
|
|
746
|
+
};
|
|
747
|
+
|
|
748
|
+
//#endregion
|
|
749
|
+
//#region src/cose/key/key.ts
|
|
750
|
+
let CoseKeyParameter = /* @__PURE__ */ function(CoseKeyParameter) {
|
|
751
|
+
CoseKeyParameter[CoseKeyParameter["KeyType"] = 1] = "KeyType";
|
|
752
|
+
CoseKeyParameter[CoseKeyParameter["KeyId"] = 2] = "KeyId";
|
|
753
|
+
CoseKeyParameter[CoseKeyParameter["Algorithm"] = 3] = "Algorithm";
|
|
754
|
+
CoseKeyParameter[CoseKeyParameter["KeyOps"] = 4] = "KeyOps";
|
|
755
|
+
CoseKeyParameter[CoseKeyParameter["BaseIv"] = 5] = "BaseIv";
|
|
756
|
+
CoseKeyParameter[CoseKeyParameter["CurveOrK"] = -1] = "CurveOrK";
|
|
757
|
+
CoseKeyParameter[CoseKeyParameter["X"] = -2] = "X";
|
|
758
|
+
CoseKeyParameter[CoseKeyParameter["Y"] = -3] = "Y";
|
|
759
|
+
CoseKeyParameter[CoseKeyParameter["D"] = -4] = "D";
|
|
760
|
+
return CoseKeyParameter;
|
|
761
|
+
}({});
|
|
762
|
+
const coseKeySchema = typedMap([
|
|
763
|
+
[CoseKeyParameter.KeyType, z.union([z.enum(KeyType), z.string()])],
|
|
764
|
+
[CoseKeyParameter.KeyId, zUint8Array.or(z.string()).exactOptional()],
|
|
765
|
+
[CoseKeyParameter.Algorithm, z.union([z.string({ error: "Cose algorithm must be a string" }), z.number({ error: "Cose algorithm must be a number" })]).exactOptional()],
|
|
766
|
+
[CoseKeyParameter.KeyOps, z.array(z.union([z.enum(KeyOps), z.string()])).exactOptional()],
|
|
767
|
+
[CoseKeyParameter.BaseIv, zUint8Array.exactOptional()],
|
|
768
|
+
[CoseKeyParameter.CurveOrK, z.union([z.enum(Curve), zUint8Array]).exactOptional()],
|
|
769
|
+
[CoseKeyParameter.X, zUint8Array.exactOptional()],
|
|
770
|
+
[CoseKeyParameter.Y, zUint8Array.exactOptional()],
|
|
771
|
+
[CoseKeyParameter.D, zUint8Array.exactOptional()]
|
|
772
|
+
]);
|
|
773
|
+
var CoseKey = class extends CborStructure {
|
|
774
|
+
static get encodingSchema() {
|
|
775
|
+
return coseKeySchema;
|
|
776
|
+
}
|
|
777
|
+
get keyType() {
|
|
778
|
+
return this.structure.get(CoseKeyParameter.KeyType);
|
|
779
|
+
}
|
|
780
|
+
get keyId() {
|
|
781
|
+
const keyId = this.structure.get(CoseKeyParameter.KeyId);
|
|
782
|
+
return keyId instanceof Uint8Array ? bytesToString(keyId) : keyId;
|
|
783
|
+
}
|
|
784
|
+
get algorithm() {
|
|
785
|
+
return this.structure.get(CoseKeyParameter.Algorithm);
|
|
786
|
+
}
|
|
787
|
+
get keyOps() {
|
|
788
|
+
return this.structure.get(CoseKeyParameter.KeyOps);
|
|
789
|
+
}
|
|
790
|
+
get baseIv() {
|
|
791
|
+
return this.structure.get(CoseKeyParameter.BaseIv);
|
|
792
|
+
}
|
|
793
|
+
get curve() {
|
|
794
|
+
if (this.keyType === KeyType.Ec || this.keyType === KeyType.Okp) return this.structure.get(CoseKeyParameter.CurveOrK);
|
|
795
|
+
}
|
|
796
|
+
get x() {
|
|
797
|
+
return this.structure.get(CoseKeyParameter.X);
|
|
798
|
+
}
|
|
799
|
+
get y() {
|
|
800
|
+
return this.structure.get(CoseKeyParameter.Y);
|
|
801
|
+
}
|
|
802
|
+
get d() {
|
|
803
|
+
return this.structure.get(CoseKeyParameter.D);
|
|
804
|
+
}
|
|
805
|
+
get k() {
|
|
806
|
+
if (this.keyType === KeyType.Oct) return this.structure.get(CoseKeyParameter.CurveOrK);
|
|
807
|
+
}
|
|
808
|
+
static create(options) {
|
|
809
|
+
const map = new TypedMap([[CoseKeyParameter.KeyType, options.keyType]]);
|
|
810
|
+
if (options.keyId !== void 0) map.set(CoseKeyParameter.KeyId, stringToBytes(options.keyId));
|
|
811
|
+
if (options.algorithm !== void 0) map.set(CoseKeyParameter.Algorithm, options.algorithm);
|
|
812
|
+
if (options.keyOps !== void 0) map.set(CoseKeyParameter.KeyOps, options.keyOps);
|
|
813
|
+
if (options.baseIv !== void 0) map.set(CoseKeyParameter.BaseIv, options.baseIv);
|
|
814
|
+
if (options.curve !== void 0) map.set(CoseKeyParameter.CurveOrK, options.curve);
|
|
815
|
+
if (options.x !== void 0) map.set(CoseKeyParameter.X, options.x);
|
|
816
|
+
if (options.y !== void 0) map.set(CoseKeyParameter.Y, options.y);
|
|
817
|
+
if (options.d !== void 0) map.set(CoseKeyParameter.D, options.d);
|
|
818
|
+
if (options.k !== void 0) map.set(CoseKeyParameter.CurveOrK, options.k);
|
|
819
|
+
return this.fromDecodedStructure(map);
|
|
820
|
+
}
|
|
821
|
+
static fromJwk(jwk) {
|
|
822
|
+
if (!("kty" in jwk)) throw new CoseInvalidValueForKtyError("JWK does not contain required kty value");
|
|
823
|
+
const options = Object.entries(jwk).reduce((prev, [key, value]) => {
|
|
824
|
+
const mappedKey = jwkCoseOptionsMap[key] ?? key;
|
|
825
|
+
const mapFunction = jwkToCoseKey[key];
|
|
826
|
+
const convertedValue = mapFunction ? mapFunction(value) : value;
|
|
827
|
+
if (convertedValue !== void 0) return {
|
|
828
|
+
...prev,
|
|
829
|
+
[mappedKey]: convertedValue
|
|
830
|
+
};
|
|
831
|
+
return prev;
|
|
832
|
+
}, {});
|
|
833
|
+
return this.create(options);
|
|
834
|
+
}
|
|
835
|
+
get publicKey() {
|
|
836
|
+
if (this.keyType !== KeyType.Ec) throw new CoseInvalidKtyForRawError();
|
|
837
|
+
if (!this.x) throw new CoseXNotDefinedError();
|
|
838
|
+
if (!this.y) throw new CoseYNotDefinedError();
|
|
839
|
+
return concatBytes([
|
|
840
|
+
Uint8Array.from([4]),
|
|
841
|
+
this.x,
|
|
842
|
+
this.y
|
|
843
|
+
]);
|
|
844
|
+
}
|
|
845
|
+
get privateKey() {
|
|
846
|
+
if (this.keyType === KeyType.Ec) {
|
|
847
|
+
if (!this.d) throw new CoseDNotDefinedError();
|
|
848
|
+
return this.d;
|
|
849
|
+
}
|
|
850
|
+
if (this.keyType === KeyType.Oct) {
|
|
851
|
+
if (!this.k) throw new CoseKNotDefinedError();
|
|
852
|
+
return this.k;
|
|
853
|
+
}
|
|
854
|
+
throw new CoseKeyTypeNotSupportedForPrivateKeyExtractionError();
|
|
855
|
+
}
|
|
856
|
+
get jwk() {
|
|
857
|
+
const options = {
|
|
858
|
+
keyType: this.keyType,
|
|
859
|
+
keyId: this.keyId,
|
|
860
|
+
algorithm: this.algorithm,
|
|
861
|
+
keyOps: this.keyOps,
|
|
862
|
+
baseIv: this.baseIv,
|
|
863
|
+
curve: this.curve,
|
|
864
|
+
x: this.x,
|
|
865
|
+
y: this.y,
|
|
866
|
+
d: this.d,
|
|
867
|
+
k: this.k
|
|
868
|
+
};
|
|
869
|
+
return Object.entries(options).reduce((prev, [key, value]) => ({
|
|
870
|
+
...prev,
|
|
871
|
+
[coseOptionsJwkMap[key] ?? key]: typeof coseKeyToJwk[key] === "function" ? coseKeyToJwk[key](value) : void 0
|
|
872
|
+
}), {});
|
|
873
|
+
}
|
|
874
|
+
};
|
|
875
|
+
|
|
876
|
+
//#endregion
|
|
877
|
+
//#region src/mdoc/models/ble-options.ts
|
|
878
|
+
var BleOptionsKeys = /* @__PURE__ */ function(BleOptionsKeys) {
|
|
879
|
+
BleOptionsKeys[BleOptionsKeys["PeripheralServerMode"] = 0] = "PeripheralServerMode";
|
|
880
|
+
BleOptionsKeys[BleOptionsKeys["CentralClientMode"] = 1] = "CentralClientMode";
|
|
881
|
+
BleOptionsKeys[BleOptionsKeys["PeripheralServerModeUuid"] = 10] = "PeripheralServerModeUuid";
|
|
882
|
+
BleOptionsKeys[BleOptionsKeys["CentralClientModeUuid"] = 11] = "CentralClientModeUuid";
|
|
883
|
+
BleOptionsKeys[BleOptionsKeys["PeripheralServerModeDeviceAddress"] = 20] = "PeripheralServerModeDeviceAddress";
|
|
884
|
+
return BleOptionsKeys;
|
|
885
|
+
}(BleOptionsKeys || {});
|
|
886
|
+
const bleOptionsSchema = typedMap([
|
|
887
|
+
[BleOptionsKeys.PeripheralServerMode, z.boolean()],
|
|
888
|
+
[BleOptionsKeys.CentralClientMode, z.boolean()],
|
|
889
|
+
[BleOptionsKeys.PeripheralServerModeUuid, zUint8Array.exactOptional()],
|
|
890
|
+
[BleOptionsKeys.CentralClientModeUuid, zUint8Array.exactOptional()],
|
|
891
|
+
[BleOptionsKeys.PeripheralServerModeDeviceAddress, zUint8Array.exactOptional()]
|
|
892
|
+
]);
|
|
893
|
+
var BleOptions = class extends CborStructure {
|
|
894
|
+
static get encodingSchema() {
|
|
895
|
+
return bleOptionsSchema;
|
|
896
|
+
}
|
|
897
|
+
get peripheralServerMode() {
|
|
898
|
+
return this.structure.get(BleOptionsKeys.PeripheralServerMode);
|
|
899
|
+
}
|
|
900
|
+
get centralClientMode() {
|
|
901
|
+
return this.structure.get(BleOptionsKeys.CentralClientMode);
|
|
902
|
+
}
|
|
903
|
+
get peripheralServerModeUuid() {
|
|
904
|
+
return this.structure.get(BleOptionsKeys.PeripheralServerModeUuid);
|
|
905
|
+
}
|
|
906
|
+
get centralClientModeUuid() {
|
|
907
|
+
return this.structure.get(BleOptionsKeys.CentralClientModeUuid);
|
|
908
|
+
}
|
|
909
|
+
get peripheralServerModeDeviceAddress() {
|
|
910
|
+
return this.structure.get(BleOptionsKeys.PeripheralServerModeDeviceAddress);
|
|
911
|
+
}
|
|
912
|
+
static create(options) {
|
|
913
|
+
const map = new Map([[BleOptionsKeys.PeripheralServerMode, options.peripheralServerMode], [BleOptionsKeys.CentralClientMode, options.centralClientMode]]);
|
|
914
|
+
if (options.peripheralServerModeUuid !== void 0) map.set(BleOptionsKeys.PeripheralServerModeUuid, options.peripheralServerModeUuid);
|
|
915
|
+
if (options.centralClientModeUuid !== void 0) map.set(BleOptionsKeys.CentralClientModeUuid, options.centralClientModeUuid);
|
|
916
|
+
if (options.peripheralServerModeDeviceAddress !== void 0) map.set(BleOptionsKeys.PeripheralServerModeDeviceAddress, options.peripheralServerModeDeviceAddress);
|
|
917
|
+
return this.fromEncodedStructure(map);
|
|
918
|
+
}
|
|
919
|
+
};
|
|
920
|
+
|
|
921
|
+
//#endregion
|
|
922
|
+
//#region src/mdoc/models/nfc-options.ts
|
|
923
|
+
var NfcOptionsKeys = /* @__PURE__ */ function(NfcOptionsKeys) {
|
|
924
|
+
NfcOptionsKeys[NfcOptionsKeys["MaxCommandDataLength"] = 0] = "MaxCommandDataLength";
|
|
925
|
+
NfcOptionsKeys[NfcOptionsKeys["MaxResponseDataLength"] = 1] = "MaxResponseDataLength";
|
|
926
|
+
return NfcOptionsKeys;
|
|
927
|
+
}(NfcOptionsKeys || {});
|
|
928
|
+
const nfcOptionsSchema = typedMap([[NfcOptionsKeys.MaxCommandDataLength, z.number()], [NfcOptionsKeys.MaxResponseDataLength, z.number()]]);
|
|
929
|
+
var NfcOptions = class extends CborStructure {
|
|
930
|
+
static get encodingSchema() {
|
|
931
|
+
return nfcOptionsSchema;
|
|
932
|
+
}
|
|
933
|
+
get maxCommandDataLength() {
|
|
934
|
+
return this.structure.get(NfcOptionsKeys.MaxCommandDataLength);
|
|
935
|
+
}
|
|
936
|
+
get maxResponseDataLength() {
|
|
937
|
+
return this.structure.get(NfcOptionsKeys.MaxResponseDataLength);
|
|
938
|
+
}
|
|
939
|
+
static create(options) {
|
|
940
|
+
const map = new Map([[NfcOptionsKeys.MaxCommandDataLength, options.maxCommandDataLength], [NfcOptionsKeys.MaxResponseDataLength, options.maxResponseDataLength]]);
|
|
941
|
+
return this.fromEncodedStructure(map);
|
|
942
|
+
}
|
|
943
|
+
};
|
|
944
|
+
|
|
945
|
+
//#endregion
|
|
946
|
+
//#region src/mdoc/models/wifi-options.ts
|
|
947
|
+
var WifiOptionsKeys = /* @__PURE__ */ function(WifiOptionsKeys) {
|
|
948
|
+
WifiOptionsKeys[WifiOptionsKeys["Passphrase"] = 0] = "Passphrase";
|
|
949
|
+
WifiOptionsKeys[WifiOptionsKeys["OperatingClass"] = 1] = "OperatingClass";
|
|
950
|
+
WifiOptionsKeys[WifiOptionsKeys["ChannelNumber"] = 2] = "ChannelNumber";
|
|
951
|
+
WifiOptionsKeys[WifiOptionsKeys["SupportedBands"] = 3] = "SupportedBands";
|
|
952
|
+
return WifiOptionsKeys;
|
|
953
|
+
}(WifiOptionsKeys || {});
|
|
954
|
+
const wifiOptionsSchema = typedMap([
|
|
955
|
+
[WifiOptionsKeys.Passphrase, z.string().exactOptional()],
|
|
956
|
+
[WifiOptionsKeys.OperatingClass, z.number().exactOptional()],
|
|
957
|
+
[WifiOptionsKeys.ChannelNumber, z.number().exactOptional()],
|
|
958
|
+
[WifiOptionsKeys.SupportedBands, zUint8Array.exactOptional()]
|
|
959
|
+
]);
|
|
960
|
+
var WifiOptions = class extends CborStructure {
|
|
961
|
+
static get encodingSchema() {
|
|
962
|
+
return wifiOptionsSchema;
|
|
963
|
+
}
|
|
964
|
+
get encodedStructure() {
|
|
965
|
+
return this.structure.toMap();
|
|
966
|
+
}
|
|
967
|
+
get passphrase() {
|
|
968
|
+
return this.structure.get(WifiOptionsKeys.Passphrase);
|
|
969
|
+
}
|
|
970
|
+
get channelInfoOperatingClass() {
|
|
971
|
+
return this.structure.get(WifiOptionsKeys.OperatingClass);
|
|
972
|
+
}
|
|
973
|
+
get channelInfoChannelNumber() {
|
|
974
|
+
return this.structure.get(WifiOptionsKeys.ChannelNumber);
|
|
975
|
+
}
|
|
976
|
+
get bandInfoSupportedBands() {
|
|
977
|
+
return this.structure.get(WifiOptionsKeys.SupportedBands);
|
|
978
|
+
}
|
|
979
|
+
static create(options) {
|
|
980
|
+
const entries = [];
|
|
981
|
+
if (options.passphrase !== void 0) entries.push([WifiOptionsKeys.Passphrase, options.passphrase]);
|
|
982
|
+
if (options.channelInfoOperatingClass !== void 0) entries.push([WifiOptionsKeys.OperatingClass, options.channelInfoOperatingClass]);
|
|
983
|
+
if (options.channelInfoChannelNumber !== void 0) entries.push([WifiOptionsKeys.ChannelNumber, options.channelInfoChannelNumber]);
|
|
984
|
+
if (options.bandInfoSupportedBands !== void 0) entries.push([WifiOptionsKeys.SupportedBands, options.bandInfoSupportedBands]);
|
|
985
|
+
const map = new Map(entries);
|
|
986
|
+
return this.fromEncodedStructure(map);
|
|
987
|
+
}
|
|
988
|
+
};
|
|
989
|
+
|
|
990
|
+
//#endregion
|
|
991
|
+
//#region src/mdoc/models/device-retrieval-method.ts
|
|
992
|
+
let DeviceRetrievalMethodType = /* @__PURE__ */ function(DeviceRetrievalMethodType) {
|
|
993
|
+
DeviceRetrievalMethodType[DeviceRetrievalMethodType["Nfc"] = 1] = "Nfc";
|
|
994
|
+
DeviceRetrievalMethodType[DeviceRetrievalMethodType["Ble"] = 2] = "Ble";
|
|
995
|
+
DeviceRetrievalMethodType[DeviceRetrievalMethodType["WifiAware"] = 3] = "WifiAware";
|
|
996
|
+
return DeviceRetrievalMethodType;
|
|
997
|
+
}({});
|
|
998
|
+
const deviceRetrievalMethodEncodedSchema = z.tuple([
|
|
999
|
+
z.enum(DeviceRetrievalMethodType).or(z.number()),
|
|
1000
|
+
z.number(),
|
|
1001
|
+
z.map(z.unknown(), z.unknown())
|
|
1002
|
+
]);
|
|
1003
|
+
const deviceRetrievalMethodDecodedSchema = z.object({
|
|
1004
|
+
type: z.enum(DeviceRetrievalMethodType).or(z.number()),
|
|
1005
|
+
version: z.number(),
|
|
1006
|
+
retrievalOptions: z.union([
|
|
1007
|
+
z.instanceof(NfcOptions),
|
|
1008
|
+
z.instanceof(BleOptions),
|
|
1009
|
+
z.instanceof(WifiOptions),
|
|
1010
|
+
z.map(z.unknown(), z.unknown())
|
|
1011
|
+
])
|
|
1012
|
+
});
|
|
1013
|
+
var DeviceRetrievalMethod = class extends CborStructure {
|
|
1014
|
+
static get encodingSchema() {
|
|
1015
|
+
return z.codec(deviceRetrievalMethodEncodedSchema, deviceRetrievalMethodDecodedSchema, {
|
|
1016
|
+
decode: ([type, version, retrievalOptions]) => {
|
|
1017
|
+
let options;
|
|
1018
|
+
if (type === DeviceRetrievalMethodType.Nfc) options = NfcOptions.fromEncodedStructure(retrievalOptions);
|
|
1019
|
+
else if (type === DeviceRetrievalMethodType.Ble) options = BleOptions.fromEncodedStructure(retrievalOptions);
|
|
1020
|
+
else if (type === DeviceRetrievalMethodType.WifiAware) options = WifiOptions.fromEncodedStructure(retrievalOptions);
|
|
1021
|
+
else options = retrievalOptions;
|
|
1022
|
+
return {
|
|
1023
|
+
type,
|
|
1024
|
+
version,
|
|
1025
|
+
retrievalOptions: options
|
|
1026
|
+
};
|
|
1027
|
+
},
|
|
1028
|
+
encode: ({ type, version, retrievalOptions }) => [
|
|
1029
|
+
type,
|
|
1030
|
+
version,
|
|
1031
|
+
retrievalOptions instanceof CborStructure ? retrievalOptions.encodedStructure : retrievalOptions
|
|
1032
|
+
]
|
|
1033
|
+
});
|
|
1034
|
+
}
|
|
1035
|
+
get type() {
|
|
1036
|
+
return this.structure.type;
|
|
1037
|
+
}
|
|
1038
|
+
get version() {
|
|
1039
|
+
return this.structure.version;
|
|
1040
|
+
}
|
|
1041
|
+
get retrievalOptions() {
|
|
1042
|
+
return this.structure.retrievalOptions;
|
|
1043
|
+
}
|
|
1044
|
+
static create(options) {
|
|
1045
|
+
return this.fromDecodedStructure({
|
|
1046
|
+
type: options.type,
|
|
1047
|
+
version: options.version,
|
|
1048
|
+
retrievalOptions: options.retrievalOptions
|
|
1049
|
+
});
|
|
1050
|
+
}
|
|
1051
|
+
};
|
|
1052
|
+
|
|
1053
|
+
//#endregion
|
|
1054
|
+
//#region src/mdoc/models/protocol-info.ts
|
|
1055
|
+
const protocolInfoSchema = z$1.unknown();
|
|
1056
|
+
var ProtocolInfo = class extends CborStructure {
|
|
1057
|
+
static get encodingSchema() {
|
|
1058
|
+
return protocolInfoSchema;
|
|
1059
|
+
}
|
|
1060
|
+
};
|
|
1061
|
+
|
|
1062
|
+
//#endregion
|
|
1063
|
+
//#region src/mdoc/models/e-device-key.ts
|
|
1064
|
+
var EDeviceKey = class extends CoseKey {};
|
|
1065
|
+
|
|
1066
|
+
//#endregion
|
|
1067
|
+
//#region src/mdoc/models/security.ts
|
|
1068
|
+
const securityEncodedSchema = z.tuple([z.number(), z.instanceof(DataItem)]);
|
|
1069
|
+
const securityDecodedSchema = z.object({
|
|
1070
|
+
cipherSuiteIdentifier: z.number(),
|
|
1071
|
+
eDeviceKey: z.instanceof(EDeviceKey)
|
|
1072
|
+
});
|
|
1073
|
+
var Security = class extends CborStructure {
|
|
1074
|
+
static get encodingSchema() {
|
|
1075
|
+
return z.codec(securityEncodedSchema, securityDecodedSchema, {
|
|
1076
|
+
decode: (input) => ({
|
|
1077
|
+
cipherSuiteIdentifier: input[0],
|
|
1078
|
+
eDeviceKey: EDeviceKey.fromEncodedStructure(input[1].data)
|
|
1079
|
+
}),
|
|
1080
|
+
encode: (output) => [output.cipherSuiteIdentifier, DataItem.fromData(output.eDeviceKey.encodedStructure)]
|
|
1081
|
+
});
|
|
1082
|
+
}
|
|
1083
|
+
get cipherSuiteIdentifier() {
|
|
1084
|
+
return this.structure.cipherSuiteIdentifier;
|
|
1085
|
+
}
|
|
1086
|
+
get eDeviceKey() {
|
|
1087
|
+
return this.structure.eDeviceKey;
|
|
1088
|
+
}
|
|
1089
|
+
static create(options) {
|
|
1090
|
+
return this.fromDecodedStructure({
|
|
1091
|
+
cipherSuiteIdentifier: options.cipherSuiteIdentifier,
|
|
1092
|
+
eDeviceKey: options.eDeviceKey
|
|
1093
|
+
});
|
|
1094
|
+
}
|
|
1095
|
+
};
|
|
1096
|
+
|
|
1097
|
+
//#endregion
|
|
1098
|
+
//#region src/mdoc/models/oidc.ts
|
|
1099
|
+
const oidcEncodedSchema = z.tuple([
|
|
1100
|
+
z.number(),
|
|
1101
|
+
z.string(),
|
|
1102
|
+
z.string()
|
|
1103
|
+
]);
|
|
1104
|
+
const oidcDecodedSchema = z.object({
|
|
1105
|
+
version: z.number(),
|
|
1106
|
+
issuerUrl: z.string(),
|
|
1107
|
+
serverRetrievalToken: z.string()
|
|
1108
|
+
});
|
|
1109
|
+
var Oidc = class Oidc extends CborStructure {
|
|
1110
|
+
static get encodingSchema() {
|
|
1111
|
+
return z.codec(oidcEncodedSchema, oidcDecodedSchema, {
|
|
1112
|
+
decode: ([version, issuerUrl, serverRetrievalToken]) => ({
|
|
1113
|
+
version,
|
|
1114
|
+
issuerUrl,
|
|
1115
|
+
serverRetrievalToken
|
|
1116
|
+
}),
|
|
1117
|
+
encode: ({ version, issuerUrl, serverRetrievalToken }) => [
|
|
1118
|
+
version,
|
|
1119
|
+
issuerUrl,
|
|
1120
|
+
serverRetrievalToken
|
|
1121
|
+
]
|
|
1122
|
+
});
|
|
1123
|
+
}
|
|
1124
|
+
get version() {
|
|
1125
|
+
return this.structure.version;
|
|
1126
|
+
}
|
|
1127
|
+
get issuerUrl() {
|
|
1128
|
+
return this.structure.issuerUrl;
|
|
1129
|
+
}
|
|
1130
|
+
get serverRetrievalToken() {
|
|
1131
|
+
return this.structure.serverRetrievalToken;
|
|
1132
|
+
}
|
|
1133
|
+
static create(options) {
|
|
1134
|
+
return new Oidc({
|
|
1135
|
+
version: options.version,
|
|
1136
|
+
issuerUrl: options.issuerUrl,
|
|
1137
|
+
serverRetrievalToken: options.serverRetrievalToken
|
|
1138
|
+
});
|
|
1139
|
+
}
|
|
1140
|
+
};
|
|
1141
|
+
|
|
1142
|
+
//#endregion
|
|
1143
|
+
//#region src/mdoc/models/web-api.ts
|
|
1144
|
+
const webApiEncodedSchema = z.tuple([
|
|
1145
|
+
z.number(),
|
|
1146
|
+
z.string(),
|
|
1147
|
+
z.string()
|
|
1148
|
+
]);
|
|
1149
|
+
const webApiDecodedSchema = z.object({
|
|
1150
|
+
version: z.number(),
|
|
1151
|
+
issuerUrl: z.string(),
|
|
1152
|
+
serverRetrievalToken: z.string()
|
|
1153
|
+
});
|
|
1154
|
+
var WebApi = class extends CborStructure {
|
|
1155
|
+
static get encodingSchema() {
|
|
1156
|
+
return z.codec(webApiEncodedSchema, webApiDecodedSchema, {
|
|
1157
|
+
encode: ({ version, issuerUrl, serverRetrievalToken }) => [
|
|
1158
|
+
version,
|
|
1159
|
+
issuerUrl,
|
|
1160
|
+
serverRetrievalToken
|
|
1161
|
+
],
|
|
1162
|
+
decode: ([version, issuerUrl, serverRetrievalToken]) => ({
|
|
1163
|
+
version,
|
|
1164
|
+
issuerUrl,
|
|
1165
|
+
serverRetrievalToken
|
|
1166
|
+
})
|
|
1167
|
+
});
|
|
1168
|
+
}
|
|
1169
|
+
get version() {
|
|
1170
|
+
return this.structure.version;
|
|
1171
|
+
}
|
|
1172
|
+
get issuerUrl() {
|
|
1173
|
+
return this.structure.issuerUrl;
|
|
1174
|
+
}
|
|
1175
|
+
get serverRetrievalToken() {
|
|
1176
|
+
return this.structure.serverRetrievalToken;
|
|
1177
|
+
}
|
|
1178
|
+
static create(options) {
|
|
1179
|
+
return this.fromDecodedStructure(options);
|
|
1180
|
+
}
|
|
1181
|
+
};
|
|
1182
|
+
|
|
1183
|
+
//#endregion
|
|
1184
|
+
//#region src/mdoc/models/server-retrieval-method.ts
|
|
1185
|
+
const serverRetrievalMethodSchema = typedMap([["webApi", z.instanceof(WebApi).exactOptional()], ["oidc", z.instanceof(Oidc).exactOptional()]]);
|
|
1186
|
+
var ServerRetrievalMethod = class extends CborStructure {
|
|
1187
|
+
static get encodingSchema() {
|
|
1188
|
+
return z.codec(serverRetrievalMethodSchema.in, serverRetrievalMethodSchema.out, {
|
|
1189
|
+
decode: (input) => {
|
|
1190
|
+
const map = TypedMap.fromMap(input);
|
|
1191
|
+
if (input.has("webApi")) map.set("webApi", WebApi.fromEncodedStructure(input.get("webApi")));
|
|
1192
|
+
if (input.has("oidc")) map.set("oidc", Oidc.fromEncodedStructure(input.get("oidc")));
|
|
1193
|
+
return map;
|
|
1194
|
+
},
|
|
1195
|
+
encode: (output) => {
|
|
1196
|
+
const map = output.toMap();
|
|
1197
|
+
const webApi = output.get("webApi");
|
|
1198
|
+
if (webApi) map.set("webApi", webApi.encodedStructure);
|
|
1199
|
+
const oidc = output.get("oidc");
|
|
1200
|
+
if (oidc) map.set("oidc", oidc.encodedStructure);
|
|
1201
|
+
return map;
|
|
1202
|
+
}
|
|
1203
|
+
});
|
|
1204
|
+
}
|
|
1205
|
+
get webApi() {
|
|
1206
|
+
return this.structure.get("webApi");
|
|
1207
|
+
}
|
|
1208
|
+
get oidc() {
|
|
1209
|
+
return this.structure.get("oidc");
|
|
1210
|
+
}
|
|
1211
|
+
static create(options) {
|
|
1212
|
+
const map = new TypedMap([]);
|
|
1213
|
+
if (options.webApi) map.set("webApi", options.webApi);
|
|
1214
|
+
if (options.oidc) map.set("oidc", options.oidc);
|
|
1215
|
+
return this.fromDecodedStructure(map);
|
|
1216
|
+
}
|
|
1217
|
+
};
|
|
1218
|
+
|
|
1219
|
+
//#endregion
|
|
1220
|
+
//#region src/mdoc/models/device-engagement.ts
|
|
1221
|
+
var DeviceEngagementKeys = /* @__PURE__ */ function(DeviceEngagementKeys) {
|
|
1222
|
+
DeviceEngagementKeys[DeviceEngagementKeys["Version"] = 0] = "Version";
|
|
1223
|
+
DeviceEngagementKeys[DeviceEngagementKeys["Security"] = 1] = "Security";
|
|
1224
|
+
DeviceEngagementKeys[DeviceEngagementKeys["DeviceRetrievalMethods"] = 2] = "DeviceRetrievalMethods";
|
|
1225
|
+
DeviceEngagementKeys[DeviceEngagementKeys["ServerRetrievalMethods"] = 3] = "ServerRetrievalMethods";
|
|
1226
|
+
DeviceEngagementKeys[DeviceEngagementKeys["ProtocolInfo"] = 4] = "ProtocolInfo";
|
|
1227
|
+
return DeviceEngagementKeys;
|
|
1228
|
+
}(DeviceEngagementKeys || {});
|
|
1229
|
+
const deviceEngagementSchema = typedMap([
|
|
1230
|
+
[DeviceEngagementKeys.Version, z.string()],
|
|
1231
|
+
[DeviceEngagementKeys.Security, z.instanceof(Security)],
|
|
1232
|
+
[DeviceEngagementKeys.DeviceRetrievalMethods, z.array(z.instanceof(DeviceRetrievalMethod)).exactOptional()],
|
|
1233
|
+
[DeviceEngagementKeys.ServerRetrievalMethods, z.array(z.instanceof(ServerRetrievalMethod)).exactOptional()],
|
|
1234
|
+
[DeviceEngagementKeys.ProtocolInfo, z.instanceof(ProtocolInfo).exactOptional()]
|
|
1235
|
+
]);
|
|
1236
|
+
var DeviceEngagement = class extends CborStructure {
|
|
1237
|
+
static get encodingSchema() {
|
|
1238
|
+
return z.codec(deviceEngagementSchema.in, deviceEngagementSchema.out, {
|
|
1239
|
+
decode: (input) => {
|
|
1240
|
+
const map = TypedMap.fromMap(input);
|
|
1241
|
+
map.set(DeviceEngagementKeys.Security, Security.fromEncodedStructure(input.get(DeviceEngagementKeys.Security)));
|
|
1242
|
+
if (input.has(DeviceEngagementKeys.DeviceRetrievalMethods)) {
|
|
1243
|
+
const deviceMethods = input.get(DeviceEngagementKeys.DeviceRetrievalMethods);
|
|
1244
|
+
map.set(DeviceEngagementKeys.DeviceRetrievalMethods, deviceMethods.map((encoded) => DeviceRetrievalMethod.fromEncodedStructure(encoded)));
|
|
1245
|
+
}
|
|
1246
|
+
if (input.has(DeviceEngagementKeys.ServerRetrievalMethods)) {
|
|
1247
|
+
const serverMethods = input.get(DeviceEngagementKeys.ServerRetrievalMethods);
|
|
1248
|
+
map.set(DeviceEngagementKeys.ServerRetrievalMethods, serverMethods.map((encoded) => ServerRetrievalMethod.fromEncodedStructure(encoded)));
|
|
1249
|
+
}
|
|
1250
|
+
if (input.has(DeviceEngagementKeys.ProtocolInfo)) map.set(DeviceEngagementKeys.ProtocolInfo, ProtocolInfo.fromEncodedStructure(input.get(DeviceEngagementKeys.ProtocolInfo)));
|
|
1251
|
+
return map;
|
|
1252
|
+
},
|
|
1253
|
+
encode: (output) => {
|
|
1254
|
+
const map = output.toMap();
|
|
1255
|
+
map.set(DeviceEngagementKeys.Security, output.get(DeviceEngagementKeys.Security).encodedStructure);
|
|
1256
|
+
const deviceRetrievalMethods = output.get(DeviceEngagementKeys.DeviceRetrievalMethods);
|
|
1257
|
+
if (deviceRetrievalMethods) map.set(DeviceEngagementKeys.DeviceRetrievalMethods, deviceRetrievalMethods.map((drm) => drm.encodedStructure));
|
|
1258
|
+
const serverRetrievalMethods = output.get(DeviceEngagementKeys.ServerRetrievalMethods);
|
|
1259
|
+
if (serverRetrievalMethods) map.set(DeviceEngagementKeys.ServerRetrievalMethods, serverRetrievalMethods.map((srm) => srm.encodedStructure));
|
|
1260
|
+
const protocolInfo = output.get(DeviceEngagementKeys.ProtocolInfo);
|
|
1261
|
+
if (protocolInfo) map.set(DeviceEngagementKeys.ProtocolInfo, protocolInfo.encodedStructure);
|
|
1262
|
+
return map;
|
|
1263
|
+
}
|
|
1264
|
+
});
|
|
1265
|
+
}
|
|
1266
|
+
get version() {
|
|
1267
|
+
return this.structure.get(DeviceEngagementKeys.Version);
|
|
1268
|
+
}
|
|
1269
|
+
get security() {
|
|
1270
|
+
return this.structure.get(DeviceEngagementKeys.Security);
|
|
1271
|
+
}
|
|
1272
|
+
get deviceRetrievalMethods() {
|
|
1273
|
+
return this.structure.get(DeviceEngagementKeys.DeviceRetrievalMethods);
|
|
1274
|
+
}
|
|
1275
|
+
get serverRetrievalMethods() {
|
|
1276
|
+
return this.structure.get(DeviceEngagementKeys.ServerRetrievalMethods);
|
|
1277
|
+
}
|
|
1278
|
+
get protocolInfo() {
|
|
1279
|
+
return this.structure.get(DeviceEngagementKeys.ProtocolInfo);
|
|
1280
|
+
}
|
|
1281
|
+
static create(options) {
|
|
1282
|
+
const map = new Map([[DeviceEngagementKeys.Version, options.version], [DeviceEngagementKeys.Security, options.security]]);
|
|
1283
|
+
if (options.deviceRetrievalMethods !== void 0) map.set(DeviceEngagementKeys.DeviceRetrievalMethods, options.deviceRetrievalMethods);
|
|
1284
|
+
if (options.serverRetrievalMethods !== void 0) map.set(DeviceEngagementKeys.ServerRetrievalMethods, options.serverRetrievalMethods);
|
|
1285
|
+
if (options.protocolInfo !== void 0) map.set(DeviceEngagementKeys.ProtocolInfo, options.protocolInfo);
|
|
1286
|
+
return this.fromEncodedStructure(map);
|
|
1287
|
+
}
|
|
1288
|
+
};
|
|
1289
|
+
|
|
1290
|
+
//#endregion
|
|
1291
|
+
//#region src/mdoc/models/e-reader-key.ts
|
|
1292
|
+
var EReaderKey = class extends CoseKey {};
|
|
1293
|
+
|
|
1294
|
+
//#endregion
|
|
1295
|
+
//#region src/mdoc/models/handover.ts
|
|
1296
|
+
var Handover = class extends CborStructure {
|
|
1297
|
+
static tryDecodeHandover(structure) {
|
|
1298
|
+
try {
|
|
1299
|
+
return new this(this.fromEncodedStructure(structure).decodedStructure);
|
|
1300
|
+
} catch {
|
|
1301
|
+
return null;
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
/**
|
|
1305
|
+
* Whether this handover structure requires a reader key. Can
|
|
1306
|
+
* be overridden in extending handover classes.
|
|
1307
|
+
*/
|
|
1308
|
+
get requiresReaderKey() {
|
|
1309
|
+
return false;
|
|
1310
|
+
}
|
|
1311
|
+
/**
|
|
1312
|
+
* Whether this handover structure requires device engagement structure. Can
|
|
1313
|
+
* be overridden in extending handover classes.
|
|
1314
|
+
*/
|
|
1315
|
+
get requiresDeviceEngagement() {
|
|
1316
|
+
return false;
|
|
1317
|
+
}
|
|
1318
|
+
};
|
|
1319
|
+
|
|
1320
|
+
//#endregion
|
|
1321
|
+
//#region src/mdoc/models/nfc-handover.ts
|
|
1322
|
+
const nfcHandoverEncodedSchema = z$1.tuple([zUint8Array, zUint8Array.nullable()]);
|
|
1323
|
+
const nfcHandoverDecodedSchema = z$1.object({
|
|
1324
|
+
selectMessage: zUint8Array,
|
|
1325
|
+
requestMessage: zUint8Array.nullable()
|
|
1326
|
+
});
|
|
1327
|
+
var NfcHandover = class extends Handover {
|
|
1328
|
+
static get encodingSchema() {
|
|
1329
|
+
return z$1.codec(nfcHandoverEncodedSchema, nfcHandoverDecodedSchema, {
|
|
1330
|
+
encode: ({ selectMessage, requestMessage }) => [selectMessage, requestMessage],
|
|
1331
|
+
decode: ([selectMessage, requestMessage]) => ({
|
|
1332
|
+
selectMessage,
|
|
1333
|
+
requestMessage
|
|
1334
|
+
})
|
|
1335
|
+
});
|
|
1336
|
+
}
|
|
1337
|
+
get selectMessage() {
|
|
1338
|
+
return this.structure.selectMessage;
|
|
1339
|
+
}
|
|
1340
|
+
get requestMessage() {
|
|
1341
|
+
return this.structure.requestMessage;
|
|
1342
|
+
}
|
|
1343
|
+
static create(options) {
|
|
1344
|
+
return this.fromDecodedStructure({
|
|
1345
|
+
requestMessage: options.requestMessage ?? null,
|
|
1346
|
+
selectMessage: options.selectMessage
|
|
1347
|
+
});
|
|
1348
|
+
}
|
|
1349
|
+
get requiresReaderKey() {
|
|
1350
|
+
return true;
|
|
1351
|
+
}
|
|
1352
|
+
get requiresDeviceEngagement() {
|
|
1353
|
+
return true;
|
|
1354
|
+
}
|
|
1355
|
+
};
|
|
1356
|
+
|
|
1357
|
+
//#endregion
|
|
1358
|
+
//#region src/mdoc/models/oid4vp-dc-api-draft24-handover-info.ts
|
|
1359
|
+
const oid4vpDcApiDraft24HandoverInfoSchema = z$1.tuple([
|
|
1360
|
+
z$1.string(),
|
|
1361
|
+
z$1.string(),
|
|
1362
|
+
z$1.string()
|
|
1363
|
+
]);
|
|
1364
|
+
const oid4vpDcApiDraft24HandoverInfoDecodedSchema = z$1.object({
|
|
1365
|
+
origin: z$1.string(),
|
|
1366
|
+
clientId: z$1.string(),
|
|
1367
|
+
nonce: z$1.string()
|
|
1368
|
+
});
|
|
1369
|
+
var Oid4vpDcApiDraft24HandoverInfo = class extends CborStructure {
|
|
1370
|
+
static get encodingSchema() {
|
|
1371
|
+
return z$1.codec(oid4vpDcApiDraft24HandoverInfoSchema, oid4vpDcApiDraft24HandoverInfoDecodedSchema, {
|
|
1372
|
+
encode: ({ origin, clientId, nonce }) => [
|
|
1373
|
+
origin,
|
|
1374
|
+
clientId,
|
|
1375
|
+
nonce
|
|
1376
|
+
],
|
|
1377
|
+
decode: ([origin, clientId, nonce]) => ({
|
|
1378
|
+
origin,
|
|
1379
|
+
clientId,
|
|
1380
|
+
nonce
|
|
1381
|
+
})
|
|
1382
|
+
});
|
|
1383
|
+
}
|
|
1384
|
+
get origin() {
|
|
1385
|
+
return this.structure.origin;
|
|
1386
|
+
}
|
|
1387
|
+
get clientId() {
|
|
1388
|
+
return this.structure.clientId;
|
|
1389
|
+
}
|
|
1390
|
+
get nonce() {
|
|
1391
|
+
return this.structure.nonce;
|
|
1392
|
+
}
|
|
1393
|
+
static create(options) {
|
|
1394
|
+
return this.fromDecodedStructure({
|
|
1395
|
+
origin: options.origin,
|
|
1396
|
+
clientId: options.clientId,
|
|
1397
|
+
nonce: options.nonce
|
|
1398
|
+
});
|
|
1399
|
+
}
|
|
1400
|
+
};
|
|
1401
|
+
|
|
1402
|
+
//#endregion
|
|
1403
|
+
//#region src/mdoc/models/oid4vp-dc-api-handover.ts
|
|
1404
|
+
const oid4vpDcApiHandoverEncodedSchema = z$1.tuple([z$1.literal("OpenID4VPDCAPIHandover"), zUint8Array]);
|
|
1405
|
+
const oid4vpDcApiHandoverDecodedSchema = zUint8Array;
|
|
1406
|
+
var Oid4vpDcApiHandover = class extends Handover {
|
|
1407
|
+
static get encodingSchema() {
|
|
1408
|
+
return z$1.codec(oid4vpDcApiHandoverEncodedSchema, oid4vpDcApiHandoverDecodedSchema, {
|
|
1409
|
+
encode: (handoverInfoHash) => ["OpenID4VPDCAPIHandover", handoverInfoHash],
|
|
1410
|
+
decode: ([, handoverInfoHash]) => handoverInfoHash
|
|
1411
|
+
});
|
|
1412
|
+
}
|
|
1413
|
+
static createFromHash(oid4vpDcApiHandoverInfoHash) {
|
|
1414
|
+
return this.fromDecodedStructure(oid4vpDcApiHandoverInfoHash);
|
|
1415
|
+
}
|
|
1416
|
+
static async create(options, ctx) {
|
|
1417
|
+
const oid4vpDcApiHandoverInfoHash = await ctx.crypto.digest({
|
|
1418
|
+
digestAlgorithm: "SHA-256",
|
|
1419
|
+
bytes: options.oid4vpDcApiHandoverInfo.encode()
|
|
1420
|
+
});
|
|
1421
|
+
return this.fromDecodedStructure(oid4vpDcApiHandoverInfoHash);
|
|
1422
|
+
}
|
|
1423
|
+
};
|
|
1424
|
+
|
|
1425
|
+
//#endregion
|
|
1426
|
+
//#region src/mdoc/models/oid4vp-dc-api-handover-info.ts
|
|
1427
|
+
const oid4vpDcApiHandoverInfoEncodedSchema = z$1.tuple([
|
|
1428
|
+
z$1.string(),
|
|
1429
|
+
z$1.string(),
|
|
1430
|
+
zUint8Array.nullable()
|
|
1431
|
+
]);
|
|
1432
|
+
const oid4vpDcApiHandoverInfoDecodedSchema = z$1.object({
|
|
1433
|
+
origin: z$1.string(),
|
|
1434
|
+
nonce: z$1.string(),
|
|
1435
|
+
jwkThumbprint: zUint8Array.nullable()
|
|
1436
|
+
});
|
|
1437
|
+
var Oid4vpDcApiHandoverInfo = class extends CborStructure {
|
|
1438
|
+
static get encodingSchema() {
|
|
1439
|
+
return z$1.codec(oid4vpDcApiHandoverInfoEncodedSchema, oid4vpDcApiHandoverInfoDecodedSchema, {
|
|
1440
|
+
encode: ({ origin, nonce, jwkThumbprint }) => [
|
|
1441
|
+
origin,
|
|
1442
|
+
nonce,
|
|
1443
|
+
jwkThumbprint
|
|
1444
|
+
],
|
|
1445
|
+
decode: ([origin, nonce, jwkThumbprint]) => ({
|
|
1446
|
+
origin,
|
|
1447
|
+
nonce,
|
|
1448
|
+
jwkThumbprint
|
|
1449
|
+
})
|
|
1450
|
+
});
|
|
1451
|
+
}
|
|
1452
|
+
get origin() {
|
|
1453
|
+
return this.structure.origin;
|
|
1454
|
+
}
|
|
1455
|
+
get nonce() {
|
|
1456
|
+
return this.structure.nonce;
|
|
1457
|
+
}
|
|
1458
|
+
get jwkThumbprint() {
|
|
1459
|
+
return this.structure.jwkThumbprint;
|
|
1460
|
+
}
|
|
1461
|
+
static create(options) {
|
|
1462
|
+
return this.fromDecodedStructure({
|
|
1463
|
+
origin: options.origin,
|
|
1464
|
+
nonce: options.nonce,
|
|
1465
|
+
jwkThumbprint: options.jwkThumbprint ?? null
|
|
1466
|
+
});
|
|
1467
|
+
}
|
|
1468
|
+
};
|
|
1469
|
+
|
|
1470
|
+
//#endregion
|
|
1471
|
+
//#region src/mdoc/models/oid4vp-draft18-handover.ts
|
|
1472
|
+
const oid4vpDraft18HandoverEncodedSchema = z$1.tuple([
|
|
1473
|
+
zUint8Array,
|
|
1474
|
+
zUint8Array,
|
|
1475
|
+
z$1.string()
|
|
1476
|
+
]);
|
|
1477
|
+
const oid4vpDraft18HandoverDecodedSchema = z$1.object({
|
|
1478
|
+
clientIdHash: zUint8Array,
|
|
1479
|
+
responseUriHash: zUint8Array,
|
|
1480
|
+
nonce: z$1.string()
|
|
1481
|
+
});
|
|
1482
|
+
var Oid4vpDraft18Handover = class extends Handover {
|
|
1483
|
+
static get encodingSchema() {
|
|
1484
|
+
return z$1.codec(oid4vpDraft18HandoverEncodedSchema, oid4vpDraft18HandoverDecodedSchema, {
|
|
1485
|
+
encode: ({ clientIdHash, responseUriHash, nonce }) => [
|
|
1486
|
+
clientIdHash,
|
|
1487
|
+
responseUriHash,
|
|
1488
|
+
nonce
|
|
1489
|
+
],
|
|
1490
|
+
decode: ([clientIdHash, responseUriHash, nonce]) => ({
|
|
1491
|
+
clientIdHash,
|
|
1492
|
+
responseUriHash,
|
|
1493
|
+
nonce
|
|
1494
|
+
})
|
|
1495
|
+
});
|
|
1496
|
+
}
|
|
1497
|
+
static async create(options, ctx) {
|
|
1498
|
+
const clientIdHash = await ctx.crypto.digest({
|
|
1499
|
+
digestAlgorithm: "SHA-256",
|
|
1500
|
+
bytes: cborEncode([options.clientId, options.mdocGeneratedNonce])
|
|
1501
|
+
});
|
|
1502
|
+
const responseUriHash = await ctx.crypto.digest({
|
|
1503
|
+
digestAlgorithm: "SHA-256",
|
|
1504
|
+
bytes: cborEncode([options.responseUri, options.mdocGeneratedNonce])
|
|
1505
|
+
});
|
|
1506
|
+
return this.fromDecodedStructure({
|
|
1507
|
+
clientIdHash,
|
|
1508
|
+
responseUriHash,
|
|
1509
|
+
nonce: options.nonce
|
|
1510
|
+
});
|
|
1511
|
+
}
|
|
1512
|
+
};
|
|
1513
|
+
|
|
1514
|
+
//#endregion
|
|
1515
|
+
//#region src/mdoc/models/oid4vp-handover.ts
|
|
1516
|
+
const oid4vpHandoverEncodedSchema = z$1.tuple([z$1.literal("OpenID4VPHandover"), zUint8Array]);
|
|
1517
|
+
const oid4vpHandoverDecodedSchema = zUint8Array;
|
|
1518
|
+
var Oid4vpHandover = class extends Handover {
|
|
1519
|
+
static get encodingSchema() {
|
|
1520
|
+
return z$1.codec(oid4vpHandoverEncodedSchema, oid4vpHandoverDecodedSchema, {
|
|
1521
|
+
encode: (handoverInfoHash) => ["OpenID4VPHandover", handoverInfoHash],
|
|
1522
|
+
decode: ([, handoverInfoHash]) => handoverInfoHash
|
|
1523
|
+
});
|
|
1524
|
+
}
|
|
1525
|
+
get handoverInfoHash() {
|
|
1526
|
+
return this.structure;
|
|
1527
|
+
}
|
|
1528
|
+
static createFromHash(oid4vpHandoverInfoHash) {
|
|
1529
|
+
return this.fromDecodedStructure(oid4vpHandoverInfoHash);
|
|
1530
|
+
}
|
|
1531
|
+
static async create(options, ctx) {
|
|
1532
|
+
const oid4vpHandoverInfoHash = await ctx.crypto.digest({
|
|
1533
|
+
digestAlgorithm: "SHA-256",
|
|
1534
|
+
bytes: options.oid4vpHandoverInfo.encode()
|
|
1535
|
+
});
|
|
1536
|
+
return this.fromDecodedStructure(oid4vpHandoverInfoHash);
|
|
1537
|
+
}
|
|
1538
|
+
};
|
|
1539
|
+
|
|
1540
|
+
//#endregion
|
|
1541
|
+
//#region src/mdoc/models/oid4vp-handover-info.ts
|
|
1542
|
+
const oid4vpHandoverInfoEncodedSchema = z$1.tuple([
|
|
1543
|
+
z$1.string(),
|
|
1544
|
+
z$1.string(),
|
|
1545
|
+
zUint8Array.nullable(),
|
|
1546
|
+
z$1.string()
|
|
1547
|
+
]);
|
|
1548
|
+
const oid4vpHandoverInfoDecodedSchema = z$1.object({
|
|
1549
|
+
clientId: z$1.string(),
|
|
1550
|
+
nonce: z$1.string(),
|
|
1551
|
+
jwkThumbprint: zUint8Array.nullable(),
|
|
1552
|
+
responseUri: z$1.string()
|
|
1553
|
+
});
|
|
1554
|
+
var Oid4vpHandoverInfo = class extends CborStructure {
|
|
1555
|
+
static get encodingSchema() {
|
|
1556
|
+
return z$1.codec(oid4vpHandoverInfoEncodedSchema, oid4vpHandoverInfoDecodedSchema, {
|
|
1557
|
+
encode: ({ clientId, nonce, jwkThumbprint, responseUri }) => [
|
|
1558
|
+
clientId,
|
|
1559
|
+
nonce,
|
|
1560
|
+
jwkThumbprint,
|
|
1561
|
+
responseUri
|
|
1562
|
+
],
|
|
1563
|
+
decode: ([clientId, nonce, jwkThumbprint, responseUri]) => ({
|
|
1564
|
+
clientId,
|
|
1565
|
+
nonce,
|
|
1566
|
+
jwkThumbprint,
|
|
1567
|
+
responseUri
|
|
1568
|
+
})
|
|
1569
|
+
});
|
|
1570
|
+
}
|
|
1571
|
+
get clientId() {
|
|
1572
|
+
return this.structure.clientId;
|
|
1573
|
+
}
|
|
1574
|
+
get nonce() {
|
|
1575
|
+
return this.structure.nonce;
|
|
1576
|
+
}
|
|
1577
|
+
get jwkThumbprint() {
|
|
1578
|
+
return this.structure.jwkThumbprint;
|
|
1579
|
+
}
|
|
1580
|
+
get responseUri() {
|
|
1581
|
+
return this.structure.responseUri;
|
|
1582
|
+
}
|
|
1583
|
+
static create(options) {
|
|
1584
|
+
return this.fromDecodedStructure({
|
|
1585
|
+
clientId: options.clientId,
|
|
1586
|
+
nonce: options.nonce,
|
|
1587
|
+
jwkThumbprint: options.jwkThumbprint ?? null,
|
|
1588
|
+
responseUri: options.responseUri
|
|
1589
|
+
});
|
|
1590
|
+
}
|
|
1591
|
+
};
|
|
1592
|
+
|
|
1593
|
+
//#endregion
|
|
1594
|
+
//#region src/mdoc/models/oid4vp-iae-handover.ts
|
|
1595
|
+
const oid4vpIaeHandoverEncodedSchema = z$1.tuple([z$1.literal("OpenID4VCIIAEHandover"), zUint8Array]);
|
|
1596
|
+
const oid4vpIaeHandoverDecodedSchema = zUint8Array;
|
|
1597
|
+
var Oid4vpIaeHandover = class extends Handover {
|
|
1598
|
+
static get encodingSchema() {
|
|
1599
|
+
return z$1.codec(oid4vpIaeHandoverEncodedSchema, oid4vpIaeHandoverDecodedSchema, {
|
|
1600
|
+
encode: (handoverInfoHash) => ["OpenID4VCIIAEHandover", handoverInfoHash],
|
|
1601
|
+
decode: ([, handoverInfoHash]) => handoverInfoHash
|
|
1602
|
+
});
|
|
1603
|
+
}
|
|
1604
|
+
static createFromHash(oid4vpIaeHandoverInfoHash) {
|
|
1605
|
+
return this.fromDecodedStructure(oid4vpIaeHandoverInfoHash);
|
|
1606
|
+
}
|
|
1607
|
+
static async create(options, ctx) {
|
|
1608
|
+
const oid4vpIaeHandoverInfoHash = await ctx.crypto.digest({
|
|
1609
|
+
digestAlgorithm: "SHA-256",
|
|
1610
|
+
bytes: options.oid4vpIaeHandoverInfo.encode()
|
|
1611
|
+
});
|
|
1612
|
+
return this.fromDecodedStructure(oid4vpIaeHandoverInfoHash);
|
|
1613
|
+
}
|
|
1614
|
+
};
|
|
1615
|
+
|
|
1616
|
+
//#endregion
|
|
1617
|
+
//#region src/mdoc/models/oid4vp-iae-handover-info.ts
|
|
1618
|
+
const oid4vpIaeHandoverInfoEncodedSchema = z$1.tuple([
|
|
1619
|
+
z$1.string(),
|
|
1620
|
+
z$1.string(),
|
|
1621
|
+
zUint8Array.nullable()
|
|
1622
|
+
]);
|
|
1623
|
+
const oid4vpIaeHandoverInfoDecodedSchema = z$1.object({
|
|
1624
|
+
interactiveAuthorizationEndpoint: z$1.string(),
|
|
1625
|
+
nonce: z$1.string(),
|
|
1626
|
+
jwkThumbprint: zUint8Array.nullable()
|
|
1627
|
+
});
|
|
1628
|
+
var Oid4vpIaeHandoverInfo = class extends CborStructure {
|
|
1629
|
+
static get encodingSchema() {
|
|
1630
|
+
return z$1.codec(oid4vpIaeHandoverInfoEncodedSchema, oid4vpIaeHandoverInfoDecodedSchema, {
|
|
1631
|
+
encode: ({ interactiveAuthorizationEndpoint, nonce, jwkThumbprint }) => [
|
|
1632
|
+
interactiveAuthorizationEndpoint,
|
|
1633
|
+
nonce,
|
|
1634
|
+
jwkThumbprint
|
|
1635
|
+
],
|
|
1636
|
+
decode: ([interactiveAuthorizationEndpoint, nonce, jwkThumbprint]) => ({
|
|
1637
|
+
interactiveAuthorizationEndpoint,
|
|
1638
|
+
nonce,
|
|
1639
|
+
jwkThumbprint
|
|
1640
|
+
})
|
|
1641
|
+
});
|
|
1642
|
+
}
|
|
1643
|
+
get interactiveAuthorizationEndpoint() {
|
|
1644
|
+
return this.structure.interactiveAuthorizationEndpoint;
|
|
1645
|
+
}
|
|
1646
|
+
get nonce() {
|
|
1647
|
+
return this.structure.nonce;
|
|
1648
|
+
}
|
|
1649
|
+
get jwkThumbprint() {
|
|
1650
|
+
return this.structure.jwkThumbprint;
|
|
1651
|
+
}
|
|
1652
|
+
static create(options) {
|
|
1653
|
+
return this.fromDecodedStructure({
|
|
1654
|
+
interactiveAuthorizationEndpoint: options.interactiveAuthorizationEndpoint,
|
|
1655
|
+
nonce: options.nonce,
|
|
1656
|
+
jwkThumbprint: options.jwkThumbprint ?? null
|
|
1657
|
+
});
|
|
1658
|
+
}
|
|
1659
|
+
};
|
|
1660
|
+
|
|
1661
|
+
//#endregion
|
|
1662
|
+
//#region src/mdoc/models/qr-handover.ts
|
|
1663
|
+
const qrHandoverSchema = z$1.null();
|
|
1664
|
+
var QrHandover = class extends Handover {
|
|
1665
|
+
static get encodingSchema() {
|
|
1666
|
+
return qrHandoverSchema;
|
|
1667
|
+
}
|
|
1668
|
+
get requiresReaderKey() {
|
|
1669
|
+
return true;
|
|
1670
|
+
}
|
|
1671
|
+
get requiresDeviceEngagement() {
|
|
1672
|
+
return true;
|
|
1673
|
+
}
|
|
1674
|
+
static create() {
|
|
1675
|
+
return this.fromDecodedStructure(null);
|
|
1676
|
+
}
|
|
1677
|
+
};
|
|
1678
|
+
|
|
1679
|
+
//#endregion
|
|
1680
|
+
//#region src/mdoc/models/session-transcript.ts
|
|
1681
|
+
const supportedHandoverStructures = [
|
|
1682
|
+
Oid4vpHandover,
|
|
1683
|
+
Oid4vpDcApiHandover,
|
|
1684
|
+
Oid4vpIaeHandover,
|
|
1685
|
+
NfcHandover,
|
|
1686
|
+
QrHandover,
|
|
1687
|
+
Oid4vpDraft18Handover
|
|
1688
|
+
];
|
|
1689
|
+
const sessionTranscriptEncodedSchema = z.tuple([
|
|
1690
|
+
z.instanceof(DataItem).nullable(),
|
|
1691
|
+
z.instanceof(DataItem).nullable(),
|
|
1692
|
+
z.unknown()
|
|
1693
|
+
]);
|
|
1694
|
+
const sessionTranscriptDecodedSchema = z.object({
|
|
1695
|
+
deviceEngagement: z.instanceof(DeviceEngagement).nullable(),
|
|
1696
|
+
eReaderKey: z.instanceof(EReaderKey).nullable(),
|
|
1697
|
+
handover: z.instanceof(Handover)
|
|
1698
|
+
});
|
|
1699
|
+
var SessionTranscript = class extends CborStructure {
|
|
1700
|
+
static get encodingSchema() {
|
|
1701
|
+
return z.codec(sessionTranscriptEncodedSchema, sessionTranscriptDecodedSchema, {
|
|
1702
|
+
decode: ([deviceEngagementDataItem, eReaderKeyDataItem, handoverData]) => {
|
|
1703
|
+
let handover = null;
|
|
1704
|
+
for (const HandoverStructure of supportedHandoverStructures) {
|
|
1705
|
+
handover = HandoverStructure.tryDecodeHandover(handoverData);
|
|
1706
|
+
if (handover) break;
|
|
1707
|
+
}
|
|
1708
|
+
if (!handover) throw new Error("Could not establish handover structure for session transcript");
|
|
1709
|
+
return {
|
|
1710
|
+
deviceEngagement: deviceEngagementDataItem ? DeviceEngagement.fromEncodedStructure(deviceEngagementDataItem.data) : null,
|
|
1711
|
+
eReaderKey: eReaderKeyDataItem ? EReaderKey.fromEncodedStructure(eReaderKeyDataItem.data) : null,
|
|
1712
|
+
handover
|
|
1713
|
+
};
|
|
1714
|
+
},
|
|
1715
|
+
encode: ({ deviceEngagement, eReaderKey, handover }) => {
|
|
1716
|
+
if (handover.requiresDeviceEngagement && !deviceEngagement) throw new Error(`Session transcript has no deviceEngagement but ${handover.constructor.name} handover requires deviceEngagement`);
|
|
1717
|
+
if (!handover.requiresDeviceEngagement && deviceEngagement) throw new Error(`Session transcript has deviceEngagement but ${handover.constructor.name} handover does not expect deviceEngagement.`);
|
|
1718
|
+
if (handover.requiresReaderKey && !eReaderKey) throw new Error(`Session transcript has no eReaderKey but ${handover.constructor.name} handover requires eReaderKey`);
|
|
1719
|
+
if (!handover.requiresReaderKey && eReaderKey) throw new Error(`Session transcript has eReaderKey but ${handover.constructor.name} handover does not expect eReaderKey.`);
|
|
1720
|
+
return [
|
|
1721
|
+
deviceEngagement ? DataItem.fromData(deviceEngagement.encodedStructure) : null,
|
|
1722
|
+
eReaderKey ? DataItem.fromData(eReaderKey.encodedStructure) : null,
|
|
1723
|
+
handover.encodedStructure
|
|
1724
|
+
];
|
|
1725
|
+
}
|
|
1726
|
+
});
|
|
1727
|
+
}
|
|
1728
|
+
get deviceEngagement() {
|
|
1729
|
+
return this.structure.deviceEngagement;
|
|
1730
|
+
}
|
|
1731
|
+
get eReaderKey() {
|
|
1732
|
+
return this.structure.eReaderKey;
|
|
1733
|
+
}
|
|
1734
|
+
get handover() {
|
|
1735
|
+
return this.structure.handover;
|
|
1736
|
+
}
|
|
1737
|
+
static create(options) {
|
|
1738
|
+
return this.fromDecodedStructure({
|
|
1739
|
+
deviceEngagement: options.deviceEngagement ?? null,
|
|
1740
|
+
eReaderKey: options.eReaderKey ?? null,
|
|
1741
|
+
handover: options.handover
|
|
1742
|
+
});
|
|
1743
|
+
}
|
|
1744
|
+
/**
|
|
1745
|
+
* Create a SessionTranscript for QR handover (ISO 18013-5 proximity presentation).
|
|
1746
|
+
*
|
|
1747
|
+
* For QR handover, exact CBOR bytes matter for session key derivation.
|
|
1748
|
+
* Use DeviceEngagement.decode() and EReaderKey.decode() to preserve original bytes -
|
|
1749
|
+
* calling encode() on decoded objects will return the identical bytes.
|
|
1750
|
+
*/
|
|
1751
|
+
static forQrHandover(options) {
|
|
1752
|
+
return this.fromDecodedStructure({
|
|
1753
|
+
deviceEngagement: options.deviceEngagement,
|
|
1754
|
+
eReaderKey: options.eReaderKey,
|
|
1755
|
+
handover: QrHandover.create()
|
|
1756
|
+
});
|
|
1757
|
+
}
|
|
1758
|
+
static async forOid4VpDcApiDraft24(options, ctx) {
|
|
1759
|
+
const info = Oid4vpDcApiDraft24HandoverInfo.create(options);
|
|
1760
|
+
const handover = await Oid4vpDcApiHandover.create({ oid4vpDcApiHandoverInfo: info }, ctx);
|
|
1761
|
+
return this.fromDecodedStructure({
|
|
1762
|
+
deviceEngagement: null,
|
|
1763
|
+
eReaderKey: null,
|
|
1764
|
+
handover
|
|
1765
|
+
});
|
|
1766
|
+
}
|
|
1767
|
+
static async forOid4VpDcApi(options, ctx) {
|
|
1768
|
+
const info = Oid4vpDcApiHandoverInfo.create(options);
|
|
1769
|
+
const handover = await Oid4vpDcApiHandover.create({ oid4vpDcApiHandoverInfo: info }, ctx);
|
|
1770
|
+
return this.fromDecodedStructure({
|
|
1771
|
+
deviceEngagement: null,
|
|
1772
|
+
eReaderKey: null,
|
|
1773
|
+
handover
|
|
1774
|
+
});
|
|
1775
|
+
}
|
|
1776
|
+
static async forOid4VpIae(options, ctx) {
|
|
1777
|
+
const info = Oid4vpIaeHandoverInfo.create(options);
|
|
1778
|
+
const handover = await Oid4vpIaeHandover.create({ oid4vpIaeHandoverInfo: info }, ctx);
|
|
1779
|
+
return this.fromDecodedStructure({
|
|
1780
|
+
deviceEngagement: null,
|
|
1781
|
+
eReaderKey: null,
|
|
1782
|
+
handover
|
|
1783
|
+
});
|
|
1784
|
+
}
|
|
1785
|
+
static async forOid4Vp(options, ctx) {
|
|
1786
|
+
const info = Oid4vpHandoverInfo.create(options);
|
|
1787
|
+
const handover = await Oid4vpHandover.create({ oid4vpHandoverInfo: info }, ctx);
|
|
1788
|
+
return this.fromDecodedStructure({
|
|
1789
|
+
deviceEngagement: null,
|
|
1790
|
+
eReaderKey: null,
|
|
1791
|
+
handover
|
|
1792
|
+
});
|
|
1793
|
+
}
|
|
1794
|
+
/**
|
|
1795
|
+
* Calculate the session transcript bytes as defined in 18013-7 first edition, based
|
|
1796
|
+
* on OpenID4VP draft 18.
|
|
1797
|
+
*/
|
|
1798
|
+
static async forOid4VpDraft18(options, ctx) {
|
|
1799
|
+
const handover = await Oid4vpDraft18Handover.create({
|
|
1800
|
+
clientId: options.clientId,
|
|
1801
|
+
nonce: options.verifierGeneratedNonce,
|
|
1802
|
+
mdocGeneratedNonce: options.mdocGeneratedNonce,
|
|
1803
|
+
responseUri: options.responseUri
|
|
1804
|
+
}, ctx);
|
|
1805
|
+
return this.fromDecodedStructure({
|
|
1806
|
+
deviceEngagement: null,
|
|
1807
|
+
eReaderKey: null,
|
|
1808
|
+
handover
|
|
1809
|
+
});
|
|
1810
|
+
}
|
|
1811
|
+
};
|
|
1812
|
+
|
|
1813
|
+
//#endregion
|
|
1814
|
+
//#region src/cose/mac0.ts
|
|
1815
|
+
const mac0EncodedSchema = z.tuple([
|
|
1816
|
+
zUint8Array,
|
|
1817
|
+
z.map(z.unknown(), z.unknown()),
|
|
1818
|
+
zUint8Array.nullable(),
|
|
1819
|
+
zUint8Array
|
|
1820
|
+
]);
|
|
1821
|
+
const mac0DecodedSchema = z.object({
|
|
1822
|
+
protectedHeaders: z.instanceof(ProtectedHeaders),
|
|
1823
|
+
unprotectedHeaders: z.instanceof(UnprotectedHeaders),
|
|
1824
|
+
payload: zUint8Array.nullable(),
|
|
1825
|
+
tag: zUint8Array
|
|
1826
|
+
});
|
|
1827
|
+
var Mac0 = class Mac0 extends CborStructure {
|
|
1828
|
+
static {
|
|
1829
|
+
this.tag = 17;
|
|
1830
|
+
}
|
|
1831
|
+
static get encodingSchema() {
|
|
1832
|
+
return z.codec(mac0EncodedSchema, mac0DecodedSchema, {
|
|
1833
|
+
decode: ([protectedHeadersBytes, unprotectedHeadersMap, payload, tag]) => ({
|
|
1834
|
+
protectedHeaders: ProtectedHeaders.fromEncodedStructure(protectedHeadersBytes),
|
|
1835
|
+
unprotectedHeaders: UnprotectedHeaders.fromEncodedStructure(unprotectedHeadersMap),
|
|
1836
|
+
payload,
|
|
1837
|
+
tag
|
|
1838
|
+
}),
|
|
1839
|
+
encode: ({ protectedHeaders, unprotectedHeaders, payload, tag }) => [
|
|
1840
|
+
protectedHeaders.encodedStructure,
|
|
1841
|
+
unprotectedHeaders.encodedStructure,
|
|
1842
|
+
payload,
|
|
1843
|
+
tag
|
|
1844
|
+
]
|
|
1845
|
+
});
|
|
1846
|
+
}
|
|
1847
|
+
get protectedHeaders() {
|
|
1848
|
+
return this.structure.protectedHeaders;
|
|
1849
|
+
}
|
|
1850
|
+
get unprotectedHeaders() {
|
|
1851
|
+
return this.structure.unprotectedHeaders;
|
|
1852
|
+
}
|
|
1853
|
+
get payload() {
|
|
1854
|
+
return this.structure.payload;
|
|
1855
|
+
}
|
|
1856
|
+
get tag() {
|
|
1857
|
+
return this.structure.tag;
|
|
1858
|
+
}
|
|
1859
|
+
get toBeAuthenticated() {
|
|
1860
|
+
const payload = this.payload ?? this.detachedPayload;
|
|
1861
|
+
if (!payload) throw new CosePayloadMustBeDefinedError();
|
|
1862
|
+
return Mac0.toBeAuthenticated({
|
|
1863
|
+
payload,
|
|
1864
|
+
protectedHeaders: this.protectedHeaders,
|
|
1865
|
+
externalAad: this.externalAad
|
|
1866
|
+
});
|
|
1867
|
+
}
|
|
1868
|
+
/**
|
|
1869
|
+
* Decodes CBOR bytes into a Sign1 instance.
|
|
1870
|
+
* Uses the encodingSchema's decode() method to validate and transform the decoded data.
|
|
1871
|
+
*/
|
|
1872
|
+
static decode(bytes) {
|
|
1873
|
+
const rawStructure = cborDecode(bytes);
|
|
1874
|
+
return new this(rawStructure instanceof Mac0 ? rawStructure.decodedStructure : this.fromEncodedStructure(rawStructure).decodedStructure);
|
|
1875
|
+
}
|
|
1876
|
+
static toBeAuthenticated(options) {
|
|
1877
|
+
const toBeAuthenticated = ["MAC0", options.protectedHeaders.encodedStructure];
|
|
1878
|
+
if (options.externalAad) toBeAuthenticated.push(options.externalAad);
|
|
1879
|
+
toBeAuthenticated.push(options.payload);
|
|
1880
|
+
return cborEncode(toBeAuthenticated);
|
|
1881
|
+
}
|
|
1882
|
+
get signatureAlgorithmName() {
|
|
1883
|
+
const algorithm = this.protectedHeaders.headers?.get(Header.Algorithm) ?? this.unprotectedHeaders.headers?.get(Header.Algorithm);
|
|
1884
|
+
if (!algorithm) throw new CoseInvalidAlgorithmError();
|
|
1885
|
+
const algorithmName = coseKeyToJwk.algorithm(algorithm);
|
|
1886
|
+
if (!algorithmName) throw new CoseInvalidAlgorithmError();
|
|
1887
|
+
return algorithmName;
|
|
1888
|
+
}
|
|
1889
|
+
static async create(options, ctx) {
|
|
1890
|
+
const protectedHeaders = options.protectedHeaders instanceof ProtectedHeaders ? options.protectedHeaders : ProtectedHeaders.create({ protectedHeaders: options.protectedHeaders });
|
|
1891
|
+
const unprotectedHeaders = options.unprotectedHeaders instanceof UnprotectedHeaders ? options.unprotectedHeaders : UnprotectedHeaders.create({ unprotectedHeaders: options.unprotectedHeaders });
|
|
1892
|
+
const ephemeralMacKey = await ctx.crypto.calculateEphemeralMacKey({
|
|
1893
|
+
privateKey: options.privateKey.encode(),
|
|
1894
|
+
publicKey: options.ephemeralKey.encode(),
|
|
1895
|
+
sessionTranscriptBytes: options.sessionTranscript instanceof SessionTranscript ? options.sessionTranscript.encode({ asDataItem: true }) : options.sessionTranscript,
|
|
1896
|
+
info: "EMacKey"
|
|
1897
|
+
});
|
|
1898
|
+
const payload = options.payload ?? options.detachedPayload;
|
|
1899
|
+
if (!payload) throw new CosePayloadMustBeDefinedError();
|
|
1900
|
+
const tag = await ctx.cose.mac0.sign({
|
|
1901
|
+
toBeAuthenticated: Mac0.toBeAuthenticated({
|
|
1902
|
+
payload,
|
|
1903
|
+
protectedHeaders,
|
|
1904
|
+
externalAad: options.externalAad
|
|
1905
|
+
}),
|
|
1906
|
+
key: ephemeralMacKey
|
|
1907
|
+
});
|
|
1908
|
+
const mac0 = this.fromDecodedStructure({
|
|
1909
|
+
protectedHeaders,
|
|
1910
|
+
unprotectedHeaders,
|
|
1911
|
+
payload: options.payload ?? null,
|
|
1912
|
+
tag
|
|
1913
|
+
});
|
|
1914
|
+
mac0.externalAad = options.externalAad;
|
|
1915
|
+
mac0.detachedPayload = options.detachedPayload;
|
|
1916
|
+
return mac0;
|
|
1917
|
+
}
|
|
1918
|
+
};
|
|
1919
|
+
addExtension$1({
|
|
1920
|
+
Class: Mac0,
|
|
1921
|
+
tag: Mac0.tag,
|
|
1922
|
+
encode(instance, encodeFn) {
|
|
1923
|
+
return encodeFn(instance.encodedStructure);
|
|
1924
|
+
},
|
|
1925
|
+
decode: (encoded) => Mac0.fromEncodedStructure(encoded)
|
|
1926
|
+
});
|
|
1927
|
+
|
|
1928
|
+
//#endregion
|
|
1929
|
+
//#region src/cose/sign1.ts
|
|
1930
|
+
const sign1EncodedSchema = z$1.tuple([
|
|
1931
|
+
protectedHeadersEncodedStructure,
|
|
1932
|
+
unprotectedHeadersStructure,
|
|
1933
|
+
zUint8Array.nullable(),
|
|
1934
|
+
zUint8Array
|
|
1935
|
+
]);
|
|
1936
|
+
const sign1DecodedSchema = z$1.object({
|
|
1937
|
+
protected: z$1.instanceof(ProtectedHeaders),
|
|
1938
|
+
unprotected: z$1.instanceof(UnprotectedHeaders),
|
|
1939
|
+
payload: sign1EncodedSchema.def.items[2],
|
|
1940
|
+
signature: sign1EncodedSchema.def.items[3]
|
|
1941
|
+
});
|
|
1942
|
+
var Sign1 = class Sign1 extends CborStructure {
|
|
1943
|
+
static {
|
|
1944
|
+
this.tag = 18;
|
|
1945
|
+
}
|
|
1946
|
+
static get encodingSchema() {
|
|
1947
|
+
return z$1.codec(sign1EncodedSchema, sign1DecodedSchema, {
|
|
1948
|
+
encode: (decoded) => [
|
|
1949
|
+
decoded.protected.encodedStructure,
|
|
1950
|
+
decoded.unprotected.encodedStructure,
|
|
1951
|
+
decoded.payload,
|
|
1952
|
+
decoded.signature
|
|
1953
|
+
],
|
|
1954
|
+
decode: ([protectedHeaders, unprotected, payload, signature]) => ({
|
|
1955
|
+
protected: ProtectedHeaders.fromEncodedStructure(protectedHeaders),
|
|
1956
|
+
unprotected: UnprotectedHeaders.fromEncodedStructure(unprotected),
|
|
1957
|
+
payload,
|
|
1958
|
+
signature
|
|
1959
|
+
})
|
|
1960
|
+
});
|
|
1961
|
+
}
|
|
1962
|
+
get protectedHeaders() {
|
|
1963
|
+
return this.structure.protected;
|
|
1964
|
+
}
|
|
1965
|
+
get unprotectedHeaders() {
|
|
1966
|
+
return this.structure.unprotected;
|
|
1967
|
+
}
|
|
1968
|
+
get payload() {
|
|
1969
|
+
return this.structure.payload;
|
|
1970
|
+
}
|
|
1971
|
+
get signature() {
|
|
1972
|
+
return this.structure.signature;
|
|
1973
|
+
}
|
|
1974
|
+
get certificateChain() {
|
|
1975
|
+
return this.x5chain ?? [];
|
|
1976
|
+
}
|
|
1977
|
+
get certificate() {
|
|
1978
|
+
const [certificate] = this.certificateChain;
|
|
1979
|
+
if (!certificate) throw new CoseCertificateNotFoundError();
|
|
1980
|
+
return certificate;
|
|
1981
|
+
}
|
|
1982
|
+
getIssuingCountry(ctx) {
|
|
1983
|
+
return ctx.x509.getIssuerNameField({
|
|
1984
|
+
certificate: this.certificate,
|
|
1985
|
+
field: "C"
|
|
1986
|
+
})[0];
|
|
1987
|
+
}
|
|
1988
|
+
getIssuingStateOrProvince(ctx) {
|
|
1989
|
+
return ctx.x509.getIssuerNameField({
|
|
1990
|
+
certificate: this.certificate,
|
|
1991
|
+
field: "ST"
|
|
1992
|
+
})[0];
|
|
1993
|
+
}
|
|
1994
|
+
get toBeSigned() {
|
|
1995
|
+
const payload = this.payload ?? this.detachedPayload;
|
|
1996
|
+
if (!payload) throw new CosePayloadMustBeDefinedError();
|
|
1997
|
+
return Sign1.toBeSigned({
|
|
1998
|
+
payload,
|
|
1999
|
+
protectedHeaders: this.protectedHeaders,
|
|
2000
|
+
externalAad: this.externalAad
|
|
2001
|
+
});
|
|
2002
|
+
}
|
|
2003
|
+
/**
|
|
2004
|
+
* Decodes CBOR bytes into a Sign1 instance.
|
|
2005
|
+
* Uses the encodingSchema's decode() method to validate and transform the decoded data.
|
|
2006
|
+
*/
|
|
2007
|
+
static decode(bytes) {
|
|
2008
|
+
const rawStructure = cborDecode(bytes);
|
|
2009
|
+
return new this(rawStructure instanceof Sign1 ? rawStructure.decodedStructure : this.fromEncodedStructure(rawStructure).decodedStructure);
|
|
2010
|
+
}
|
|
2011
|
+
static toBeSigned(options) {
|
|
2012
|
+
return cborEncode([
|
|
2013
|
+
"Signature1",
|
|
2014
|
+
options.protectedHeaders.encodedStructure,
|
|
2015
|
+
options.externalAad ?? new Uint8Array(),
|
|
2016
|
+
options.payload
|
|
2017
|
+
]);
|
|
2018
|
+
}
|
|
2019
|
+
get signatureAlgorithmName() {
|
|
2020
|
+
const algorithm = this.protectedHeaders.headers?.get(Header.Algorithm) ?? this.unprotectedHeaders.headers?.get(Header.Algorithm);
|
|
2021
|
+
if (!algorithm) throw new CoseInvalidAlgorithmError();
|
|
2022
|
+
const algorithmName = coseKeyToJwk.algorithm(algorithm);
|
|
2023
|
+
if (!algorithmName) throw new CoseInvalidAlgorithmError();
|
|
2024
|
+
return algorithmName;
|
|
2025
|
+
}
|
|
2026
|
+
get x5chain() {
|
|
2027
|
+
const x5chain = this.protectedHeaders.headers?.get(Header.X5Chain) ?? this.unprotectedHeaders.headers?.get(Header.X5Chain);
|
|
2028
|
+
if (!x5chain?.[0]) return;
|
|
2029
|
+
return Array.isArray(x5chain) ? x5chain : [x5chain];
|
|
2030
|
+
}
|
|
2031
|
+
async verifySignature(options, ctx) {
|
|
2032
|
+
const publicKey = options.key ?? await ctx.x509.getPublicKey({
|
|
2033
|
+
certificate: this.certificate,
|
|
2034
|
+
alg: this.signatureAlgorithmName
|
|
2035
|
+
});
|
|
2036
|
+
return await ctx.cose.sign1.verify({
|
|
2037
|
+
sign1: this,
|
|
2038
|
+
key: publicKey
|
|
2039
|
+
});
|
|
2040
|
+
}
|
|
2041
|
+
static async create(options, ctx) {
|
|
2042
|
+
const payload = options.payload ?? options.detachedPayload;
|
|
2043
|
+
if (!payload) throw new CosePayloadMustBeDefinedError();
|
|
2044
|
+
const protectedHeaders = options.protectedHeaders instanceof ProtectedHeaders ? options.protectedHeaders : options.protectedHeaders ? ProtectedHeaders.fromDecodedStructure(options.protectedHeaders) : ProtectedHeaders.create({});
|
|
2045
|
+
const signature = await ctx.cose.sign1.sign({
|
|
2046
|
+
toBeSigned: Sign1.toBeSigned({
|
|
2047
|
+
payload,
|
|
2048
|
+
protectedHeaders,
|
|
2049
|
+
externalAad: options.externalAad
|
|
2050
|
+
}),
|
|
2051
|
+
key: options.signingKey
|
|
2052
|
+
});
|
|
2053
|
+
const sign1 = this.fromDecodedStructure({
|
|
2054
|
+
payload: options.payload ?? null,
|
|
2055
|
+
protected: protectedHeaders,
|
|
2056
|
+
unprotected: options.unprotectedHeaders instanceof UnprotectedHeaders ? options.unprotectedHeaders : options.unprotectedHeaders ? UnprotectedHeaders.fromEncodedStructure(options.unprotectedHeaders) : UnprotectedHeaders.create({}),
|
|
2057
|
+
signature
|
|
2058
|
+
});
|
|
2059
|
+
sign1.detachedPayload = options.detachedPayload;
|
|
2060
|
+
sign1.externalAad = options.externalAad;
|
|
2061
|
+
return sign1;
|
|
2062
|
+
}
|
|
2063
|
+
};
|
|
2064
|
+
addExtension$1({
|
|
2065
|
+
Class: Sign1,
|
|
2066
|
+
tag: Sign1.tag,
|
|
2067
|
+
encode(instance, encodeFn) {
|
|
2068
|
+
return encodeFn(instance);
|
|
2069
|
+
},
|
|
2070
|
+
decode: (encoded) => Sign1.fromEncodedStructure(encoded)
|
|
2071
|
+
});
|
|
2072
|
+
|
|
2073
|
+
//#endregion
|
|
2074
|
+
//#region src/mdoc/errors.ts
|
|
2075
|
+
var MdlError = class extends Error {
|
|
2076
|
+
constructor(message = new.target.name) {
|
|
2077
|
+
super(message);
|
|
2078
|
+
}
|
|
2079
|
+
};
|
|
2080
|
+
var MdlParseError = class extends MdlError {};
|
|
2081
|
+
var PresentationDefinitionOrDocRequestsAreRequiredError = class extends MdlError {};
|
|
2082
|
+
var SessionTranscriptOrSessionTranscriptBytesAreRequiredError = class extends MdlError {};
|
|
2083
|
+
var DuplicateNamespaceInIssuerNamespacesError = class extends MdlError {};
|
|
2084
|
+
var DuplicateDocumentInDeviceResponseError = class extends MdlError {};
|
|
2085
|
+
var EitherSignatureOrMacMustBeProvidedError = class extends MdlError {};
|
|
2086
|
+
|
|
2087
|
+
//#endregion
|
|
2088
|
+
//#region src/mdoc/check-callback.ts
|
|
2089
|
+
const defaultVerificationCallback = (verification) => {
|
|
2090
|
+
if (verification.status !== "FAILED") return;
|
|
2091
|
+
throw new MdlError(verification.reason ?? verification.check);
|
|
2092
|
+
};
|
|
2093
|
+
const onCategoryCheck = (onCheck, category) => {
|
|
2094
|
+
return (item) => {
|
|
2095
|
+
onCheck({
|
|
2096
|
+
...item,
|
|
2097
|
+
category
|
|
2098
|
+
});
|
|
2099
|
+
};
|
|
2100
|
+
};
|
|
2101
|
+
|
|
2102
|
+
//#endregion
|
|
2103
|
+
//#region src/mdoc/models/device-signed-items.ts
|
|
2104
|
+
const deviceSignedItemsSchema = z.map(z.string(), z.unknown());
|
|
2105
|
+
var DeviceSignedItems = class extends CborStructure {
|
|
2106
|
+
static get encodingSchema() {
|
|
2107
|
+
return deviceSignedItemsSchema;
|
|
2108
|
+
}
|
|
2109
|
+
get deviceSignedItems() {
|
|
2110
|
+
return this.structure;
|
|
2111
|
+
}
|
|
2112
|
+
static create(options) {
|
|
2113
|
+
return this.fromEncodedStructure(options.deviceSignedItems);
|
|
2114
|
+
}
|
|
2115
|
+
};
|
|
2116
|
+
|
|
2117
|
+
//#endregion
|
|
2118
|
+
//#region src/mdoc/models/device-namespaces.ts
|
|
2119
|
+
const deviceNamespacesEncodedSchema = z.map(z.string(), deviceSignedItemsSchema);
|
|
2120
|
+
const deviceNamespacesDecodedSchema = z.map(z.string(), z.instanceof(DeviceSignedItems));
|
|
2121
|
+
var DeviceNamespaces = class extends CborStructure {
|
|
2122
|
+
static get encodingSchema() {
|
|
2123
|
+
return z.codec(deviceNamespacesEncodedSchema, deviceNamespacesDecodedSchema, {
|
|
2124
|
+
decode: (input) => {
|
|
2125
|
+
const deviceNamespaces = /* @__PURE__ */ new Map();
|
|
2126
|
+
input.forEach((value, key) => {
|
|
2127
|
+
deviceNamespaces.set(key, DeviceSignedItems.fromEncodedStructure(value));
|
|
2128
|
+
});
|
|
2129
|
+
return deviceNamespaces;
|
|
2130
|
+
},
|
|
2131
|
+
encode: (output) => {
|
|
2132
|
+
const map = /* @__PURE__ */ new Map();
|
|
2133
|
+
output.forEach((value, key) => {
|
|
2134
|
+
map.set(key, value.encodedStructure);
|
|
2135
|
+
});
|
|
2136
|
+
return map;
|
|
2137
|
+
}
|
|
2138
|
+
});
|
|
2139
|
+
}
|
|
2140
|
+
get deviceNamespaces() {
|
|
2141
|
+
return this.structure;
|
|
2142
|
+
}
|
|
2143
|
+
static create(options) {
|
|
2144
|
+
return this.fromDecodedStructure(options.deviceNamespaces);
|
|
2145
|
+
}
|
|
2146
|
+
};
|
|
2147
|
+
|
|
2148
|
+
//#endregion
|
|
2149
|
+
//#region src/mdoc/models/device-authentication.ts
|
|
2150
|
+
const deviceAuthenticationEncodedSchema = z.tuple([
|
|
2151
|
+
z.literal("DeviceAuthentication"),
|
|
2152
|
+
sessionTranscriptEncodedSchema,
|
|
2153
|
+
z.string(),
|
|
2154
|
+
z.instanceof(DataItem)
|
|
2155
|
+
]);
|
|
2156
|
+
const deviceAuthenticationDecodedSchema = z.object({
|
|
2157
|
+
sessionTranscript: z.instanceof(SessionTranscript),
|
|
2158
|
+
docType: z.string(),
|
|
2159
|
+
deviceNamespaces: z.instanceof(DeviceNamespaces)
|
|
2160
|
+
});
|
|
2161
|
+
var DeviceAuthentication = class extends CborStructure {
|
|
2162
|
+
static get encodingSchema() {
|
|
2163
|
+
return z.codec(deviceAuthenticationEncodedSchema, deviceAuthenticationDecodedSchema, {
|
|
2164
|
+
decode: ([, sessionTranscript, docType, deviceNamespacesDataItem]) => ({
|
|
2165
|
+
sessionTranscript: SessionTranscript.fromEncodedStructure(sessionTranscript),
|
|
2166
|
+
docType,
|
|
2167
|
+
deviceNamespaces: DeviceNamespaces.fromEncodedStructure(deviceNamespacesDataItem.data)
|
|
2168
|
+
}),
|
|
2169
|
+
encode: ({ sessionTranscript, docType, deviceNamespaces }) => [
|
|
2170
|
+
"DeviceAuthentication",
|
|
2171
|
+
sessionTranscript.encodedStructure,
|
|
2172
|
+
docType,
|
|
2173
|
+
DataItem.fromData(deviceNamespaces.encodedStructure)
|
|
2174
|
+
]
|
|
2175
|
+
});
|
|
2176
|
+
}
|
|
2177
|
+
get sessionTranscript() {
|
|
2178
|
+
return this.structure.sessionTranscript;
|
|
2179
|
+
}
|
|
2180
|
+
get docType() {
|
|
2181
|
+
return this.structure.docType;
|
|
2182
|
+
}
|
|
2183
|
+
get deviceNamespaces() {
|
|
2184
|
+
return this.structure.deviceNamespaces;
|
|
2185
|
+
}
|
|
2186
|
+
static create(options) {
|
|
2187
|
+
const sessionTranscript = options.sessionTranscript instanceof SessionTranscript ? options.sessionTranscript : SessionTranscript.decode(options.sessionTranscript);
|
|
2188
|
+
return this.fromDecodedStructure({
|
|
2189
|
+
sessionTranscript,
|
|
2190
|
+
docType: options.docType,
|
|
2191
|
+
deviceNamespaces: options.deviceNamespaces
|
|
2192
|
+
});
|
|
2193
|
+
}
|
|
2194
|
+
};
|
|
2195
|
+
|
|
2196
|
+
//#endregion
|
|
2197
|
+
//#region src/mdoc/models/device-mac.ts
|
|
2198
|
+
var DeviceMac = class extends Mac0 {
|
|
2199
|
+
async verify(options, ctx) {
|
|
2200
|
+
const key = await ctx.crypto.calculateEphemeralMacKey({
|
|
2201
|
+
privateKey: options.privateKey.privateKey,
|
|
2202
|
+
publicKey: options.publicKey.publicKey,
|
|
2203
|
+
sessionTranscriptBytes: options.sessionTranscript instanceof SessionTranscript ? options.sessionTranscript.encode({ asDataItem: true }) : options.sessionTranscript,
|
|
2204
|
+
info: options.info ?? "EMacKey"
|
|
2205
|
+
});
|
|
2206
|
+
return ctx.cose.mac0.verify({
|
|
2207
|
+
mac0: this,
|
|
2208
|
+
key
|
|
2209
|
+
});
|
|
2210
|
+
}
|
|
2211
|
+
static async create(options, ctx) {
|
|
2212
|
+
return super.create(options, ctx);
|
|
2213
|
+
}
|
|
2214
|
+
};
|
|
2215
|
+
|
|
2216
|
+
//#endregion
|
|
2217
|
+
//#region src/mdoc/models/device-signature.ts
|
|
2218
|
+
var DeviceSignature = class extends Sign1 {
|
|
2219
|
+
static create(options, ctx) {
|
|
2220
|
+
return super.create(options, ctx);
|
|
2221
|
+
}
|
|
2222
|
+
};
|
|
2223
|
+
|
|
2224
|
+
//#endregion
|
|
2225
|
+
//#region src/mdoc/models/device-auth.ts
|
|
2226
|
+
const deviceAuthSchema = typedMap([["deviceSignature", z.instanceof(DeviceSignature).exactOptional()], ["deviceMac", z.instanceof(DeviceMac).exactOptional()]]).refine((map) => [map.get("deviceMac"), map.get("deviceSignature")].filter((i) => i !== void 0).length === 1, { error: () => "deviceAuth must contain either a deviceMac or deviceSignature, but not both or neither" });
|
|
2227
|
+
var DeviceAuth = class extends CborStructure {
|
|
2228
|
+
static get encodingSchema() {
|
|
2229
|
+
return z.codec(deviceAuthSchema.in, deviceAuthSchema.out, {
|
|
2230
|
+
decode: (input) => {
|
|
2231
|
+
const map = TypedMap.fromMap(input);
|
|
2232
|
+
if (input.has("deviceSignature")) map.set("deviceSignature", DeviceSignature.fromEncodedStructure(input.get("deviceSignature")));
|
|
2233
|
+
if (input.has("deviceMac")) map.set("deviceMac", DeviceMac.fromEncodedStructure(input.get("deviceMac")));
|
|
2234
|
+
return map;
|
|
2235
|
+
},
|
|
2236
|
+
encode: (output) => {
|
|
2237
|
+
const map = output.toMap();
|
|
2238
|
+
const deviceSignature = output.get("deviceSignature");
|
|
2239
|
+
if (deviceSignature) map.set("deviceSignature", deviceSignature.encodedStructure);
|
|
2240
|
+
const deviceMac = output.get("deviceMac");
|
|
2241
|
+
if (deviceMac) map.set("deviceMac", deviceMac.encodedStructure);
|
|
2242
|
+
return map;
|
|
2243
|
+
}
|
|
2244
|
+
});
|
|
2245
|
+
}
|
|
2246
|
+
get deviceSignature() {
|
|
2247
|
+
return this.structure.get("deviceSignature");
|
|
2248
|
+
}
|
|
2249
|
+
get deviceMac() {
|
|
2250
|
+
return this.structure.get("deviceMac");
|
|
2251
|
+
}
|
|
2252
|
+
async verify(options, ctx) {
|
|
2253
|
+
const onCheck = onCategoryCheck(options.verificationCallback ?? defaultVerificationCallback, "DEVICE_AUTH");
|
|
2254
|
+
const { deviceKey } = options.document.issuerSigned.issuerAuth.mobileSecurityObject.deviceKeyInfo;
|
|
2255
|
+
const deviceMac = this.structure.get("deviceMac");
|
|
2256
|
+
const deviceSignature = this.structure.get("deviceSignature");
|
|
2257
|
+
if (!deviceMac && !deviceSignature) {
|
|
2258
|
+
onCheck({
|
|
2259
|
+
status: "FAILED",
|
|
2260
|
+
check: "Device Auth must contain a deviceSignature or deviceMac element"
|
|
2261
|
+
});
|
|
2262
|
+
return;
|
|
2263
|
+
}
|
|
2264
|
+
const deviceAuthenticationBytes = DeviceAuthentication.create({
|
|
2265
|
+
sessionTranscript: options.sessionTranscript,
|
|
2266
|
+
docType: options.document.docType,
|
|
2267
|
+
deviceNamespaces: options.document.deviceSigned.deviceNamespaces
|
|
2268
|
+
}).encode({ asDataItem: true });
|
|
2269
|
+
if (deviceSignature) {
|
|
2270
|
+
try {
|
|
2271
|
+
deviceSignature.detachedPayload = deviceAuthenticationBytes;
|
|
2272
|
+
onCheck({
|
|
2273
|
+
status: await ctx.cose.sign1.verify({
|
|
2274
|
+
sign1: deviceSignature,
|
|
2275
|
+
key: deviceKey
|
|
2276
|
+
}) ? "PASSED" : "FAILED",
|
|
2277
|
+
check: "Device signature must be valid"
|
|
2278
|
+
});
|
|
2279
|
+
} catch (err) {
|
|
2280
|
+
onCheck({
|
|
2281
|
+
status: "FAILED",
|
|
2282
|
+
check: "Device signature must be valid",
|
|
2283
|
+
reason: `Unable to verify deviceAuth signature (ECDSA/EdDSA): ${err instanceof Error ? err.message : "Unknown error"}`
|
|
2284
|
+
});
|
|
2285
|
+
}
|
|
2286
|
+
return;
|
|
2287
|
+
}
|
|
2288
|
+
if (deviceMac) {
|
|
2289
|
+
if (deviceMac.signatureAlgorithmName !== MacAlgorithm.HS256) {
|
|
2290
|
+
onCheck({
|
|
2291
|
+
status: "FAILED",
|
|
2292
|
+
check: "Device MAC must use alg 5 (HMAC 256/256)"
|
|
2293
|
+
});
|
|
2294
|
+
return;
|
|
2295
|
+
}
|
|
2296
|
+
onCheck({
|
|
2297
|
+
status: options.ephemeralMacPrivateKey ? "PASSED" : "FAILED",
|
|
2298
|
+
check: "Ephemeral private key must be present when using MAC authentication"
|
|
2299
|
+
});
|
|
2300
|
+
if (!options.ephemeralMacPrivateKey) return;
|
|
2301
|
+
try {
|
|
2302
|
+
deviceMac.detachedPayload = deviceAuthenticationBytes;
|
|
2303
|
+
onCheck({
|
|
2304
|
+
status: await deviceMac.verify({
|
|
2305
|
+
publicKey: deviceKey,
|
|
2306
|
+
privateKey: options.ephemeralMacPrivateKey,
|
|
2307
|
+
sessionTranscript: options.sessionTranscript,
|
|
2308
|
+
info: "EMacKey"
|
|
2309
|
+
}, ctx) ? "PASSED" : "FAILED",
|
|
2310
|
+
check: "Device MAC must be valid"
|
|
2311
|
+
});
|
|
2312
|
+
} catch (err) {
|
|
2313
|
+
onCheck({
|
|
2314
|
+
status: "FAILED",
|
|
2315
|
+
check: "Device MAC must be valid",
|
|
2316
|
+
reason: `Unable to verify deviceAuth MAC: ${err instanceof Error ? err.message : "Unknown error"}`
|
|
2317
|
+
});
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
onCheck({
|
|
2321
|
+
status: "FAILED",
|
|
2322
|
+
check: "No Device Signature or Device Mac found on Device Auth",
|
|
2323
|
+
reason: "No Device Signature or Device Mac found on Device Auth"
|
|
2324
|
+
});
|
|
2325
|
+
}
|
|
2326
|
+
static create(options) {
|
|
2327
|
+
const map = new TypedMap([]);
|
|
2328
|
+
if (options.deviceSignature) map.set("deviceSignature", options.deviceSignature);
|
|
2329
|
+
if (options.deviceMac) map.set("deviceMac", options.deviceMac);
|
|
2330
|
+
return this.fromDecodedStructure(map);
|
|
2331
|
+
}
|
|
2332
|
+
};
|
|
2333
|
+
|
|
2334
|
+
//#endregion
|
|
2335
|
+
//#region src/mdoc/models/device-key.ts
|
|
2336
|
+
var DeviceKey = class extends CoseKey {};
|
|
2337
|
+
|
|
2338
|
+
//#endregion
|
|
2339
|
+
//#region src/mdoc/models/key-authorizations.ts
|
|
2340
|
+
const keyAuthorizationsSchema = typedMap([["nameSpaces", z.array(z.string()).exactOptional()], ["dataElements", z.map(z.string(), z.array(z.string())).exactOptional()]]);
|
|
2341
|
+
var KeyAuthorizations = class extends CborStructure {
|
|
2342
|
+
static get encodingSchema() {
|
|
2343
|
+
return keyAuthorizationsSchema;
|
|
2344
|
+
}
|
|
2345
|
+
get namespaces() {
|
|
2346
|
+
return this.structure.get("nameSpaces");
|
|
2347
|
+
}
|
|
2348
|
+
get dataElements() {
|
|
2349
|
+
return this.structure.get("dataElements");
|
|
2350
|
+
}
|
|
2351
|
+
static create(options) {
|
|
2352
|
+
const map = new TypedMap([]);
|
|
2353
|
+
if (options.namespaces !== void 0) map.set("nameSpaces", options.namespaces);
|
|
2354
|
+
if (options.dataElements !== void 0) map.set("dataElements", options.dataElements);
|
|
2355
|
+
return this.fromDecodedStructure(map);
|
|
2356
|
+
}
|
|
2357
|
+
};
|
|
2358
|
+
|
|
2359
|
+
//#endregion
|
|
2360
|
+
//#region src/mdoc/models/key-info.ts
|
|
2361
|
+
const keyInfoSchema = z.map(z.number(), z.unknown());
|
|
2362
|
+
var KeyInfo = class extends CborStructure {
|
|
2363
|
+
static get encodingSchema() {
|
|
2364
|
+
return keyInfoSchema;
|
|
2365
|
+
}
|
|
2366
|
+
get keyInfo() {
|
|
2367
|
+
return this.structure;
|
|
2368
|
+
}
|
|
2369
|
+
static create(options) {
|
|
2370
|
+
return this.fromEncodedStructure(options.keyInfo);
|
|
2371
|
+
}
|
|
2372
|
+
};
|
|
2373
|
+
|
|
2374
|
+
//#endregion
|
|
2375
|
+
//#region src/mdoc/models/device-key-info.ts
|
|
2376
|
+
const deviceKeyInfoSchema = typedMap([
|
|
2377
|
+
["deviceKey", z.instanceof(DeviceKey)],
|
|
2378
|
+
["keyAuthorizations", z.instanceof(KeyAuthorizations).exactOptional()],
|
|
2379
|
+
["keyInfo", z.instanceof(KeyInfo).exactOptional()]
|
|
2380
|
+
]);
|
|
2381
|
+
var DeviceKeyInfo = class extends CborStructure {
|
|
2382
|
+
static get encodingSchema() {
|
|
2383
|
+
return z.codec(deviceKeyInfoSchema.in, deviceKeyInfoSchema.out, {
|
|
2384
|
+
decode: (input) => {
|
|
2385
|
+
const map = TypedMap.fromMap(input);
|
|
2386
|
+
map.set("deviceKey", DeviceKey.fromEncodedStructure(input.get("deviceKey")));
|
|
2387
|
+
if (input.has("keyAuthorizations")) map.set("keyAuthorizations", KeyAuthorizations.fromEncodedStructure(input.get("keyAuthorizations")));
|
|
2388
|
+
if (input.has("keyInfo")) map.set("keyInfo", KeyInfo.fromEncodedStructure(input.get("keyInfo")));
|
|
2389
|
+
return map;
|
|
2390
|
+
},
|
|
2391
|
+
encode: (output) => {
|
|
2392
|
+
const map = output.toMap();
|
|
2393
|
+
map.set("deviceKey", output.get("deviceKey").encodedStructure);
|
|
2394
|
+
const keyAuthorizations = output.get("keyAuthorizations");
|
|
2395
|
+
if (keyAuthorizations) map.set("keyAuthorizations", keyAuthorizations.encodedStructure);
|
|
2396
|
+
const keyInfo = output.get("keyInfo");
|
|
2397
|
+
if (keyInfo) map.set("keyInfo", keyInfo.encodedStructure);
|
|
2398
|
+
return map;
|
|
2399
|
+
}
|
|
2400
|
+
});
|
|
2401
|
+
}
|
|
2402
|
+
get deviceKey() {
|
|
2403
|
+
return this.structure.get("deviceKey");
|
|
2404
|
+
}
|
|
2405
|
+
get keyAuthorizations() {
|
|
2406
|
+
return this.structure.get("keyAuthorizations");
|
|
2407
|
+
}
|
|
2408
|
+
get keyInfo() {
|
|
2409
|
+
return this.structure.get("keyInfo");
|
|
2410
|
+
}
|
|
2411
|
+
static create(options) {
|
|
2412
|
+
const map = new TypedMap([["deviceKey", options.deviceKey]]);
|
|
2413
|
+
if (options.keyAuthorizations) map.set("keyAuthorizations", options.keyAuthorizations);
|
|
2414
|
+
if (options.keyInfo) map.set("keyInfo", options.keyInfo);
|
|
2415
|
+
return this.fromDecodedStructure(map);
|
|
2416
|
+
}
|
|
2417
|
+
};
|
|
2418
|
+
|
|
2419
|
+
//#endregion
|
|
2420
|
+
//#region src/mdoc/models/items-request.ts
|
|
2421
|
+
const namespacesSchema = z.map(z.string(), z.map(z.string(), z.boolean()));
|
|
2422
|
+
const itemsRequestSchema = typedMap([["docType", z.string()], ["nameSpaces", namespacesSchema]]);
|
|
2423
|
+
var ItemsRequest = class extends CborStructure {
|
|
2424
|
+
static get encodingSchema() {
|
|
2425
|
+
return itemsRequestSchema;
|
|
2426
|
+
}
|
|
2427
|
+
get docType() {
|
|
2428
|
+
return this.structure.get("docType");
|
|
2429
|
+
}
|
|
2430
|
+
get namespaces() {
|
|
2431
|
+
return this.structure.get("nameSpaces");
|
|
2432
|
+
}
|
|
2433
|
+
static create(options) {
|
|
2434
|
+
const namespaces = options.namespaces instanceof Map ? options.namespaces : new Map(Object.entries(options.namespaces).map(([ns, inner]) => [ns, new Map(Object.entries(inner))]));
|
|
2435
|
+
const structure = new Map([["docType", options.docType], ["nameSpaces", namespaces]]);
|
|
2436
|
+
return this.fromEncodedStructure(structure);
|
|
2437
|
+
}
|
|
2438
|
+
};
|
|
2439
|
+
|
|
2440
|
+
//#endregion
|
|
2441
|
+
//#region src/mdoc/models/reader-authentication.ts
|
|
2442
|
+
const readerAuthenticationEncodedSchema = z.tuple([
|
|
2443
|
+
z.literal("ReaderAuthentication"),
|
|
2444
|
+
sessionTranscriptEncodedSchema,
|
|
2445
|
+
z.instanceof(DataItem)
|
|
2446
|
+
]);
|
|
2447
|
+
const readerAuthenticationDecodedSchema = z.object({
|
|
2448
|
+
sessionTranscript: z.instanceof(SessionTranscript),
|
|
2449
|
+
itemsRequest: z.instanceof(ItemsRequest)
|
|
2450
|
+
});
|
|
2451
|
+
var ReaderAuthentication = class extends CborStructure {
|
|
2452
|
+
static get encodingSchema() {
|
|
2453
|
+
return z.codec(readerAuthenticationEncodedSchema, readerAuthenticationDecodedSchema, {
|
|
2454
|
+
decode: ([, sessionTranscript, itemsRequestDataItem]) => ({
|
|
2455
|
+
sessionTranscript: SessionTranscript.fromEncodedStructure(sessionTranscript),
|
|
2456
|
+
itemsRequest: ItemsRequest.fromEncodedStructure(itemsRequestDataItem.data)
|
|
2457
|
+
}),
|
|
2458
|
+
encode: ({ sessionTranscript, itemsRequest }) => [
|
|
2459
|
+
"ReaderAuthentication",
|
|
2460
|
+
sessionTranscript.encodedStructure,
|
|
2461
|
+
DataItem.fromData(itemsRequest.encodedStructure)
|
|
2462
|
+
]
|
|
2463
|
+
});
|
|
2464
|
+
}
|
|
2465
|
+
get sessionTranscript() {
|
|
2466
|
+
return this.structure.sessionTranscript;
|
|
2467
|
+
}
|
|
2468
|
+
get itemsRequest() {
|
|
2469
|
+
return this.structure.itemsRequest;
|
|
2470
|
+
}
|
|
2471
|
+
static create(options) {
|
|
2472
|
+
return this.fromDecodedStructure({
|
|
2473
|
+
sessionTranscript: options.sessionTranscript,
|
|
2474
|
+
itemsRequest: options.itemsRequest
|
|
2475
|
+
});
|
|
2476
|
+
}
|
|
2477
|
+
};
|
|
2478
|
+
|
|
2479
|
+
//#endregion
|
|
2480
|
+
//#region src/mdoc/models/reader-auth.ts
|
|
2481
|
+
var ReaderAuth = class extends Sign1 {
|
|
2482
|
+
async verify(options, ctx) {
|
|
2483
|
+
const readerAuthentication = options.readerAuthentication instanceof ReaderAuthentication ? options.readerAuthentication : new ReaderAuthentication(options.readerAuthentication);
|
|
2484
|
+
const onCheck = onCategoryCheck(options.verificationCallback ?? defaultVerificationCallback, "READER_AUTH");
|
|
2485
|
+
this.detachedPayload = readerAuthentication.encode({ asDataItem: true });
|
|
2486
|
+
onCheck({
|
|
2487
|
+
status: await this.verifySignature({}, ctx) ? "PASSED" : "FAILED",
|
|
2488
|
+
check: "Signature is invalid on the reader auth",
|
|
2489
|
+
reason: "Signature is invalid on the reader auth"
|
|
2490
|
+
});
|
|
2491
|
+
}
|
|
2492
|
+
static create(options, ctx) {
|
|
2493
|
+
return super.create(options, ctx);
|
|
2494
|
+
}
|
|
2495
|
+
};
|
|
2496
|
+
|
|
2497
|
+
//#endregion
|
|
2498
|
+
//#region src/mdoc/models/doc-request.ts
|
|
2499
|
+
const docRequestSchema = typedMap([["itemsRequest", z.instanceof(ItemsRequest)], ["readerAuth", z.instanceof(ReaderAuth).exactOptional()]]);
|
|
2500
|
+
var DocRequest = class extends CborStructure {
|
|
2501
|
+
static get encodingSchema() {
|
|
2502
|
+
return z.codec(docRequestSchema.in, docRequestSchema.out, {
|
|
2503
|
+
decode: (input) => {
|
|
2504
|
+
const map = TypedMap.fromMap(input);
|
|
2505
|
+
const itemsRequestData = input.get("itemsRequest");
|
|
2506
|
+
map.set("itemsRequest", ItemsRequest.fromEncodedStructure(itemsRequestData.data));
|
|
2507
|
+
if (input.has("readerAuth")) map.set("readerAuth", ReaderAuth.fromEncodedStructure(input.get("readerAuth")));
|
|
2508
|
+
return map;
|
|
2509
|
+
},
|
|
2510
|
+
encode: (output) => {
|
|
2511
|
+
const map = output.toMap();
|
|
2512
|
+
map.set("itemsRequest", DataItem.fromData(output.get("itemsRequest").encodedStructure));
|
|
2513
|
+
const readerAuth = output.get("readerAuth");
|
|
2514
|
+
if (readerAuth) map.set("readerAuth", readerAuth.encodedStructure);
|
|
2515
|
+
return map;
|
|
2516
|
+
}
|
|
2517
|
+
});
|
|
2518
|
+
}
|
|
2519
|
+
get itemsRequest() {
|
|
2520
|
+
return this.structure.get("itemsRequest");
|
|
2521
|
+
}
|
|
2522
|
+
get readerAuth() {
|
|
2523
|
+
return this.structure.get("readerAuth");
|
|
2524
|
+
}
|
|
2525
|
+
static create(options) {
|
|
2526
|
+
const map = new TypedMap([["itemsRequest", options.itemsRequest]]);
|
|
2527
|
+
if (options.readerAuth) map.set("readerAuth", options.readerAuth);
|
|
2528
|
+
return this.fromDecodedStructure(map);
|
|
2529
|
+
}
|
|
2530
|
+
};
|
|
2531
|
+
|
|
2532
|
+
//#endregion
|
|
2533
|
+
//#region src/mdoc/models/device-request.ts
|
|
2534
|
+
const deviceRequestSchema = typedMap([["version", z.string()], ["docRequests", z.array(z.instanceof(DocRequest))]]);
|
|
2535
|
+
var DeviceRequest = class extends CborStructure {
|
|
2536
|
+
static get encodingSchema() {
|
|
2537
|
+
return z.codec(deviceRequestSchema.in, deviceRequestSchema.out, {
|
|
2538
|
+
decode: (input) => {
|
|
2539
|
+
const map = TypedMap.fromMap(input);
|
|
2540
|
+
const docRequests = input.get("docRequests");
|
|
2541
|
+
map.set("docRequests", docRequests.map((dr) => DocRequest.fromEncodedStructure(dr)));
|
|
2542
|
+
return map;
|
|
2543
|
+
},
|
|
2544
|
+
encode: (output) => {
|
|
2545
|
+
const map = output.toMap();
|
|
2546
|
+
map.set("docRequests", output.get("docRequests").map((dr) => dr.encodedStructure));
|
|
2547
|
+
return map;
|
|
2548
|
+
}
|
|
2549
|
+
});
|
|
2550
|
+
}
|
|
2551
|
+
get version() {
|
|
2552
|
+
return this.structure.get("version");
|
|
2553
|
+
}
|
|
2554
|
+
get docRequests() {
|
|
2555
|
+
return this.structure.get("docRequests");
|
|
2556
|
+
}
|
|
2557
|
+
static create(options) {
|
|
2558
|
+
const map = new TypedMap([["version", options.version ?? "1.0"], ["docRequests", options.docRequests]]);
|
|
2559
|
+
return this.fromDecodedStructure(map);
|
|
2560
|
+
}
|
|
2561
|
+
};
|
|
2562
|
+
|
|
2563
|
+
//#endregion
|
|
2564
|
+
//#region src/utils/findIssuerSigned.ts
|
|
2565
|
+
const findIssuerSigned = (is, docType) => {
|
|
2566
|
+
const issuerSigned = is.filter((i) => i.issuerAuth.mobileSecurityObject.docType === docType);
|
|
2567
|
+
if (!issuerSigned || !issuerSigned[0]) throw new Error(`No Issuer Signed matching docType '${docType}'`);
|
|
2568
|
+
if (issuerSigned.length > 1) throw new Error(`Multiple Issuer Signed matching docType '${docType}'`);
|
|
2569
|
+
return issuerSigned[0];
|
|
2570
|
+
};
|
|
2571
|
+
|
|
2572
|
+
//#endregion
|
|
2573
|
+
//#region src/mdoc/models/issuer-signed-item.ts
|
|
2574
|
+
const issuerSignedItemSchema = typedMap([
|
|
2575
|
+
["digestID", z.number()],
|
|
2576
|
+
["random", zUint8Array],
|
|
2577
|
+
["elementIdentifier", z.string()],
|
|
2578
|
+
["elementValue", z.unknown()]
|
|
2579
|
+
]);
|
|
2580
|
+
var IssuerSignedItem = class extends CborStructure {
|
|
2581
|
+
static get encodingSchema() {
|
|
2582
|
+
return issuerSignedItemSchema;
|
|
2583
|
+
}
|
|
2584
|
+
get random() {
|
|
2585
|
+
return this.structure.get("random");
|
|
2586
|
+
}
|
|
2587
|
+
get elementIdentifier() {
|
|
2588
|
+
return this.structure.get("elementIdentifier");
|
|
2589
|
+
}
|
|
2590
|
+
get elementValue() {
|
|
2591
|
+
return this.structure.get("elementValue");
|
|
2592
|
+
}
|
|
2593
|
+
get digestId() {
|
|
2594
|
+
return this.structure.get("digestID");
|
|
2595
|
+
}
|
|
2596
|
+
async isValid(namespace, issuerAuth, ctx) {
|
|
2597
|
+
const digest = await ctx.crypto.digest({
|
|
2598
|
+
digestAlgorithm: issuerAuth.mobileSecurityObject.digestAlgorithm,
|
|
2599
|
+
bytes: this.encode({ asDataItem: true })
|
|
2600
|
+
});
|
|
2601
|
+
const digests = issuerAuth.mobileSecurityObject.valueDigests.valueDigests.get(namespace);
|
|
2602
|
+
if (!digests) return false;
|
|
2603
|
+
const expectedDigest = digests.get(this.digestId);
|
|
2604
|
+
return expectedDigest !== void 0 && compareBytes(digest, expectedDigest);
|
|
2605
|
+
}
|
|
2606
|
+
matchCertificate(issuerAuth, ctx) {
|
|
2607
|
+
if (this.elementIdentifier === "issuing_country") return this.elementValue === issuerAuth.getIssuingCountry(ctx);
|
|
2608
|
+
if (this.elementIdentifier === "issuing_jurisdiction") return this.elementValue === issuerAuth.getIssuingStateOrProvince(ctx);
|
|
2609
|
+
return false;
|
|
2610
|
+
}
|
|
2611
|
+
static fromOptions(options) {
|
|
2612
|
+
const map = new Map([
|
|
2613
|
+
["digestID", options.digestId],
|
|
2614
|
+
["random", options.random],
|
|
2615
|
+
["elementIdentifier", options.elementIdentifier],
|
|
2616
|
+
["elementValue", options.elementValue]
|
|
2617
|
+
]);
|
|
2618
|
+
return this.fromEncodedStructure(map);
|
|
2619
|
+
}
|
|
2620
|
+
};
|
|
2621
|
+
|
|
2622
|
+
//#endregion
|
|
2623
|
+
//#region src/mdoc/models/issuer-namespaces.ts
|
|
2624
|
+
const issuerNamespacesEncodedSchema = z$1.map(z$1.string(), z$1.array(z$1.instanceof(DataItem)));
|
|
2625
|
+
const issuerNamespacesDecodedSchema = z$1.map(z$1.string(), z$1.array(z$1.instanceof(IssuerSignedItem)));
|
|
2626
|
+
var IssuerNamespaces = class extends CborStructure {
|
|
2627
|
+
static get encodingSchema() {
|
|
2628
|
+
return z$1.codec(issuerNamespacesEncodedSchema, issuerNamespacesDecodedSchema, {
|
|
2629
|
+
decode: (encoded) => {
|
|
2630
|
+
const issuerNamespaces = /* @__PURE__ */ new Map();
|
|
2631
|
+
encoded.forEach((value, key) => {
|
|
2632
|
+
issuerNamespaces.set(key, value.map((isi) => IssuerSignedItem.fromEncodedStructure(isi.data)));
|
|
2633
|
+
});
|
|
2634
|
+
return issuerNamespaces;
|
|
2635
|
+
},
|
|
2636
|
+
encode: (decoded) => {
|
|
2637
|
+
const issuerNamespaces = /* @__PURE__ */ new Map();
|
|
2638
|
+
decoded.forEach((value, key) => {
|
|
2639
|
+
issuerNamespaces.set(key, value.map((isi) => DataItem.fromData(isi.encodedStructure)));
|
|
2640
|
+
});
|
|
2641
|
+
return issuerNamespaces;
|
|
2642
|
+
}
|
|
2643
|
+
});
|
|
2644
|
+
}
|
|
2645
|
+
get issuerNamespaces() {
|
|
2646
|
+
return this.structure;
|
|
2647
|
+
}
|
|
2648
|
+
getIssuerNamespace(namespace) {
|
|
2649
|
+
return this.structure.get(namespace);
|
|
2650
|
+
}
|
|
2651
|
+
setIssuerNamespace(namespace, issuerSignedItems) {
|
|
2652
|
+
return this.structure.set(namespace, issuerSignedItems);
|
|
2653
|
+
}
|
|
2654
|
+
static create(options) {
|
|
2655
|
+
return this.fromDecodedStructure(options.issuerNamespaces);
|
|
2656
|
+
}
|
|
2657
|
+
};
|
|
2658
|
+
|
|
2659
|
+
//#endregion
|
|
2660
|
+
//#region src/utils/limitDisclosure.ts
|
|
2661
|
+
const limitDisclosureToDeviceRequestNameSpaces = (issuerSigned, docRequest) => {
|
|
2662
|
+
const issuerNamespaces = /* @__PURE__ */ new Map();
|
|
2663
|
+
for (const [namespace, nameSpaceFields] of docRequest.itemsRequest.namespaces.entries()) {
|
|
2664
|
+
const nsAttrs = issuerSigned.issuerNamespaces?.issuerNamespaces.get(namespace) ?? [];
|
|
2665
|
+
const issuerSignedItems = Array.from(nameSpaceFields.entries()).map(([elementIdentifier, _]) => {
|
|
2666
|
+
const issuerSignedItem = prepareIssuerSignedItem(elementIdentifier, nsAttrs);
|
|
2667
|
+
if (!issuerSignedItem) throw new Error(`No matching field found for '${elementIdentifier}'`);
|
|
2668
|
+
return issuerSignedItem;
|
|
2669
|
+
});
|
|
2670
|
+
issuerNamespaces.set(namespace, issuerSignedItems);
|
|
2671
|
+
}
|
|
2672
|
+
return IssuerNamespaces.create({ issuerNamespaces });
|
|
2673
|
+
};
|
|
2674
|
+
const prepareIssuerSignedItem = (elementIdentifier, nsAttrs) => {
|
|
2675
|
+
if (elementIdentifier.startsWith("age_over_")) return handleAgeOverNN(elementIdentifier, nsAttrs);
|
|
2676
|
+
return nsAttrs.find((d) => d.elementIdentifier === elementIdentifier) ?? null;
|
|
2677
|
+
};
|
|
2678
|
+
const handleAgeOverNN = (request, attributes) => {
|
|
2679
|
+
const ageOverList = attributes.map((a, i) => {
|
|
2680
|
+
const { elementIdentifier: key, elementValue: value } = a;
|
|
2681
|
+
return {
|
|
2682
|
+
key,
|
|
2683
|
+
value,
|
|
2684
|
+
index: i
|
|
2685
|
+
};
|
|
2686
|
+
}).filter((i) => i.key.startsWith("age_over_")).map((i) => ({
|
|
2687
|
+
nn: Number.parseInt(i.key.replace("age_over_", ""), 10),
|
|
2688
|
+
...i
|
|
2689
|
+
})).sort((a, b) => a.nn - b.nn);
|
|
2690
|
+
const reqNN = Number.parseInt(request.replace("age_over_", ""), 10);
|
|
2691
|
+
let item;
|
|
2692
|
+
item = ageOverList.find((i) => i.value === true && i.nn >= reqNN);
|
|
2693
|
+
if (!item) item = ageOverList.sort((a, b) => b.nn - a.nn).find((i) => i.value === false && i.nn <= reqNN);
|
|
2694
|
+
if (!item) return null;
|
|
2695
|
+
return attributes[item.index];
|
|
2696
|
+
};
|
|
2697
|
+
|
|
2698
|
+
//#endregion
|
|
2699
|
+
//#region src/utils/verifyDocRequestsWithIssuerSigned.ts
|
|
2700
|
+
const verifyDocRequestsWithIssuerSigned = (docRequests, is) => {
|
|
2701
|
+
for (const docRequest of docRequests) {
|
|
2702
|
+
const issuerSigned = findIssuerSigned(is, docRequest.itemsRequest.docType);
|
|
2703
|
+
for (const [namespace, values] of docRequest.itemsRequest.namespaces) {
|
|
2704
|
+
const issuerSignedItems = issuerSigned.getIssuerNamespace(namespace);
|
|
2705
|
+
if (!issuerSignedItems) throw new Error(`Could not find issuer namespace for the requested namespace '${namespace}'`);
|
|
2706
|
+
for (const identifier of values.keys()) if (!issuerSignedItems.find((isi) => isi.elementIdentifier === identifier)) throw new Error(`Found issuer namespace '${namespace}', but could not find the element for identifier '${identifier}'`);
|
|
2707
|
+
}
|
|
2708
|
+
}
|
|
2709
|
+
};
|
|
2710
|
+
|
|
2711
|
+
//#endregion
|
|
2712
|
+
//#region src/mdoc/models/device-signed.ts
|
|
2713
|
+
const deviceSignedSchema = typedMap([["nameSpaces", z.instanceof(DeviceNamespaces)], ["deviceAuth", z.instanceof(DeviceAuth)]]);
|
|
2714
|
+
var DeviceSigned = class extends CborStructure {
|
|
2715
|
+
static get encodingSchema() {
|
|
2716
|
+
return z.codec(deviceSignedSchema.in, deviceSignedSchema.out, {
|
|
2717
|
+
decode: (input) => {
|
|
2718
|
+
const map = TypedMap.fromMap(input);
|
|
2719
|
+
const nameSpaces = input.get("nameSpaces");
|
|
2720
|
+
map.set("nameSpaces", DeviceNamespaces.fromEncodedStructure(nameSpaces.data));
|
|
2721
|
+
map.set("deviceAuth", DeviceAuth.fromEncodedStructure(input.get("deviceAuth")));
|
|
2722
|
+
return map;
|
|
2723
|
+
},
|
|
2724
|
+
encode: (output) => {
|
|
2725
|
+
const map = output.toMap();
|
|
2726
|
+
map.set("nameSpaces", DataItem.fromData(output.get("nameSpaces").encodedStructure));
|
|
2727
|
+
map.set("deviceAuth", output.get("deviceAuth").encodedStructure);
|
|
2728
|
+
return map;
|
|
2729
|
+
}
|
|
2730
|
+
});
|
|
2731
|
+
}
|
|
2732
|
+
get deviceNamespaces() {
|
|
2733
|
+
return this.structure.get("nameSpaces");
|
|
2734
|
+
}
|
|
2735
|
+
get deviceAuth() {
|
|
2736
|
+
return this.structure.get("deviceAuth");
|
|
2737
|
+
}
|
|
2738
|
+
static create(options) {
|
|
2739
|
+
const map = new TypedMap([["nameSpaces", options.deviceNamespaces], ["deviceAuth", options.deviceAuth]]);
|
|
2740
|
+
return this.fromDecodedStructure(map);
|
|
2741
|
+
}
|
|
2742
|
+
};
|
|
2743
|
+
|
|
2744
|
+
//#endregion
|
|
2745
|
+
//#region src/mdoc/models/validity-info.ts
|
|
2746
|
+
const validityInfoSchema = typedMap([
|
|
2747
|
+
["signed", z.date()],
|
|
2748
|
+
["validFrom", z.date()],
|
|
2749
|
+
["validUntil", z.date()],
|
|
2750
|
+
["expectedUpdate", z.date().exactOptional()]
|
|
2751
|
+
]);
|
|
2752
|
+
var ValidityInfo = class extends CborStructure {
|
|
2753
|
+
static get encodingSchema() {
|
|
2754
|
+
return validityInfoSchema;
|
|
2755
|
+
}
|
|
2756
|
+
get signed() {
|
|
2757
|
+
return this.structure.get("signed");
|
|
2758
|
+
}
|
|
2759
|
+
get validFrom() {
|
|
2760
|
+
return this.structure.get("validFrom");
|
|
2761
|
+
}
|
|
2762
|
+
get validUntil() {
|
|
2763
|
+
return this.structure.get("validUntil");
|
|
2764
|
+
}
|
|
2765
|
+
get expectedUpdate() {
|
|
2766
|
+
return this.structure.get("expectedUpdate");
|
|
2767
|
+
}
|
|
2768
|
+
isSignedBetweenDates(notBefore, notAfter, skewSeconds = 30) {
|
|
2769
|
+
const skewMs = skewSeconds * 1e3;
|
|
2770
|
+
const notBeforeWithSkew = new Date(notBefore.getTime() - skewMs);
|
|
2771
|
+
const notAfterWithSkew = new Date(notAfter.getTime() + skewMs);
|
|
2772
|
+
return this.signed > notBeforeWithSkew && this.signed < notAfterWithSkew;
|
|
2773
|
+
}
|
|
2774
|
+
isValidUntilAfterNow(now = /* @__PURE__ */ new Date(), skewSeconds = 30) {
|
|
2775
|
+
const skewMs = skewSeconds * 1e3;
|
|
2776
|
+
return new Date(this.validUntil.getTime() + skewMs) >= now;
|
|
2777
|
+
}
|
|
2778
|
+
isValidFromBeforeNow(now = /* @__PURE__ */ new Date(), skewSeconds = 30) {
|
|
2779
|
+
const skewMs = skewSeconds * 1e3;
|
|
2780
|
+
return new Date(this.validFrom.getTime() - skewMs) <= now;
|
|
2781
|
+
}
|
|
2782
|
+
static create(options) {
|
|
2783
|
+
const encodedStructure = new Map([
|
|
2784
|
+
["signed", options.signed],
|
|
2785
|
+
["validFrom", options.validFrom],
|
|
2786
|
+
["validUntil", options.validUntil]
|
|
2787
|
+
]);
|
|
2788
|
+
if (options.expectedUpdate !== void 0) encodedStructure.set("expectedUpdate", options.expectedUpdate);
|
|
2789
|
+
return this.fromEncodedStructure(encodedStructure);
|
|
2790
|
+
}
|
|
2791
|
+
};
|
|
2792
|
+
|
|
2793
|
+
//#endregion
|
|
2794
|
+
//#region src/mdoc/models/value-digests.ts
|
|
2795
|
+
const valueDigestsSchema = z.map(z.string(), z.map(z.number(), zUint8Array));
|
|
2796
|
+
var ValueDigests = class extends CborStructure {
|
|
2797
|
+
static get encodingSchema() {
|
|
2798
|
+
return valueDigestsSchema;
|
|
2799
|
+
}
|
|
2800
|
+
get valueDigests() {
|
|
2801
|
+
return this.structure;
|
|
2802
|
+
}
|
|
2803
|
+
static create(options) {
|
|
2804
|
+
return this.fromEncodedStructure(options.digests);
|
|
2805
|
+
}
|
|
2806
|
+
getDigestForNamespace(namespace, digestId) {
|
|
2807
|
+
return this.structure.get(namespace)?.get(digestId);
|
|
2808
|
+
}
|
|
2809
|
+
hasDigestForNamespace(namespace, digestId) {
|
|
2810
|
+
return this.structure.get(namespace)?.has(digestId) ?? false;
|
|
2811
|
+
}
|
|
2812
|
+
getNamespaces() {
|
|
2813
|
+
return Array.from(this.structure.keys());
|
|
2814
|
+
}
|
|
2815
|
+
getDigestIdsForNamespace(namespace) {
|
|
2816
|
+
const namespaceDigests = this.structure.get(namespace);
|
|
2817
|
+
if (!namespaceDigests) return [];
|
|
2818
|
+
return Array.from(namespaceDigests.keys());
|
|
2819
|
+
}
|
|
2820
|
+
};
|
|
2821
|
+
|
|
2822
|
+
//#endregion
|
|
2823
|
+
//#region src/mdoc/models/mobile-security-object.ts
|
|
2824
|
+
const mobileSecurityObjectSchema = typedMap([
|
|
2825
|
+
["version", z.literal("1.0")],
|
|
2826
|
+
["digestAlgorithm", z.enum([
|
|
2827
|
+
"SHA-256",
|
|
2828
|
+
"SHA-384",
|
|
2829
|
+
"SHA-512"
|
|
2830
|
+
])],
|
|
2831
|
+
["docType", z.string()],
|
|
2832
|
+
["valueDigests", z.instanceof(ValueDigests)],
|
|
2833
|
+
["deviceKeyInfo", z.instanceof(DeviceKeyInfo)],
|
|
2834
|
+
["validityInfo", z.instanceof(ValidityInfo)]
|
|
2835
|
+
]);
|
|
2836
|
+
var MobileSecurityObject = class extends CborStructure {
|
|
2837
|
+
static get encodingSchema() {
|
|
2838
|
+
return z.codec(mobileSecurityObjectSchema.in, mobileSecurityObjectSchema.out, {
|
|
2839
|
+
decode: (input) => {
|
|
2840
|
+
const map = TypedMap.fromMap(input);
|
|
2841
|
+
map.set("valueDigests", ValueDigests.fromEncodedStructure(input.get("valueDigests")));
|
|
2842
|
+
map.set("deviceKeyInfo", DeviceKeyInfo.fromEncodedStructure(input.get("deviceKeyInfo")));
|
|
2843
|
+
map.set("validityInfo", ValidityInfo.fromEncodedStructure(input.get("validityInfo")));
|
|
2844
|
+
return map;
|
|
2845
|
+
},
|
|
2846
|
+
encode: (output) => {
|
|
2847
|
+
const map = output.toMap();
|
|
2848
|
+
map.set("valueDigests", output.get("valueDigests").encodedStructure);
|
|
2849
|
+
map.set("deviceKeyInfo", output.get("deviceKeyInfo").encodedStructure);
|
|
2850
|
+
map.set("validityInfo", output.get("validityInfo").encodedStructure);
|
|
2851
|
+
return map;
|
|
2852
|
+
}
|
|
2853
|
+
});
|
|
2854
|
+
}
|
|
2855
|
+
get version() {
|
|
2856
|
+
return this.structure.get("version");
|
|
2857
|
+
}
|
|
2858
|
+
get digestAlgorithm() {
|
|
2859
|
+
return this.structure.get("digestAlgorithm");
|
|
2860
|
+
}
|
|
2861
|
+
get docType() {
|
|
2862
|
+
return this.structure.get("docType");
|
|
2863
|
+
}
|
|
2864
|
+
get validityInfo() {
|
|
2865
|
+
return this.structure.get("validityInfo");
|
|
2866
|
+
}
|
|
2867
|
+
get valueDigests() {
|
|
2868
|
+
return this.structure.get("valueDigests");
|
|
2869
|
+
}
|
|
2870
|
+
get deviceKeyInfo() {
|
|
2871
|
+
return this.structure.get("deviceKeyInfo");
|
|
2872
|
+
}
|
|
2873
|
+
static create(options) {
|
|
2874
|
+
const map = new TypedMap([
|
|
2875
|
+
["version", options.version ?? "1.0"],
|
|
2876
|
+
["digestAlgorithm", options.digestAlgorithm],
|
|
2877
|
+
["valueDigests", options.valueDigests],
|
|
2878
|
+
["deviceKeyInfo", options.deviceKeyInfo],
|
|
2879
|
+
["docType", options.docType],
|
|
2880
|
+
["validityInfo", options.validityInfo]
|
|
2881
|
+
]);
|
|
2882
|
+
return this.fromDecodedStructure(map);
|
|
2883
|
+
}
|
|
2884
|
+
};
|
|
2885
|
+
|
|
2886
|
+
//#endregion
|
|
2887
|
+
//#region src/mdoc/models/issuer-auth.ts
|
|
2888
|
+
var IssuerAuth = class extends Sign1 {
|
|
2889
|
+
static create(options, ctx) {
|
|
2890
|
+
return super.create({
|
|
2891
|
+
...options,
|
|
2892
|
+
payload: options.payload instanceof MobileSecurityObject ? options.payload.encode({ asDataItem: true }) : options.payload
|
|
2893
|
+
}, ctx);
|
|
2894
|
+
}
|
|
2895
|
+
get mobileSecurityObject() {
|
|
2896
|
+
if (!this.payload) throw new CosePayloadMustBeDefinedError();
|
|
2897
|
+
return zUint8Array.transform((payload) => cborDecode(payload, { unwrapTopLevelDataItem: false })).pipe(z$1.instanceof(DataItem).transform((di) => MobileSecurityObject.fromEncodedStructure(di.data))).parse(this.payload);
|
|
2898
|
+
}
|
|
2899
|
+
async verify(options, ctx) {
|
|
2900
|
+
const verificationCallback = options.verificationCallback ?? defaultVerificationCallback;
|
|
2901
|
+
const now = options.now ?? /* @__PURE__ */ new Date();
|
|
2902
|
+
const disableCertificateChainValidation = options.disableCertificateChainValidation ?? false;
|
|
2903
|
+
const trustedCertificates = options.trustedCertificates ?? [];
|
|
2904
|
+
const skewSeconds = options.skewSeconds ?? 30;
|
|
2905
|
+
const onCheck = onCategoryCheck(verificationCallback, "ISSUER_AUTH");
|
|
2906
|
+
onCheck({
|
|
2907
|
+
status: this.getIssuingCountry(ctx) ? "PASSED" : "FAILED",
|
|
2908
|
+
check: "Country name (C) must be present in the issuer certificate's subject distinguished name"
|
|
2909
|
+
});
|
|
2910
|
+
if (!disableCertificateChainValidation) try {
|
|
2911
|
+
if (!trustedCertificates[0]) throw new Error("No trusted certificates found. Cannot verify issuer signature.");
|
|
2912
|
+
await ctx.x509.verifyCertificateChain({
|
|
2913
|
+
trustedCertificates,
|
|
2914
|
+
x5chain: this.certificateChain,
|
|
2915
|
+
now
|
|
2916
|
+
});
|
|
2917
|
+
onCheck({
|
|
2918
|
+
status: "PASSED",
|
|
2919
|
+
check: "Issuer certificate must be valid"
|
|
2920
|
+
});
|
|
2921
|
+
} catch (err) {
|
|
2922
|
+
onCheck({
|
|
2923
|
+
status: "FAILED",
|
|
2924
|
+
check: "Issuer certificate must be valid",
|
|
2925
|
+
reason: err instanceof Error ? err.message : "Unknown error"
|
|
2926
|
+
});
|
|
2927
|
+
}
|
|
2928
|
+
onCheck({
|
|
2929
|
+
status: await this.verifySignature({}, ctx) ? "PASSED" : "FAILED",
|
|
2930
|
+
check: "Issuer auth signature is invalid"
|
|
2931
|
+
});
|
|
2932
|
+
const { validityInfo } = this.mobileSecurityObject;
|
|
2933
|
+
const { notAfter, notBefore } = await ctx.x509.getCertificateData({ certificate: this.certificate });
|
|
2934
|
+
onCheck({
|
|
2935
|
+
status: validityInfo.isSignedBetweenDates(notBefore, notAfter, skewSeconds) ? "PASSED" : "FAILED",
|
|
2936
|
+
check: "The MSO signed date must be within the validity period of the certificate",
|
|
2937
|
+
reason: `The MSO signed date (${validityInfo.signed.toUTCString()}) must be within the validity period of the certificate (${notBefore.toUTCString()} to ${notAfter.toUTCString()})`
|
|
2938
|
+
});
|
|
2939
|
+
onCheck({
|
|
2940
|
+
status: validityInfo.isValidFromBeforeNow(now, skewSeconds) && validityInfo.isValidUntilAfterNow(now, skewSeconds) ? "PASSED" : "FAILED",
|
|
2941
|
+
check: "The MSO must be valid at the time of verification",
|
|
2942
|
+
reason: `The MSO must be valid at the time of verification (${now.toUTCString()})`
|
|
2943
|
+
});
|
|
2944
|
+
}
|
|
2945
|
+
};
|
|
2946
|
+
|
|
2947
|
+
//#endregion
|
|
2948
|
+
//#region src/mdoc/models/issuer-signed.ts
|
|
2949
|
+
const issuerSignedSchema = typedMap([["nameSpaces", z.instanceof(IssuerNamespaces)], ["issuerAuth", z.instanceof(IssuerAuth)]]);
|
|
2950
|
+
var IssuerSigned = class extends CborStructure {
|
|
2951
|
+
static get encodingSchema() {
|
|
2952
|
+
return z.codec(issuerSignedSchema.in, issuerSignedSchema.out, {
|
|
2953
|
+
decode: (input) => {
|
|
2954
|
+
const map = TypedMap.fromMap(input);
|
|
2955
|
+
map.set("nameSpaces", IssuerNamespaces.fromEncodedStructure(input.get("nameSpaces")));
|
|
2956
|
+
map.set("issuerAuth", IssuerAuth.fromEncodedStructure(input.get("issuerAuth")));
|
|
2957
|
+
return map;
|
|
2958
|
+
},
|
|
2959
|
+
encode: (output) => {
|
|
2960
|
+
const map = output.toMap();
|
|
2961
|
+
map.set("nameSpaces", output.get("nameSpaces").encodedStructure);
|
|
2962
|
+
map.set("issuerAuth", output.get("issuerAuth").encodedStructure);
|
|
2963
|
+
return map;
|
|
2964
|
+
}
|
|
2965
|
+
});
|
|
2966
|
+
}
|
|
2967
|
+
get issuerNamespaces() {
|
|
2968
|
+
return this.structure.get("nameSpaces");
|
|
2969
|
+
}
|
|
2970
|
+
get issuerAuth() {
|
|
2971
|
+
return this.structure.get("issuerAuth");
|
|
2972
|
+
}
|
|
2973
|
+
getIssuerNamespace(namespace) {
|
|
2974
|
+
return this.issuerNamespaces.getIssuerNamespace(namespace);
|
|
2975
|
+
}
|
|
2976
|
+
getPrettyClaims(namespace) {
|
|
2977
|
+
const issuerSignedItems = this.getIssuerNamespace(namespace);
|
|
2978
|
+
if (!issuerSignedItems) return void 0;
|
|
2979
|
+
return issuerSignedItems.reduce((prev, curr) => ({
|
|
2980
|
+
...prev,
|
|
2981
|
+
[curr.elementIdentifier]: curr.elementValue
|
|
2982
|
+
}), {});
|
|
2983
|
+
}
|
|
2984
|
+
get encodedForOid4Vci() {
|
|
2985
|
+
return base64url.encode(this.encode());
|
|
2986
|
+
}
|
|
2987
|
+
static fromEncodedForOid4Vci(encoded) {
|
|
2988
|
+
return this.decode(base64url.decode(encoded));
|
|
2989
|
+
}
|
|
2990
|
+
async verify(options, ctx) {
|
|
2991
|
+
const { valueDigests, digestAlgorithm } = this.issuerAuth.mobileSecurityObject;
|
|
2992
|
+
const onCheck = onCategoryCheck(options.verificationCallback ?? defaultVerificationCallback, "DATA_INTEGRITY");
|
|
2993
|
+
onCheck({
|
|
2994
|
+
status: digestAlgorithm ? "PASSED" : "FAILED",
|
|
2995
|
+
check: "Issuer Auth must include a supported digestAlgorithm element"
|
|
2996
|
+
});
|
|
2997
|
+
const namespaces = this.issuerNamespaces?.issuerNamespaces ?? /* @__PURE__ */ new Map();
|
|
2998
|
+
await Promise.all(Array.from(namespaces.entries()).map(async ([ns, nsItems]) => {
|
|
2999
|
+
onCheck({
|
|
3000
|
+
status: valueDigests?.valueDigests.has(ns) ? "PASSED" : "FAILED",
|
|
3001
|
+
check: `Issuer Auth must include digests for namespace: ${ns}`
|
|
3002
|
+
});
|
|
3003
|
+
const verifications = await Promise.all(nsItems.map(async (ev) => {
|
|
3004
|
+
return {
|
|
3005
|
+
ev,
|
|
3006
|
+
ns,
|
|
3007
|
+
isValid: await ev.isValid(ns, this.issuerAuth, ctx)
|
|
3008
|
+
};
|
|
3009
|
+
}));
|
|
3010
|
+
for (const verification of verifications.filter((v) => v.isValid)) onCheck({
|
|
3011
|
+
status: "PASSED",
|
|
3012
|
+
check: `The calculated digest for ${ns}/${verification.ev.elementIdentifier} attribute must match the digest in the issuerAuth element`
|
|
3013
|
+
});
|
|
3014
|
+
for (const verification of verifications.filter((v) => !v.isValid)) onCheck({
|
|
3015
|
+
status: "FAILED",
|
|
3016
|
+
check: `The calculated digest for ${ns}/${verification.ev.elementIdentifier} attribute must match the digest in the issuerAuth element`
|
|
3017
|
+
});
|
|
3018
|
+
if (ns === "org.iso.18013.5.1") if (!(await ctx.x509.getCertificateData({ certificate: this.issuerAuth.certificate })).issuerName) onCheck({
|
|
3019
|
+
status: "FAILED",
|
|
3020
|
+
check: "The 'issuing_country' if present must match the 'countryName' in the subject field within the DS certificate",
|
|
3021
|
+
reason: "The 'issuing_country' and 'issuing_jurisdiction' cannot be verified because the DS certificate was not provided"
|
|
3022
|
+
});
|
|
3023
|
+
else {
|
|
3024
|
+
const invalidCountry = verifications.filter((v) => v.ns === ns && v.ev.elementIdentifier === "issuing_country").find((v) => !v.isValid || !v.ev.matchCertificate(this.issuerAuth, ctx));
|
|
3025
|
+
onCheck({
|
|
3026
|
+
status: invalidCountry ? "FAILED" : "PASSED",
|
|
3027
|
+
check: "The 'issuing_country' if present must match the 'countryName' in the subject field within the DS certificate",
|
|
3028
|
+
reason: invalidCountry ? `The 'issuing_country' (${invalidCountry.ev.elementValue}) must match the 'countryName' (${this.issuerAuth.getIssuingCountry(ctx)}) in the subject field within the issuer certificate` : void 0
|
|
3029
|
+
});
|
|
3030
|
+
const invalidJurisdiction = verifications.filter((v) => v.ns === ns && v.ev.elementIdentifier === "issuing_jurisdiction").find((v) => !v.isValid || !v.ev.matchCertificate(this.issuerAuth, ctx));
|
|
3031
|
+
onCheck({
|
|
3032
|
+
status: invalidJurisdiction ? "FAILED" : "PASSED",
|
|
3033
|
+
check: "The 'issuing_jurisdiction' if present must match the 'stateOrProvinceName' in the subject field within the DS certificate",
|
|
3034
|
+
reason: invalidJurisdiction ? `The 'issuing_jurisdiction' (${invalidJurisdiction.ev.elementValue}) must match the 'stateOrProvinceName' (${this.issuerAuth.getIssuingStateOrProvince(ctx)}) in the subject field within the issuer certificate` : void 0
|
|
3035
|
+
});
|
|
3036
|
+
}
|
|
3037
|
+
}));
|
|
3038
|
+
}
|
|
3039
|
+
static create(options) {
|
|
3040
|
+
const map = new TypedMap([]);
|
|
3041
|
+
if (options.issuerNamespaces) map.set("nameSpaces", options.issuerNamespaces);
|
|
3042
|
+
map.set("issuerAuth", options.issuerAuth);
|
|
3043
|
+
return this.fromDecodedStructure(map);
|
|
3044
|
+
}
|
|
3045
|
+
};
|
|
3046
|
+
|
|
3047
|
+
//#endregion
|
|
3048
|
+
//#region src/mdoc/models/document.ts
|
|
3049
|
+
const documentSchema = typedMap([
|
|
3050
|
+
["docType", z.string()],
|
|
3051
|
+
["issuerSigned", z.instanceof(IssuerSigned)],
|
|
3052
|
+
["deviceSigned", z.instanceof(DeviceSigned)],
|
|
3053
|
+
["errors", z.map(z.string(), z.unknown()).exactOptional()]
|
|
3054
|
+
]);
|
|
3055
|
+
var Document = class extends CborStructure {
|
|
3056
|
+
static get encodingSchema() {
|
|
3057
|
+
return z.codec(documentSchema.in, documentSchema.out, {
|
|
3058
|
+
decode: (input) => {
|
|
3059
|
+
const map = TypedMap.fromMap(input);
|
|
3060
|
+
map.set("issuerSigned", IssuerSigned.fromEncodedStructure(input.get("issuerSigned")));
|
|
3061
|
+
map.set("deviceSigned", DeviceSigned.fromEncodedStructure(input.get("deviceSigned")));
|
|
3062
|
+
if (input.has("errors")) map.set("errors", input.get("errors"));
|
|
3063
|
+
return map;
|
|
3064
|
+
},
|
|
3065
|
+
encode: (output) => {
|
|
3066
|
+
const map = output.toMap();
|
|
3067
|
+
map.set("issuerSigned", output.get("issuerSigned").encodedStructure);
|
|
3068
|
+
map.set("deviceSigned", output.get("deviceSigned").encodedStructure);
|
|
3069
|
+
return map;
|
|
3070
|
+
}
|
|
3071
|
+
});
|
|
3072
|
+
}
|
|
3073
|
+
get docType() {
|
|
3074
|
+
return this.structure.get("docType");
|
|
3075
|
+
}
|
|
3076
|
+
get issuerSigned() {
|
|
3077
|
+
return this.structure.get("issuerSigned");
|
|
3078
|
+
}
|
|
3079
|
+
get deviceSigned() {
|
|
3080
|
+
return this.structure.get("deviceSigned");
|
|
3081
|
+
}
|
|
3082
|
+
get errors() {
|
|
3083
|
+
return this.structure.get("errors");
|
|
3084
|
+
}
|
|
3085
|
+
getIssuerNamespace(namespace) {
|
|
3086
|
+
const issuerNamespaces = this.structure.get("issuerSigned")?.issuerNamespaces?.issuerNamespaces;
|
|
3087
|
+
if (!issuerNamespaces) return;
|
|
3088
|
+
return issuerNamespaces.get(namespace);
|
|
3089
|
+
}
|
|
3090
|
+
static create(options) {
|
|
3091
|
+
const map = new TypedMap([
|
|
3092
|
+
["docType", options.docType],
|
|
3093
|
+
["issuerSigned", options.issuerSigned],
|
|
3094
|
+
["deviceSigned", options.deviceSigned]
|
|
3095
|
+
]);
|
|
3096
|
+
if (options.errors) map.set("errors", options.errors);
|
|
3097
|
+
return this.fromDecodedStructure(map);
|
|
3098
|
+
}
|
|
3099
|
+
};
|
|
3100
|
+
|
|
3101
|
+
//#endregion
|
|
3102
|
+
//#region src/mdoc/models/document-error.ts
|
|
3103
|
+
const documentErrorSchema = z.map(z.string(), z.number());
|
|
3104
|
+
var DocumentError = class DocumentError extends CborStructure {
|
|
3105
|
+
static get encodingSchema() {
|
|
3106
|
+
return documentErrorSchema;
|
|
3107
|
+
}
|
|
3108
|
+
/**
|
|
3109
|
+
* Map where keys are namespaces and values are error codes
|
|
3110
|
+
*/
|
|
3111
|
+
get documentError() {
|
|
3112
|
+
return this.structure;
|
|
3113
|
+
}
|
|
3114
|
+
static create(options) {
|
|
3115
|
+
return new DocumentError(options.documentError);
|
|
3116
|
+
}
|
|
3117
|
+
};
|
|
3118
|
+
|
|
3119
|
+
//#endregion
|
|
3120
|
+
//#region src/mdoc/models/device-response.ts
|
|
3121
|
+
const deviceResponseEncodedSchema = typedMap([
|
|
3122
|
+
["version", z.string()],
|
|
3123
|
+
["status", z.number()],
|
|
3124
|
+
["documents", z.array(z.unknown()).exactOptional()],
|
|
3125
|
+
["documentErrors", z.array(z.unknown()).exactOptional()]
|
|
3126
|
+
]);
|
|
3127
|
+
const deviceResponseDecodedSchema = typedMap([
|
|
3128
|
+
["version", z.string()],
|
|
3129
|
+
["status", z.number()],
|
|
3130
|
+
["documents", z.array(z.instanceof(Document)).exactOptional()],
|
|
3131
|
+
["documentErrors", z.array(z.instanceof(DocumentError)).exactOptional()]
|
|
3132
|
+
]);
|
|
3133
|
+
var DeviceResponse = class DeviceResponse extends CborStructure {
|
|
3134
|
+
static get encodingSchema() {
|
|
3135
|
+
return z.codec(deviceResponseEncodedSchema.in, deviceResponseDecodedSchema.out, {
|
|
3136
|
+
decode: (input) => {
|
|
3137
|
+
const map = TypedMap.fromMap(input);
|
|
3138
|
+
if (input.has("documents")) map.set("documents", input.get("documents").map((d) => Document.fromEncodedStructure(d)));
|
|
3139
|
+
if (input.has("documentErrors")) map.set("documentErrors", input.get("documentErrors").map((d) => DocumentError.fromEncodedStructure(d)));
|
|
3140
|
+
return map;
|
|
3141
|
+
},
|
|
3142
|
+
encode: (output) => {
|
|
3143
|
+
const map = output.toMap();
|
|
3144
|
+
const documents = output.get("documents");
|
|
3145
|
+
if (documents !== void 0) map.set("documents", documents.map((d) => d.encodedStructure));
|
|
3146
|
+
const documentErrors = output.get("documentErrors");
|
|
3147
|
+
if (documentErrors !== void 0) map.set("documentErrors", documentErrors.map((d) => d.encodedStructure));
|
|
3148
|
+
return map;
|
|
3149
|
+
}
|
|
3150
|
+
});
|
|
3151
|
+
}
|
|
3152
|
+
get version() {
|
|
3153
|
+
return this.structure.get("version");
|
|
3154
|
+
}
|
|
3155
|
+
get documents() {
|
|
3156
|
+
return this.structure.get("documents");
|
|
3157
|
+
}
|
|
3158
|
+
get documentErrors() {
|
|
3159
|
+
return this.structure.get("documentErrors");
|
|
3160
|
+
}
|
|
3161
|
+
get status() {
|
|
3162
|
+
return this.structure.get("status");
|
|
3163
|
+
}
|
|
3164
|
+
async verify(options, ctx) {
|
|
3165
|
+
const onCheck = options.onCheck ?? defaultVerificationCallback;
|
|
3166
|
+
onCheck({
|
|
3167
|
+
status: this.structure.get("version") ? "PASSED" : "FAILED",
|
|
3168
|
+
check: "Device Response must include \"version\" element.",
|
|
3169
|
+
category: "DOCUMENT_FORMAT"
|
|
3170
|
+
});
|
|
3171
|
+
const documents = this.structure.get("documents");
|
|
3172
|
+
onCheck({
|
|
3173
|
+
status: !documents || documents.length > 0 ? "PASSED" : "FAILED",
|
|
3174
|
+
check: "Device Response must not include documents or at least one document.",
|
|
3175
|
+
category: "DOCUMENT_FORMAT"
|
|
3176
|
+
});
|
|
3177
|
+
for (const document of documents ?? []) {
|
|
3178
|
+
await document.issuerSigned.issuerAuth.verify({
|
|
3179
|
+
disableCertificateChainValidation: options.disableCertificateChainValidation,
|
|
3180
|
+
now: options.now,
|
|
3181
|
+
trustedCertificates: options.trustedCertificates,
|
|
3182
|
+
verificationCallback: onCheck,
|
|
3183
|
+
skewSeconds: options.skewSeconds
|
|
3184
|
+
}, ctx);
|
|
3185
|
+
await document.deviceSigned.deviceAuth.verify({
|
|
3186
|
+
document,
|
|
3187
|
+
ephemeralMacPrivateKey: options.ephemeralReaderKey,
|
|
3188
|
+
sessionTranscript: options.sessionTranscript,
|
|
3189
|
+
verificationCallback: onCheck
|
|
3190
|
+
}, ctx);
|
|
3191
|
+
await document.issuerSigned.verify({ verificationCallback: onCheck }, ctx);
|
|
3192
|
+
}
|
|
3193
|
+
if (options.deviceRequest?.docRequests && documents) try {
|
|
3194
|
+
verifyDocRequestsWithIssuerSigned(options.deviceRequest.docRequests, documents.map((d) => d.issuerSigned));
|
|
3195
|
+
onCheck({
|
|
3196
|
+
status: "PASSED",
|
|
3197
|
+
check: "Device Response did match the Device Request",
|
|
3198
|
+
category: "DOCUMENT_FORMAT"
|
|
3199
|
+
});
|
|
3200
|
+
} catch (e) {
|
|
3201
|
+
onCheck({
|
|
3202
|
+
status: "FAILED",
|
|
3203
|
+
check: `Device Response did not match the Device Request: ${e.message}`,
|
|
3204
|
+
category: "DOCUMENT_FORMAT"
|
|
3205
|
+
});
|
|
3206
|
+
}
|
|
3207
|
+
}
|
|
3208
|
+
get encodedForOid4Vp() {
|
|
3209
|
+
return base64url.encode(this.encode());
|
|
3210
|
+
}
|
|
3211
|
+
static fromEncodedForOid4Vp(encoded) {
|
|
3212
|
+
return DeviceResponse.decode(base64url.decode(encoded));
|
|
3213
|
+
}
|
|
3214
|
+
static async create(options, ctx) {
|
|
3215
|
+
const useMac = !!options.mac;
|
|
3216
|
+
const useSignature = !!options.signature;
|
|
3217
|
+
if (useMac === useSignature) throw new EitherSignatureOrMacMustBeProvidedError();
|
|
3218
|
+
const signingKey = useSignature ? options.signature?.signingKey : options.mac?.signingKey;
|
|
3219
|
+
if (!signingKey) throw new Error("Signing key is missing");
|
|
3220
|
+
const map = new TypedMap([
|
|
3221
|
+
["version", "1.0"],
|
|
3222
|
+
["status", 0],
|
|
3223
|
+
["documents", await Promise.all(options.deviceRequest.docRequests.map(async (docRequest) => {
|
|
3224
|
+
const issuerSigned = findIssuerSigned(options.issuerSigned, docRequest.itemsRequest.docType);
|
|
3225
|
+
const disclosedIssuerNamespace = limitDisclosureToDeviceRequestNameSpaces(issuerSigned, docRequest);
|
|
3226
|
+
const docType = docRequest.itemsRequest.docType;
|
|
3227
|
+
const deviceNamespaces = options.deviceNamespaces ?? DeviceNamespaces.create({ deviceNamespaces: /* @__PURE__ */ new Map() });
|
|
3228
|
+
const deviceAuthenticationBytes = DeviceAuthentication.create({
|
|
3229
|
+
sessionTranscript: options.sessionTranscript,
|
|
3230
|
+
docType,
|
|
3231
|
+
deviceNamespaces
|
|
3232
|
+
}).encode({ asDataItem: true });
|
|
3233
|
+
const unprotectedHeaders = signingKey.keyId ? UnprotectedHeaders.create({ unprotectedHeaders: new Map([[Header.KeyId, signingKey.keyId]]) }) : UnprotectedHeaders.create({});
|
|
3234
|
+
const protectedHeaders = ProtectedHeaders.create({ protectedHeaders: new Map([[Header.Algorithm, signingKey.algorithm]]) });
|
|
3235
|
+
const deviceAuthOptions = {};
|
|
3236
|
+
if (useSignature) deviceAuthOptions.deviceSignature = await DeviceSignature.create({
|
|
3237
|
+
unprotectedHeaders,
|
|
3238
|
+
protectedHeaders,
|
|
3239
|
+
detachedPayload: deviceAuthenticationBytes,
|
|
3240
|
+
signingKey
|
|
3241
|
+
}, ctx);
|
|
3242
|
+
else {
|
|
3243
|
+
const ephemeralKey = options.mac?.ephemeralKey;
|
|
3244
|
+
if (!ephemeralKey) throw new Error("Ephemeral key is missing");
|
|
3245
|
+
deviceAuthOptions.deviceMac = await DeviceMac.create({
|
|
3246
|
+
protectedHeaders,
|
|
3247
|
+
unprotectedHeaders,
|
|
3248
|
+
detachedPayload: deviceAuthenticationBytes,
|
|
3249
|
+
privateKey: signingKey,
|
|
3250
|
+
ephemeralKey,
|
|
3251
|
+
sessionTranscript: options.sessionTranscript
|
|
3252
|
+
}, ctx);
|
|
3253
|
+
}
|
|
3254
|
+
return Document.create({
|
|
3255
|
+
docType,
|
|
3256
|
+
issuerSigned: IssuerSigned.create({
|
|
3257
|
+
issuerNamespaces: disclosedIssuerNamespace,
|
|
3258
|
+
issuerAuth: issuerSigned.issuerAuth
|
|
3259
|
+
}),
|
|
3260
|
+
deviceSigned: DeviceSigned.create({
|
|
3261
|
+
deviceNamespaces,
|
|
3262
|
+
deviceAuth: DeviceAuth.create(deviceAuthOptions)
|
|
3263
|
+
})
|
|
3264
|
+
});
|
|
3265
|
+
}))]
|
|
3266
|
+
]);
|
|
3267
|
+
return DeviceResponse.fromDecodedStructure(map);
|
|
3268
|
+
}
|
|
3269
|
+
static async createWithDeviceRequest(options, ctx) {
|
|
3270
|
+
return await DeviceResponse.create(options, ctx);
|
|
3271
|
+
}
|
|
3272
|
+
static createSimple(options) {
|
|
3273
|
+
const map = new TypedMap([["version", options.version ?? "1.0"], ["status", options.status ?? 0]]);
|
|
3274
|
+
if (options.documents !== void 0) map.set("documents", options.documents);
|
|
3275
|
+
if (options.documentErrors !== void 0) map.set("documentErrors", options.documentErrors);
|
|
3276
|
+
return this.fromDecodedStructure(map);
|
|
3277
|
+
}
|
|
3278
|
+
};
|
|
3279
|
+
|
|
3280
|
+
//#endregion
|
|
3281
|
+
//#region src/mdoc/models/error-items.ts
|
|
3282
|
+
const errorItemsSchema = z$1.map(z$1.string(), z$1.number());
|
|
3283
|
+
var ErrorItems = class extends CborStructure {
|
|
3284
|
+
static get encodingSchema() {
|
|
3285
|
+
return errorItemsSchema;
|
|
3286
|
+
}
|
|
3287
|
+
static create(options) {
|
|
3288
|
+
return this.fromDecodedStructure(options.errorItems);
|
|
3289
|
+
}
|
|
3290
|
+
};
|
|
3291
|
+
|
|
3292
|
+
//#endregion
|
|
3293
|
+
//#region src/mdoc/models/errors.ts
|
|
3294
|
+
const errorsEncodedSchema = z$1.map(z$1.string(), errorItemsSchema);
|
|
3295
|
+
const errorsDecodedSchema = z$1.map(z$1.string(), z$1.instanceof(ErrorItems));
|
|
3296
|
+
var Errors = class extends CborStructure {
|
|
3297
|
+
static get encodingSchema() {
|
|
3298
|
+
return z$1.codec(errorsEncodedSchema, errorsDecodedSchema, {
|
|
3299
|
+
encode: (decoded) => {
|
|
3300
|
+
const errorsDecoded = /* @__PURE__ */ new Map();
|
|
3301
|
+
decoded.forEach((value, key) => {
|
|
3302
|
+
errorsDecoded.set(key, value.encodedStructure);
|
|
3303
|
+
});
|
|
3304
|
+
return errorsDecoded;
|
|
3305
|
+
},
|
|
3306
|
+
decode: (encoded) => {
|
|
3307
|
+
const errorsDecoded = /* @__PURE__ */ new Map();
|
|
3308
|
+
encoded.forEach((value, key) => {
|
|
3309
|
+
errorsDecoded.set(key, ErrorItems.fromEncodedStructure(value));
|
|
3310
|
+
});
|
|
3311
|
+
return errorsDecoded;
|
|
3312
|
+
}
|
|
3313
|
+
});
|
|
3314
|
+
}
|
|
3315
|
+
};
|
|
3316
|
+
|
|
3317
|
+
//#endregion
|
|
3318
|
+
//#region src/mdoc/builders/device-signed-builder.ts
|
|
3319
|
+
var DeviceSignedBuilder = class {
|
|
3320
|
+
constructor(docType, ctx) {
|
|
3321
|
+
this.docType = docType;
|
|
3322
|
+
this.namespaces = DeviceNamespaces.create({ deviceNamespaces: /* @__PURE__ */ new Map() });
|
|
3323
|
+
this.ctx = ctx;
|
|
3324
|
+
}
|
|
3325
|
+
addDeviceNamespace(namespace, value) {
|
|
3326
|
+
const deviceSignedItems = this.namespaces.deviceNamespaces.get(namespace) ?? DeviceSignedItems.create({ deviceSignedItems: /* @__PURE__ */ new Map() });
|
|
3327
|
+
for (const [k, v] of Object.entries(value)) deviceSignedItems.deviceSignedItems.set(k, v);
|
|
3328
|
+
this.namespaces.deviceNamespaces.set(namespace, deviceSignedItems);
|
|
3329
|
+
return this;
|
|
3330
|
+
}
|
|
3331
|
+
async sign(options) {
|
|
3332
|
+
const protectedHeaders = ProtectedHeaders.create({ protectedHeaders: new Map([[Header.Algorithm, options.algorithm]]) });
|
|
3333
|
+
const unprotectedHeaders = UnprotectedHeaders.create({ unprotectedHeaders: new Map([[Header.X5Chain, base64.decode(options.derCertificate)]]) });
|
|
3334
|
+
if (options.signingKey.keyId) unprotectedHeaders.headers?.set(Header.KeyId, options.signingKey.keyId);
|
|
3335
|
+
const deviceAuthentication = DeviceAuthentication.create({
|
|
3336
|
+
sessionTranscript: options.sessionTranscript,
|
|
3337
|
+
deviceNamespaces: this.namespaces,
|
|
3338
|
+
docType: this.docType
|
|
3339
|
+
});
|
|
3340
|
+
const deviceSignature = await DeviceSignature.create({
|
|
3341
|
+
unprotectedHeaders,
|
|
3342
|
+
protectedHeaders,
|
|
3343
|
+
detachedPayload: deviceAuthentication.encode({ asDataItem: true }),
|
|
3344
|
+
signingKey: options.signingKey
|
|
3345
|
+
}, this.ctx);
|
|
3346
|
+
return DeviceSigned.create({
|
|
3347
|
+
deviceNamespaces: this.namespaces,
|
|
3348
|
+
deviceAuth: DeviceAuth.create({ deviceSignature })
|
|
3349
|
+
});
|
|
3350
|
+
}
|
|
3351
|
+
async tag(options) {
|
|
3352
|
+
const protectedHeaders = ProtectedHeaders.create({ protectedHeaders: new Map([[Header.Algorithm, options.algorithm]]) });
|
|
3353
|
+
const unprotectedHeaders = UnprotectedHeaders.create({ unprotectedHeaders: new Map([[Header.X5Chain, base64.decode(options.derCertificate)]]) });
|
|
3354
|
+
if (options.privateKey.keyId) unprotectedHeaders.headers?.set(Header.KeyId, options.privateKey.keyId);
|
|
3355
|
+
const deviceAuthentication = DeviceAuthentication.create({
|
|
3356
|
+
sessionTranscript: options.sessionTranscript,
|
|
3357
|
+
deviceNamespaces: this.namespaces,
|
|
3358
|
+
docType: this.docType
|
|
3359
|
+
});
|
|
3360
|
+
const deviceMac = await DeviceMac.create({
|
|
3361
|
+
unprotectedHeaders,
|
|
3362
|
+
protectedHeaders,
|
|
3363
|
+
detachedPayload: deviceAuthentication.encode({ asDataItem: true }),
|
|
3364
|
+
privateKey: options.privateKey,
|
|
3365
|
+
ephemeralKey: options.publicKey,
|
|
3366
|
+
sessionTranscript: options.sessionTranscript
|
|
3367
|
+
}, this.ctx);
|
|
3368
|
+
return DeviceSigned.create({
|
|
3369
|
+
deviceNamespaces: this.namespaces,
|
|
3370
|
+
deviceAuth: DeviceAuth.create({ deviceMac })
|
|
3371
|
+
});
|
|
3372
|
+
}
|
|
3373
|
+
};
|
|
3374
|
+
|
|
3375
|
+
//#endregion
|
|
3376
|
+
//#region src/utils/randomUnsignedInteger.ts
|
|
3377
|
+
const randomUnsignedInteger = (ctx) => {
|
|
3378
|
+
const bytes = ctx.crypto.random(4);
|
|
3379
|
+
return (bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3]) >>> 0;
|
|
3380
|
+
};
|
|
3381
|
+
|
|
3382
|
+
//#endregion
|
|
3383
|
+
//#region src/mdoc/builders/issuer-signed-builder.ts
|
|
3384
|
+
var IssuerSignedBuilder = class {
|
|
3385
|
+
constructor(docType, ctx) {
|
|
3386
|
+
this.docType = docType;
|
|
3387
|
+
this.ctx = ctx;
|
|
3388
|
+
this.namespaces = IssuerNamespaces.create({ issuerNamespaces: /* @__PURE__ */ new Map() });
|
|
3389
|
+
}
|
|
3390
|
+
addIssuerNamespace(namespace, values) {
|
|
3391
|
+
const issuerNamespace = this.namespaces.getIssuerNamespace(namespace) ?? [];
|
|
3392
|
+
const issuerSignedItems = (values instanceof Map ? Array.from(values.entries()) : Object.entries(values)).map(([key, value]) => IssuerSignedItem.fromOptions({
|
|
3393
|
+
digestId: randomUnsignedInteger(this.ctx),
|
|
3394
|
+
random: this.ctx.crypto.random(32),
|
|
3395
|
+
elementIdentifier: key,
|
|
3396
|
+
elementValue: value
|
|
3397
|
+
}));
|
|
3398
|
+
issuerNamespace.push(...issuerSignedItems);
|
|
3399
|
+
this.namespaces.setIssuerNamespace(namespace, issuerNamespace);
|
|
3400
|
+
return this;
|
|
3401
|
+
}
|
|
3402
|
+
async convertIssuerNamespacesIntoValueDigests(digestAlgorithm) {
|
|
3403
|
+
const valueDigests = /* @__PURE__ */ new Map();
|
|
3404
|
+
for (const [namespace, issuerSignedItems] of this.namespaces.issuerNamespaces) {
|
|
3405
|
+
const digests = /* @__PURE__ */ new Map();
|
|
3406
|
+
for (const issuerSignedItem of issuerSignedItems) {
|
|
3407
|
+
const digest = await this.ctx.crypto.digest({
|
|
3408
|
+
digestAlgorithm,
|
|
3409
|
+
bytes: issuerSignedItem.encode({ asDataItem: true })
|
|
3410
|
+
});
|
|
3411
|
+
digests.set(issuerSignedItem.digestId, digest);
|
|
3412
|
+
}
|
|
3413
|
+
valueDigests.set(namespace, digests);
|
|
3414
|
+
}
|
|
3415
|
+
return ValueDigests.create({ digests: valueDigests });
|
|
3416
|
+
}
|
|
3417
|
+
async sign(options) {
|
|
3418
|
+
const validityInfo = options.validityInfo instanceof ValidityInfo ? options.validityInfo : ValidityInfo.create(options.validityInfo);
|
|
3419
|
+
const deviceKeyInfo = options.deviceKeyInfo instanceof DeviceKeyInfo ? options.deviceKeyInfo : DeviceKeyInfo.create(options.deviceKeyInfo);
|
|
3420
|
+
const mso = MobileSecurityObject.create({
|
|
3421
|
+
docType: this.docType,
|
|
3422
|
+
validityInfo,
|
|
3423
|
+
digestAlgorithm: options.digestAlgorithm,
|
|
3424
|
+
deviceKeyInfo,
|
|
3425
|
+
valueDigests: await this.convertIssuerNamespacesIntoValueDigests(options.digestAlgorithm)
|
|
3426
|
+
});
|
|
3427
|
+
const protectedHeaders = ProtectedHeaders.create({ protectedHeaders: new Map([[Header.Algorithm, options.algorithm]]) });
|
|
3428
|
+
const unprotectedHeaders = UnprotectedHeaders.create({ unprotectedHeaders: new Map([[Header.X5Chain, options.certificate]]) });
|
|
3429
|
+
if (options.signingKey.keyId) unprotectedHeaders.headers?.set(Header.KeyId, options.signingKey.keyId);
|
|
3430
|
+
const issuerAuth = await IssuerAuth.create({
|
|
3431
|
+
payload: mso,
|
|
3432
|
+
unprotectedHeaders,
|
|
3433
|
+
protectedHeaders,
|
|
3434
|
+
signingKey: options.signingKey
|
|
3435
|
+
}, this.ctx);
|
|
3436
|
+
return IssuerSigned.create({
|
|
3437
|
+
issuerNamespaces: this.namespaces,
|
|
3438
|
+
issuerAuth
|
|
3439
|
+
});
|
|
3440
|
+
}
|
|
3441
|
+
};
|
|
3442
|
+
|
|
3443
|
+
//#endregion
|
|
3444
|
+
//#region src/holder.ts
|
|
3445
|
+
var Holder = class {
|
|
3446
|
+
/**
|
|
3447
|
+
*
|
|
3448
|
+
* string should be base64url encoded as defined in openid4vci Draft 15
|
|
3449
|
+
*
|
|
3450
|
+
*/
|
|
3451
|
+
static async verifyIssuerSigned(options, ctx) {
|
|
3452
|
+
await (typeof options.issuerSigned === "string" ? IssuerSigned.decode(base64url.decode(options.issuerSigned)) : options.issuerSigned instanceof Uint8Array ? IssuerSigned.decode(options.issuerSigned) : options.issuerSigned).issuerAuth.verify(options, ctx);
|
|
3453
|
+
}
|
|
3454
|
+
static async verifyDeviceRequest(options, ctx) {
|
|
3455
|
+
const deviceRequest = options.deviceRequest instanceof DeviceRequest ? options.deviceRequest : DeviceRequest.decode(options.deviceRequest);
|
|
3456
|
+
const sessionTranscript = options.sessionTranscript instanceof SessionTranscript ? options.sessionTranscript : SessionTranscript.decode(options.sessionTranscript);
|
|
3457
|
+
for (const docRequest of deviceRequest.docRequests) await docRequest.readerAuth?.verify({
|
|
3458
|
+
readerAuthentication: {
|
|
3459
|
+
itemsRequest: docRequest.itemsRequest,
|
|
3460
|
+
sessionTranscript
|
|
3461
|
+
},
|
|
3462
|
+
verificationCallback: options.verificationCallback
|
|
3463
|
+
}, ctx);
|
|
3464
|
+
}
|
|
3465
|
+
static async createDeviceResponseForDeviceRequest(options, context) {
|
|
3466
|
+
return await DeviceResponse.createWithDeviceRequest(options, context);
|
|
3467
|
+
}
|
|
3468
|
+
};
|
|
3469
|
+
|
|
3470
|
+
//#endregion
|
|
3471
|
+
//#region src/issuer.ts
|
|
3472
|
+
var Issuer = class {
|
|
3473
|
+
constructor(docType, ctx) {
|
|
3474
|
+
this.isb = new IssuerSignedBuilder(docType, ctx);
|
|
3475
|
+
}
|
|
3476
|
+
addIssuerNamespace(namespace, value) {
|
|
3477
|
+
this.isb = this.isb.addIssuerNamespace(namespace, value);
|
|
3478
|
+
return this;
|
|
3479
|
+
}
|
|
3480
|
+
async sign(options) {
|
|
3481
|
+
const signingKey = options.signingKey instanceof CoseKey ? options.signingKey : CoseKey.fromJwk(options.signingKey);
|
|
3482
|
+
return await this.isb.sign({
|
|
3483
|
+
...options,
|
|
3484
|
+
signingKey
|
|
3485
|
+
});
|
|
3486
|
+
}
|
|
3487
|
+
};
|
|
3488
|
+
|
|
3489
|
+
//#endregion
|
|
3490
|
+
//#region src/verifier.ts
|
|
3491
|
+
var Verifier = class {
|
|
3492
|
+
static async verifyDeviceResponse(options, ctx) {
|
|
3493
|
+
await (options.deviceResponse instanceof DeviceResponse ? options.deviceResponse : DeviceResponse.decode(options.deviceResponse)).verify(options, ctx);
|
|
3494
|
+
}
|
|
3495
|
+
};
|
|
3496
|
+
|
|
3497
|
+
//#endregion
|
|
3498
|
+
export { BleOptions, CoseCertificateNotFoundError, CoseDNotDefinedError, CoseEphemeralMacKeyIsRequiredError, CoseInvalidAlgorithmError, CoseInvalidKtyForRawError, CoseInvalidSignatureError, CoseInvalidTypeForKeyError, CoseInvalidValueForKtyError, CoseKNotDefinedError, CoseKey, CoseKeyParameter, CoseKeyTypeNotSupportedForPrivateKeyExtractionError, CosePayloadInvalidStructureError, CosePayloadMustBeDefinedError, CosePayloadMustBeNullError, CoseUnsupportedMacError, CoseXNotDefinedError, CoseYNotDefinedError, Curve, DataItem, DateOnly, DeviceAuth, DeviceAuthentication, DeviceEngagement, DeviceKey, DeviceKeyInfo, DeviceMac, DeviceNamespaces, DeviceRequest, DeviceResponse, DeviceRetrievalMethod, DeviceRetrievalMethodType, DeviceSignature, DeviceSigned, DeviceSignedBuilder, DeviceSignedItems, DocRequest, Document, DocumentError, DuplicateDocumentInDeviceResponseError, DuplicateNamespaceInIssuerNamespacesError, EDeviceKey, EReaderKey, EitherSignatureOrMacMustBeProvidedError, EncryptionAlgorithm, ErrorItems, Errors, Header, Holder, Issuer, IssuerAuth, IssuerNamespaces, IssuerSigned, IssuerSignedBuilder, IssuerSignedItem, ItemsRequest, KeyAuthorizations, KeyInfo, KeyOps, KeyType, Mac0, MacAlgorithm, MdlError, MdlParseError, MobileSecurityObject, NfcHandover, NfcOptions, Oidc, PresentationDefinitionOrDocRequestsAreRequiredError, ProtectedHeaders, ProtocolInfo, QrHandover, ReaderAuth, Security, ServerRetrievalMethod, SessionTranscript, SessionTranscriptOrSessionTranscriptBytesAreRequiredError, Sign1, SignatureAlgorithm, TypedMap, UnprotectedHeaders, ValidityInfo, ValueDigests, Verifier, WebApi, WifiOptions, base64, base64url, bytesToString, cborDecode, cborEncode, compareBytes, concatBytes, coseKeyToJwk, coseOptionsJwkMap, defaultVerificationCallback, deviceSignedItemsSchema, errorItemsSchema, hex, issuerNamespacesDecodedSchema, issuerNamespacesEncodedSchema, issuerSignedItemSchema, jwkCoseOptionsMap, jwkToCoseKey, onCategoryCheck, protectedHeadersDecodedStructure, protectedHeadersEncodedStructure, sessionTranscriptEncodedSchema, stringToBytes, typedMap, unprotectedHeadersStructure };
|
|
3499
|
+
//# sourceMappingURL=index.mjs.map
|