@sphereon/ssi-sdk-ext.jwt-service 0.28.1-feature.jose.vcdm.52 → 0.28.1-feature.oyd.cmsm.improv.20

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.
@@ -1,34 +1,31 @@
1
- import { Loggers } from '@sphereon/ssi-types'
2
- import type { IAgentPlugin } from '@veramo/core'
3
- const logger = Loggers.DEFAULT.get('sphereon:jwt-service')
1
+ import { IAgentPlugin } from '@veramo/core'
2
+ import debug from 'debug'
4
3
  import { importJWK } from 'jose'
5
4
 
6
- // @ts-ignore
7
5
  import * as u8a from 'uint8arrays'
8
- const { fromString } = u8a
9
6
  import {
10
7
  createJwsCompact,
11
- type CreateJwsCompactArgs,
12
- type CreateJwsFlattenedArgs,
13
- type CreateJwsJsonArgs,
8
+ CreateJwsCompactArgs,
9
+ CreateJwsFlattenedArgs,
10
+ CreateJwsJsonArgs,
14
11
  createJwsJsonFlattened,
15
12
  createJwsJsonGeneral,
16
- type DecryptJweCompactJwtArgs,
17
- type EncryptJweCompactJwtArgs,
18
- type IJwsValidationResult,
19
- type IJwtService,
20
- type IRequiredContext,
13
+ DecryptJweCompactJwtArgs,
14
+ EncryptJweCompactJwtArgs,
15
+ IJwsValidationResult,
16
+ IJwtService,
17
+ IRequiredContext,
21
18
  jweAlg,
22
19
  jweEnc,
23
- type JwsJsonFlattened,
24
- type JwsJsonGeneral,
25
- type JwtCompactResult,
20
+ JwsJsonFlattened,
21
+ JwsJsonGeneral,
22
+ JwtCompactResult,
26
23
  JwtLogger,
27
- type PreparedJwsObject,
24
+ PreparedJwsObject,
28
25
  prepareJwsObject,
29
26
  schema,
30
27
  verifyJws,
31
- type VerifyJwsArgs,
28
+ VerifyJwsArgs,
32
29
  } from '..'
33
30
  import { CompactJwtEncrypter } from '../functions/JWE'
34
31
 
