@owf/cose 0.1.0 → 0.2.0-alpha-20260508112151
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 +201 -0
- package/dist/index.cjs +1132 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +620 -0
- package/dist/index.d.mts +620 -0
- package/dist/index.mjs +1051 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +21 -22
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,1132 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
13
|
+
get: ((k) => from[k]).bind(null, key),
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
20
|
+
value: mod,
|
|
21
|
+
enumerable: true
|
|
22
|
+
}) : target, mod));
|
|
23
|
+
//#endregion
|
|
24
|
+
let cbor_x = require("cbor-x");
|
|
25
|
+
let zod = require("zod");
|
|
26
|
+
zod = __toESM(zod);
|
|
27
|
+
let zod_validation_error = require("zod-validation-error");
|
|
28
|
+
let _owf_identity_common = require("@owf/identity-common");
|
|
29
|
+
//#region src/utils/zod-error.ts
|
|
30
|
+
zod.default.config({ customError: (0, zod_validation_error.createErrorMap)() });
|
|
31
|
+
function formatZodError(error) {
|
|
32
|
+
if (!error) return "";
|
|
33
|
+
return (0, zod_validation_error.fromError)(error, {
|
|
34
|
+
prefix: "",
|
|
35
|
+
prefixSeparator: "✖ ",
|
|
36
|
+
issueSeparator: "\n✖ ",
|
|
37
|
+
unionSeparator: "\n OR ✖ "
|
|
38
|
+
}).toString();
|
|
39
|
+
}
|
|
40
|
+
var ValidationError = class extends Error {
|
|
41
|
+
constructor(message, zodError) {
|
|
42
|
+
super(message);
|
|
43
|
+
const formattedError = zodError ? formatZodError(zodError) : "";
|
|
44
|
+
this.message = `${message}\n${formattedError}`;
|
|
45
|
+
Object.defineProperty(this, "zodError", {
|
|
46
|
+
value: zodError,
|
|
47
|
+
writable: false,
|
|
48
|
+
enumerable: false
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region src/utils/zod.ts
|
|
54
|
+
const zUint8Array = zod.default.instanceof(Uint8Array);
|
|
55
|
+
function parseStructureWithErrorHandling(structureName, schema, data, customErrorMessage) {
|
|
56
|
+
const parseResult = zod.default.safeParse(schema, data);
|
|
57
|
+
if (!parseResult.success) throw new ValidationError(customErrorMessage ?? `Error decoding ${structureName}`, parseResult.error);
|
|
58
|
+
return parseResult.data;
|
|
59
|
+
}
|
|
60
|
+
function decodeStructureWithErrorHandling(structureName, schema, data, customErrorMessage) {
|
|
61
|
+
const decodeResult = zod.default.safeDecode(schema, data);
|
|
62
|
+
if (!decodeResult.success) throw new ValidationError(customErrorMessage ?? `Error decoding ${structureName}`, decodeResult.error);
|
|
63
|
+
return decodeResult.data;
|
|
64
|
+
}
|
|
65
|
+
function encodeStructureWithErrorHandling(structureName, schema, data, customErrorMessage) {
|
|
66
|
+
const encodeResult = zod.default.safeEncode(schema, data);
|
|
67
|
+
if (!encodeResult.success) throw new ValidationError(customErrorMessage ?? `Error encoding ${structureName}`, encodeResult.error);
|
|
68
|
+
return encodeResult.data;
|
|
69
|
+
}
|
|
70
|
+
//#endregion
|
|
71
|
+
//#region src/cbor/parser.ts
|
|
72
|
+
const encoderDefaults = {
|
|
73
|
+
tagUint8Array: false,
|
|
74
|
+
useRecords: false,
|
|
75
|
+
mapsAsObjects: false,
|
|
76
|
+
unwrapTopLevelDataItem: true,
|
|
77
|
+
variableMapSize: true
|
|
78
|
+
};
|
|
79
|
+
const cborDecode = (input, options = encoderDefaults) => {
|
|
80
|
+
const params = {
|
|
81
|
+
...encoderDefaults,
|
|
82
|
+
...options
|
|
83
|
+
};
|
|
84
|
+
const decoded = new cbor_x.Encoder(params).decode(input);
|
|
85
|
+
return params.unwrapTopLevelDataItem && typeof decoded === "object" && decoded instanceof DataItem ? decoded.data : decoded;
|
|
86
|
+
};
|
|
87
|
+
const cborEncode = (obj, options = encoderDefaults) => {
|
|
88
|
+
const enc = new cbor_x.Encoder({
|
|
89
|
+
...encoderDefaults,
|
|
90
|
+
...options
|
|
91
|
+
});
|
|
92
|
+
return Uint8Array.from(enc.encode(obj));
|
|
93
|
+
};
|
|
94
|
+
//#endregion
|
|
95
|
+
//#region src/cbor/data-item.ts
|
|
96
|
+
const zDataItemCodec = (outputSchema) => zod.default.codec(zod.default.instanceof(DataItem), outputSchema, {
|
|
97
|
+
encode: (data) => DataItem.fromData(data),
|
|
98
|
+
decode: (dataItem) => dataItem.data
|
|
99
|
+
});
|
|
100
|
+
/**
|
|
101
|
+
* DataItem is an extension defined https://www.rfc-editor.org/rfc/rfc8949.html#name-encoded-cbor-data-item
|
|
102
|
+
* > Sometimes it is beneficial to carry an embedded CBOR data item that is
|
|
103
|
+
* > not meant to be decoded immediately at the time the enclosing data item is being decoded.
|
|
104
|
+
*
|
|
105
|
+
* The idea of this class is to provide lazy encode and decode of cbor data.
|
|
106
|
+
*
|
|
107
|
+
* Due to a bug in the cbor-x library, we are eagerly encoding the data in the constructor.
|
|
108
|
+
* https://github.com/kriszyp/cbor-x/issues/83
|
|
109
|
+
*
|
|
110
|
+
*/
|
|
111
|
+
var DataItem = class DataItem {
|
|
112
|
+
#data;
|
|
113
|
+
#buffer;
|
|
114
|
+
constructor(options) {
|
|
115
|
+
if (!("data" in options) && !("buffer" in options)) throw new Error("DataItem must be initialized with either the data or a buffer");
|
|
116
|
+
if ("data" in options) this.#data = options.data;
|
|
117
|
+
this.#buffer = "buffer" in options ? options.buffer : cborEncode(options.data);
|
|
118
|
+
}
|
|
119
|
+
get data() {
|
|
120
|
+
if (!this.#data) this.#data = cborDecode(this.#buffer);
|
|
121
|
+
return this.#data;
|
|
122
|
+
}
|
|
123
|
+
get buffer() {
|
|
124
|
+
return this.#buffer;
|
|
125
|
+
}
|
|
126
|
+
static fromData(data) {
|
|
127
|
+
return new DataItem({ data });
|
|
128
|
+
}
|
|
129
|
+
static fromBuffer(buffer) {
|
|
130
|
+
return new DataItem({ buffer });
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
(0, cbor_x.addExtension)({
|
|
134
|
+
Class: DataItem,
|
|
135
|
+
tag: 24,
|
|
136
|
+
encode: (instance, encode) => {
|
|
137
|
+
return encode(instance.buffer);
|
|
138
|
+
},
|
|
139
|
+
decode: (buffer) => {
|
|
140
|
+
return DataItem.fromBuffer(buffer);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
//#endregion
|
|
144
|
+
//#region src/cbor/cbor-structure.ts
|
|
145
|
+
var CborStructure = class {
|
|
146
|
+
constructor(structure) {
|
|
147
|
+
this.structure = structure;
|
|
148
|
+
}
|
|
149
|
+
get decodedStructure() {
|
|
150
|
+
return this.structure;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Static getter for the Zod codec schema that defines the CBOR structure.
|
|
154
|
+
* Subclasses CAN override this to provide their specific schema for automatic encoding/decoding.
|
|
155
|
+
* The schema should be a Zod schema or codec that handles validation and transformation.
|
|
156
|
+
* If not provided, subclasses must override encode(), decode(), and fromEncodedStructure().
|
|
157
|
+
*/
|
|
158
|
+
static get encodingSchema() {}
|
|
159
|
+
/**
|
|
160
|
+
* Returns the encoded structure that will be serialized to CBOR.
|
|
161
|
+
* By default, returns the protected structure property.
|
|
162
|
+
* Override if custom encoding logic is needed.
|
|
163
|
+
*/
|
|
164
|
+
get encodedStructure() {
|
|
165
|
+
const encodingSchema = this.constructor.encodingSchema;
|
|
166
|
+
if (!encodingSchema) throw new Error("encodedStructure must be implemented when encodingSchema is not provided");
|
|
167
|
+
return encodeStructureWithErrorHandling(this.constructor.name, encodingSchema, this.structure);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Encodes this structure to CBOR bytes.
|
|
171
|
+
*/
|
|
172
|
+
encode(options) {
|
|
173
|
+
const encodedStructure = options?.asDataItem ? DataItem.fromData(this.encodedStructure) : this.encodedStructure;
|
|
174
|
+
return cborEncode(this._tag ? new cbor_x.Tag(encodedStructure, this._tag) : encodedStructure);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Decodes CBOR bytes into a structure instance.
|
|
178
|
+
* Uses the encodingSchema's decode() method to validate and transform the decoded data.
|
|
179
|
+
*/
|
|
180
|
+
static decode(bytes) {
|
|
181
|
+
const rawStructure = cborDecode(bytes);
|
|
182
|
+
return new this(this.fromEncodedStructure(rawStructure).decodedStructure);
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Creates a structure instance from the encoded CBOR structure (after calling cborDecode).
|
|
186
|
+
*
|
|
187
|
+
* Uses the encodingSchema's decode() method to validate and transform the structure if available.
|
|
188
|
+
* Otherwise, subclasses must override this method.
|
|
189
|
+
*/
|
|
190
|
+
static fromEncodedStructure(encodedStructure) {
|
|
191
|
+
if (!this.encodingSchema) throw new Error("fromEncodedStructure must be implemented when encodingSchema is not provided");
|
|
192
|
+
return new this(decodeStructureWithErrorHandling(this.name, this.encodingSchema, encodedStructure));
|
|
193
|
+
}
|
|
194
|
+
static fromDataItem(dataItem) {
|
|
195
|
+
return new this(parseStructureWithErrorHandling(this.name, zod.z.instanceof(DataItem).transform((di) => di.data).transform((d) => this.fromEncodedStructure(d).decodedStructure), dataItem, `Error decoding ${this.name} from DateItem`));
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Creates a structure instance from the decoded structure.
|
|
199
|
+
*
|
|
200
|
+
* Uses the encodingSchema's parse method to validate the structure if available.
|
|
201
|
+
* Otherwise, subclasses must override this method.
|
|
202
|
+
*/
|
|
203
|
+
static fromDecodedStructure(decodedStructure) {
|
|
204
|
+
const encodingSchema = this.encodingSchema;
|
|
205
|
+
if (!encodingSchema) throw new Error("fromDecodedStructure must be implemented when encodingSchema is not provided");
|
|
206
|
+
const decodedSchema = encodingSchema instanceof zod.z.ZodPipe ? encodingSchema.out : encodingSchema;
|
|
207
|
+
return new this(parseStructureWithErrorHandling(this.name, decodedSchema, decodedStructure));
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
//#endregion
|
|
211
|
+
//#region src/cbor/models/date.ts
|
|
212
|
+
(0, cbor_x.addExtension)({
|
|
213
|
+
Class: Date,
|
|
214
|
+
tag: 0,
|
|
215
|
+
encode: (date, encode) => encode(`${date.toISOString().split(".")[0]}Z`),
|
|
216
|
+
decode: (isoStringDateTime) => new Date(isoStringDateTime)
|
|
217
|
+
});
|
|
218
|
+
//#endregion
|
|
219
|
+
//#region src/cbor/models/date-only.ts
|
|
220
|
+
const customInspectSymbol = Symbol.for("nodejs.util.inspect.custom");
|
|
221
|
+
var DateOnly = class DateOnly {
|
|
222
|
+
constructor(date) {
|
|
223
|
+
this.date = date ? new Date(date) : /* @__PURE__ */ new Date();
|
|
224
|
+
}
|
|
225
|
+
get [Symbol.toStringTag]() {
|
|
226
|
+
return DateOnly.name;
|
|
227
|
+
}
|
|
228
|
+
toString() {
|
|
229
|
+
return this.toISOString();
|
|
230
|
+
}
|
|
231
|
+
toJSON() {
|
|
232
|
+
return this.toISOString();
|
|
233
|
+
}
|
|
234
|
+
toISOString() {
|
|
235
|
+
return this.date.toISOString().split("T")[0];
|
|
236
|
+
}
|
|
237
|
+
[customInspectSymbol]() {
|
|
238
|
+
return this.toISOString();
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
(0, cbor_x.addExtension)({
|
|
242
|
+
Class: DateOnly,
|
|
243
|
+
tag: 1004,
|
|
244
|
+
encode: (date, encode) => encode(date.toISOString()),
|
|
245
|
+
decode: (isoStringDate) => new DateOnly(isoStringDate)
|
|
246
|
+
});
|
|
247
|
+
//#endregion
|
|
248
|
+
//#region src/cose/claims/default.ts
|
|
249
|
+
/**
|
|
250
|
+
*
|
|
251
|
+
* Registered CWT claim keys
|
|
252
|
+
* @see https://www.rfc-editor.org/rfc/rfc8392#section-3.1
|
|
253
|
+
*
|
|
254
|
+
*/
|
|
255
|
+
let RegisteredCwtClaimKey = /* @__PURE__ */ function(RegisteredCwtClaimKey) {
|
|
256
|
+
RegisteredCwtClaimKey[RegisteredCwtClaimKey["Issuer"] = 1] = "Issuer";
|
|
257
|
+
RegisteredCwtClaimKey[RegisteredCwtClaimKey["Subject"] = 2] = "Subject";
|
|
258
|
+
RegisteredCwtClaimKey[RegisteredCwtClaimKey["Audience"] = 3] = "Audience";
|
|
259
|
+
RegisteredCwtClaimKey[RegisteredCwtClaimKey["ExpirationTime"] = 4] = "ExpirationTime";
|
|
260
|
+
RegisteredCwtClaimKey[RegisteredCwtClaimKey["NotBefore"] = 5] = "NotBefore";
|
|
261
|
+
RegisteredCwtClaimKey[RegisteredCwtClaimKey["IssuedAt"] = 6] = "IssuedAt";
|
|
262
|
+
RegisteredCwtClaimKey[RegisteredCwtClaimKey["CwtId"] = 7] = "CwtId";
|
|
263
|
+
return RegisteredCwtClaimKey;
|
|
264
|
+
}({});
|
|
265
|
+
//#endregion
|
|
266
|
+
//#region src/cose/error.ts
|
|
267
|
+
var CoseError = class extends Error {
|
|
268
|
+
constructor(message = new.target.name) {
|
|
269
|
+
super(message);
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
var CoseUnsupportedMacError = class extends CoseError {};
|
|
273
|
+
var CoseInvalidSignatureError = class extends CoseError {};
|
|
274
|
+
var CoseInvalidAlgorithmError = class extends CoseError {};
|
|
275
|
+
var CosePayloadMustBeNullError = class extends CoseError {};
|
|
276
|
+
var CosePayloadMustBeDefinedError = class extends CoseError {};
|
|
277
|
+
var CosePayloadInvalidStructureError = class extends CoseError {};
|
|
278
|
+
var CoseInvalidTypeForKeyError = class extends CoseError {};
|
|
279
|
+
var CoseInvalidValueForKtyError = class extends CoseError {};
|
|
280
|
+
var CoseInvalidKtyForRawError = class extends CoseError {};
|
|
281
|
+
var CoseXNotDefinedError = class extends CoseError {};
|
|
282
|
+
var CoseYNotDefinedError = class extends CoseError {};
|
|
283
|
+
var CoseDNotDefinedError = class extends CoseError {};
|
|
284
|
+
var CoseKNotDefinedError = class extends CoseError {};
|
|
285
|
+
var CoseEphemeralMacKeyIsRequiredError = class extends CoseError {};
|
|
286
|
+
var CoseCertificateNotFoundError = class extends CoseError {};
|
|
287
|
+
var CoseKeyTypeNotSupportedForPrivateKeyExtractionError = class extends CoseError {};
|
|
288
|
+
//#endregion
|
|
289
|
+
//#region src/cose/headers/defaults.ts
|
|
290
|
+
/**
|
|
291
|
+
*
|
|
292
|
+
* Registered CWT header keys
|
|
293
|
+
*
|
|
294
|
+
*/
|
|
295
|
+
let RegisteredCwtHeaderClaimKey = /* @__PURE__ */ function(RegisteredCwtHeaderClaimKey) {
|
|
296
|
+
RegisteredCwtHeaderClaimKey[RegisteredCwtHeaderClaimKey["Algorithm"] = 1] = "Algorithm";
|
|
297
|
+
RegisteredCwtHeaderClaimKey[RegisteredCwtHeaderClaimKey["Critical"] = 2] = "Critical";
|
|
298
|
+
RegisteredCwtHeaderClaimKey[RegisteredCwtHeaderClaimKey["ContentType"] = 3] = "ContentType";
|
|
299
|
+
RegisteredCwtHeaderClaimKey[RegisteredCwtHeaderClaimKey["KeyId"] = 4] = "KeyId";
|
|
300
|
+
RegisteredCwtHeaderClaimKey[RegisteredCwtHeaderClaimKey["Iv"] = 5] = "Iv";
|
|
301
|
+
RegisteredCwtHeaderClaimKey[RegisteredCwtHeaderClaimKey["PartialIv"] = 6] = "PartialIv";
|
|
302
|
+
RegisteredCwtHeaderClaimKey[RegisteredCwtHeaderClaimKey["CounterSignature"] = 7] = "CounterSignature";
|
|
303
|
+
RegisteredCwtHeaderClaimKey[RegisteredCwtHeaderClaimKey["CounterSignature0"] = 9] = "CounterSignature0";
|
|
304
|
+
RegisteredCwtHeaderClaimKey[RegisteredCwtHeaderClaimKey["CounterSignatureV2"] = 11] = "CounterSignatureV2";
|
|
305
|
+
RegisteredCwtHeaderClaimKey[RegisteredCwtHeaderClaimKey["CounterSignature0V2"] = 12] = "CounterSignature0V2";
|
|
306
|
+
RegisteredCwtHeaderClaimKey[RegisteredCwtHeaderClaimKey["X5Bag"] = 32] = "X5Bag";
|
|
307
|
+
RegisteredCwtHeaderClaimKey[RegisteredCwtHeaderClaimKey["X5Chain"] = 33] = "X5Chain";
|
|
308
|
+
RegisteredCwtHeaderClaimKey[RegisteredCwtHeaderClaimKey["X5T"] = 34] = "X5T";
|
|
309
|
+
RegisteredCwtHeaderClaimKey[RegisteredCwtHeaderClaimKey["X5U"] = 35] = "X5U";
|
|
310
|
+
return RegisteredCwtHeaderClaimKey;
|
|
311
|
+
}({});
|
|
312
|
+
let SignatureAlgorithm = /* @__PURE__ */ function(SignatureAlgorithm) {
|
|
313
|
+
SignatureAlgorithm[SignatureAlgorithm["EdDSA"] = -8] = "EdDSA";
|
|
314
|
+
SignatureAlgorithm[SignatureAlgorithm["ES256"] = -7] = "ES256";
|
|
315
|
+
SignatureAlgorithm[SignatureAlgorithm["ES384"] = -35] = "ES384";
|
|
316
|
+
SignatureAlgorithm[SignatureAlgorithm["ES512"] = -36] = "ES512";
|
|
317
|
+
SignatureAlgorithm[SignatureAlgorithm["PS256"] = -37] = "PS256";
|
|
318
|
+
SignatureAlgorithm[SignatureAlgorithm["PS384"] = -38] = "PS384";
|
|
319
|
+
SignatureAlgorithm[SignatureAlgorithm["PS512"] = -39] = "PS512";
|
|
320
|
+
SignatureAlgorithm[SignatureAlgorithm["RS256"] = -257] = "RS256";
|
|
321
|
+
SignatureAlgorithm[SignatureAlgorithm["RS384"] = -258] = "RS384";
|
|
322
|
+
SignatureAlgorithm[SignatureAlgorithm["RS512"] = -259] = "RS512";
|
|
323
|
+
return SignatureAlgorithm;
|
|
324
|
+
}({});
|
|
325
|
+
let MacAlgorithm = /* @__PURE__ */ function(MacAlgorithm) {
|
|
326
|
+
MacAlgorithm[MacAlgorithm["HS256"] = 5] = "HS256";
|
|
327
|
+
MacAlgorithm[MacAlgorithm["HS384"] = 6] = "HS384";
|
|
328
|
+
MacAlgorithm[MacAlgorithm["HS512"] = 7] = "HS512";
|
|
329
|
+
return MacAlgorithm;
|
|
330
|
+
}({});
|
|
331
|
+
let EncryptionAlgorithm = /* @__PURE__ */ function(EncryptionAlgorithm) {
|
|
332
|
+
EncryptionAlgorithm[EncryptionAlgorithm["A128GCM"] = 1] = "A128GCM";
|
|
333
|
+
EncryptionAlgorithm[EncryptionAlgorithm["A192GCM"] = 2] = "A192GCM";
|
|
334
|
+
EncryptionAlgorithm[EncryptionAlgorithm["A256GCM"] = 3] = "A256GCM";
|
|
335
|
+
EncryptionAlgorithm[EncryptionAlgorithm["Direct"] = -6] = "Direct";
|
|
336
|
+
return EncryptionAlgorithm;
|
|
337
|
+
}({});
|
|
338
|
+
//#endregion
|
|
339
|
+
//#region src/cose/headers/protected-headers.ts
|
|
340
|
+
const protectedHeadersEncodedStructure = zUint8Array;
|
|
341
|
+
const protectedHeadersDecodedStructure = zod.default.map(zod.default.number(), zod.default.unknown());
|
|
342
|
+
var ProtectedHeaders = class ProtectedHeaders extends CborStructure {
|
|
343
|
+
static get encodingSchema() {
|
|
344
|
+
return zod.default.codec(protectedHeadersEncodedStructure, protectedHeadersDecodedStructure, {
|
|
345
|
+
encode: (decoded) => cborEncode(decoded),
|
|
346
|
+
decode: (encoded) => cborDecode(encoded)
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
get headers() {
|
|
350
|
+
return this.structure;
|
|
351
|
+
}
|
|
352
|
+
static create(options) {
|
|
353
|
+
return ProtectedHeaders.fromDecodedStructure(options.protectedHeaders ?? /* @__PURE__ */ new Map());
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
//#endregion
|
|
357
|
+
//#region src/cose/headers/unprotected-headers.ts
|
|
358
|
+
const unprotectedHeadersStructure = zod.default.map(zod.default.number(), zod.default.unknown());
|
|
359
|
+
var UnprotectedHeaders = class UnprotectedHeaders extends CborStructure {
|
|
360
|
+
static get encodingSchema() {
|
|
361
|
+
return unprotectedHeadersStructure;
|
|
362
|
+
}
|
|
363
|
+
get headers() {
|
|
364
|
+
return this.structure;
|
|
365
|
+
}
|
|
366
|
+
static create(options) {
|
|
367
|
+
return UnprotectedHeaders.fromDecodedStructure(options.unprotectedHeaders ?? /* @__PURE__ */ new Map());
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
//#endregion
|
|
371
|
+
//#region src/cose/key/curve.ts
|
|
372
|
+
let Curve = /* @__PURE__ */ function(Curve) {
|
|
373
|
+
Curve[Curve["P-256"] = 1] = "P-256";
|
|
374
|
+
Curve[Curve["P-384"] = 2] = "P-384";
|
|
375
|
+
Curve[Curve["P-521"] = 3] = "P-521";
|
|
376
|
+
Curve[Curve["X25519"] = 4] = "X25519";
|
|
377
|
+
Curve[Curve["X448"] = 5] = "X448";
|
|
378
|
+
Curve[Curve["Ed25519"] = 6] = "Ed25519";
|
|
379
|
+
Curve[Curve["Ed448"] = 7] = "Ed448";
|
|
380
|
+
return Curve;
|
|
381
|
+
}({});
|
|
382
|
+
//#endregion
|
|
383
|
+
//#region src/cose/key/key-operation.ts
|
|
384
|
+
let KeyOps = /* @__PURE__ */ function(KeyOps) {
|
|
385
|
+
KeyOps[KeyOps["Sign"] = 1] = "Sign";
|
|
386
|
+
KeyOps[KeyOps["Verify"] = 2] = "Verify";
|
|
387
|
+
KeyOps[KeyOps["Encrypt"] = 3] = "Encrypt";
|
|
388
|
+
KeyOps[KeyOps["Decrypt"] = 4] = "Decrypt";
|
|
389
|
+
KeyOps[KeyOps["WrapKey"] = 5] = "WrapKey";
|
|
390
|
+
KeyOps[KeyOps["UnwrapKey"] = 6] = "UnwrapKey";
|
|
391
|
+
KeyOps[KeyOps["DeriveKey"] = 7] = "DeriveKey";
|
|
392
|
+
KeyOps[KeyOps["DeriveBits"] = 8] = "DeriveBits";
|
|
393
|
+
KeyOps[KeyOps["MACCreate"] = 9] = "MACCreate";
|
|
394
|
+
KeyOps[KeyOps["MACVerify"] = 10] = "MACVerify";
|
|
395
|
+
return KeyOps;
|
|
396
|
+
}({});
|
|
397
|
+
//#endregion
|
|
398
|
+
//#region src/cose/key/key-type.ts
|
|
399
|
+
let KeyType = /* @__PURE__ */ function(KeyType) {
|
|
400
|
+
KeyType[KeyType["Okp"] = 1] = "Okp";
|
|
401
|
+
KeyType[KeyType["Ec"] = 2] = "Ec";
|
|
402
|
+
KeyType[KeyType["Oct"] = 4] = "Oct";
|
|
403
|
+
KeyType[KeyType["Reserved"] = 0] = "Reserved";
|
|
404
|
+
return KeyType;
|
|
405
|
+
}({});
|
|
406
|
+
//#endregion
|
|
407
|
+
//#region src/cose/key/jwk.ts
|
|
408
|
+
const swapMap = (map) => Object.fromEntries(Object.entries(map).map(([key, value]) => [value, key]));
|
|
409
|
+
const swapNestedMap = (nestedMap) => Object.fromEntries(Object.entries(nestedMap).map(([category, mappings]) => [category, Object.fromEntries(Object.entries(mappings).map(([key, value]) => [value, key]))]));
|
|
410
|
+
const jwkCoseKeyMap = {
|
|
411
|
+
kty: {
|
|
412
|
+
OKP: 1,
|
|
413
|
+
EC: 2,
|
|
414
|
+
OCT: 4
|
|
415
|
+
},
|
|
416
|
+
crv: {
|
|
417
|
+
"P-256": 1,
|
|
418
|
+
"p-384": 2,
|
|
419
|
+
"p-521": 3,
|
|
420
|
+
X25519: 4,
|
|
421
|
+
Ed25519: 6,
|
|
422
|
+
Ed448: 7
|
|
423
|
+
},
|
|
424
|
+
alg: {
|
|
425
|
+
EdDSA: -8,
|
|
426
|
+
ES256: -7,
|
|
427
|
+
ES384: -35,
|
|
428
|
+
ES512: -36,
|
|
429
|
+
PS256: -37,
|
|
430
|
+
PS384: -38,
|
|
431
|
+
PS512: -39,
|
|
432
|
+
RS256: -257,
|
|
433
|
+
RS384: -258,
|
|
434
|
+
RS512: -259,
|
|
435
|
+
HS256: 5,
|
|
436
|
+
HS384: 6,
|
|
437
|
+
HS512: 7,
|
|
438
|
+
A128GCM: 1,
|
|
439
|
+
A192GCM: 2,
|
|
440
|
+
A256GCM: 3,
|
|
441
|
+
Direct: -6
|
|
442
|
+
},
|
|
443
|
+
keyOps: {
|
|
444
|
+
sign: 1,
|
|
445
|
+
verify: 2,
|
|
446
|
+
encrypt: 3,
|
|
447
|
+
decrypt: 4,
|
|
448
|
+
wrapKey: 5,
|
|
449
|
+
unwrapKey: 6,
|
|
450
|
+
deriveKey: 7,
|
|
451
|
+
deriveBits: 8,
|
|
452
|
+
mACCreate: 9,
|
|
453
|
+
mACVerify: 10
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
const coseKeyJwkMap = swapNestedMap(jwkCoseKeyMap);
|
|
457
|
+
const jwkCoseOptionsMap = {
|
|
458
|
+
kty: "keyType",
|
|
459
|
+
kid: "keyId",
|
|
460
|
+
alg: "algorithm",
|
|
461
|
+
keyOps: "keyOps",
|
|
462
|
+
baseIv: "baseIv",
|
|
463
|
+
crv: "curve",
|
|
464
|
+
x: "x",
|
|
465
|
+
y: "y",
|
|
466
|
+
d: "d"
|
|
467
|
+
};
|
|
468
|
+
const coseOptionsJwkMap = swapMap(jwkCoseOptionsMap);
|
|
469
|
+
const jwkToCoseKey = {
|
|
470
|
+
kty: (kty) => {
|
|
471
|
+
return jwkCoseKeyMap.kty[kty] ?? kty;
|
|
472
|
+
},
|
|
473
|
+
crv: (crv) => jwkCoseKeyMap.crv[crv] ?? crv,
|
|
474
|
+
alg: (alg) => jwkCoseKeyMap.alg[alg] ?? alg,
|
|
475
|
+
kid: (kid) => kid,
|
|
476
|
+
keyOps: (keyOps) => Array.isArray(keyOps) ? keyOps?.map((ko) => jwkCoseKeyMap.keyOps[ko] ?? ko) : void 0,
|
|
477
|
+
x: (s) => s && typeof s === "string" ? _owf_identity_common.base64url.decode(s) : void 0,
|
|
478
|
+
y: (s) => s && typeof s === "string" ? _owf_identity_common.base64url.decode(s) : void 0,
|
|
479
|
+
d: (s) => s && typeof s === "string" ? _owf_identity_common.base64url.decode(s) : void 0
|
|
480
|
+
};
|
|
481
|
+
const coseKeyToJwk = {
|
|
482
|
+
keyType: (keyType) => coseKeyJwkMap.kty[keyType],
|
|
483
|
+
keyId: (keyId) => keyId,
|
|
484
|
+
algorithm: (algorithm) => algorithm ? coseKeyJwkMap.alg[algorithm] : void 0,
|
|
485
|
+
keyOps: (keyOps) => keyOps && Array.isArray(keyOps) ? keyOps.map((ko) => coseKeyJwkMap.keyOps[ko]) : void 0,
|
|
486
|
+
baseIv: (baseIv) => baseIv,
|
|
487
|
+
curve: (curve) => curve ? coseKeyJwkMap.crv[curve] : void 0,
|
|
488
|
+
x: (x) => x ? _owf_identity_common.base64url.encode(x) : void 0,
|
|
489
|
+
y: (y) => y ? _owf_identity_common.base64url.encode(y) : void 0,
|
|
490
|
+
d: (d) => d ? _owf_identity_common.base64url.encode(d) : void 0
|
|
491
|
+
};
|
|
492
|
+
//#endregion
|
|
493
|
+
//#region src/cose/mac0.ts
|
|
494
|
+
const mac0EncodedSchema = zod.z.tuple([
|
|
495
|
+
zUint8Array,
|
|
496
|
+
zod.z.map(zod.z.unknown(), zod.z.unknown()),
|
|
497
|
+
zUint8Array.nullable(),
|
|
498
|
+
zUint8Array
|
|
499
|
+
]);
|
|
500
|
+
const mac0DecodedSchema = zod.z.object({
|
|
501
|
+
protectedHeaders: zod.z.instanceof(ProtectedHeaders),
|
|
502
|
+
unprotectedHeaders: zod.z.instanceof(UnprotectedHeaders),
|
|
503
|
+
payload: zUint8Array.nullable(),
|
|
504
|
+
tag: zUint8Array
|
|
505
|
+
});
|
|
506
|
+
var Mac0 = class Mac0 extends CborStructure {
|
|
507
|
+
constructor(..._args) {
|
|
508
|
+
super(..._args);
|
|
509
|
+
this._tag = Mac0.tag;
|
|
510
|
+
}
|
|
511
|
+
static {
|
|
512
|
+
this.tag = 17;
|
|
513
|
+
}
|
|
514
|
+
static get encodingSchema() {
|
|
515
|
+
return zod.z.codec(mac0EncodedSchema, mac0DecodedSchema, {
|
|
516
|
+
encode: ({ protectedHeaders, unprotectedHeaders, payload, tag }) => {
|
|
517
|
+
if (tag.length === 0) throw new Error("Tag has not been set. Required for encoding the mac0 structure");
|
|
518
|
+
return [
|
|
519
|
+
protectedHeaders.encodedStructure,
|
|
520
|
+
unprotectedHeaders.encodedStructure,
|
|
521
|
+
payload,
|
|
522
|
+
tag
|
|
523
|
+
];
|
|
524
|
+
},
|
|
525
|
+
decode: ([protectedHeadersBytes, unprotectedHeadersMap, payload, tag]) => ({
|
|
526
|
+
protectedHeaders: ProtectedHeaders.fromEncodedStructure(protectedHeadersBytes),
|
|
527
|
+
unprotectedHeaders: UnprotectedHeaders.fromEncodedStructure(unprotectedHeadersMap),
|
|
528
|
+
payload,
|
|
529
|
+
tag
|
|
530
|
+
})
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
get protectedHeaders() {
|
|
534
|
+
return this.structure.protectedHeaders;
|
|
535
|
+
}
|
|
536
|
+
get unprotectedHeaders() {
|
|
537
|
+
return this.structure.unprotectedHeaders;
|
|
538
|
+
}
|
|
539
|
+
get payload() {
|
|
540
|
+
return this.structure.payload;
|
|
541
|
+
}
|
|
542
|
+
get tag() {
|
|
543
|
+
return this.structure.tag;
|
|
544
|
+
}
|
|
545
|
+
get toBeAuthenticated() {
|
|
546
|
+
const payload = this.payload ?? this.detachedPayload;
|
|
547
|
+
if (!payload) throw new CosePayloadMustBeDefinedError();
|
|
548
|
+
return Mac0.toBeAuthenticated({
|
|
549
|
+
payload,
|
|
550
|
+
protectedHeaders: this.protectedHeaders,
|
|
551
|
+
externalAad: this.externalAad
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* Decodes CBOR bytes into a Sign1 instance.
|
|
556
|
+
* Uses the encodingSchema's decode() method to validate and transform the decoded data.
|
|
557
|
+
*/
|
|
558
|
+
static decode(bytes) {
|
|
559
|
+
const rawStructure = cborDecode(bytes);
|
|
560
|
+
return new Mac0(rawStructure instanceof Mac0 ? rawStructure.decodedStructure : Mac0.fromEncodedStructure(rawStructure).decodedStructure);
|
|
561
|
+
}
|
|
562
|
+
static toBeAuthenticated(options) {
|
|
563
|
+
const toBeAuthenticated = ["MAC0", options.protectedHeaders.encodedStructure];
|
|
564
|
+
if (options.externalAad) toBeAuthenticated.push(options.externalAad);
|
|
565
|
+
toBeAuthenticated.push(options.payload);
|
|
566
|
+
return cborEncode(toBeAuthenticated);
|
|
567
|
+
}
|
|
568
|
+
get signatureAlgorithmName() {
|
|
569
|
+
const algorithm = this.protectedHeaders.headers?.get(1) ?? this.unprotectedHeaders.headers?.get(1);
|
|
570
|
+
if (!algorithm) throw new CoseInvalidAlgorithmError();
|
|
571
|
+
const algorithmName = coseKeyToJwk.algorithm(algorithm);
|
|
572
|
+
if (!algorithmName) throw new CoseInvalidAlgorithmError();
|
|
573
|
+
return algorithmName;
|
|
574
|
+
}
|
|
575
|
+
static create(options) {
|
|
576
|
+
const protectedHeaders = options.protectedHeaders instanceof ProtectedHeaders ? options.protectedHeaders : ProtectedHeaders.create({ protectedHeaders: options.protectedHeaders });
|
|
577
|
+
const unprotectedHeaders = options.unprotectedHeaders instanceof UnprotectedHeaders ? options.unprotectedHeaders : UnprotectedHeaders.create({ unprotectedHeaders: options.unprotectedHeaders });
|
|
578
|
+
if (!(options.payload ?? options.detachedPayload)) throw new CosePayloadMustBeDefinedError();
|
|
579
|
+
const mac0 = new Mac0({
|
|
580
|
+
protectedHeaders,
|
|
581
|
+
unprotectedHeaders,
|
|
582
|
+
payload: options.payload ?? null,
|
|
583
|
+
tag: new Uint8Array()
|
|
584
|
+
});
|
|
585
|
+
mac0.externalAad = options.externalAad;
|
|
586
|
+
mac0.detachedPayload = options.detachedPayload;
|
|
587
|
+
return mac0;
|
|
588
|
+
}
|
|
589
|
+
async authenticate(options, ctx) {
|
|
590
|
+
const payload = this.payload ?? this.detachedPayload;
|
|
591
|
+
if (!payload) throw new CosePayloadMustBeDefinedError();
|
|
592
|
+
this.structure.tag = await ctx.mac({
|
|
593
|
+
toBeAuthenticated: Mac0.toBeAuthenticated({
|
|
594
|
+
payload,
|
|
595
|
+
protectedHeaders: this.protectedHeaders,
|
|
596
|
+
externalAad: this.externalAad
|
|
597
|
+
}),
|
|
598
|
+
key: options.key
|
|
599
|
+
});
|
|
600
|
+
return this;
|
|
601
|
+
}
|
|
602
|
+
};
|
|
603
|
+
(0, cbor_x.addExtension)({
|
|
604
|
+
Class: Mac0,
|
|
605
|
+
tag: Mac0.tag,
|
|
606
|
+
encode(instance, encodeFn) {
|
|
607
|
+
return encodeFn(instance);
|
|
608
|
+
},
|
|
609
|
+
decode: (encoded) => Mac0.fromEncodedStructure(encoded)
|
|
610
|
+
});
|
|
611
|
+
//#endregion
|
|
612
|
+
//#region src/utils/typed-map.ts
|
|
613
|
+
/**
|
|
614
|
+
* TypedMap provides compile-time type safety for Maps where each key has its own specific value type.
|
|
615
|
+
* Unlike Map<K, V> which has the same value type V for all keys, TypedMap<Schema, OptionalKeys>
|
|
616
|
+
* allows different value types per key (heterogeneous values).
|
|
617
|
+
*
|
|
618
|
+
* Example:
|
|
619
|
+
* type CoseKeySchema = {
|
|
620
|
+
* [CoseKeyParameter.KeyType]: KeyType // number key → KeyType value
|
|
621
|
+
* [CoseKeyParameter.Curve]: Curve // number key → Curve value
|
|
622
|
+
* [CoseKeyParameter.X]: Uint8Array // number key → Uint8Array value
|
|
623
|
+
* }
|
|
624
|
+
*
|
|
625
|
+
* const map = new TypedMap<CoseKeySchema>()
|
|
626
|
+
* map.get(CoseKeyParameter.KeyType) // TypeScript knows this is KeyType!
|
|
627
|
+
* map.get(CoseKeyParameter.Curve) // TypeScript knows this is Curve!
|
|
628
|
+
* map.get(CoseKeyParameter.X) // TypeScript knows this is Uint8Array!
|
|
629
|
+
*
|
|
630
|
+
* @template Schema - Object type mapping keys to their value types
|
|
631
|
+
* @template OptionalKeys - Union of keys that are optional (can be absent)
|
|
632
|
+
*/
|
|
633
|
+
var TypedMap = class TypedMap {
|
|
634
|
+
constructor(entries) {
|
|
635
|
+
this.map = new Map(entries);
|
|
636
|
+
}
|
|
637
|
+
static fromMap(map) {
|
|
638
|
+
return new TypedMap(Array.from(map.entries()));
|
|
639
|
+
}
|
|
640
|
+
static fromObject(object) {
|
|
641
|
+
return new TypedMap(Array.from(Object.entries(object)));
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* Type-safe get that returns the correct value type for each key.
|
|
645
|
+
* Required keys return T, optional keys return T | undefined.
|
|
646
|
+
*/
|
|
647
|
+
get(key) {
|
|
648
|
+
return this.map.get(key);
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* Type-safe set that ensures the value matches the key's type
|
|
652
|
+
*/
|
|
653
|
+
set(key, value) {
|
|
654
|
+
this.map.set(key, value);
|
|
655
|
+
return this;
|
|
656
|
+
}
|
|
657
|
+
has(key) {
|
|
658
|
+
return this.map.has(key);
|
|
659
|
+
}
|
|
660
|
+
delete(key) {
|
|
661
|
+
return this.map.delete(key);
|
|
662
|
+
}
|
|
663
|
+
clear() {
|
|
664
|
+
this.map.clear();
|
|
665
|
+
}
|
|
666
|
+
get size() {
|
|
667
|
+
return this.map.size;
|
|
668
|
+
}
|
|
669
|
+
keys() {
|
|
670
|
+
return this.map.keys();
|
|
671
|
+
}
|
|
672
|
+
values() {
|
|
673
|
+
return this.map.values();
|
|
674
|
+
}
|
|
675
|
+
entries() {
|
|
676
|
+
return this.map.entries();
|
|
677
|
+
}
|
|
678
|
+
forEach(callbackfn, thisArg) {
|
|
679
|
+
this.map.forEach(callbackfn, thisArg);
|
|
680
|
+
}
|
|
681
|
+
[Symbol.iterator]() {
|
|
682
|
+
return this.map[Symbol.iterator]();
|
|
683
|
+
}
|
|
684
|
+
toMap() {
|
|
685
|
+
return new Map(this.map);
|
|
686
|
+
}
|
|
687
|
+
};
|
|
688
|
+
/**
|
|
689
|
+
* This checks whether the property is exact optional. exact optional means that the value cannot be undefined, but if used
|
|
690
|
+
* in an object the key can be omitted. This is important for CBOR structures, as undefined will be encoded, and thus must be
|
|
691
|
+
* omitted in most cases.
|
|
692
|
+
*
|
|
693
|
+
* Zod recommend to check for optionality by just parsing undefined.
|
|
694
|
+
*/
|
|
695
|
+
const isExactOptional = (schema) => !schema.safeParse(void 0).success && zod.z.object({ test: schema }).safeParse({}).success;
|
|
696
|
+
/**
|
|
697
|
+
* Utility function to create a typed map codec.
|
|
698
|
+
* Takes an array of [key, valueSchema] entries to support any key type (including non-string keys for CBOR).
|
|
699
|
+
*
|
|
700
|
+
* Example:
|
|
701
|
+
* const coseKeyMap = typedMap([
|
|
702
|
+
* [CoseKeyParameter.KeyType, z.number()],
|
|
703
|
+
* [CoseKeyParameter.Curve, z.number()],
|
|
704
|
+
* [CoseKeyParameter.X, z.instanceof(Uint8Array)]
|
|
705
|
+
* ] as const)
|
|
706
|
+
*
|
|
707
|
+
* The resulting schema validates a Map and transforms it to TypedMap<Schema, never>.
|
|
708
|
+
*/
|
|
709
|
+
function typedMap(entries, { allowAdditionalKeys = true, encode, decode } = {}) {
|
|
710
|
+
const requiredKeys = entries.filter(([, valueSchema]) => !isExactOptional(valueSchema)).map(([key]) => key);
|
|
711
|
+
const schemaMap = new Map(entries);
|
|
712
|
+
const originalEncode = (decoded) => decoded.toMap();
|
|
713
|
+
const originalDecode = (encoded) => TypedMap.fromMap(encoded);
|
|
714
|
+
return zod.z.codec(zod.z.map(zod.z.unknown(), zod.z.unknown()), zod.z.instanceof(TypedMap).superRefine((map, ctx) => {
|
|
715
|
+
const additionalKeys = Array.from(map.keys()).filter((key) => !schemaMap.has(key));
|
|
716
|
+
if (additionalKeys.length > 0 && !allowAdditionalKeys) for (const additionalKey of additionalKeys) if (typeof additionalKey !== "string" && typeof additionalKey !== "number") ctx.addIssue({
|
|
717
|
+
code: "invalid_key",
|
|
718
|
+
origin: "map",
|
|
719
|
+
continue: true,
|
|
720
|
+
path: [],
|
|
721
|
+
input: map,
|
|
722
|
+
issues: [],
|
|
723
|
+
message: "Key found in map that is not a string or number"
|
|
724
|
+
});
|
|
725
|
+
else ctx.addIssue({
|
|
726
|
+
code: "invalid_key",
|
|
727
|
+
origin: "map",
|
|
728
|
+
continue: true,
|
|
729
|
+
path: [additionalKey],
|
|
730
|
+
input: map,
|
|
731
|
+
issues: [],
|
|
732
|
+
message: `Unexpected key '${additionalKey}' found in map, additional keys are not allowed.`
|
|
733
|
+
});
|
|
734
|
+
for (const [key, valueSchema] of schemaMap.entries()) {
|
|
735
|
+
const hasKey = map.has(key);
|
|
736
|
+
const value = map.get(key);
|
|
737
|
+
if (!hasKey && requiredKeys.includes(key)) {
|
|
738
|
+
ctx.addIssue({
|
|
739
|
+
code: "invalid_value",
|
|
740
|
+
continue: true,
|
|
741
|
+
message: `Expected key '${key}' to be defined.`,
|
|
742
|
+
path: [key],
|
|
743
|
+
values: [],
|
|
744
|
+
input: value
|
|
745
|
+
});
|
|
746
|
+
continue;
|
|
747
|
+
}
|
|
748
|
+
if (!hasKey && !requiredKeys.includes(key)) continue;
|
|
749
|
+
const parseResult = valueSchema.safeParse(value);
|
|
750
|
+
if (!parseResult.success) for (const issue of parseResult.error.issues) ctx.addIssue({
|
|
751
|
+
...issue,
|
|
752
|
+
path: [`${key}`, ...issue.path]
|
|
753
|
+
});
|
|
754
|
+
}
|
|
755
|
+
}), {
|
|
756
|
+
decode: (input) => decode ? decode(input, originalDecode) : originalDecode(input),
|
|
757
|
+
encode: (output) => encode ? encode(output, originalEncode) : originalEncode(output)
|
|
758
|
+
});
|
|
759
|
+
}
|
|
760
|
+
//#endregion
|
|
761
|
+
//#region src/cose/key/key.ts
|
|
762
|
+
let CoseKeyParameter = /* @__PURE__ */ function(CoseKeyParameter) {
|
|
763
|
+
CoseKeyParameter[CoseKeyParameter["KeyType"] = 1] = "KeyType";
|
|
764
|
+
CoseKeyParameter[CoseKeyParameter["KeyId"] = 2] = "KeyId";
|
|
765
|
+
CoseKeyParameter[CoseKeyParameter["Algorithm"] = 3] = "Algorithm";
|
|
766
|
+
CoseKeyParameter[CoseKeyParameter["KeyOps"] = 4] = "KeyOps";
|
|
767
|
+
CoseKeyParameter[CoseKeyParameter["BaseIv"] = 5] = "BaseIv";
|
|
768
|
+
CoseKeyParameter[CoseKeyParameter["CurveOrK"] = -1] = "CurveOrK";
|
|
769
|
+
CoseKeyParameter[CoseKeyParameter["X"] = -2] = "X";
|
|
770
|
+
CoseKeyParameter[CoseKeyParameter["Y"] = -3] = "Y";
|
|
771
|
+
CoseKeyParameter[CoseKeyParameter["D"] = -4] = "D";
|
|
772
|
+
return CoseKeyParameter;
|
|
773
|
+
}({});
|
|
774
|
+
const coseKeySchema = typedMap([
|
|
775
|
+
[1, zod.z.union([zod.z.enum(KeyType), zod.z.string()])],
|
|
776
|
+
[2, zUint8Array.or(zod.z.string()).exactOptional()],
|
|
777
|
+
[3, zod.z.union([zod.z.string({ error: "Cose algorithm must be a string" }), zod.z.number({ error: "Cose algorithm must be a number" })]).exactOptional()],
|
|
778
|
+
[4, zod.z.array(zod.z.union([zod.z.enum(KeyOps), zod.z.string()])).exactOptional()],
|
|
779
|
+
[5, zUint8Array.exactOptional()],
|
|
780
|
+
[-1, zod.z.union([zod.z.enum(Curve), zUint8Array]).exactOptional()],
|
|
781
|
+
[-2, zUint8Array.exactOptional()],
|
|
782
|
+
[-3, zUint8Array.exactOptional()],
|
|
783
|
+
[-4, zUint8Array.exactOptional()]
|
|
784
|
+
]);
|
|
785
|
+
var CoseKey = class CoseKey extends CborStructure {
|
|
786
|
+
static get encodingSchema() {
|
|
787
|
+
return coseKeySchema;
|
|
788
|
+
}
|
|
789
|
+
get keyType() {
|
|
790
|
+
return this.structure.get(1);
|
|
791
|
+
}
|
|
792
|
+
get keyId() {
|
|
793
|
+
const keyId = this.structure.get(2);
|
|
794
|
+
return keyId instanceof Uint8Array ? (0, _owf_identity_common.bytesToString)(keyId) : keyId;
|
|
795
|
+
}
|
|
796
|
+
get algorithm() {
|
|
797
|
+
return this.structure.get(3);
|
|
798
|
+
}
|
|
799
|
+
get keyOps() {
|
|
800
|
+
return this.structure.get(4);
|
|
801
|
+
}
|
|
802
|
+
get baseIv() {
|
|
803
|
+
return this.structure.get(5);
|
|
804
|
+
}
|
|
805
|
+
get curve() {
|
|
806
|
+
if (this.keyType === 2 || this.keyType === 1) return this.structure.get(-1);
|
|
807
|
+
}
|
|
808
|
+
get x() {
|
|
809
|
+
return this.structure.get(-2);
|
|
810
|
+
}
|
|
811
|
+
get y() {
|
|
812
|
+
return this.structure.get(-3);
|
|
813
|
+
}
|
|
814
|
+
get d() {
|
|
815
|
+
return this.structure.get(-4);
|
|
816
|
+
}
|
|
817
|
+
get k() {
|
|
818
|
+
if (this.keyType === 4) return this.structure.get(-1);
|
|
819
|
+
}
|
|
820
|
+
static create(options) {
|
|
821
|
+
const map = new TypedMap([[1, options.keyType]]);
|
|
822
|
+
if (options.keyId !== void 0) map.set(2, (0, _owf_identity_common.stringToBytes)(options.keyId));
|
|
823
|
+
if (options.algorithm !== void 0) map.set(3, options.algorithm);
|
|
824
|
+
if (options.keyOps !== void 0) map.set(4, options.keyOps);
|
|
825
|
+
if (options.baseIv !== void 0) map.set(5, options.baseIv);
|
|
826
|
+
if (options.curve !== void 0) map.set(-1, options.curve);
|
|
827
|
+
if (options.x !== void 0) map.set(-2, options.x);
|
|
828
|
+
if (options.y !== void 0) map.set(-3, options.y);
|
|
829
|
+
if (options.d !== void 0) map.set(-4, options.d);
|
|
830
|
+
if (options.k !== void 0) map.set(-1, options.k);
|
|
831
|
+
return CoseKey.fromDecodedStructure(map);
|
|
832
|
+
}
|
|
833
|
+
static fromJwk(jwk) {
|
|
834
|
+
if (!("kty" in jwk)) throw new CoseInvalidValueForKtyError("JWK does not contain required kty value");
|
|
835
|
+
const options = Object.entries(jwk).reduce((prev, [key, value]) => {
|
|
836
|
+
const mappedKey = jwkCoseOptionsMap[key] ?? key;
|
|
837
|
+
const mapFunction = jwkToCoseKey[key];
|
|
838
|
+
const convertedValue = mapFunction ? mapFunction(value) : value;
|
|
839
|
+
if (convertedValue !== void 0) return {
|
|
840
|
+
...prev,
|
|
841
|
+
[mappedKey]: convertedValue
|
|
842
|
+
};
|
|
843
|
+
return prev;
|
|
844
|
+
}, {});
|
|
845
|
+
return CoseKey.create(options);
|
|
846
|
+
}
|
|
847
|
+
get publicKey() {
|
|
848
|
+
if (this.keyType !== 2) throw new CoseInvalidKtyForRawError();
|
|
849
|
+
if (!this.x) throw new CoseXNotDefinedError();
|
|
850
|
+
if (!this.y) throw new CoseYNotDefinedError();
|
|
851
|
+
return (0, _owf_identity_common.concatBytes)(Uint8Array.from([4]), this.x, this.y);
|
|
852
|
+
}
|
|
853
|
+
get privateKey() {
|
|
854
|
+
if (this.keyType === 2) {
|
|
855
|
+
if (!this.d) throw new CoseDNotDefinedError();
|
|
856
|
+
return this.d;
|
|
857
|
+
}
|
|
858
|
+
if (this.keyType === 4) {
|
|
859
|
+
if (!this.k) throw new CoseKNotDefinedError();
|
|
860
|
+
return this.k;
|
|
861
|
+
}
|
|
862
|
+
throw new CoseKeyTypeNotSupportedForPrivateKeyExtractionError();
|
|
863
|
+
}
|
|
864
|
+
get jwk() {
|
|
865
|
+
const options = {
|
|
866
|
+
keyType: this.keyType,
|
|
867
|
+
keyId: this.keyId,
|
|
868
|
+
algorithm: this.algorithm,
|
|
869
|
+
keyOps: this.keyOps,
|
|
870
|
+
baseIv: this.baseIv,
|
|
871
|
+
curve: this.curve,
|
|
872
|
+
x: this.x,
|
|
873
|
+
y: this.y,
|
|
874
|
+
d: this.d,
|
|
875
|
+
k: this.k
|
|
876
|
+
};
|
|
877
|
+
return Object.entries(options).reduce((prev, [key, value]) => ({
|
|
878
|
+
...prev,
|
|
879
|
+
[coseOptionsJwkMap[key] ?? key]: typeof coseKeyToJwk[key] === "function" ? coseKeyToJwk[key](value) : void 0
|
|
880
|
+
}), {});
|
|
881
|
+
}
|
|
882
|
+
};
|
|
883
|
+
//#endregion
|
|
884
|
+
//#region src/cose/sign1.ts
|
|
885
|
+
const sign1EncodedSchema = zod.default.tuple([
|
|
886
|
+
protectedHeadersEncodedStructure,
|
|
887
|
+
unprotectedHeadersStructure,
|
|
888
|
+
zUint8Array.nullable(),
|
|
889
|
+
zUint8Array
|
|
890
|
+
]);
|
|
891
|
+
const sign1DecodedSchema = zod.default.object({
|
|
892
|
+
protectedHeaders: zod.default.instanceof(ProtectedHeaders),
|
|
893
|
+
unprotectedHeaders: zod.default.instanceof(UnprotectedHeaders),
|
|
894
|
+
payload: sign1EncodedSchema.def.items[2],
|
|
895
|
+
signature: sign1EncodedSchema.def.items[3]
|
|
896
|
+
});
|
|
897
|
+
var Sign1 = class Sign1 extends CborStructure {
|
|
898
|
+
constructor(..._args) {
|
|
899
|
+
super(..._args);
|
|
900
|
+
this._tag = Sign1.tag;
|
|
901
|
+
}
|
|
902
|
+
static {
|
|
903
|
+
this.tag = 18;
|
|
904
|
+
}
|
|
905
|
+
static get encodingSchema() {
|
|
906
|
+
return zod.default.codec(sign1EncodedSchema, sign1DecodedSchema, {
|
|
907
|
+
encode: (decoded) => {
|
|
908
|
+
if (decoded.signature.length === 0) throw new Error("Signature has not been set. Required for encoding the sign1 structure");
|
|
909
|
+
return [
|
|
910
|
+
decoded.protectedHeaders.encodedStructure,
|
|
911
|
+
decoded.unprotectedHeaders.encodedStructure,
|
|
912
|
+
decoded.payload,
|
|
913
|
+
decoded.signature
|
|
914
|
+
];
|
|
915
|
+
},
|
|
916
|
+
decode: ([protectedHeaders, unprotected, payload, signature]) => ({
|
|
917
|
+
protectedHeaders: ProtectedHeaders.fromEncodedStructure(protectedHeaders),
|
|
918
|
+
unprotectedHeaders: UnprotectedHeaders.fromEncodedStructure(unprotected),
|
|
919
|
+
payload,
|
|
920
|
+
signature
|
|
921
|
+
})
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
get protectedHeaders() {
|
|
925
|
+
return this.structure.protectedHeaders;
|
|
926
|
+
}
|
|
927
|
+
get unprotectedHeaders() {
|
|
928
|
+
return this.structure.unprotectedHeaders;
|
|
929
|
+
}
|
|
930
|
+
get payload() {
|
|
931
|
+
return this.structure.payload;
|
|
932
|
+
}
|
|
933
|
+
get signature() {
|
|
934
|
+
return this.structure.signature;
|
|
935
|
+
}
|
|
936
|
+
get certificateChain() {
|
|
937
|
+
return this.x5chain ?? [];
|
|
938
|
+
}
|
|
939
|
+
get certificate() {
|
|
940
|
+
const [certificate] = this.certificateChain;
|
|
941
|
+
if (!certificate) throw new CoseCertificateNotFoundError();
|
|
942
|
+
return certificate;
|
|
943
|
+
}
|
|
944
|
+
getIssuingCountry(ctx) {
|
|
945
|
+
return ctx.x509.getIssuerNameField({
|
|
946
|
+
certificate: this.certificate,
|
|
947
|
+
field: "C"
|
|
948
|
+
})[0];
|
|
949
|
+
}
|
|
950
|
+
getIssuingStateOrProvince(ctx) {
|
|
951
|
+
return ctx.x509.getIssuerNameField({
|
|
952
|
+
certificate: this.certificate,
|
|
953
|
+
field: "ST"
|
|
954
|
+
})[0];
|
|
955
|
+
}
|
|
956
|
+
get toBeSigned() {
|
|
957
|
+
const payload = this.payload ?? this.detachedPayload;
|
|
958
|
+
if (!payload) throw new CosePayloadMustBeDefinedError();
|
|
959
|
+
return Sign1.toBeSigned({
|
|
960
|
+
payload,
|
|
961
|
+
protectedHeaders: this.protectedHeaders,
|
|
962
|
+
externalAad: this.externalAad
|
|
963
|
+
});
|
|
964
|
+
}
|
|
965
|
+
/**
|
|
966
|
+
* Decodes CBOR bytes into a Sign1 instance.
|
|
967
|
+
* Uses the encodingSchema's decode() method to validate and transform the decoded data.
|
|
968
|
+
*/
|
|
969
|
+
static decode(bytes) {
|
|
970
|
+
const rawStructure = cborDecode(bytes);
|
|
971
|
+
return new Sign1(rawStructure instanceof Sign1 ? rawStructure.decodedStructure : Sign1.fromEncodedStructure(rawStructure).decodedStructure);
|
|
972
|
+
}
|
|
973
|
+
static toBeSigned(options) {
|
|
974
|
+
return cborEncode([
|
|
975
|
+
"Signature1",
|
|
976
|
+
options.protectedHeaders.encodedStructure,
|
|
977
|
+
options.externalAad ?? new Uint8Array(),
|
|
978
|
+
options.payload
|
|
979
|
+
]);
|
|
980
|
+
}
|
|
981
|
+
get signatureAlgorithmName() {
|
|
982
|
+
const algorithm = this.protectedHeaders.headers?.get(1) ?? this.unprotectedHeaders.headers?.get(1);
|
|
983
|
+
if (!algorithm) throw new CoseInvalidAlgorithmError();
|
|
984
|
+
const algorithmName = coseKeyToJwk.algorithm(algorithm);
|
|
985
|
+
if (!algorithmName) throw new CoseInvalidAlgorithmError();
|
|
986
|
+
return algorithmName;
|
|
987
|
+
}
|
|
988
|
+
get x5chain() {
|
|
989
|
+
const x5chain = this.protectedHeaders.headers?.get(33) ?? this.unprotectedHeaders.headers?.get(33);
|
|
990
|
+
if (!x5chain?.[0]) return;
|
|
991
|
+
return Array.isArray(x5chain) ? x5chain : [x5chain];
|
|
992
|
+
}
|
|
993
|
+
async verifySignature(options, ctx) {
|
|
994
|
+
const publicKey = options.key ?? (this.certificate ? await ctx.getPublicKey({
|
|
995
|
+
certificate: this.certificate,
|
|
996
|
+
alg: this.signatureAlgorithmName
|
|
997
|
+
}) : void 0);
|
|
998
|
+
if (!publicKey) throw new CoseCertificateNotFoundError();
|
|
999
|
+
return await ctx.verify({
|
|
1000
|
+
sign1: this,
|
|
1001
|
+
key: publicKey
|
|
1002
|
+
});
|
|
1003
|
+
}
|
|
1004
|
+
static create(options) {
|
|
1005
|
+
const payload = options.payload ?? options.detachedPayload;
|
|
1006
|
+
if (!payload) throw new CosePayloadMustBeDefinedError();
|
|
1007
|
+
const sign1 = new Sign1({
|
|
1008
|
+
protectedHeaders: options.protectedHeaders instanceof ProtectedHeaders ? options.protectedHeaders : options.protectedHeaders ? ProtectedHeaders.fromDecodedStructure(options.protectedHeaders) : ProtectedHeaders.create({}),
|
|
1009
|
+
unprotectedHeaders: options.unprotectedHeaders instanceof UnprotectedHeaders ? options.unprotectedHeaders : options.unprotectedHeaders ? UnprotectedHeaders.fromDecodedStructure(options.unprotectedHeaders) : UnprotectedHeaders.create({}),
|
|
1010
|
+
payload,
|
|
1011
|
+
signature: new Uint8Array()
|
|
1012
|
+
});
|
|
1013
|
+
sign1.externalAad = options.externalAad;
|
|
1014
|
+
sign1.detachedPayload = options.detachedPayload;
|
|
1015
|
+
return sign1;
|
|
1016
|
+
}
|
|
1017
|
+
async sign(options, ctx) {
|
|
1018
|
+
const payload = this.payload ?? options.detachedPayload;
|
|
1019
|
+
if (!payload) throw new CosePayloadMustBeDefinedError();
|
|
1020
|
+
const signatureAlgorithm = options.algorithm ?? options.signingKey.algorithm;
|
|
1021
|
+
if (!signatureAlgorithm) throw new CoseInvalidAlgorithmError("Could not establish signature algorithm. Either provide it in the options directly, or provide it in the signingKey");
|
|
1022
|
+
this.structure.signature = await ctx.sign({
|
|
1023
|
+
toBeSigned: Sign1.toBeSigned({
|
|
1024
|
+
payload,
|
|
1025
|
+
protectedHeaders: this.protectedHeaders,
|
|
1026
|
+
externalAad: options.externalAad
|
|
1027
|
+
}),
|
|
1028
|
+
key: options.signingKey,
|
|
1029
|
+
algorithm: signatureAlgorithm
|
|
1030
|
+
});
|
|
1031
|
+
return this;
|
|
1032
|
+
}
|
|
1033
|
+
};
|
|
1034
|
+
(0, cbor_x.addExtension)({
|
|
1035
|
+
Class: Sign1,
|
|
1036
|
+
tag: Sign1.tag,
|
|
1037
|
+
encode(instance, encodeFn) {
|
|
1038
|
+
return encodeFn(instance);
|
|
1039
|
+
},
|
|
1040
|
+
decode: (encoded) => Sign1.fromEncodedStructure(encoded)
|
|
1041
|
+
});
|
|
1042
|
+
//#endregion
|
|
1043
|
+
//#region src/cose/cwt.ts
|
|
1044
|
+
var Cwt = class Cwt {
|
|
1045
|
+
constructor(options) {
|
|
1046
|
+
this.options = options;
|
|
1047
|
+
}
|
|
1048
|
+
static create(options) {
|
|
1049
|
+
return new Cwt(options);
|
|
1050
|
+
}
|
|
1051
|
+
static fromToken(token) {
|
|
1052
|
+
return new Cwt(cborDecode(token));
|
|
1053
|
+
}
|
|
1054
|
+
get asSign1() {
|
|
1055
|
+
return Sign1.create(this.options);
|
|
1056
|
+
}
|
|
1057
|
+
get asMac0() {
|
|
1058
|
+
return Mac0.create(this.options);
|
|
1059
|
+
}
|
|
1060
|
+
get payload() {
|
|
1061
|
+
const payload = this.options.payload ?? this.options.detachedPayload;
|
|
1062
|
+
if (!payload) throw new Error("Neither `payload`, nor `detachedPayload` is defined");
|
|
1063
|
+
return payload;
|
|
1064
|
+
}
|
|
1065
|
+
get protectedHeaders() {
|
|
1066
|
+
return this.options.protectedHeaders;
|
|
1067
|
+
}
|
|
1068
|
+
get unprotectedHeaders() {
|
|
1069
|
+
return this.options.unprotectedHeaders;
|
|
1070
|
+
}
|
|
1071
|
+
};
|
|
1072
|
+
//#endregion
|
|
1073
|
+
exports.CborStructure = CborStructure;
|
|
1074
|
+
exports.CoseCertificateNotFoundError = CoseCertificateNotFoundError;
|
|
1075
|
+
exports.CoseDNotDefinedError = CoseDNotDefinedError;
|
|
1076
|
+
exports.CoseEphemeralMacKeyIsRequiredError = CoseEphemeralMacKeyIsRequiredError;
|
|
1077
|
+
exports.CoseInvalidAlgorithmError = CoseInvalidAlgorithmError;
|
|
1078
|
+
exports.CoseInvalidKtyForRawError = CoseInvalidKtyForRawError;
|
|
1079
|
+
exports.CoseInvalidSignatureError = CoseInvalidSignatureError;
|
|
1080
|
+
exports.CoseInvalidTypeForKeyError = CoseInvalidTypeForKeyError;
|
|
1081
|
+
exports.CoseInvalidValueForKtyError = CoseInvalidValueForKtyError;
|
|
1082
|
+
exports.CoseKNotDefinedError = CoseKNotDefinedError;
|
|
1083
|
+
exports.CoseKey = CoseKey;
|
|
1084
|
+
exports.CoseKeyParameter = CoseKeyParameter;
|
|
1085
|
+
exports.CoseKeyTypeNotSupportedForPrivateKeyExtractionError = CoseKeyTypeNotSupportedForPrivateKeyExtractionError;
|
|
1086
|
+
exports.CosePayloadInvalidStructureError = CosePayloadInvalidStructureError;
|
|
1087
|
+
exports.CosePayloadMustBeDefinedError = CosePayloadMustBeDefinedError;
|
|
1088
|
+
exports.CosePayloadMustBeNullError = CosePayloadMustBeNullError;
|
|
1089
|
+
exports.CoseUnsupportedMacError = CoseUnsupportedMacError;
|
|
1090
|
+
exports.CoseXNotDefinedError = CoseXNotDefinedError;
|
|
1091
|
+
exports.CoseYNotDefinedError = CoseYNotDefinedError;
|
|
1092
|
+
exports.Curve = Curve;
|
|
1093
|
+
exports.Cwt = Cwt;
|
|
1094
|
+
exports.DataItem = DataItem;
|
|
1095
|
+
exports.DateOnly = DateOnly;
|
|
1096
|
+
exports.EncryptionAlgorithm = EncryptionAlgorithm;
|
|
1097
|
+
exports.KeyOps = KeyOps;
|
|
1098
|
+
exports.KeyType = KeyType;
|
|
1099
|
+
exports.Mac0 = Mac0;
|
|
1100
|
+
exports.MacAlgorithm = MacAlgorithm;
|
|
1101
|
+
exports.ProtectedHeaders = ProtectedHeaders;
|
|
1102
|
+
exports.RegisteredCwtClaimKey = RegisteredCwtClaimKey;
|
|
1103
|
+
exports.RegisteredCwtHeaderClaimKey = RegisteredCwtHeaderClaimKey;
|
|
1104
|
+
exports.Sign1 = Sign1;
|
|
1105
|
+
exports.SignatureAlgorithm = SignatureAlgorithm;
|
|
1106
|
+
exports.TypedMap = TypedMap;
|
|
1107
|
+
exports.UnprotectedHeaders = UnprotectedHeaders;
|
|
1108
|
+
exports.ValidationError = ValidationError;
|
|
1109
|
+
Object.defineProperty(exports, "addExtension", {
|
|
1110
|
+
enumerable: true,
|
|
1111
|
+
get: function() {
|
|
1112
|
+
return cbor_x.addExtension;
|
|
1113
|
+
}
|
|
1114
|
+
});
|
|
1115
|
+
exports.cborDecode = cborDecode;
|
|
1116
|
+
exports.cborEncode = cborEncode;
|
|
1117
|
+
exports.coseKeyToJwk = coseKeyToJwk;
|
|
1118
|
+
exports.coseOptionsJwkMap = coseOptionsJwkMap;
|
|
1119
|
+
exports.jwkCoseOptionsMap = jwkCoseOptionsMap;
|
|
1120
|
+
exports.jwkToCoseKey = jwkToCoseKey;
|
|
1121
|
+
exports.mac0DecodedSchema = mac0DecodedSchema;
|
|
1122
|
+
exports.mac0EncodedSchema = mac0EncodedSchema;
|
|
1123
|
+
exports.protectedHeadersDecodedStructure = protectedHeadersDecodedStructure;
|
|
1124
|
+
exports.protectedHeadersEncodedStructure = protectedHeadersEncodedStructure;
|
|
1125
|
+
exports.sign1DecodedSchema = sign1DecodedSchema;
|
|
1126
|
+
exports.sign1EncodedSchema = sign1EncodedSchema;
|
|
1127
|
+
exports.typedMap = typedMap;
|
|
1128
|
+
exports.unprotectedHeadersStructure = unprotectedHeadersStructure;
|
|
1129
|
+
exports.zDataItemCodec = zDataItemCodec;
|
|
1130
|
+
exports.zUint8Array = zUint8Array;
|
|
1131
|
+
|
|
1132
|
+
//# sourceMappingURL=index.cjs.map
|