@sphereon/ssi-sdk.credential-vcdm2-jose-provider 0.33.1-feature.jose.vcdm.61 → 0.33.1-feature.jose.vcdm.63

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.
@@ -5,7 +5,6 @@ import { decodeBase64url, type EcdsaSignature, encodeBase64url, type KNOWN_JWA,
5
5
  import VerifierAlgorithm from './VerifierAlgorithm'
6
6
  import { JWT_ERROR } from 'did-jwt'
7
7
 
8
-
9
8
  export type Signer = (data: string | Uint8Array) => Promise<EcdsaSignature | string>
10
9
  export type SignerAlgorithm = (payload: string, signer: Signer) => Promise<string>
11
10
 
@@ -221,7 +220,7 @@ export async function createJWS(
221
220
  payload: string | Partial<JWTPayload>,
222
221
  signer: Signer,
223
222
  header: Partial<JWTHeader> = {},
224
- options: JWSCreationOptions = {}
223
+ options: JWSCreationOptions = {},
225
224
  ): Promise<string> {
226
225
  if (!header.alg) header.alg = defaultAlg
227
226
  const encodedPayload = typeof payload === 'string' ? payload : encodeSection(payload, options.canonicalize)
@@ -259,7 +258,7 @@ export async function createJWS(
259
258
  export async function createJWT(
260
259
  payload: Partial<JWTPayload>,
261
260
  { issuer, signer, alg, expiresIn, canonicalize }: JWTOptions,
262
- header: Partial<JWTHeader> = {}
261
+ header: Partial<JWTHeader> = {},
263
262
  ): Promise<string> {
264
263
  if (!signer) throw new Error('missing_signer: No Signer functionality has been configured')
265
264
  if (!issuer) throw new Error('missing_issuer: No issuing DID has been configured')
@@ -305,7 +304,7 @@ export async function createJWT(
305
304
  export async function createMultisignatureJWT(
306
305
  payload: Partial<JWTPayload>,
307
306
  { expiresIn, canonicalize }: Partial<JWTOptions>,
308
- issuers: { issuer: string; signer: Signer; alg: string }[]
307
+ issuers: { issuer: string; signer: Signer; alg: string }[],
309
308
  ): Promise<string> {
310
309
  if (issuers.length === 0) throw new Error('invalid_argument: must provide one or more issuers')
311
310
 
@@ -337,7 +336,7 @@ export async function createMultisignatureJWT(
337
336
 
338
337
  export function verifyJWTDecoded(
339
338
  { header, payload, data, signature }: JWTDecoded,
340
- pubKeys: VerificationMethod | VerificationMethod[]
339
+ pubKeys: VerificationMethod | VerificationMethod[],
341
340
  ): VerificationMethod {
342
341
  if (!Array.isArray(pubKeys)) pubKeys = [pubKeys]
343
342
 
@@ -365,10 +364,7 @@ export function verifyJWTDecoded(
365
364
  throw new Error(`${JWT_ERROR.INVALID_SIGNATURE}: no matching public key found`)
366
365
  }
367
366
 
368
- export function verifyJWSDecoded(
369
- { header, data, signature }: JWSDecoded,
370
- pubKeys: VerificationMethod | VerificationMethod[]
371
- ): VerificationMethod {
367
+ export function verifyJWSDecoded({ header, data, signature }: JWSDecoded, pubKeys: VerificationMethod | VerificationMethod[]): VerificationMethod {
372
368
  if (!Array.isArray(pubKeys)) pubKeys = [pubKeys]
373
369
  const signer: VerificationMethod = VerifierAlgorithm(header.alg)(data, signature, pubKeys)
374
370
  return signer
@@ -429,10 +425,10 @@ export async function verifyJWT(
429
425
  proofPurpose: undefined,
430
426
  policies: {},
431
427
  didAuthenticator: undefined,
432
- }
428
+ },
433
429
  ): Promise<JWTVerified> {
434
430
  if (!options.resolver) throw new Error('missing_resolver: No DID resolver has been configured')
435
- const { payload, header/*, signature, data*/ }: JWTDecoded = decodeJWT(jwt, false)
431
+ const { payload, header /*, signature, data*/ }: JWTDecoded = decodeJWT(jwt, false)
436
432
  const proofPurpose: ProofPurposeTypes | undefined = Object.prototype.hasOwnProperty.call(options, 'auth')
437
433
  ? options.auth
438
434
  ? 'authentication'
@@ -482,12 +478,7 @@ export async function verifyJWT(
482
478
  if (options.didAuthenticator) {
483
479
  ;({ didResolutionResult, authenticators, issuer } = options.didAuthenticator)
484
480
  } else {
485
- ;({ didResolutionResult, authenticators, issuer } = await resolveAuthenticator(
486
- options.resolver,
487
- header.alg,
488
- didUrl,
489
- proofPurpose
490
- ))
481
+ ;({ didResolutionResult, authenticators, issuer } = await resolveAuthenticator(options.resolver, header.alg, didUrl, proofPurpose))
491
482
  // Add to options object for recursive reference
492
483
  options.didAuthenticator = { didResolutionResult, authenticators, issuer }
493
484
  }
@@ -534,9 +525,7 @@ export async function verifyJWT(
534
525
  }
535
526
  if (options.policies?.aud !== false && payload.aud) {
536
527
  if (!options.audience && !options.callbackUrl) {
537
- throw new Error(
538
- `${JWT_ERROR.INVALID_AUDIENCE}: JWT audience is required but your app address has not been configured`
539
- )
528
+ throw new Error(`${JWT_ERROR.INVALID_AUDIENCE}: JWT audience is required but your app address has not been configured`)
540
529
  }
541
530
  const audArray = Array.isArray(payload.aud) ? payload.aud : [payload.aud]
542
531
  const matchedAudience = audArray.find((item) => options.audience === item || options.callbackUrl === item)
@@ -549,7 +538,7 @@ export async function verifyJWT(
549
538
  return { verified: true, payload, didResolutionResult, issuer, signer, jwt, policies: options.policies }
550
539
  }
551
540
  throw new Error(
552
- `${JWT_ERROR.INVALID_SIGNATURE}: JWT not valid. issuer DID document does not contain a verificationMethod that matches the signature.`
541
+ `${JWT_ERROR.INVALID_SIGNATURE}: JWT not valid. issuer DID document does not contain a verificationMethod that matches the signature.`,
553
542
  )
554
543
  }
555
544
 
@@ -579,7 +568,7 @@ export async function resolveAuthenticator(
579
568
  resolver: Resolvable,
580
569
  alg: string,
581
570
  issuer: string,
582
- proofPurpose?: ProofPurposeTypes
571
+ proofPurpose?: ProofPurposeTypes,
583
572
  ): Promise<DIDAuthenticator> {
584
573
  const types: string[] = SUPPORTED_PUBLIC_KEY_TYPES[alg as KNOWN_JWA]
585
574
  if (!types || types.length === 0) {
@@ -601,9 +590,7 @@ export async function resolveAuthenticator(
601
590
 
602
591
  if (didResult.didResolutionMetadata?.error || didResult.didDocument == null) {
603
592
  const { error, message } = didResult.didResolutionMetadata
604
- throw new Error(
605
- `${JWT_ERROR.RESOLVER_ERROR}: Unable to resolve DID document for ${issuer}: ${error}, ${message || ''}`
606
- )
593
+ throw new Error(`${JWT_ERROR.RESOLVER_ERROR}: Unable to resolve DID document for ${issuer}: ${error}, ${message || ''}`)
607
594
  }
608
595
 
609
596
  const getPublicKeyById = (verificationMethods: VerificationMethod[], pubid?: string): VerificationMethod | null => {
@@ -611,16 +598,10 @@ export async function resolveAuthenticator(
611
598
  return filtered.length > 0 ? filtered[0] : null
612
599
  }
613
600
 
614
- let publicKeysToCheck: VerificationMethod[] = [
615
- ...(didResult?.didDocument?.verificationMethod || []),
616
- ...(didResult?.didDocument?.publicKey || []),
617
- ]
601
+ let publicKeysToCheck: VerificationMethod[] = [...(didResult?.didDocument?.verificationMethod || []), ...(didResult?.didDocument?.publicKey || [])]
618
602
  if (typeof proofPurpose === 'string') {
619
603
  // support legacy DID Documents that do not list assertionMethod
620
- if (
621
- proofPurpose.startsWith('assertion') &&
622
- !Object.getOwnPropertyNames(didResult?.didDocument).includes('assertionMethod')
623
- ) {
604
+ if (proofPurpose.startsWith('assertion') && !Object.getOwnPropertyNames(didResult?.didDocument).includes('assertionMethod')) {
624
605
  didResult.didDocument = { ...(<DIDDocument>didResult.didDocument) }
625
606
  didResult.didDocument.assertionMethod = [...publicKeysToCheck.map((pk) => pk.id)]
626
607
  }
@@ -639,13 +620,11 @@ export async function resolveAuthenticator(
639
620
  .filter((key) => key != null) as VerificationMethod[]
640
621
  }
641
622
 
642
- const authenticators: VerificationMethod[] = publicKeysToCheck.filter(({ type }) =>
643
- types.find((supported) => supported === type)
644
- )
623
+ const authenticators: VerificationMethod[] = publicKeysToCheck.filter(({ type }) => types.find((supported) => supported === type))
645
624
 
646
625
  if (typeof proofPurpose === 'string' && (!authenticators || authenticators.length === 0)) {
647
626
  throw new Error(
648
- `${JWT_ERROR.NO_SUITABLE_KEYS}: DID document for ${issuer} does not have public keys suitable for ${alg} with ${proofPurpose} purpose`
627
+ `${JWT_ERROR.NO_SUITABLE_KEYS}: DID document for ${issuer} does not have public keys suitable for ${alg} with ${proofPurpose} purpose`,
649
628
  )
650
629
  }
651
630
  if (!authenticators || authenticators.length === 0) {
@@ -1,14 +1,6 @@
1
1
  import { toEthereumAddress } from 'did-jwt'
2
2
  import type { VerificationMethod } from 'did-resolver'
3
- import {
4
- base64ToBytes,
5
- bytesToHex,
6
- type EcdsaSignature,
7
- type ECDSASignature,
8
- extractPublicKeyBytes,
9
- type KNOWN_JWA,
10
- stringToBytes,
11
- } from './util'
3
+ import { base64ToBytes, bytesToHex, type EcdsaSignature, type ECDSASignature, extractPublicKeyBytes, type KNOWN_JWA, stringToBytes } from './util'
12
4
  // @ts-ignore
13
5
  // import { verifyBlockchainAccountId } from 'did-jwt'
14
6
  import { secp256k1 } from '@noble/curves/secp256k1'
@@ -66,11 +58,7 @@ export function verifyES256(data: string, signature: string, authenticators: Ver
66
58
  return signer
67
59
  }
68
60
 
69
- export function verifyES256K(
70
- data: string,
71
- signature: string,
72
- authenticators: VerificationMethod[]
73
- ): VerificationMethod {
61
+ export function verifyES256K(data: string, signature: string, authenticators: VerificationMethod[]): VerificationMethod {
74
62
  const hash = sha256(data)
75
63
  const signatureNormalized = secp256k1.Signature.fromCompact(base64ToBytes(signature)).normalizeS()
76
64
  const fullPublicKeys = authenticators.filter((a: VerificationMethod) => {
@@ -97,11 +85,7 @@ export function verifyES256K(
97
85
  return signer
98
86
  }
99
87
 
100
- export function verifyRecoverableES256K(
101
- data: string,
102
- signature: string,
103
- authenticators: VerificationMethod[]
104
- ): VerificationMethod {
88
+ export function verifyRecoverableES256K(data: string, signature: string, authenticators: VerificationMethod[]): VerificationMethod {
105
89
  const signatures: ECDSASignature[] = []
106
90
  if (signature.length > 86) {
107
91
  signatures.push(toSignatureObject2(signature, true))
@@ -141,11 +125,7 @@ export function verifyRecoverableES256K(
141
125
  throw new Error('invalid_signature: Signature invalid for JWT')
142
126
  }
143
127
 
144
- export function verifyEd25519(
145
- data: string,
146
- signature: string,
147
- authenticators: VerificationMethod[]
148
- ): VerificationMethod {
128
+ export function verifyEd25519(data: string, signature: string, authenticators: VerificationMethod[]): VerificationMethod {
149
129
  const clear = stringToBytes(data)
150
130
  const signatureBytes = base64ToBytes(signature)
151
131
  const signer = authenticators.find((a: VerificationMethod) => {
@@ -12,8 +12,6 @@ import { p256 } from '@noble/curves/p256'
12
12
 
13
13
  // const u8a = { toString, fromString, concat }
14
14
 
15
-
16
-
17
15
  export interface EphemeralPublicKey {
18
16
  kty?: string
19
17
  //ECC
@@ -148,20 +146,8 @@ export const SUPPORTED_PUBLIC_KEY_TYPES: PublicKeyTypes = {
148
146
  'JsonWebKey2020',
149
147
  'Multikey',
150
148
  ],
151
- Ed25519: [
152
- 'ED25519SignatureVerification',
153
- 'Ed25519VerificationKey2018',
154
- 'Ed25519VerificationKey2020',
155
- 'JsonWebKey2020',
156
- 'Multikey',
157
- ],
158
- EdDSA: [
159
- 'ED25519SignatureVerification',
160
- 'Ed25519VerificationKey2018',
161
- 'Ed25519VerificationKey2020',
162
- 'JsonWebKey2020',
163
- 'Multikey',
164
- ],
149
+ Ed25519: ['ED25519SignatureVerification', 'Ed25519VerificationKey2018', 'Ed25519VerificationKey2020', 'JsonWebKey2020', 'Multikey'],
150
+ EdDSA: ['ED25519SignatureVerification', 'Ed25519VerificationKey2018', 'Ed25519VerificationKey2020', 'JsonWebKey2020', 'Multikey'],
165
151
  }
166
152
 
167
153
  export const VM_TO_KEY_TYPE: Record<KNOWN_VERIFICATION_METHOD, KNOWN_KEY_TYPE | undefined> = {
@@ -181,13 +167,7 @@ export const VM_TO_KEY_TYPE: Record<KNOWN_VERIFICATION_METHOD, KNOWN_KEY_TYPE |
181
167
  Multikey: undefined, // key type must be extracted from the multicodec
182
168
  }
183
169
 
184
- export type KNOWN_CODECS =
185
- | 'ed25519-pub'
186
- | 'x25519-pub'
187
- | 'secp256k1-pub'
188
- | 'bls12_381-g1-pub'
189
- | 'bls12_381-g2-pub'
190
- | 'p256-pub'
170
+ export type KNOWN_CODECS = 'ed25519-pub' | 'x25519-pub' | 'secp256k1-pub' | 'bls12_381-g1-pub' | 'bls12_381-g2-pub' | 'p256-pub'
191
171
 
192
172
  // this is from the multicodec table https://github.com/multiformats/multicodec/blob/master/table.csv
193
173
  export const supportedCodecs: Record<KNOWN_CODECS, number> = {
@@ -242,12 +222,7 @@ export function extractPublicKeyBytes(pk: VerificationMethod): { keyBytes: Uint8
242
222
  }).toRawBytes(false),
243
223
  keyType: 'P-256',
244
224
  }
245
- } else if (
246
- pk.publicKeyJwk &&
247
- pk.publicKeyJwk.kty === 'OKP' &&
248
- ['Ed25519', 'X25519'].includes(pk.publicKeyJwk.crv ?? '') &&
249
- pk.publicKeyJwk.x
250
- ) {
225
+ } else if (pk.publicKeyJwk && pk.publicKeyJwk.kty === 'OKP' && ['Ed25519', 'X25519'].includes(pk.publicKeyJwk.crv ?? '') && pk.publicKeyJwk.x) {
251
226
  return { keyBytes: base64ToBytes(pk.publicKeyJwk.x), keyType: pk.publicKeyJwk.crv as KNOWN_KEY_TYPE }
252
227
  } else if (pk.publicKeyMultibase) {
253
228
  const { keyBytes, keyType } = multibaseToBytes(pk.publicKeyMultibase)
@@ -268,11 +243,7 @@ export function extractPublicKeyBytes(pk: VerificationMethod): { keyBytes: Uint8
268
243
  *
269
244
  * @public
270
245
  */
271
- export function bytesToMultibase(
272
- b: Uint8Array,
273
- base: BaseName = 'base58btc',
274
- codec?: keyof typeof supportedCodecs | number
275
- ): string {
246
+ export function bytesToMultibase(b: Uint8Array, base: BaseName = 'base58btc', codec?: keyof typeof supportedCodecs | number): string {
276
247
  if (!codec) {
277
248
  return u8a.toString(encode(base, b), 'utf-8')
278
249
  } else {
@@ -308,8 +279,7 @@ export function multibaseToBytes(s: string): { keyBytes: Uint8Array; keyType?: K
308
279
  try {
309
280
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
310
281
  const [codec, length] = varint.decode(bytes)
311
- const possibleCodec: string | undefined =
312
- Object.entries(supportedCodecs).filter(([, code]) => code === codec)?.[0][0] ?? ''
282
+ const possibleCodec: string | undefined = Object.entries(supportedCodecs).filter(([, code]) => code === codec)?.[0][0] ?? ''
313
283
  return { keyBytes: bytes.slice(length), keyType: CODEC_TO_KEY_TYPE[possibleCodec as KNOWN_CODECS] }
314
284
  } catch (e) {
315
285
  // not a multicodec, return the bytes