@@ -72,7 +69,7 @@ export class JwtService implements IAgentPlugin {
72
69
  const { payload, protectedHeader = { alg: args.alg, enc: args.enc }, recipientKey, issuer, expirationTime, audience } = args
73
70
 
74
71
  try {
75
- logger.debug(`JWE Encrypt: ${JSON.stringify(args, null, 2)}`)
72
+ debug(`JWE Encrypt: ${JSON.stringify(args, null, 2)}`)
76
73
 
77
74
  const alg = jweAlg(args.alg) ?? jweAlg(protectedHeader.alg) ?? 'ECDH-ES'
78
75
  const enc = jweEnc(args.enc) ?? jweEnc(protectedHeader.enc) ?? 'A256GCM'
@@ -91,9 +88,9 @@ export class JwtService implements IAgentPlugin {
91
88
  return Promise.reject(Error(`Currently only ECDH-ES is supported for encryption. JWK alg ${jwkInfo.jwk.kty}, header alg ${alg}`)) // TODO: Probably we support way more already
92
89
  }
93
90
  const apuVal = protectedHeader.apu ?? args.apu
94
- const apu = apuVal ? fromString(apuVal, 'base64url') : undefined
91
+ const apu = apuVal ? u8a.fromString(apuVal, 'base64url') : undefined
95
92
  const apvVal = protectedHeader.apv ?? args.apv
96
- const apv = apvVal ? fromString(apvVal, 'base64url') : undefined
93
+ const apv = apvVal ? u8a.fromString(apvVal, 'base64url') : undefined
97
94
 
98
95
  const pubKey = await importJWK(jwkInfo.jwk)
99
96
  const encrypter = new CompactJwtEncrypter({
@@ -1,24 +1,20 @@
1
- import { defaultRandomSource, randomBytes, type RandomSource } from '@stablelib/random'
1
+ import { defaultRandomSource, randomBytes, RandomSource } from '@stablelib/random'
2
2
  import { base64ToBytes, bytesToBase64url, decodeBase64url } from '@veramo/utils'
3
3
  import * as jose from 'jose'
4
- import type { JWEKeyManagementHeaderParameters, JWTDecryptOptions } from 'jose'
5
- // // @ts-ignore
6
- // import type { KeyLike } from 'jose/dist/types/types'
7
- export type KeyLike = { type: string }
8
- // @ts-ignore
4
+ import { JWEKeyManagementHeaderParameters, JWTDecryptOptions } from 'jose'
5
+ import type { KeyLike } from 'jose/dist/types/types'
9
6
  import * as u8a from 'uint8arrays'
10
- const { fromString, toString, concat } = u8a
11
7
  import {
12
- type JweAlg,
8
+ JweAlg,
13
9
  JweAlgs,
14
- type JweEnc,
10
+ JweEnc,
15
11
  JweEncs,
16
- type JweHeader,
17
- type JweJsonGeneral,
18
- type JweProtectedHeader,
19
- type JweRecipient,
20
- type JweRecipientUnprotectedHeader,
21
- type JwsPayload,
12
+ JweHeader,
13
+ JweJsonGeneral,
14
+ JweProtectedHeader,
15
+ JweRecipient,
16
+ JweRecipientUnprotectedHeader,
17
+ JwsPayload,
22
18
  } from '../types/IJwtService'
23
19
 
24
20
  export interface EncryptionResult {
@@ -241,7 +237,7 @@ export class CompactJwtEncrypter implements JweEncrypter {
241
237
  }
242
238
 
243
239
  async encrypt(payload: Uint8Array, jweProtectedHeader: JweProtectedHeader, aad?: Uint8Array | undefined): Promise<EncryptionResult> {
244
- const jwt = await this.encryptCompactJWT(JSON.parse(toString(payload)), jweProtectedHeader, aad)
240
+ const jwt = await this.encryptCompactJWT(JSON.parse(u8a.toString(payload)), jweProtectedHeader, aad)
245
241
  const [protectedHeader, encryptedKey, ivB64, payloadB64, tagB64] = jwt.split('.')
246
242
  //[jwe.protected, jwe.encrypted_key, jwe.iv, jwe.ciphertext, jwe.tag].join('.');
247
243
  console.log(`FIXME: TO EncryptionResult`)
@@ -339,7 +335,7 @@ export async function decryptJwe(jwe: JweJsonGeneral, decrypter: JweDecrypter):
339
335
  return Promise.reject(Error(`Decrypter enc '${decrypter.enc}' does not support header enc '${protectedHeader.enc}'`))
340
336
  }
341
337
  const sealed = toWebCryptoCiphertext(jwe.ciphertext, jwe.tag)
342
- const aad = fromString(jwe.aad ? `${jwe.protected}.${jwe.aad}` : jwe.protected)
338
+ const aad = u8a.fromString(jwe.aad ? `${jwe.protected}.${jwe.aad}` : jwe.protected)
343
339
  let cleartext = null
344
340
  if (protectedHeader.alg === 'dir' && decrypter.alg === 'dir') {
345
341
  cleartext = await decrypter.decrypt(sealed, base64ToBytes(jwe.iv), aad)
@@ -359,5 +355,5 @@ export async function decryptJwe(jwe: JweJsonGeneral, decrypter: JweDecrypter):
359
355
  }
360
356
 
361
357
  export function toWebCryptoCiphertext(ciphertext: string, tag: string): Uint8Array {
362
- return concat([base64ToBytes(ciphertext), base64ToBytes(tag)])
358
+ return u8a.concat([base64ToBytes(ciphertext), base64ToBytes(tag)])
363
359
  }
@@ -1,28 +1,28 @@
1
- import { jwkTtoPublicKeyHex } from '@sphereon/ssi-sdk-ext.did-utils'
2
1
  import {
3
2
  ensureManagedIdentifierResult,
4
- type ExternalIdentifierDidOpts,
5
- type ExternalIdentifierX5cOpts,
6
- type IIdentifierResolution,
3
+ ExternalIdentifierDidOpts,
4
+ ExternalIdentifierX5cOpts,
5
+ IIdentifierResolution,
7
6
  isManagedIdentifierDidResult,
8
7
  isManagedIdentifierX5cResult,
9
- type ManagedIdentifierMethod,
10
- type ManagedIdentifierResult,
8
+ ManagedIdentifierMethod,
9
+ ManagedIdentifierResult,
11
10
  resolveExternalJwkIdentifier,
12
11
  } from '@sphereon/ssi-sdk-ext.identifier-resolution'
13
- import { keyTypeFromCryptographicSuite, signatureAlgorithmFromKeyType, verifyRawSignature } from '@sphereon/ssi-sdk-ext.key-utils'
14
- import { contextHasPlugin } from '@sphereon/ssi-sdk.agent-config'
15
- import type { JoseSignatureAlgorithm, JWK } from '@sphereon/ssi-types'
16
- import type { IAgentContext } from '@veramo/core'
12
+ import { verifyRawSignature } from '@sphereon/ssi-sdk-ext.key-utils'
13
+ import { JWK } from '@sphereon/ssi-types'
14
+ import { IAgentContext } from '@veramo/core'
17
15
  import { base64ToBytes, bytesToBase64url, decodeJoseBlob, encodeJoseBlob } from '@veramo/utils'
18
- // @ts-ignore
19
16
  import * as u8a from 'uint8arrays'
20
- import type {
17
+ import {
21
18
  CreateJwsCompactArgs,
22
19
  CreateJwsFlattenedArgs,
23
20
  CreateJwsJsonArgs,
24
21
  IJwsValidationResult,
25
22
  IRequiredContext,
23
+ isJwsCompact,
24
+ isJwsJsonFlattened,
25
+ isJwsJsonGeneral,
26
26
  JweHeader,
27
27
  Jws,
28
28
  JwsCompact,
@@ -37,14 +37,11 @@ import type {
37
37
  PreparedJwsObject,
38
38
  VerifyJwsArgs,
39
39
  } from '../types/IJwtService'
40
- import { isJwsCompact, isJwsJsonFlattened, isJwsJsonGeneral } from '../types/IJwtService'
41
-
42
- const { fromString } = u8a
43
40
 
44
41
  const payloadToBytes = (payload: string | JwsPayload | Uint8Array): Uint8Array => {
45
42
  const isBytes = payload instanceof Uint8Array
46
43
  const isString = typeof payload === 'string'
47
- return isBytes ? payload : isString ? fromString(payload, 'base64url') : fromString(JSON.stringify(payload), 'utf-8')
44
+ return isBytes ? payload : isString ? u8a.fromString(payload, 'base64url') : u8a.fromString(JSON.stringify(payload), 'utf-8')
48
45
  }
49
46
 
50
47
  export const prepareJwsObject = async (args: CreateJwsJsonArgs, context: IRequiredContext): Promise<PreparedJwsObject> => {
@@ -114,15 +111,11 @@ export const createJwsJsonGeneral = async (args: CreateJwsJsonArgs, context: IRe
114
111
  },
115
112
  context
116
113
  )
117
-
118
- const alg: string | undefined = protectedHeader.alg ?? signatureAlgorithmFromKeyType({ type: identifier.key.type })
119
-
120
114
  // const algorithm = await signatureAlgorithmFromKey({ key: identifier.key })
121
115
  const signature = await context.agent.keyManagerSign({
122
116
  keyRef: identifier.kmsKeyRef,
123
117
  data: `${b64.protectedHeader}.${b64.payload}`,
124
118
  encoding: undefined,
125
- algorithm: alg,
126
119
  })
127
120
  const jsonSignature = {
128
121
  protected: b64.protectedHeader,
@@ -158,8 +151,6 @@ export const checkAndUpdateJwsHeader = async (
158
151
  },
159
152
  context: IRequiredContext
160
153
  ) => {
161
- // Make sure we have an alg in the header (https://datatracker.ietf.org/doc/html/rfc7515#section-4.1.1)
162
- header.alg = header.alg ?? signatureAlgorithmFromKeyType({ type: identifier.key.type })
163
154
  if (isIdentifierMode(mode, identifier.method, 'did')) {
164
155
  // kid is VM of the DID
165
156
  // @see https://datatracker.ietf.org/doc/html/rfc7515#section-4.1.4
@@ -321,31 +312,25 @@ export const verifyJws = async (args: VerifyJwsArgs, context: IAgentContext<IIde
321
312
  // If we have a specific KMS agent plugin that can do the verification prefer that over the generic verification
322
313
  index++
323
314
  let valid: boolean
324
- const data = fromString(`${sigWithId.protected}.${jws.payload}`, 'utf-8')
315
+ const data = u8a.fromString(`${sigWithId.protected}.${jws.payload}`, 'utf-8')
325
316
  const jwkInfo = sigWithId.identifier.jwks[0]
326
- let signatureAlg: JoseSignatureAlgorithm | undefined = undefined
327
- if (sigWithId.protected.startsWith(`ey`)) {
328
- const header = decodeJoseBlob(sigWithId.protected)
329
- signatureAlg = header.alg as JoseSignatureAlgorithm | undefined
330
- }
331
-
332
- if (false && signatureAlg?.startsWith('PS') && contextHasPlugin(context, 'keyManagerVerify')) {
317
+ /* if (sigWithId.header?.alg === 'RSA' && contextHasPlugin(context, 'keyManagerVerify')) {
333
318
  const publicKeyHex = jwkTtoPublicKeyHex(jwkInfo.jwk)
334
319
  valid = await context.agent.keyManagerVerify({
335
320
  signature: sigWithId.signature,
336
321
  data,
337
322
  publicKeyHex,
338
- type: keyTypeFromCryptographicSuite({ ...(jwkInfo.jwk.crv && { crv: jwkInfo.jwk.crv }), alg: signatureAlg as string }),
323
+ type: keyTypeFromCryptographicSuite({ crv: jwkInfo.jwk.crv ?? 'ES256' }),
339
324
  // no kms arg, as the current key manager needs a bit more work
340
325
  })
341
- } else {
342
- const signature = base64ToBytes(sigWithId.signature)
343
- valid = await verifyRawSignature({ data, signature, key: jwkInfo.jwk, opts: { signatureAlg: signatureAlg } })
344
- // }
345
- }
326
+ } else {*/
327
+ const signature = base64ToBytes(sigWithId.signature)
328
+ valid = await verifyRawSignature({ data, signature, key: jwkInfo.jwk })
329
+ // }
346
330
  if (!valid) {
347
331
  errorMessages.push(`Signature ${index} was not valid`)
348
332
  }
333
+
349
334
  return {
350
335
  sigWithId,
351
336
  valid,
@@ -1,4 +1,4 @@
1
- import type {
1
+ import {
2
2
  ExternalIdentifierDidOpts,
3
3
  ExternalIdentifierResult,
4
4
  ExternalIdentifierX5cOpts,
@@ -6,9 +6,9 @@ import type {
6
6
  ManagedIdentifierOptsOrResult,
7
7
  ManagedIdentifierResult,
8
8
  } from '@sphereon/ssi-sdk-ext.identifier-resolution'
9
- import type { ClientIdScheme } from '@sphereon/ssi-sdk-ext.x509-utils'
10
- import type { BaseJWK, IValidationResult, JoseSignatureAlgorithm, JoseSignatureAlgorithmString, JWK } from '@sphereon/ssi-types'
11
- import type { IAgentContext, IKeyManager, IPluginMethodMap } from '@veramo/core'
9
+ import { ClientIdScheme } from '@sphereon/ssi-sdk-ext.x509-utils'
10
+ import { BaseJWK, IValidationResult, JoseSignatureAlgorithm, JoseSignatureAlgorithmString, JWK } from '@sphereon/ssi-types'
11
+ import { IAgentContext, IKeyManager, IPluginMethodMap } from '@veramo/core'
12
12
 
13
13
  export type IRequiredContext = IAgentContext<IIdentifierResolution & IKeyManager> // could we still interop with Veramo?
14
14