@sphereon/ssi-sdk.credential-vcdm2-jose-provider 0.33.1-feature.jose.vcdm.59

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/index.js ADDED
@@ -0,0 +1,741 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ // src/agent/CredentialProviderVcdm2Jose.ts
5
+ import { pickSigningKey, preProcessCredentialPayload, preProcessPresentation } from "@sphereon/ssi-sdk.credential-vcdm";
6
+ import { normalizeCredential, normalizePresentation, verifyPresentation as verifyPresentationJWT } from "did-jwt-vc";
7
+ import { decodeJWT, JWT_ERROR as JWT_ERROR2 } from "did-jwt";
8
+ import Debug from "debug";
9
+ import { asArray, intersect } from "@sphereon/ssi-sdk.core";
10
+ import { contextHasPlugin } from "@sphereon/ssi-sdk.agent-config";
11
+ import { isDidIdentifier } from "@sphereon/ssi-sdk-ext.identifier-resolution";
12
+ import { CredentialMapper, isVcdm2Credential } from "@sphereon/ssi-types";
13
+
14
+ // src/did-jwt/JWT.ts
15
+ import canonicalizeData from "canonicalize";
16
+ import { parse } from "did-resolver";
17
+
18
+ // src/did-jwt/util.ts
19
+ import { concat, fromString, toString } from "uint8arrays";
20
+ import { x25519 } from "@noble/curves/ed25519";
21
+ import { varint } from "multiformats";
22
+ import { decode, encode } from "multibase";
23
+ import { secp256k1 } from "@noble/curves/secp256k1";
24
+ import { p256 } from "@noble/curves/p256";
25
+ var u8a = {
26
+ toString,
27
+ fromString,
28
+ concat
29
+ };
30
+ function bytesToBase64url(b) {
31
+ return u8a.toString(b, "base64url");
32
+ }
33
+ __name(bytesToBase64url, "bytesToBase64url");
34
+ function base64ToBytes(s) {
35
+ const inputBase64Url = s.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
36
+ return u8a.fromString(inputBase64Url, "base64url");
37
+ }
38
+ __name(base64ToBytes, "base64ToBytes");
39
+ function base58ToBytes(s) {
40
+ return u8a.fromString(s, "base58btc");
41
+ }
42
+ __name(base58ToBytes, "base58ToBytes");
43
+ var VM_TO_KEY_TYPE = {
44
+ Secp256k1SignatureVerificationKey2018: "Secp256k1",
45
+ Secp256k1VerificationKey2018: "Secp256k1",
46
+ EcdsaSecp256k1VerificationKey2019: "Secp256k1",
47
+ EcdsaPublicKeySecp256k1: "Secp256k1",
48
+ EcdsaSecp256k1RecoveryMethod2020: "Secp256k1",
49
+ EcdsaSecp256r1VerificationKey2019: "P-256",
50
+ Ed25519VerificationKey2018: "Ed25519",
51
+ Ed25519VerificationKey2020: "Ed25519",
52
+ ED25519SignatureVerification: "Ed25519",
53
+ X25519KeyAgreementKey2019: "X25519",
54
+ X25519KeyAgreementKey2020: "X25519",
55
+ ConditionalProof2022: void 0,
56
+ JsonWebKey2020: void 0,
57
+ Multikey: void 0
58
+ };
59
+ var supportedCodecs = {
60
+ "ed25519-pub": 237,
61
+ "x25519-pub": 236,
62
+ "secp256k1-pub": 231,
63
+ "bls12_381-g1-pub": 234,
64
+ "bls12_381-g2-pub": 235,
65
+ "p256-pub": 4608
66
+ };
67
+ var CODEC_TO_KEY_TYPE = {
68
+ "bls12_381-g1-pub": "Bls12381G1",
69
+ "bls12_381-g2-pub": "Bls12381G2",
70
+ "ed25519-pub": "Ed25519",
71
+ "p256-pub": "P-256",
72
+ "secp256k1-pub": "Secp256k1",
73
+ "x25519-pub": "X25519"
74
+ };
75
+ function extractPublicKeyBytes(pk) {
76
+ if (pk.publicKeyBase58) {
77
+ return {
78
+ keyBytes: base58ToBytes(pk.publicKeyBase58),
79
+ keyType: VM_TO_KEY_TYPE[pk.type]
80
+ };
81
+ } else if (pk.publicKeyBase64) {
82
+ return {
83
+ keyBytes: base64ToBytes(pk.publicKeyBase64),
84
+ keyType: VM_TO_KEY_TYPE[pk.type]
85
+ };
86
+ } else if (pk.publicKeyHex) {
87
+ return {
88
+ keyBytes: hexToBytes(pk.publicKeyHex),
89
+ keyType: VM_TO_KEY_TYPE[pk.type]
90
+ };
91
+ } else if (pk.publicKeyJwk && pk.publicKeyJwk.crv === "secp256k1" && pk.publicKeyJwk.x && pk.publicKeyJwk.y) {
92
+ return {
93
+ keyBytes: secp256k1.ProjectivePoint.fromAffine({
94
+ x: bytesToBigInt(base64ToBytes(pk.publicKeyJwk.x)),
95
+ y: bytesToBigInt(base64ToBytes(pk.publicKeyJwk.y))
96
+ }).toRawBytes(false),
97
+ keyType: "Secp256k1"
98
+ };
99
+ } else if (pk.publicKeyJwk && pk.publicKeyJwk.crv === "P-256" && pk.publicKeyJwk.x && pk.publicKeyJwk.y) {
100
+ return {
101
+ keyBytes: p256.ProjectivePoint.fromAffine({
102
+ x: bytesToBigInt(base64ToBytes(pk.publicKeyJwk.x)),
103
+ y: bytesToBigInt(base64ToBytes(pk.publicKeyJwk.y))
104
+ }).toRawBytes(false),
105
+ keyType: "P-256"
106
+ };
107
+ } else if (pk.publicKeyJwk && pk.publicKeyJwk.kty === "OKP" && [
108
+ "Ed25519",
109
+ "X25519"
110
+ ].includes(pk.publicKeyJwk.crv ?? "") && pk.publicKeyJwk.x) {
111
+ return {
112
+ keyBytes: base64ToBytes(pk.publicKeyJwk.x),
113
+ keyType: pk.publicKeyJwk.crv
114
+ };
115
+ } else if (pk.publicKeyMultibase) {
116
+ const { keyBytes, keyType } = multibaseToBytes(pk.publicKeyMultibase);
117
+ return {
118
+ keyBytes,
119
+ keyType: keyType ?? VM_TO_KEY_TYPE[pk.type]
120
+ };
121
+ }
122
+ return {
123
+ keyBytes: new Uint8Array()
124
+ };
125
+ }
126
+ __name(extractPublicKeyBytes, "extractPublicKeyBytes");
127
+ function multibaseToBytes(s) {
128
+ const bytes = decode(s);
129
+ if ([
130
+ 32,
131
+ 33,
132
+ 48,
133
+ 64,
134
+ 65,
135
+ 96
136
+ ].includes(bytes.length)) {
137
+ return {
138
+ keyBytes: bytes
139
+ };
140
+ }
141
+ try {
142
+ const [codec, length] = varint.decode(bytes);
143
+ const possibleCodec = Object.entries(supportedCodecs).filter(([, code]) => code === codec)?.[0][0] ?? "";
144
+ return {
145
+ keyBytes: bytes.slice(length),
146
+ keyType: CODEC_TO_KEY_TYPE[possibleCodec]
147
+ };
148
+ } catch (e) {
149
+ return {
150
+ keyBytes: bytes
151
+ };
152
+ }
153
+ }
154
+ __name(multibaseToBytes, "multibaseToBytes");
155
+ function hexToBytes(s, minLength) {
156
+ let input = s.startsWith("0x") ? s.substring(2) : s;
157
+ if (input.length % 2 !== 0) {
158
+ input = `0${input}`;
159
+ }
160
+ if (minLength) {
161
+ const paddedLength = Math.max(input.length, minLength * 2);
162
+ input = input.padStart(paddedLength, "00");
163
+ }
164
+ return u8a.fromString(input.toLowerCase(), "base16");
165
+ }
166
+ __name(hexToBytes, "hexToBytes");
167
+ function bytesToHex(b) {
168
+ return u8a.toString(b, "base16");
169
+ }
170
+ __name(bytesToHex, "bytesToHex");
171
+ function bytesToBigInt(b) {
172
+ return BigInt(`0x` + u8a.toString(b, "base16"));
173
+ }
174
+ __name(bytesToBigInt, "bytesToBigInt");
175
+ function stringToBytes(s) {
176
+ return u8a.fromString(s, "utf-8");
177
+ }
178
+ __name(stringToBytes, "stringToBytes");
179
+ function toJose({ r, s, recoveryParam }, recoverable) {
180
+ const jose = new Uint8Array(recoverable ? 65 : 64);
181
+ jose.set(u8a.fromString(r, "base16"), 0);
182
+ jose.set(u8a.fromString(s, "base16"), 32);
183
+ if (recoverable) {
184
+ if (typeof recoveryParam === "undefined") {
185
+ throw new Error("Signer did not return a recoveryParam");
186
+ }
187
+ jose[64] = recoveryParam;
188
+ }
189
+ return bytesToBase64url(jose);
190
+ }
191
+ __name(toJose, "toJose");
192
+ function fromJose(signature) {
193
+ const signatureBytes = base64ToBytes(signature);
194
+ if (signatureBytes.length < 64 || signatureBytes.length > 65) {
195
+ throw new TypeError(`Wrong size for signature. Expected 64 or 65 bytes, but got ${signatureBytes.length}`);
196
+ }
197
+ const r = bytesToHex(signatureBytes.slice(0, 32));
198
+ const s = bytesToHex(signatureBytes.slice(32, 64));
199
+ const recoveryParam = signatureBytes.length === 65 ? signatureBytes[64] : void 0;
200
+ return {
201
+ r,
202
+ s,
203
+ recoveryParam
204
+ };
205
+ }
206
+ __name(fromJose, "fromJose");
207
+
208
+ // src/did-jwt/SignerAlgorithm.ts
209
+ function instanceOfEcdsaSignature(object) {
210
+ return typeof object === "object" && "r" in object && "s" in object;
211
+ }
212
+ __name(instanceOfEcdsaSignature, "instanceOfEcdsaSignature");
213
+ function ES256SignerAlg() {
214
+ return /* @__PURE__ */ __name(async function sign(payload, signer) {
215
+ const signature = await signer(payload);
216
+ if (instanceOfEcdsaSignature(signature)) {
217
+ return toJose(signature);
218
+ } else {
219
+ return signature;
220
+ }
221
+ }, "sign");
222
+ }
223
+ __name(ES256SignerAlg, "ES256SignerAlg");
224
+ function ES256KSignerAlg(recoverable) {
225
+ return /* @__PURE__ */ __name(async function sign(payload, signer) {
226
+ const signature = await signer(payload);
227
+ if (instanceOfEcdsaSignature(signature)) {
228
+ return toJose(signature, recoverable);
229
+ } else {
230
+ if (recoverable && typeof fromJose(signature).recoveryParam === "undefined") {
231
+ throw new Error(`not_supported: ES256K-R not supported when signer doesn't provide a recovery param`);
232
+ }
233
+ return signature;
234
+ }
235
+ }, "sign");
236
+ }
237
+ __name(ES256KSignerAlg, "ES256KSignerAlg");
238
+ function Ed25519SignerAlg() {
239
+ return /* @__PURE__ */ __name(async function sign(payload, signer) {
240
+ const signature = await signer(payload);
241
+ if (!instanceOfEcdsaSignature(signature)) {
242
+ return signature;
243
+ } else {
244
+ throw new Error("invalid_config: expected a signer function that returns a string instead of signature object");
245
+ }
246
+ }, "sign");
247
+ }
248
+ __name(Ed25519SignerAlg, "Ed25519SignerAlg");
249
+ var algorithms = {
250
+ ES256: ES256SignerAlg(),
251
+ ES256K: ES256KSignerAlg(),
252
+ // This is a non-standard algorithm but retained for backwards compatibility
253
+ // see https://github.com/decentralized-identity/did-jwt/issues/146
254
+ "ES256K-R": ES256KSignerAlg(true),
255
+ // This is actually incorrect but retained for backwards compatibility
256
+ // see https://github.com/decentralized-identity/did-jwt/issues/130
257
+ Ed25519: Ed25519SignerAlg(),
258
+ EdDSA: Ed25519SignerAlg()
259
+ };
260
+
261
+ // src/did-jwt/VerifierAlgorithm.ts
262
+ import { sha256, toEthereumAddress } from "did-jwt-vc";
263
+ import { verifyBlockchainAccountId } from "did-jwt-vc";
264
+ import { secp256k1 as secp256k12 } from "@noble/curves/secp256k1";
265
+ import { p256 as p2562 } from "@noble/curves/p256";
266
+ import { ed25519 } from "@noble/curves/ed25519";
267
+ function toSignatureObject(signature, recoverable = false) {
268
+ const rawSig = base64ToBytes(signature);
269
+ if (rawSig.length !== (recoverable ? 65 : 64)) {
270
+ throw new Error("wrong signature length");
271
+ }
272
+ const r = bytesToHex(rawSig.slice(0, 32));
273
+ const s = bytesToHex(rawSig.slice(32, 64));
274
+ const sigObj = {
275
+ r,
276
+ s
277
+ };
278
+ if (recoverable) {
279
+ sigObj.recoveryParam = rawSig[64];
280
+ }
281
+ return sigObj;
282
+ }
283
+ __name(toSignatureObject, "toSignatureObject");
284
+ function toSignatureObject2(signature, recoverable = false) {
285
+ const bytes = base64ToBytes(signature);
286
+ if (bytes.length !== (recoverable ? 65 : 64)) {
287
+ throw new Error("wrong signature length");
288
+ }
289
+ return {
290
+ compact: bytes.slice(0, 64),
291
+ recovery: bytes[64]
292
+ };
293
+ }
294
+ __name(toSignatureObject2, "toSignatureObject2");
295
+ function verifyES256(data, signature, authenticators) {
296
+ const hash = sha256(data);
297
+ const sig = p2562.Signature.fromCompact(toSignatureObject2(signature).compact);
298
+ const fullPublicKeys = authenticators.filter((a) => !a.ethereumAddress && !a.blockchainAccountId);
299
+ const signer = fullPublicKeys.find((pk) => {
300
+ try {
301
+ const { keyBytes } = extractPublicKeyBytes(pk);
302
+ return p2562.verify(sig, hash, keyBytes);
303
+ } catch (err) {
304
+ return false;
305
+ }
306
+ });
307
+ if (!signer) throw new Error("invalid_signature: Signature invalid for JWT");
308
+ return signer;
309
+ }
310
+ __name(verifyES256, "verifyES256");
311
+ function verifyES256K(data, signature, authenticators) {
312
+ const hash = sha256(data);
313
+ const signatureNormalized = secp256k12.Signature.fromCompact(base64ToBytes(signature)).normalizeS();
314
+ const fullPublicKeys = authenticators.filter((a) => {
315
+ return !a.ethereumAddress && !a.blockchainAccountId;
316
+ });
317
+ const blockchainAddressKeys = authenticators.filter((a) => {
318
+ return a.ethereumAddress || a.blockchainAccountId;
319
+ });
320
+ let signer = fullPublicKeys.find((pk) => {
321
+ try {
322
+ const { keyBytes } = extractPublicKeyBytes(pk);
323
+ return secp256k12.verify(signatureNormalized, hash, keyBytes);
324
+ } catch (err) {
325
+ return false;
326
+ }
327
+ });
328
+ if (!signer && blockchainAddressKeys.length > 0) {
329
+ signer = verifyRecoverableES256K(data, signature, blockchainAddressKeys);
330
+ }
331
+ if (!signer) throw new Error("invalid_signature: Signature invalid for JWT");
332
+ return signer;
333
+ }
334
+ __name(verifyES256K, "verifyES256K");
335
+ function verifyRecoverableES256K(data, signature, authenticators) {
336
+ const signatures = [];
337
+ if (signature.length > 86) {
338
+ signatures.push(toSignatureObject2(signature, true));
339
+ } else {
340
+ const so = toSignatureObject2(signature, false);
341
+ signatures.push({
342
+ ...so,
343
+ recovery: 0
344
+ });
345
+ signatures.push({
346
+ ...so,
347
+ recovery: 1
348
+ });
349
+ }
350
+ const hash = sha256(data);
351
+ const checkSignatureAgainstSigner = /* @__PURE__ */ __name((sigObj) => {
352
+ const signature2 = secp256k12.Signature.fromCompact(sigObj.compact).addRecoveryBit(sigObj.recovery || 0);
353
+ const recoveredPublicKey = signature2.recoverPublicKey(hash);
354
+ const recoveredAddress = toEthereumAddress(recoveredPublicKey.toHex(false)).toLowerCase();
355
+ const recoveredPublicKeyHex = recoveredPublicKey.toHex(false);
356
+ const recoveredCompressedPublicKeyHex = recoveredPublicKey.toHex(true);
357
+ return authenticators.find((a) => {
358
+ const { keyBytes } = extractPublicKeyBytes(a);
359
+ const keyHex = bytesToHex(keyBytes);
360
+ return keyHex === recoveredPublicKeyHex || keyHex === recoveredCompressedPublicKeyHex || a.ethereumAddress?.toLowerCase() === recoveredAddress || a.blockchainAccountId?.split("@eip155")?.[0].toLowerCase() === recoveredAddress || // CAIP-2
361
+ verifyBlockchainAccountId(recoveredPublicKeyHex, a.blockchainAccountId);
362
+ });
363
+ }, "checkSignatureAgainstSigner");
364
+ for (const signature2 of signatures) {
365
+ const verificationMethod = checkSignatureAgainstSigner(signature2);
366
+ if (verificationMethod) return verificationMethod;
367
+ }
368
+ throw new Error("invalid_signature: Signature invalid for JWT");
369
+ }
370
+ __name(verifyRecoverableES256K, "verifyRecoverableES256K");
371
+ function verifyEd25519(data, signature, authenticators) {
372
+ const clear = stringToBytes(data);
373
+ const signatureBytes = base64ToBytes(signature);
374
+ const signer = authenticators.find((a) => {
375
+ const { keyBytes, keyType } = extractPublicKeyBytes(a);
376
+ if (keyType === "Ed25519") {
377
+ return ed25519.verify(signatureBytes, clear, keyBytes);
378
+ } else {
379
+ return false;
380
+ }
381
+ });
382
+ if (!signer) throw new Error("invalid_signature: Signature invalid for JWT");
383
+ return signer;
384
+ }
385
+ __name(verifyEd25519, "verifyEd25519");
386
+ var algorithms2 = {
387
+ ES256: verifyES256,
388
+ ES256K: verifyES256K,
389
+ // This is a non-standard algorithm but retained for backwards compatibility
390
+ // see https://github.com/decentralized-identity/did-jwt/issues/146
391
+ "ES256K-R": verifyRecoverableES256K,
392
+ // This is actually incorrect but retained for backwards compatibility
393
+ // see https://github.com/decentralized-identity/did-jwt/issues/130
394
+ Ed25519: verifyEd25519,
395
+ EdDSA: verifyEd25519
396
+ };
397
+ function VerifierAlgorithm(alg) {
398
+ const impl = algorithms2[alg];
399
+ if (!impl) throw new Error(`not_supported: Unsupported algorithm ${alg}`);
400
+ return impl;
401
+ }
402
+ __name(VerifierAlgorithm, "VerifierAlgorithm");
403
+ VerifierAlgorithm.toSignatureObject = toSignatureObject;
404
+
405
+ // src/did-jwt/JWT.ts
406
+ import { JWT_ERROR } from "did-jwt";
407
+ var SELF_ISSUED_V2 = "https://self-issued.me/v2";
408
+ var SELF_ISSUED_V2_VC_INTEROP = "https://self-issued.me/v2/openid-vc";
409
+ var SELF_ISSUED_V0_1 = "https://self-issued.me";
410
+
411
+ // src/agent/CredentialProviderVcdm2Jose.ts
412
+ var debug = Debug("sphereon:ssi-sdk:credential-jwt");
413
+ var CredentialProviderVcdm2Jose = class {
414
+ static {
415
+ __name(this, "CredentialProviderVcdm2Jose");
416
+ }
417
+ /** {@inheritdoc @veramo/credential-w3c#AbstractCredentialProvider.matchKeyForType} */
418
+ matchKeyForType(key) {
419
+ return this.matchKeyForJWT(key);
420
+ }
421
+ /** {@inheritdoc @veramo/credential-w3c#AbstractCredentialProvider.getTypeProofFormat} */
422
+ getTypeProofFormat() {
423
+ return "vcdm2_jose";
424
+ }
425
+ /** {@inheritdoc @veramo/credential-w3c#AbstractCredentialProvider.canIssueCredentialType} */
426
+ canIssueCredentialType(args) {
427
+ return args.proofFormat === "vcdm2_jose" || args.proofFormat === "vcdm_jose" || args.proofFormat === "jose";
428
+ }
429
+ /** {@inheritdoc @veramo/credential-w3c#AbstractCredentialProvider.canVerifyDocumentType */
430
+ canVerifyDocumentType(args) {
431
+ const { document } = args;
432
+ const jwt = typeof document === "string" ? document : document?.proof?.jwt;
433
+ if (!jwt) {
434
+ return false;
435
+ }
436
+ const { payload } = decodeJWT(jwt);
437
+ return isVcdm2Credential(payload);
438
+ }
439
+ /** {@inheritdoc @veramo/credential-w3c#AbstractCredentialProvider.createVerifiableCredential} */
440
+ async createVerifiableCredential(args, context) {
441
+ const { keyRef } = args;
442
+ const agent = assertContext(context).agent;
443
+ const { credential, issuer } = preProcessCredentialPayload(args);
444
+ if (!isVcdm2Credential(credential)) {
445
+ return Promise.reject(new Error("invalid_argument: credential must be a VCDM2 credential. Context: " + credential["@context"]));
446
+ }
447
+ let identifier;
448
+ try {
449
+ identifier = await agent.didManagerGet({
450
+ did: issuer
451
+ });
452
+ } catch (e) {
453
+ throw new Error(`invalid_argument: ${credential.issuer} must be a DID managed by this agent. ${e}`);
454
+ }
455
+ const managedIdentifier = await agent.identifierManagedGetByDid({
456
+ identifier: identifier.did,
457
+ kmsKeyRef: keyRef
458
+ });
459
+ const key = await pickSigningKey({
460
+ identifier,
461
+ kmsKeyRef: keyRef
462
+ }, context);
463
+ debug("Signing VC with", identifier.did);
464
+ let alg = "ES256";
465
+ if (key.type === "Ed25519") {
466
+ alg = "EdDSA";
467
+ } else if (key.type === "Secp256k1") {
468
+ alg = "ES256K";
469
+ }
470
+ const header = {
471
+ kid: key.meta.verificationMethod.id ?? key.kid,
472
+ alg,
473
+ typ: "vc+jwt",
474
+ cty: "vc"
475
+ };
476
+ const jwt = await context.agent.jwtCreateJwsCompactSignature({
477
+ mode: "did",
478
+ issuer: managedIdentifier,
479
+ payload: credential,
480
+ protectedHeader: header,
481
+ clientIdScheme: "did"
482
+ });
483
+ debug(jwt);
484
+ return normalizeCredential(jwt.jwt);
485
+ }
486
+ /** {@inheritdoc ICredentialVerifier.verifyCredential} */
487
+ async verifyCredential(args, context) {
488
+ let {
489
+ credential
490
+ /*policies, ...otherOptions*/
491
+ } = args;
492
+ const uniform = CredentialMapper.toUniformCredential(credential);
493
+ if (!isVcdm2Credential(uniform)) {
494
+ return Promise.reject(new Error("invalid_argument: credential must be a VCDM2 credential. Context: " + credential["@context"]));
495
+ }
496
+ let verificationResult = {
497
+ verified: false
498
+ };
499
+ let jwt = typeof credential === "string" ? credential : asArray(uniform.proof)?.[0]?.jwt;
500
+ if (!jwt) {
501
+ return Promise.reject(new Error("invalid_argument: credential must be a VCDM2 credential in JOSE format (string)"));
502
+ }
503
+ verificationResult = await verifierSignature({
504
+ jwt
505
+ }, context);
506
+ return verificationResult;
507
+ }
508
+ /** {@inheritdoc @veramo/credential-w3c#AbstractCredentialProvider.createVerifiablePresentation} */
509
+ async createVerifiablePresentation(args, context) {
510
+ const { presentation, holder } = preProcessPresentation(args);
511
+ let {
512
+ domain,
513
+ challenge,
514
+ keyRef
515
+ /* removeOriginalFields, keyRef, now, ...otherOptions*/
516
+ } = args;
517
+ const agent = assertContext(context).agent;
518
+ const managedIdentifier = await agent.identifierManagedGetByDid({
519
+ identifier: holder,
520
+ kmsKeyRef: keyRef
521
+ });
522
+ const identifier = managedIdentifier.identifier;
523
+ const key = await pickSigningKey({
524
+ identifier: managedIdentifier.identifier,
525
+ kmsKeyRef: managedIdentifier.kmsKeyRef
526
+ }, context);
527
+ debug("Signing VC with", identifier.did);
528
+ let alg = "ES256";
529
+ if (key.type === "Ed25519") {
530
+ alg = "EdDSA";
531
+ } else if (key.type === "Secp256k1") {
532
+ alg = "ES256K";
533
+ }
534
+ const header = {
535
+ kid: key.meta.verificationMethod.id ?? key.kid,
536
+ alg,
537
+ typ: "vp+jwt",
538
+ cty: "vp"
539
+ };
540
+ const payload = {
541
+ ...presentation,
542
+ ...domain && {
543
+ aud: domain
544
+ },
545
+ ...challenge && {
546
+ nonce: challenge
547
+ }
548
+ };
549
+ const jwt = await agent.jwtCreateJwsCompactSignature({
550
+ mode: "did",
551
+ issuer: managedIdentifier,
552
+ payload,
553
+ protectedHeader: header,
554
+ clientIdScheme: "did"
555
+ });
556
+ debug(jwt);
557
+ return normalizePresentation(jwt.jwt);
558
+ }
559
+ /** {@inheritdoc @veramo/credential-w3c#AbstractCredentialProvider.verifyPresentation} */
560
+ async verifyPresentation(args, context) {
561
+ let { presentation, domain, challenge, fetchRemoteContexts, policies, ...otherOptions } = args;
562
+ let jwt;
563
+ if (typeof presentation === "string") {
564
+ jwt = presentation;
565
+ } else {
566
+ jwt = asArray(presentation.proof)[0].jwt;
567
+ }
568
+ const resolver = {
569
+ resolve: /* @__PURE__ */ __name((didUrl) => context.agent.resolveDid({
570
+ didUrl,
571
+ options: otherOptions?.resolutionOptions
572
+ }), "resolve")
573
+ };
574
+ let audience = domain;
575
+ if (!audience) {
576
+ const { payload } = await decodeJWT(jwt);
577
+ if (payload.aud) {
578
+ const intendedAudience = asArray(payload.aud);
579
+ const managedDids = await context.agent.didManagerFind();
580
+ const filtered = managedDids.filter((identifier) => intendedAudience.includes(identifier.did));
581
+ if (filtered.length > 0) {
582
+ audience = filtered[0].did;
583
+ }
584
+ }
585
+ }
586
+ let message, errorCode;
587
+ try {
588
+ const result = await verifyPresentationJWT(jwt, resolver, {
589
+ challenge,
590
+ domain,
591
+ audience,
592
+ policies: {
593
+ ...policies,
594
+ nbf: policies?.nbf ?? policies?.issuanceDate,
595
+ iat: policies?.iat ?? policies?.issuanceDate,
596
+ exp: policies?.exp ?? policies?.expirationDate,
597
+ aud: policies?.aud ?? policies?.audience
598
+ },
599
+ ...otherOptions
600
+ });
601
+ if (result) {
602
+ return {
603
+ verified: true,
604
+ verifiablePresentation: result
605
+ };
606
+ }
607
+ } catch (e) {
608
+ message = e.message;
609
+ errorCode = e.errorCode;
610
+ }
611
+ return {
612
+ verified: false,
613
+ error: {
614
+ message,
615
+ errorCode: errorCode ? errorCode : message?.split(":")[0]
616
+ }
617
+ };
618
+ }
619
+ /**
620
+ * Checks if a key is suitable for signing JWT payloads.
621
+ * @param key - the key to check
622
+ * @param context - the Veramo agent context, unused here
623
+ *
624
+ * @beta
625
+ */
626
+ matchKeyForJWT(key) {
627
+ switch (key.type) {
628
+ case "Ed25519":
629
+ case "Secp256r1":
630
+ return true;
631
+ case "Secp256k1":
632
+ return intersect(key.meta?.algorithms ?? [], [
633
+ "ES256K",
634
+ "ES256K-R"
635
+ ]).length > 0;
636
+ default:
637
+ return false;
638
+ }
639
+ }
640
+ wrapSigner(context, key, algorithm) {
641
+ return async (data) => {
642
+ const result = await context.agent.keyManagerSign({
643
+ keyRef: key.kid,
644
+ data,
645
+ algorithm
646
+ });
647
+ return result;
648
+ };
649
+ }
650
+ };
651
+ async function verifierSignature({ jwt }, verifierContext) {
652
+ let credIssuer = void 0;
653
+ const context = assertContext(verifierContext);
654
+ const agent = context.agent;
655
+ const {
656
+ payload,
657
+ header
658
+ /*signature, data*/
659
+ } = decodeJWT(jwt);
660
+ if (!payload.iss && !payload.client_id) {
661
+ throw new Error(`${JWT_ERROR2.INVALID_JWT}: JWT iss or client_id are required`);
662
+ }
663
+ if (payload.iss === SELF_ISSUED_V2 || payload.iss === SELF_ISSUED_V2_VC_INTEROP) {
664
+ if (!payload.sub) {
665
+ throw new Error(`${JWT_ERROR2.INVALID_JWT}: JWT sub is required`);
666
+ }
667
+ if (typeof payload.sub_jwk === "undefined") {
668
+ credIssuer = payload.sub;
669
+ } else {
670
+ credIssuer = (header.kid || "").split("#")[0];
671
+ }
672
+ } else if (payload.iss === SELF_ISSUED_V0_1) {
673
+ if (!payload.did) {
674
+ throw new Error(`${JWT_ERROR2.INVALID_JWT}: JWT did is required`);
675
+ }
676
+ credIssuer = payload.did;
677
+ } else if (!payload.iss && payload.scope === "openid" && payload.redirect_uri) {
678
+ if (!payload.client_id) {
679
+ throw new Error(`${JWT_ERROR2.INVALID_JWT}: JWT client_id is required`);
680
+ }
681
+ credIssuer = payload.client_id;
682
+ } else if (payload.iss?.indexOf("did:") === 0) {
683
+ credIssuer = payload.iss;
684
+ } else if (header.kid?.indexOf("did:") === 0) {
685
+ credIssuer = (header.kid || "").split("#")[0];
686
+ } else if (payload.iss) {
687
+ credIssuer = payload.iss;
688
+ }
689
+ if (!credIssuer) {
690
+ throw new Error(`${JWT_ERROR2.INVALID_JWT}: No DID has been found in the JWT`);
691
+ }
692
+ const resolution = await agent.identifierExternalResolve({
693
+ identifier: credIssuer
694
+ });
695
+ const didOpts = {
696
+ method: "did",
697
+ identifier: credIssuer
698
+ };
699
+ const jwtResult = await agent.jwtVerifyJwsSignature({
700
+ jws: jwt,
701
+ // @ts-ignore
702
+ jwk: resolution.jwks[0].jwk,
703
+ opts: {
704
+ ...isDidIdentifier(credIssuer) && {
705
+ did: didOpts
706
+ }
707
+ }
708
+ });
709
+ if (jwtResult.error) {
710
+ return {
711
+ verified: false,
712
+ error: {
713
+ message: jwtResult.message,
714
+ errorCode: jwtResult.name
715
+ },
716
+ payload,
717
+ didResolutionResult: resolution,
718
+ jwt
719
+ };
720
+ }
721
+ return {
722
+ verified: true,
723
+ payload,
724
+ didResolutionResult: resolution,
725
+ jwt
726
+ };
727
+ }
728
+ __name(verifierSignature, "verifierSignature");
729
+ function assertContext(context) {
730
+ if (!contextHasPlugin(context, "jwtPrepareJws")) {
731
+ throw Error("JwtService plugin not found, which is required for JWT signing in the VCDM2 Jose credential provider. Please add the JwtService plugin to your agent configuration.");
732
+ } else if (!contextHasPlugin(context, "identifierManagedGet")) {
733
+ throw Error("Identifier resolution plugin not found, which is required for JWT signing in the VCDM2 Jose credential provider. Please add the JwtService plugin to your agent configuration.");
734
+ }
735
+ return context;
736
+ }
737
+ __name(assertContext, "assertContext");
738
+ export {
739
+ CredentialProviderVcdm2Jose
740
+ };
741
+ //# sourceMappingURL=index.js.map