@sphereon/ssi-sdk-ext.key-utils 0.28.1-feature.oyd.cmsm.improv.21 → 0.28.1-next.53

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/dist/functions.js DELETED
@@ -1,756 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
- return new (P || (P = Promise))(function (resolve, reject) {
28
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
- step((generator = generator.apply(thisArg, _arguments || [])).next());
32
- });
33
- };
34
- var __importDefault = (this && this.__importDefault) || function (mod) {
35
- return (mod && mod.__esModule) ? mod : { "default": mod };
36
- };
37
- Object.defineProperty(exports, "__esModule", { value: true });
38
- exports.sanitizedJwk = exports.globalCrypto = exports.keyTypeFromCryptographicSuite = exports.signatureAlgorithmFromKeyType = exports.signatureAlgorithmFromKey = exports.hexStringFromUint8Array = exports.toRawCompressedHexPublicKey = exports.isRawCompressedPublicKey = exports.asn1DerToRawPublicKey = exports.isAsn1Der = exports.padLeft = exports.jwkDetermineUse = exports.jwkToRawHexKey = exports.toJwk = exports.toJwkFromKey = exports.calculateJwkThumbprint = exports.toBase64url = exports.calculateJwkThumbprintForKey = exports.generatePrivateKeyHex = exports.getKms = exports.logger = void 0;
39
- exports.importProvidedOrGeneratedKey = importProvidedOrGeneratedKey;
40
- exports.removeNulls = removeNulls;
41
- exports.verifyRawSignature = verifyRawSignature;
42
- const random_1 = require("@ethersproject/random");
43
- // Do not change these require statements to imports before we change to ESM. Breaks external CJS packages depending on this module
44
- const bls12_381_1 = require("@noble/curves/bls12-381");
45
- const ed25519_1 = require("@noble/curves/ed25519");
46
- const p256_1 = require("@noble/curves/p256");
47
- const p384_1 = require("@noble/curves/p384");
48
- const p521_1 = require("@noble/curves/p521");
49
- const secp256k1_1 = require("@noble/curves/secp256k1");
50
- const sha256_1 = require("@noble/hashes/sha256");
51
- const sha512_1 = require("@noble/hashes/sha512");
52
- const ssi_sdk_ext_x509_utils_1 = require("@sphereon/ssi-sdk-ext.x509-utils");
53
- const ssi_types_1 = require("@sphereon/ssi-types");
54
- const ed25519_2 = require("@stablelib/ed25519");
55
- const debug_1 = __importDefault(require("debug"));
56
- const elliptic_1 = __importDefault(require("elliptic"));
57
- const rsa = __importStar(require("micro-rsa-dsa-dh/rsa.js"));
58
- const u8a = __importStar(require("uint8arrays"));
59
- const digest_methods_1 = require("./digest-methods");
60
- const jwk_jcs_1 = require("./jwk-jcs");
61
- const types_1 = require("./types");
62
- exports.logger = ssi_types_1.Loggers.DEFAULT.get('sphereon:key-utils');
63
- /**
64
- * Function that returns the provided KMS name or the default KMS name if none is provided.
65
- * The default KMS is either explicitly defined during agent construction, or the first KMS available in the system
66
- * @param context
67
- * @param kms. Optional KMS to use. If provided will be the returned name. Otherwise the default KMS will be returned
68
- */
69
- const getKms = (context, kms) => __awaiter(void 0, void 0, void 0, function* () {
70
- if (kms) {
71
- return kms;
72
- }
73
- if (!context.agent.availableMethods().includes('keyManagerGetDefaultKeyManagementSystem')) {
74
- throw Error('Cannot determine default KMS if not provided and a non Sphereon Key Manager is being used');
75
- }
76
- return context.agent.keyManagerGetDefaultKeyManagementSystem();
77
- });
78
- exports.getKms = getKms;
79
- /**
80
- * Generates a random Private Hex Key for the specified key type
81
- * @param type The key type
82
- * @return The private key in Hex form
83
- */
84
- const generatePrivateKeyHex = (type) => __awaiter(void 0, void 0, void 0, function* () {
85
- switch (type) {
86
- case 'Ed25519': {
87
- const keyPairEd25519 = (0, ed25519_2.generateKeyPair)();
88
- return u8a.toString(keyPairEd25519.secretKey, 'base16');
89
- }
90
- // The Secp256 types use the same method to generate the key
91
- case 'Secp256r1':
92
- case 'Secp256k1': {
93
- const privateBytes = (0, random_1.randomBytes)(32);
94
- return u8a.toString(privateBytes, 'base16');
95
- }
96
- case 'RSA': {
97
- const pem = yield (0, ssi_sdk_ext_x509_utils_1.generateRSAKeyAsPEM)('RSA-PSS', 'SHA-256', 2048);
98
- return (0, ssi_sdk_ext_x509_utils_1.privateKeyHexFromPEM)(pem);
99
- }
100
- default:
101
- throw Error(`not_supported: Key type ${type} not yet supported for this did:jwk implementation`);
102
- }
103
- });
104
- exports.generatePrivateKeyHex = generatePrivateKeyHex;
105
- const keyMetaAlgorithmsFromKeyType = (type) => {
106
- switch (type) {
107
- case 'Ed25519':
108
- return ['Ed25519', 'EdDSA'];
109
- case 'ES256K':
110
- case 'Secp256k1':
111
- return ['ES256K', 'ES256K-R', 'eth_signTransaction', 'eth_signTypedData', 'eth_signMessage', 'eth_rawSign'];
112
- case 'Secp256r1':
113
- return ['ES256'];
114
- case 'X25519':
115
- return ['ECDH', 'ECDH-ES', 'ECDH-1PU'];
116
- case 'RSA':
117
- return ['RS256', 'RS512', 'PS256', 'PS512'];
118
- }
119
- return [type];
120
- };
121
- /**
122
- * We optionally generate and then import our own keys.
123
- *
124
- * @param args The key arguments
125
- * @param context The Veramo agent context
126
- * @private
127
- */
128
- function importProvidedOrGeneratedKey(args, context) {
129
- return __awaiter(this, void 0, void 0, function* () {
130
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
131
- // @ts-ignore
132
- const type = (_g = (_e = (_b = (_a = args.options) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : (_d = (_c = args.options) === null || _c === void 0 ? void 0 : _c.key) === null || _d === void 0 ? void 0 : _d.type) !== null && _e !== void 0 ? _e : (_f = args.options) === null || _f === void 0 ? void 0 : _f.keyType) !== null && _g !== void 0 ? _g : 'Secp256r1';
133
- const key = (_h = args === null || args === void 0 ? void 0 : args.options) === null || _h === void 0 ? void 0 : _h.key;
134
- // Make sure x509 options are also set on the metadata as that is what the kms will look for
135
- if (((_j = args.options) === null || _j === void 0 ? void 0 : _j.x509) && key) {
136
- key.meta = Object.assign(Object.assign({}, key.meta), { x509: Object.assign(Object.assign({}, args.options.x509), (_k = key.meta) === null || _k === void 0 ? void 0 : _k.x509) });
137
- }
138
- if (args.options && ((_l = args.options) === null || _l === void 0 ? void 0 : _l.use) === types_1.JwkKeyUse.Encryption && !types_1.ENC_KEY_ALGS.includes(type)) {
139
- throw new Error(`${type} keys are not valid for encryption`);
140
- }
141
- let privateKeyHex = undefined;
142
- if (key) {
143
- privateKeyHex = (_m = key.privateKeyHex) !== null && _m !== void 0 ? _m : (_p = (_o = key.meta) === null || _o === void 0 ? void 0 : _o.x509) === null || _p === void 0 ? void 0 : _p.privateKeyHex;
144
- if ((!privateKeyHex || privateKeyHex.trim() === '') && ((_r = (_q = key === null || key === void 0 ? void 0 : key.meta) === null || _q === void 0 ? void 0 : _q.x509) === null || _r === void 0 ? void 0 : _r.privateKeyPEM)) {
145
- // If we do not have a privateKeyHex but do have a PEM
146
- privateKeyHex = (0, ssi_sdk_ext_x509_utils_1.privateKeyHexFromPEM)(key.meta.x509.privateKeyPEM);
147
- }
148
- }
149
- if (privateKeyHex) {
150
- return context.agent.keyManagerImport(Object.assign(Object.assign({}, key), { kms: args.kms, type, privateKeyHex: privateKeyHex }));
151
- }
152
- return context.agent.keyManagerCreate({
153
- type,
154
- kms: args.kms,
155
- meta: Object.assign(Object.assign({}, key === null || key === void 0 ? void 0 : key.meta), { algorithms: keyMetaAlgorithmsFromKeyType(type), keyAlias: args.alias }),
156
- });
157
- });
158
- }
159
- const calculateJwkThumbprintForKey = (args) => {
160
- const { key } = args;
161
- const jwk = key.publicKeyHex
162
- ? (0, exports.toJwk)(key.publicKeyHex, key.type, { key: key, isPrivateKey: false })
163
- : 'privateKeyHex' in key && key.privateKeyHex
164
- ? (0, exports.toJwk)(key.privateKeyHex, key.type, { isPrivateKey: true })
165
- : undefined;
166
- if (!jwk) {
167
- throw Error(`Could not determine jwk from key ${key.kid}`);
168
- }
169
- return (0, exports.calculateJwkThumbprint)({ jwk, digestAlgorithm: args.digestAlgorithm });
170
- };
171
- exports.calculateJwkThumbprintForKey = calculateJwkThumbprintForKey;
172
- const assertJwkClaimPresent = (value, description) => {
173
- if (typeof value !== 'string' || !value) {
174
- throw new Error(`${description} missing or invalid`);
175
- }
176
- };
177
- const toBase64url = (input) => u8a.toString(u8a.fromString(input), 'base64url');
178
- exports.toBase64url = toBase64url;
179
- /**
180
- * Calculate the JWK thumbprint
181
- * @param args
182
- */
183
- const calculateJwkThumbprint = (args) => {
184
- const { digestAlgorithm = 'sha256' } = args;
185
- const jwk = (0, exports.sanitizedJwk)(args.jwk);
186
- let components;
187
- switch (jwk.kty) {
188
- case 'EC':
189
- assertJwkClaimPresent(jwk.crv, '"crv" (Curve) Parameter');
190
- assertJwkClaimPresent(jwk.x, '"x" (X Coordinate) Parameter');
191
- assertJwkClaimPresent(jwk.y, '"y" (Y Coordinate) Parameter');
192
- components = { crv: jwk.crv, kty: jwk.kty, x: jwk.x, y: jwk.y };
193
- break;
194
- case 'OKP':
195
- assertJwkClaimPresent(jwk.crv, '"crv" (Subtype of Key Pair) Parameter');
196
- assertJwkClaimPresent(jwk.x, '"x" (Public Key) Parameter');
197
- components = { crv: jwk.crv, kty: jwk.kty, x: jwk.x };
198
- break;
199
- case 'RSA':
200
- assertJwkClaimPresent(jwk.e, '"e" (Exponent) Parameter');
201
- assertJwkClaimPresent(jwk.n, '"n" (Modulus) Parameter');
202
- components = { e: jwk.e, kty: jwk.kty, n: jwk.n };
203
- break;
204
- case 'oct':
205
- assertJwkClaimPresent(jwk.k, '"k" (Key Value) Parameter');
206
- components = { k: jwk.k, kty: jwk.kty };
207
- break;
208
- default:
209
- throw new Error('"kty" (Key Type) Parameter missing or unsupported');
210
- }
211
- const data = JSON.stringify(components);
212
- return digestAlgorithm === 'sha512'
213
- ? (0, digest_methods_1.digestMethodParams)('SHA-512').digestMethod(data, 'base64url')
214
- : (0, digest_methods_1.digestMethodParams)('SHA-256').digestMethod(data, 'base64url');
215
- };
216
- exports.calculateJwkThumbprint = calculateJwkThumbprint;
217
- const toJwkFromKey = (key, opts) => {
218
- const isPrivateKey = 'privateKeyHex' in key;
219
- return (0, exports.toJwk)(key.publicKeyHex, key.type, Object.assign(Object.assign({}, opts), { key, isPrivateKey }));
220
- };
221
- exports.toJwkFromKey = toJwkFromKey;
222
- /**
223
- * Converts a public key in hex format to a JWK
224
- * @param publicKeyHex public key in hex
225
- * @param type The type of the key (Ed25519, Secp256k1/r1)
226
- * @param opts. Options, like the optional use for the key (sig/enc)
227
- * @return The JWK
228
- */
229
- const toJwk = (publicKeyHex, type, opts) => {
230
- const { key, noKidThumbprint = false } = opts !== null && opts !== void 0 ? opts : {};
231
- if (key && key.publicKeyHex !== publicKeyHex && (opts === null || opts === void 0 ? void 0 : opts.isPrivateKey) !== true) {
232
- throw Error(`Provided key with id ${key.kid}, has a different public key hex ${key.publicKeyHex} than supplied public key ${publicKeyHex}`);
233
- }
234
- let jwk;
235
- switch (type) {
236
- case 'Ed25519':
237
- jwk = toEd25519OrX25519Jwk(publicKeyHex, Object.assign(Object.assign({}, opts), { crv: ssi_types_1.JoseCurve.Ed25519 }));
238
- break;
239
- case 'X25519':
240
- jwk = toEd25519OrX25519Jwk(publicKeyHex, Object.assign(Object.assign({}, opts), { crv: ssi_types_1.JoseCurve.X25519 }));
241
- break;
242
- case 'Secp256k1':
243
- jwk = toSecp256k1Jwk(publicKeyHex, opts);
244
- break;
245
- case 'Secp256r1':
246
- jwk = toSecp256r1Jwk(publicKeyHex, opts);
247
- break;
248
- case 'RSA':
249
- jwk = toRSAJwk(publicKeyHex, opts);
250
- break;
251
- default:
252
- throw new Error(`not_supported: Key type ${type} not yet supported for this did:jwk implementation`);
253
- }
254
- if (!jwk.kid && !noKidThumbprint) {
255
- jwk['kid'] = (0, exports.calculateJwkThumbprint)({ jwk });
256
- }
257
- return (0, exports.sanitizedJwk)(jwk);
258
- };
259
- exports.toJwk = toJwk;
260
- /**
261
- * Convert a JWK to a raw hex key.
262
- * Currently supports `RSA` and `EC` keys. Extendable for other key types.
263
- * @param jwk - The JSON Web Key object.
264
- * @returns A string representing the key in raw hexadecimal format.
265
- */
266
- const jwkToRawHexKey = (jwk) => __awaiter(void 0, void 0, void 0, function* () {
267
- // TODO: Probably makes sense to have an option to do the same for private keys
268
- jwk = (0, exports.sanitizedJwk)(jwk);
269
- if (jwk.kty === 'RSA') {
270
- return rsaJwkToRawHexKey(jwk);
271
- }
272
- else if (jwk.kty === 'EC') {
273
- return ecJwkToRawHexKey(jwk);
274
- }
275
- else if (jwk.kty === 'OKP') {
276
- return okpJwkToRawHexKey(jwk);
277
- }
278
- else if (jwk.kty === 'oct') {
279
- return octJwkToRawHexKey(jwk);
280
- }
281
- else {
282
- throw new Error(`Unsupported key type: ${jwk.kty}`);
283
- }
284
- });
285
- exports.jwkToRawHexKey = jwkToRawHexKey;
286
- /**
287
- * Convert an RSA JWK to a raw hex key.
288
- * @param jwk - The RSA JWK object.
289
- * @returns A string representing the RSA key in raw hexadecimal format.
290
- */
291
- function rsaJwkToRawHexKey(jwk) {
292
- jwk = (0, exports.sanitizedJwk)(jwk);
293
- if (!jwk.n || !jwk.e) {
294
- throw new Error("RSA JWK must contain 'n' and 'e' properties.");
295
- }
296
- // We are converting from base64 to base64url to be sure. The spec uses base64url, but in the wild we sometimes encounter a base64 string
297
- const modulus = u8a.fromString(jwk.n.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''), 'base64url'); // 'n' is the modulus
298
- const exponent = u8a.fromString(jwk.e.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''), 'base64url'); // 'e' is the exponent
299
- return u8a.toString(modulus, 'hex') + u8a.toString(exponent, 'hex');
300
- }
301
- /**
302
- * Convert an EC JWK to a raw hex key.
303
- * @param jwk - The EC JWK object.
304
- * @returns A string representing the EC key in raw hexadecimal format.
305
- */
306
- function ecJwkToRawHexKey(jwk) {
307
- jwk = (0, exports.sanitizedJwk)(jwk);
308
- if (!jwk.x || !jwk.y) {
309
- throw new Error("EC JWK must contain 'x' and 'y' properties.");
310
- }
311
- // We are converting from base64 to base64url to be sure. The spec uses base64url, but in the wild we sometimes encounter a base64 string
312
- const x = u8a.fromString(jwk.x.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''), 'base64url');
313
- const y = u8a.fromString(jwk.y.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''), 'base64url');
314
- return '04' + u8a.toString(x, 'hex') + u8a.toString(y, 'hex');
315
- }
316
- /**
317
- * Convert an EC JWK to a raw hex key.
318
- * @param jwk - The EC JWK object.
319
- * @returns A string representing the EC key in raw hexadecimal format.
320
- */
321
- function okpJwkToRawHexKey(jwk) {
322
- jwk = (0, exports.sanitizedJwk)(jwk);
323
- if (!jwk.x) {
324
- throw new Error("OKP JWK must contain 'x' property.");
325
- }
326
- // We are converting from base64 to base64url to be sure. The spec uses base64url, but in the wild we sometimes encounter a base64 string
327
- const x = u8a.fromString(jwk.x.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''), 'base64url');
328
- return u8a.toString(x, 'hex');
329
- }
330
- /**
331
- * Convert an octet JWK to a raw hex key.
332
- * @param jwk - The octet JWK object.
333
- * @returns A string representing the octet key in raw hexadecimal format.
334
- */
335
- function octJwkToRawHexKey(jwk) {
336
- jwk = (0, exports.sanitizedJwk)(jwk);
337
- if (!jwk.k) {
338
- throw new Error("Octet JWK must contain 'k' property.");
339
- }
340
- // We are converting from base64 to base64url to be sure. The spec uses base64url, but in the wild we sometimes encounter a base64 string
341
- const key = u8a.fromString(jwk.k.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''), 'base64url');
342
- return u8a.toString(key, 'hex');
343
- }
344
- /**
345
- * Determines the use param based upon the key/signature type or supplied use value.
346
- *
347
- * @param type The key type
348
- * @param suppliedUse A supplied use. Will be used in case it is present
349
- */
350
- const jwkDetermineUse = (type, suppliedUse) => {
351
- return suppliedUse
352
- ? suppliedUse
353
- : types_1.SIG_KEY_ALGS.includes(type)
354
- ? types_1.JwkKeyUse.Signature
355
- : types_1.ENC_KEY_ALGS.includes(type)
356
- ? types_1.JwkKeyUse.Encryption
357
- : undefined;
358
- };
359
- exports.jwkDetermineUse = jwkDetermineUse;
360
- /**
361
- * Assert the key has a proper length
362
- *
363
- * @param keyHex Input key
364
- * @param expectedKeyLength Expected key length(s)
365
- */
366
- const assertProperKeyLength = (keyHex, expectedKeyLength) => {
367
- if (Array.isArray(expectedKeyLength)) {
368
- if (!expectedKeyLength.includes(keyHex.length)) {
369
- throw Error(`Invalid key length. Needs to be a hex string with length from ${JSON.stringify(expectedKeyLength)} instead of ${keyHex.length}. Input: ${keyHex}`);
370
- }
371
- }
372
- else if (keyHex.length !== expectedKeyLength) {
373
- throw Error(`Invalid key length. Needs to be a hex string with length ${expectedKeyLength} instead of ${keyHex.length}. Input: ${keyHex}`);
374
- }
375
- };
376
- /**
377
- * Generates a JWK from a Secp256k1 public key
378
- * @param keyHex Secp256k1 public or private key in hex
379
- * @param use The use for the key
380
- * @return The JWK
381
- */
382
- const toSecp256k1Jwk = (keyHex, opts) => {
383
- const { use } = opts !== null && opts !== void 0 ? opts : {};
384
- exports.logger.debug(`toSecp256k1Jwk keyHex: ${keyHex}, length: ${keyHex.length}`);
385
- if (opts === null || opts === void 0 ? void 0 : opts.isPrivateKey) {
386
- assertProperKeyLength(keyHex, [64]);
387
- }
388
- else {
389
- assertProperKeyLength(keyHex, [66, 130]);
390
- }
391
- const secp256k1 = new elliptic_1.default.ec('secp256k1');
392
- const keyBytes = u8a.fromString(keyHex, 'base16');
393
- const keyPair = (opts === null || opts === void 0 ? void 0 : opts.isPrivateKey) ? secp256k1.keyFromPrivate(keyBytes) : secp256k1.keyFromPublic(keyBytes);
394
- const pubPoint = keyPair.getPublic();
395
- return (0, exports.sanitizedJwk)(Object.assign(Object.assign(Object.assign({ alg: ssi_types_1.JoseSignatureAlgorithm.ES256K }, (use !== undefined && { use })), { kty: ssi_types_1.JwkKeyType.EC, crv: ssi_types_1.JoseCurve.secp256k1, x: (0, ssi_sdk_ext_x509_utils_1.hexToBase64)(pubPoint.getX().toString('hex'), 'base64url'), y: (0, ssi_sdk_ext_x509_utils_1.hexToBase64)(pubPoint.getY().toString('hex'), 'base64url') }), ((opts === null || opts === void 0 ? void 0 : opts.isPrivateKey) && { d: (0, ssi_sdk_ext_x509_utils_1.hexToBase64)(keyPair.getPrivate('hex'), 'base64url') })));
396
- };
397
- /**
398
- * Generates a JWK from a Secp256r1 public key
399
- * @param keyHex Secp256r1 public key in hex
400
- * @param use The use for the key
401
- * @return The JWK
402
- */
403
- const toSecp256r1Jwk = (keyHex, opts) => {
404
- const { use } = opts !== null && opts !== void 0 ? opts : {};
405
- exports.logger.debug(`toSecp256r1Jwk keyHex: ${keyHex}, length: ${keyHex.length}`);
406
- if (opts === null || opts === void 0 ? void 0 : opts.isPrivateKey) {
407
- assertProperKeyLength(keyHex, [64]);
408
- }
409
- else {
410
- assertProperKeyLength(keyHex, [66, 130]);
411
- }
412
- const secp256r1 = new elliptic_1.default.ec('p256');
413
- const keyBytes = u8a.fromString(keyHex, 'base16');
414
- exports.logger.debug(`keyBytes length: ${keyBytes}`);
415
- const keyPair = (opts === null || opts === void 0 ? void 0 : opts.isPrivateKey) ? secp256r1.keyFromPrivate(keyBytes) : secp256r1.keyFromPublic(keyBytes);
416
- const pubPoint = keyPair.getPublic();
417
- return (0, exports.sanitizedJwk)(Object.assign(Object.assign(Object.assign({ alg: ssi_types_1.JoseSignatureAlgorithm.ES256 }, (use !== undefined && { use })), { kty: ssi_types_1.JwkKeyType.EC, crv: ssi_types_1.JoseCurve.P_256, x: (0, ssi_sdk_ext_x509_utils_1.hexToBase64)(pubPoint.getX().toString('hex'), 'base64url'), y: (0, ssi_sdk_ext_x509_utils_1.hexToBase64)(pubPoint.getY().toString('hex'), 'base64url') }), ((opts === null || opts === void 0 ? void 0 : opts.isPrivateKey) && { d: (0, ssi_sdk_ext_x509_utils_1.hexToBase64)(keyPair.getPrivate('hex'), 'base64url') })));
418
- };
419
- /**
420
- * Generates a JWK from an Ed25519/X25519 public key
421
- * @param publicKeyHex Ed25519/X25519 public key in hex
422
- * @param opts
423
- * @return The JWK
424
- */
425
- const toEd25519OrX25519Jwk = (publicKeyHex, opts) => {
426
- var _a;
427
- assertProperKeyLength(publicKeyHex, 64);
428
- const { use } = opts !== null && opts !== void 0 ? opts : {};
429
- return (0, exports.sanitizedJwk)(Object.assign(Object.assign({ alg: ssi_types_1.JoseSignatureAlgorithm.EdDSA }, (use !== undefined && { use })), { kty: ssi_types_1.JwkKeyType.OKP, crv: (_a = opts === null || opts === void 0 ? void 0 : opts.crv) !== null && _a !== void 0 ? _a : ssi_types_1.JoseCurve.Ed25519, x: (0, ssi_sdk_ext_x509_utils_1.hexToBase64)(publicKeyHex, 'base64url') }));
430
- };
431
- const toRSAJwk = (publicKeyHex, opts) => {
432
- var _a, _b;
433
- const meta = (_a = opts === null || opts === void 0 ? void 0 : opts.key) === null || _a === void 0 ? void 0 : _a.meta;
434
- if ((meta === null || meta === void 0 ? void 0 : meta.publicKeyJwk) || (meta === null || meta === void 0 ? void 0 : meta.publicKeyPEM)) {
435
- if (meta === null || meta === void 0 ? void 0 : meta.publicKeyJwk) {
436
- return meta.publicKeyJwk;
437
- }
438
- const publicKeyPEM = (_b = meta === null || meta === void 0 ? void 0 : meta.publicKeyPEM) !== null && _b !== void 0 ? _b : (0, ssi_sdk_ext_x509_utils_1.hexToPEM)(publicKeyHex, 'public');
439
- return (0, ssi_sdk_ext_x509_utils_1.PEMToJwk)(publicKeyPEM, 'public');
440
- }
441
- // exponent (e) is 5 chars long, rest is modulus (n)
442
- // const publicKey = publicKeyHex
443
- // assertProperKeyLength(publicKey, [2048, 3072, 4096])
444
- const exponent = publicKeyHex.slice(-5);
445
- const modulus = publicKeyHex.slice(0, -5);
446
- // const modulusBitLength = (modulus.length / 2) * 8
447
- // const alg = modulusBitLength === 2048 ? JoseSignatureAlgorithm.RS256 : modulusBitLength === 3072 ? JoseSignatureAlgorithm.RS384 : modulusBitLength === 4096 ? JoseSignatureAlgorithm.RS512 : undefined
448
- return (0, exports.sanitizedJwk)({
449
- kty: 'RSA',
450
- n: (0, ssi_sdk_ext_x509_utils_1.hexToBase64)(modulus, 'base64url'),
451
- e: (0, ssi_sdk_ext_x509_utils_1.hexToBase64)(exponent, 'base64url'),
452
- // ...(alg && { alg }),
453
- });
454
- };
455
- const padLeft = (args) => {
456
- var _a, _b;
457
- const { data } = args;
458
- const size = (_a = args.size) !== null && _a !== void 0 ? _a : 32;
459
- const padString = (_b = args.padString) !== null && _b !== void 0 ? _b : '0';
460
- if (data.length >= size) {
461
- return data;
462
- }
463
- if (padString && padString.length === 0) {
464
- throw Error(`Pad string needs to have at least a length of 1`);
465
- }
466
- const length = padString.length;
467
- return padString.repeat((size - data.length) / length) + data;
468
- };
469
- exports.padLeft = padLeft;
470
- var OIDType;
471
- (function (OIDType) {
472
- OIDType[OIDType["Secp256k1"] = 0] = "Secp256k1";
473
- OIDType[OIDType["Secp256r1"] = 1] = "Secp256r1";
474
- OIDType[OIDType["Ed25519"] = 2] = "Ed25519";
475
- })(OIDType || (OIDType = {}));
476
- const OID = {
477
- [OIDType.Secp256k1]: new Uint8Array([0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01]),
478
- [OIDType.Secp256r1]: new Uint8Array([0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07]),
479
- [OIDType.Ed25519]: new Uint8Array([0x06, 0x03, 0x2b, 0x65, 0x70]),
480
- };
481
- const compareUint8Arrays = (a, b) => {
482
- if (a.length !== b.length) {
483
- return false;
484
- }
485
- for (let i = 0; i < a.length; i++) {
486
- if (a[i] !== b[i]) {
487
- return false;
488
- }
489
- }
490
- return true;
491
- };
492
- const findSubarray = (haystack, needle) => {
493
- for (let i = 0; i <= haystack.length - needle.length; i++) {
494
- if (compareUint8Arrays(haystack.subarray(i, i + needle.length), needle)) {
495
- return i;
496
- }
497
- }
498
- return -1;
499
- };
500
- const getTargetOID = (keyType) => {
501
- switch (keyType) {
502
- case 'Secp256k1':
503
- return OID[OIDType.Secp256k1];
504
- case 'Secp256r1':
505
- return OID[OIDType.Secp256r1];
506
- case 'Ed25519':
507
- return OID[OIDType.Ed25519];
508
- default:
509
- throw new Error(`Unsupported key type: ${keyType}`);
510
- }
511
- };
512
- const isAsn1Der = (key) => key[0] === 0x30;
513
- exports.isAsn1Der = isAsn1Der;
514
- const asn1DerToRawPublicKey = (derKey, keyType) => {
515
- if (!(0, exports.isAsn1Der)(derKey)) {
516
- throw new Error('Invalid DER encoding: Expected to start with sequence tag');
517
- }
518
- let index = 2;
519
- if (derKey[1] & 0x80) {
520
- const lengthBytesCount = derKey[1] & 0x7f;
521
- index += lengthBytesCount;
522
- }
523
- const targetOid = getTargetOID(keyType);
524
- const oidIndex = findSubarray(derKey, targetOid);
525
- if (oidIndex === -1) {
526
- throw new Error(`OID for ${keyType} not found in DER encoding`);
527
- }
528
- index = oidIndex + targetOid.length;
529
- while (index < derKey.length && derKey[index] !== 0x03) {
530
- index++;
531
- }
532
- if (index >= derKey.length) {
533
- throw new Error('Invalid DER encoding: Bit string not found');
534
- }
535
- // Skip the bit string tag (0x03) and length byte
536
- index += 2;
537
- // Skip the unused bits count byte
538
- index++;
539
- return derKey.slice(index);
540
- };
541
- exports.asn1DerToRawPublicKey = asn1DerToRawPublicKey;
542
- const isRawCompressedPublicKey = (key) => key.length === 33 && (key[0] === 0x02 || key[0] === 0x03);
543
- exports.isRawCompressedPublicKey = isRawCompressedPublicKey;
544
- const toRawCompressedHexPublicKey = (rawPublicKey, keyType) => {
545
- if ((0, exports.isRawCompressedPublicKey)(rawPublicKey)) {
546
- return (0, exports.hexStringFromUint8Array)(rawPublicKey);
547
- }
548
- if (keyType === 'Secp256k1' || keyType === 'Secp256r1') {
549
- if (rawPublicKey[0] === 0x04 && rawPublicKey.length === 65) {
550
- const xCoordinate = rawPublicKey.slice(1, 33);
551
- const yCoordinate = rawPublicKey.slice(33);
552
- const prefix = new Uint8Array([yCoordinate[31] % 2 === 0 ? 0x02 : 0x03]);
553
- const resultKey = (0, exports.hexStringFromUint8Array)(new Uint8Array([...prefix, ...xCoordinate]));
554
- exports.logger.debug(`converted public key ${(0, exports.hexStringFromUint8Array)(rawPublicKey)} to ${resultKey}`);
555
- return resultKey;
556
- }
557
- return u8a.toString(rawPublicKey, 'base16');
558
- }
559
- else if (keyType === 'Ed25519') {
560
- // Ed25519 keys are always in compressed form
561
- return u8a.toString(rawPublicKey, 'base16');
562
- }
563
- throw new Error(`Unsupported key type: ${keyType}`);
564
- };
565
- exports.toRawCompressedHexPublicKey = toRawCompressedHexPublicKey;
566
- const hexStringFromUint8Array = (value) => u8a.toString(value, 'base16');
567
- exports.hexStringFromUint8Array = hexStringFromUint8Array;
568
- const signatureAlgorithmFromKey = (args) => __awaiter(void 0, void 0, void 0, function* () {
569
- const { key } = args;
570
- return (0, exports.signatureAlgorithmFromKeyType)({ type: key.type });
571
- });
572
- exports.signatureAlgorithmFromKey = signatureAlgorithmFromKey;
573
- const signatureAlgorithmFromKeyType = (args) => {
574
- const { type } = args;
575
- switch (type) {
576
- case 'Ed25519':
577
- case 'X25519':
578
- return ssi_types_1.JoseSignatureAlgorithm.EdDSA;
579
- case 'Secp256r1':
580
- return ssi_types_1.JoseSignatureAlgorithm.ES256;
581
- case 'Secp384r1':
582
- return ssi_types_1.JoseSignatureAlgorithm.ES384;
583
- case 'Secp521r1':
584
- return ssi_types_1.JoseSignatureAlgorithm.ES512;
585
- case 'Secp256k1':
586
- return ssi_types_1.JoseSignatureAlgorithm.ES256K;
587
- default:
588
- throw new Error(`Key type '${type}' not supported`);
589
- }
590
- };
591
- exports.signatureAlgorithmFromKeyType = signatureAlgorithmFromKeyType;
592
- // TODO improve this conversion for jwt and jsonld, not a fan of current structure
593
- const keyTypeFromCryptographicSuite = (args) => {
594
- const { crv, kty, alg } = args;
595
- switch (alg) {
596
- case 'RSASSA-PSS':
597
- case 'RS256':
598
- case 'RS384':
599
- case 'RS512':
600
- case 'PS256':
601
- case 'PS384':
602
- case 'PS512':
603
- return 'RSA';
604
- }
605
- switch (crv) {
606
- case 'EdDSA':
607
- case 'Ed25519':
608
- case 'Ed25519Signature2018':
609
- case 'Ed25519Signature2020':
610
- case 'JcsEd25519Signature2020':
611
- return 'Ed25519';
612
- case 'JsonWebSignature2020':
613
- case 'ES256':
614
- case 'ECDSA':
615
- case 'P-256':
616
- return 'Secp256r1';
617
- case 'ES384':
618
- case 'P-384':
619
- return 'Secp384r1';
620
- case 'ES512':
621
- case 'P-521':
622
- return 'Secp521r1';
623
- case 'EcdsaSecp256k1Signature2019':
624
- case 'secp256k1':
625
- case 'ES256K':
626
- return 'Secp256k1';
627
- }
628
- if (kty) {
629
- return kty;
630
- }
631
- throw new Error(`Cryptographic suite '${crv}' not supported`);
632
- };
633
- exports.keyTypeFromCryptographicSuite = keyTypeFromCryptographicSuite;
634
- function removeNulls(obj) {
635
- Object.keys(obj).forEach((key) => {
636
- if (obj[key] && typeof obj[key] === 'object')
637
- removeNulls(obj[key]);
638
- else if (obj[key] == null)
639
- delete obj[key];
640
- });
641
- return obj;
642
- }
643
- const globalCrypto = (setGlobal, suppliedCrypto) => {
644
- var _a, _b;
645
- let webcrypto;
646
- if (typeof suppliedCrypto !== 'undefined') {
647
- webcrypto = suppliedCrypto;
648
- }
649
- else if (typeof crypto !== 'undefined') {
650
- webcrypto = crypto;
651
- }
652
- else if (typeof global.crypto !== 'undefined') {
653
- webcrypto = global.crypto;
654
- }
655
- else if (typeof ((_b = (_a = global.window) === null || _a === void 0 ? void 0 : _a.crypto) === null || _b === void 0 ? void 0 : _b.subtle) !== 'undefined') {
656
- webcrypto = global.window.crypto;
657
- }
658
- else {
659
- webcrypto = require('crypto');
660
- }
661
- if (setGlobal) {
662
- global.crypto = webcrypto;
663
- }
664
- return webcrypto;
665
- };
666
- exports.globalCrypto = globalCrypto;
667
- const sanitizedJwk = (input) => {
668
- const inputJwk = typeof input['toJsonDTO'] === 'function' ? input['toJsonDTO']() : Object.assign({}, input); // KMP code can expose this. It converts a KMP JWK with mangled names into a clean JWK
669
- const jwk = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, inputJwk), (inputJwk.x && { x: base64ToBase64Url(inputJwk.x) })), (inputJwk.y && { y: base64ToBase64Url(inputJwk.y) })), (inputJwk.d && { d: base64ToBase64Url(inputJwk.d) })), (inputJwk.n && { n: base64ToBase64Url(inputJwk.n) })), (inputJwk.e && { e: base64ToBase64Url(inputJwk.e) })), (inputJwk.k && { k: base64ToBase64Url(inputJwk.k) }));
670
- return removeNulls(jwk);
671
- };
672
- exports.sanitizedJwk = sanitizedJwk;
673
- const base64ToBase64Url = (input) => {
674
- return input.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
675
- };
676
- /**
677
- *
678
- */
679
- function verifyRawSignature(_a) {
680
- return __awaiter(this, arguments, void 0, function* ({ data, signature, key: inputKey, opts, }) {
681
- var _b, _c;
682
- /**
683
- * Converts a Base64URL-encoded JWK property to a BigInt.
684
- * @param jwkProp - The Base64URL-encoded string.
685
- * @returns The BigInt representation of the decoded value.
686
- */
687
- function jwkPropertyToBigInt(jwkProp) {
688
- // Decode Base64URL to Uint8Array
689
- const byteArray = u8a.fromString(jwkProp, 'base64url');
690
- // Convert Uint8Array to hexadecimal string and then to BigInt
691
- const hex = u8a.toString(byteArray, 'hex');
692
- return BigInt(`0x${hex}`);
693
- }
694
- try {
695
- (0, debug_1.default)(`verifyRawSignature for: ${inputKey}`);
696
- const jwk = (0, exports.sanitizedJwk)(inputKey);
697
- (0, jwk_jcs_1.validateJwk)(jwk, { crvOptional: true });
698
- const keyType = (0, exports.keyTypeFromCryptographicSuite)({ crv: jwk.crv, kty: jwk.kty, alg: jwk.alg });
699
- const publicKeyHex = yield (0, exports.jwkToRawHexKey)(jwk);
700
- // TODO: We really should look at the signature alg first if provided! From key type should be the last resort
701
- switch (keyType) {
702
- case 'Secp256k1':
703
- return secp256k1_1.secp256k1.verify(signature, data, publicKeyHex, { format: 'compact', prehash: true });
704
- case 'Secp256r1':
705
- return p256_1.p256.verify(signature, data, publicKeyHex, { format: 'compact', prehash: true });
706
- case 'Secp384r1':
707
- return p384_1.p384.verify(signature, data, publicKeyHex, { format: 'compact', prehash: true });
708
- case 'Secp521r1':
709
- return p521_1.p521.verify(signature, data, publicKeyHex, { format: 'compact', prehash: true });
710
- case 'Ed25519':
711
- return ed25519_1.ed25519.verify(signature, data, u8a.fromString(publicKeyHex, 'hex'));
712
- case 'Bls12381G1':
713
- case 'Bls12381G2':
714
- return bls12_381_1.bls12_381.verify(signature, data, u8a.fromString(publicKeyHex, 'hex'));
715
- case 'RSA': {
716
- const signatureAlgorithm = (_c = (_b = opts === null || opts === void 0 ? void 0 : opts.signatureAlg) !== null && _b !== void 0 ? _b : jwk.alg) !== null && _c !== void 0 ? _c : ssi_types_1.JoseSignatureAlgorithm.PS256;
717
- const hashAlg = signatureAlgorithm === (ssi_types_1.JoseSignatureAlgorithm.RS512 || ssi_types_1.JoseSignatureAlgorithm.PS512)
718
- ? sha512_1.sha512
719
- : signatureAlgorithm === (ssi_types_1.JoseSignatureAlgorithm.RS384 || ssi_types_1.JoseSignatureAlgorithm.PS384)
720
- ? sha512_1.sha384
721
- : sha256_1.sha256;
722
- switch (signatureAlgorithm) {
723
- case ssi_types_1.JoseSignatureAlgorithm.RS256:
724
- return rsa.PKCS1_SHA256.verify({
725
- n: jwkPropertyToBigInt(jwk.n),
726
- e: jwkPropertyToBigInt(jwk.e),
727
- }, data, signature);
728
- case ssi_types_1.JoseSignatureAlgorithm.RS384:
729
- return rsa.PKCS1_SHA384.verify({
730
- n: jwkPropertyToBigInt(jwk.n),
731
- e: jwkPropertyToBigInt(jwk.e),
732
- }, data, signature);
733
- case ssi_types_1.JoseSignatureAlgorithm.RS512:
734
- return rsa.PKCS1_SHA512.verify({
735
- n: jwkPropertyToBigInt(jwk.n),
736
- e: jwkPropertyToBigInt(jwk.e),
737
- }, data, signature);
738
- case ssi_types_1.JoseSignatureAlgorithm.PS256:
739
- case ssi_types_1.JoseSignatureAlgorithm.PS384:
740
- case ssi_types_1.JoseSignatureAlgorithm.PS512:
741
- return rsa.PSS(hashAlg, rsa.mgf1(hashAlg)).verify({
742
- n: jwkPropertyToBigInt(jwk.n),
743
- e: jwkPropertyToBigInt(jwk.e),
744
- }, data, signature);
745
- }
746
- }
747
- }
748
- throw Error(`Unsupported key type for signature validation: ${keyType}`);
749
- }
750
- catch (error) {
751
- exports.logger.error(`Error: ${error}`);
752
- throw error;
753
- }
754
- });
755
- }
756
- //# sourceMappingURL=functions.js.map