@sphereon/ssi-sdk-ext.identifier-resolution 0.24.1-unstable.93 → 0.25.1-feature.SDK.41.oidf.support.11

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.
Files changed (54) hide show
  1. package/dist/agent/IdentifierResolution.d.ts +5 -0
  2. package/dist/agent/IdentifierResolution.d.ts.map +1 -1
  3. package/dist/agent/IdentifierResolution.js +31 -1
  4. package/dist/agent/IdentifierResolution.js.map +1 -1
  5. package/dist/functions/LegacySupport.d.ts +12 -0
  6. package/dist/functions/LegacySupport.d.ts.map +1 -0
  7. package/dist/functions/LegacySupport.js +39 -0
  8. package/dist/functions/LegacySupport.js.map +1 -0
  9. package/dist/functions/externalIdentifierFunctions.d.ts +17 -1
  10. package/dist/functions/externalIdentifierFunctions.d.ts.map +1 -1
  11. package/dist/functions/externalIdentifierFunctions.js +89 -6
  12. package/dist/functions/externalIdentifierFunctions.js.map +1 -1
  13. package/dist/functions/externalOIDFIdentifier.d.ts +19 -0
  14. package/dist/functions/externalOIDFIdentifier.d.ts.map +1 -0
  15. package/dist/functions/externalOIDFIdentifier.js +84 -0
  16. package/dist/functions/externalOIDFIdentifier.js.map +1 -0
  17. package/dist/functions/index.d.ts +2 -11
  18. package/dist/functions/index.d.ts.map +1 -1
  19. package/dist/functions/index.js +2 -36
  20. package/dist/functions/index.js.map +1 -1
  21. package/dist/functions/managedIdentifierFunctions.d.ts +17 -3
  22. package/dist/functions/managedIdentifierFunctions.d.ts.map +1 -1
  23. package/dist/functions/managedIdentifierFunctions.js +134 -12
  24. package/dist/functions/managedIdentifierFunctions.js.map +1 -1
  25. package/dist/tsdoc-metadata.json +1 -1
  26. package/dist/types/IIdentifierResolution.d.ts +14 -3
  27. package/dist/types/IIdentifierResolution.d.ts.map +1 -1
  28. package/dist/types/IIdentifierResolution.js +18 -0
  29. package/dist/types/IIdentifierResolution.js.map +1 -1
  30. package/dist/types/common.d.ts +4 -1
  31. package/dist/types/common.d.ts.map +1 -1
  32. package/dist/types/common.js +21 -10
  33. package/dist/types/common.js.map +1 -1
  34. package/dist/types/externalIdentifierTypes.d.ts +38 -6
  35. package/dist/types/externalIdentifierTypes.d.ts.map +1 -1
  36. package/dist/types/externalIdentifierTypes.js +16 -7
  37. package/dist/types/externalIdentifierTypes.js.map +1 -1
  38. package/dist/types/managedIdentifierTypes.d.ts +43 -15
  39. package/dist/types/managedIdentifierTypes.d.ts.map +1 -1
  40. package/dist/types/managedIdentifierTypes.js +24 -11
  41. package/dist/types/managedIdentifierTypes.js.map +1 -1
  42. package/package.json +13 -12
  43. package/plugin.schema.json +2652 -281
  44. package/src/agent/IdentifierResolution.ts +71 -11
  45. package/src/functions/LegacySupport.ts +54 -0
  46. package/src/functions/externalIdentifierFunctions.ts +101 -6
  47. package/src/functions/externalOIDFIdentifier.ts +95 -0
  48. package/src/functions/index.ts +2 -51
  49. package/src/functions/managedIdentifierFunctions.ts +162 -14
  50. package/src/types/IIdentifierResolution.ts +47 -3
  51. package/src/types/IJwtService.d.ts +226 -0
  52. package/src/types/common.ts +14 -2
  53. package/src/types/externalIdentifierTypes.ts +76 -12
  54. package/src/types/managedIdentifierTypes.ts +78 -16
@@ -1,6 +1,6 @@
1
1
  import { IAgentContext, IAgentPlugin, IDIDManager, IKeyManager } from '@veramo/core'
2
- import { ManagedIdentifierKeyOpts, ManagedIdentifierKeyResult, schema } from '..'
3
- import { getManagedIdentifier, resolveExternalIdentifier } from '../functions'
2
+ import { ExternalIdentifierOIDFEntityIdOpts, ExternalIdentifierOIDFEntityIdResult, schema } from '..'
3
+ import { resolveExternalIdentifier, ensureManagedIdentifierResult } from '../functions'
4
4
  import {
5
5
  ExternalIdentifierDidOpts,
6
6
  ExternalIdentifierDidResult,
@@ -8,18 +8,29 @@ import {
8
8
  ExternalIdentifierResult,
9
9
  ExternalIdentifierX5cOpts,
10
10
  ExternalIdentifierX5cResult,
11
+ ExternalIdentifierCoseKeyOpts,
12
+ ExternalIdentifierCoseKeyResult,
13
+ ExternalIdentifierJwkOpts,
14
+ ExternalIdentifierJwkResult,
11
15
  IIdentifierResolution,
16
+ ManagedIdentifierCoseKeyOpts,
17
+ ManagedIdentifierCoseKeyResult,
12
18
  ManagedIdentifierDidOpts,
13
19
  ManagedIdentifierDidResult,
14
20
  ManagedIdentifierJwkOpts,
15
21
  ManagedIdentifierJwkResult,
16
22
  ManagedIdentifierKidOpts,
17
23
  ManagedIdentifierKidResult,
18
- ManagedIdentifierOpts,
19
24
  ManagedIdentifierResult,
20
25
  ManagedIdentifierX5cOpts,
21
26
  ManagedIdentifierX5cResult,
27
+ ManagedIdentifierOID4VCIssuerResult,
28
+ ManagedIdentifierKeyOpts,
29
+ ManagedIdentifierKeyResult,
30
+ ManagedIdentifierOptsOrResult,
31
+ ManagedIdentifierOID4VCIssuerOpts
22
32
  } from '../types'
33
+ import { IOIDFClient } from '@sphereon/ssi-sdk.oidf-client'
23
34
 
24
35
  /**
25
36
  * @public
@@ -35,10 +46,15 @@ export class IdentifierResolution implements IAgentPlugin {
35
46
  identifierManagedGetByJwk: this.identifierGetManagedByJwk.bind(this),
36
47
  identifierManagedGetByX5c: this.identifierGetManagedByX5c.bind(this),
37
48
  identifierManagedGetByKey: this.identifierGetManagedByKey.bind(this),
49
+ identifierManagedGetByCoseKey: this.identifierGetManagedByCoseKey.bind(this),
50
+ identifierManagedGetByOID4VCIssuer: this.identifierGetManagedByOID4VCIssuer.bind(this),
38
51
 
39
52
  identifierExternalResolve: this.identifierResolveExternal.bind(this),
40
53
  identifierExternalResolveByDid: this.identifierExternalResolveByDid.bind(this),
41
54
  identifierExternalResolveByX5c: this.identifierExternalResolveByX5c.bind(this),
55
+ identifierExternalResolveByJwk: this.identifierExternalResolveByJwk.bind(this),
56
+ identifierExternalResolveByCoseKey: this.identifierExternalResolveByCoseKey.bind(this),
57
+ identifierExternalResolveByOIDFEntityId: this.identifierExternalResolveByOIDFEntityId.bind(this),
42
58
 
43
59
  // todo: JWKSet, oidc-discovery, oid4vci-issuer etc. Anything we already can resolve and need keys of
44
60
  }
@@ -57,34 +73,63 @@ export class IdentifierResolution implements IAgentPlugin {
57
73
  * @param context
58
74
  * @private
59
75
  */
60
- private async identifierGetManaged(args: ManagedIdentifierOpts, context: IAgentContext<IKeyManager>): Promise<ManagedIdentifierResult> {
61
- return await getManagedIdentifier({ ...args, crypto: this._crypto }, context)
76
+ private async identifierGetManaged(
77
+ args: ManagedIdentifierOptsOrResult,
78
+ context: IAgentContext<IKeyManager & IIdentifierResolution>
79
+ ): Promise<ManagedIdentifierResult> {
80
+ return await ensureManagedIdentifierResult({ ...args, crypto: this._crypto }, context)
62
81
  }
63
82
 
64
83
  private async identifierGetManagedByDid(
65
84
  args: ManagedIdentifierDidOpts,
66
- context: IAgentContext<IKeyManager & IDIDManager>
85
+ context: IAgentContext<IKeyManager & IDIDManager & IIdentifierResolution>
67
86
  ): Promise<ManagedIdentifierDidResult> {
68
87
  return (await this.identifierGetManaged({ ...args, method: 'did' }, context)) as ManagedIdentifierDidResult
69
88
  }
70
89
 
71
- private async identifierGetManagedByKid(args: ManagedIdentifierKidOpts, context: IAgentContext<IKeyManager>): Promise<ManagedIdentifierKidResult> {
90
+ private async identifierGetManagedByKid(
91
+ args: ManagedIdentifierKidOpts,
92
+ context: IAgentContext<IKeyManager & IIdentifierResolution>
93
+ ): Promise<ManagedIdentifierKidResult> {
72
94
  return (await this.identifierGetManaged({ ...args, method: 'kid' }, context)) as ManagedIdentifierKidResult
73
95
  }
74
96
 
75
- private async identifierGetManagedByKey(args: ManagedIdentifierKeyOpts, context: IAgentContext<IKeyManager>): Promise<ManagedIdentifierKeyResult> {
97
+ private async identifierGetManagedByKey(
98
+ args: ManagedIdentifierKeyOpts,
99
+ context: IAgentContext<IKeyManager & IIdentifierResolution>
100
+ ): Promise<ManagedIdentifierKeyResult> {
76
101
  return (await this.identifierGetManaged({ ...args, method: 'key' }, context)) as ManagedIdentifierKeyResult
77
102
  }
78
103
 
79
- private async identifierGetManagedByJwk(args: ManagedIdentifierJwkOpts, context: IAgentContext<IKeyManager>): Promise<ManagedIdentifierJwkResult> {
104
+ private async identifierGetManagedByCoseKey(
105
+ args: ManagedIdentifierCoseKeyOpts,
106
+ context: IAgentContext<IKeyManager & IIdentifierResolution>
107
+ ): Promise<ManagedIdentifierCoseKeyResult> {
108
+ return (await this.identifierGetManaged({ ...args, method: 'cose_key' }, context)) as ManagedIdentifierCoseKeyResult
109
+ }
110
+
111
+ private async identifierGetManagedByOID4VCIssuer(
112
+ args: ManagedIdentifierOID4VCIssuerOpts,
113
+ context: IAgentContext<IKeyManager & IIdentifierResolution>
114
+ ): Promise<ManagedIdentifierOID4VCIssuerResult> {
115
+ return (await this.identifierGetManaged({ ...args, method: 'oid4vci-issuer' }, context)) as ManagedIdentifierOID4VCIssuerResult
116
+ }
117
+
118
+ private async identifierGetManagedByJwk(
119
+ args: ManagedIdentifierJwkOpts,
120
+ context: IAgentContext<IKeyManager & IIdentifierResolution>
121
+ ): Promise<ManagedIdentifierJwkResult> {
80
122
  return (await this.identifierGetManaged({ ...args, method: 'jwk' }, context)) as ManagedIdentifierJwkResult
81
123
  }
82
124
 
83
- private async identifierGetManagedByX5c(args: ManagedIdentifierX5cOpts, context: IAgentContext<IKeyManager>): Promise<ManagedIdentifierX5cResult> {
125
+ private async identifierGetManagedByX5c(
126
+ args: ManagedIdentifierX5cOpts,
127
+ context: IAgentContext<IKeyManager & IIdentifierResolution>
128
+ ): Promise<ManagedIdentifierX5cResult> {
84
129
  return (await this.identifierGetManaged({ ...args, method: 'x5c' }, context)) as ManagedIdentifierX5cResult
85
130
  }
86
131
 
87
- private async identifierResolveExternal(args: ExternalIdentifierOpts, context: IAgentContext<IKeyManager>): Promise<ExternalIdentifierResult> {
132
+ private async identifierResolveExternal(args: ExternalIdentifierOpts, context: IAgentContext<IKeyManager | IOIDFClient>): Promise<ExternalIdentifierResult> {
88
133
  return await resolveExternalIdentifier({ ...args, crypto: this._crypto }, context)
89
134
  }
90
135
 
@@ -95,4 +140,19 @@ export class IdentifierResolution implements IAgentPlugin {
95
140
  private async identifierExternalResolveByX5c(args: ExternalIdentifierX5cOpts, context: IAgentContext<any>): Promise<ExternalIdentifierX5cResult> {
96
141
  return (await this.identifierResolveExternal({ ...args, method: 'x5c' }, context)) as ExternalIdentifierX5cResult
97
142
  }
143
+
144
+ private async identifierExternalResolveByCoseKey(
145
+ args: ExternalIdentifierCoseKeyOpts,
146
+ context: IAgentContext<any>
147
+ ): Promise<ExternalIdentifierCoseKeyResult> {
148
+ return (await this.identifierResolveExternal({ ...args, method: 'cose_key' }, context)) as ExternalIdentifierCoseKeyResult
149
+ }
150
+
151
+ private async identifierExternalResolveByJwk(args: ExternalIdentifierJwkOpts, context: IAgentContext<any>): Promise<ExternalIdentifierJwkResult> {
152
+ return (await this.identifierResolveExternal({ ...args, method: 'jwk' }, context)) as ExternalIdentifierJwkResult
153
+ }
154
+
155
+ private async identifierExternalResolveByOIDFEntityId(args: ExternalIdentifierOIDFEntityIdOpts, context: IAgentContext<IOIDFClient>): Promise<ExternalIdentifierOIDFEntityIdResult> {
156
+ return (await this.identifierResolveExternal({ ...args, method: 'entity_id' }, context)) as ExternalIdentifierOIDFEntityIdResult
157
+ }
98
158
  }
@@ -0,0 +1,54 @@
1
+ import { IIdentifier } from '@veramo/core'
2
+ import { ManagedIdentifierDidOpts, ManagedIdentifierOptsOrResult } from '../types'
3
+
4
+ /**
5
+ * Converts legacy id opts key refs to the new ManagedIdentifierOpts
6
+ * @param opts
7
+ */
8
+ export function legacyKeyRefsToIdentifierOpts(opts: {
9
+ idOpts?: ManagedIdentifierOptsOrResult
10
+ iss?: string
11
+ keyRef?: string
12
+ didOpts?: any
13
+ }): ManagedIdentifierOptsOrResult {
14
+ if (!opts.idOpts) {
15
+ console.warn(
16
+ `Legacy idOpts being used. Support will be dropped in the future. Consider switching to the idOpts, to have support for DIDs, JWKS, x5c etc. See https://github.com/Sphereon-Opensource/SSI-SDK-crypto-extensions/tree/feature/multi_identifier_support/packages/identifier-resolution`
17
+ )
18
+ // legacy way
19
+ let kmsKeyRef =
20
+ opts.keyRef ??
21
+ opts.didOpts?.idOpts?.kmsKeyRef ??
22
+ opts.didOpts?.kid ??
23
+ opts.didOpts.idOpts?.kid ??
24
+ (typeof opts.didOpts?.idOpts.identifier === 'object' ? (opts.didOpts?.idOpts.identifier as IIdentifier).keys[0].kid : undefined)
25
+ if (!kmsKeyRef) {
26
+ throw Error('Key ref is needed for access token signer')
27
+ }
28
+ let identifier = (opts.didOpts?.identifier ?? opts.didOpts?.idOpts?.identifier) as IIdentifier | undefined
29
+
30
+ return {
31
+ kmsKeyRef: opts.keyRef ?? kmsKeyRef,
32
+ identifier: identifier ?? kmsKeyRef,
33
+ issuer: opts.iss,
34
+ } satisfies ManagedIdentifierDidOpts
35
+ } else {
36
+ const idOpts = opts.idOpts
37
+ if (opts.keyRef && !idOpts.kmsKeyRef) {
38
+ // legacy way
39
+ console.warn(
40
+ `Legacy keyRef being used. Support will be dropped in the future. Consider switching to the idOpts, to have support for DIDs, JWKS, x5c etc. See https://github.com/Sphereon-Opensource/SSI-SDK-crypto-extensions/tree/feature/multi_identifier_support/packages/identifier-resolution`
41
+ )
42
+ idOpts.kmsKeyRef = opts.keyRef
43
+ }
44
+ if (opts.iss && !idOpts.issuer) {
45
+ // legacy way
46
+ console.warn(
47
+ `Legacy iss being used. Support will be dropped in the future. Consider switching to the idOpts, to have support for DIDs, JWKS, x5c etc. See https://github.com/Sphereon-Opensource/SSI-SDK-crypto-extensions/tree/feature/multi_identifier_support/packages/identifier-resolution`
48
+ )
49
+ idOpts.issuer = opts.iss
50
+ }
51
+
52
+ return idOpts
53
+ }
54
+ }
@@ -1,5 +1,5 @@
1
- import { didDocumentToJwks, getAgentResolver } from '@sphereon/ssi-sdk-ext.did-utils'
2
- import { calculateJwkThumbprint, JWK } from '@sphereon/ssi-sdk-ext.key-utils'
1
+ import { didDocumentToJwks, getAgentResolver, jwkTtoPublicKeyHex } from '@sphereon/ssi-sdk-ext.did-utils'
2
+ import { calculateJwkThumbprint, coseKeyToJwk } from '@sphereon/ssi-sdk-ext.key-utils'
3
3
  import {
4
4
  getSubjectDN,
5
5
  pemOrDerToX509Certificate,
@@ -8,25 +8,34 @@ import {
8
8
  X509ValidationResult,
9
9
  } from '@sphereon/ssi-sdk-ext.x509-utils'
10
10
  import { contextHasPlugin } from '@sphereon/ssi-sdk.agent-config'
11
- import { IParsedDID, parseDid } from '@sphereon/ssi-types'
11
+ import { IParsedDID, JWK, parseDid } from '@sphereon/ssi-types'
12
12
  import { IAgentContext, IDIDManager, IResolver } from '@veramo/core'
13
13
  import { isDefined } from '@veramo/utils'
14
14
  import { CryptoEngine, setEngine } from 'pkijs'
15
15
  import {
16
+ ExternalIdentifierCoseKeyOpts,
17
+ ExternalIdentifierCoseKeyResult,
16
18
  ExternalIdentifierDidOpts,
17
19
  ExternalIdentifierDidResult,
20
+ ExternalIdentifierJwkOpts,
21
+ ExternalIdentifierJwkResult,
18
22
  ExternalIdentifierMethod,
19
23
  ExternalIdentifierOpts,
20
24
  ExternalIdentifierResult,
21
25
  ExternalIdentifierX5cOpts,
22
26
  ExternalIdentifierX5cResult,
23
27
  ExternalJwkInfo,
28
+ isExternalIdentifierCoseKeyOpts,
24
29
  isExternalIdentifierDidOpts,
30
+ isExternalIdentifierJwkOpts,
25
31
  isExternalIdentifierJwksUrlOpts,
26
32
  isExternalIdentifierKidOpts,
27
33
  isExternalIdentifierOidcDiscoveryOpts,
34
+ isExternalIdentifierOIDFEntityIdOpts,
28
35
  isExternalIdentifierX5cOpts,
29
36
  } from '../types'
37
+ import { resolveExternalOIDFEntityIdIdentifier } from '.'
38
+
30
39
 
31
40
  export async function resolveExternalIdentifier(
32
41
  opts: ExternalIdentifierOpts & {
@@ -39,13 +48,19 @@ export async function resolveExternalIdentifier(
39
48
  return resolveExternalDidIdentifier(opts, context)
40
49
  } else if (isExternalIdentifierX5cOpts(opts)) {
41
50
  return resolveExternalX5cIdentifier(opts, context)
51
+ } else if (isExternalIdentifierJwkOpts(opts)) {
52
+ return resolveExternalJwkIdentifier(opts, context)
53
+ } else if (isExternalIdentifierCoseKeyOpts(opts)) {
54
+ return resolveExternalCoseKeyIdentifier(opts, context)
55
+ } else if (isExternalIdentifierOIDFEntityIdOpts(opts)) {
56
+ return resolveExternalOIDFEntityIdIdentifier(opts, context)
42
57
  } else if (isExternalIdentifierKidOpts(opts)) {
43
58
  method = 'kid'
44
59
  } else if (isExternalIdentifierJwksUrlOpts(opts)) {
45
60
  method = 'jwks-url'
46
61
  } else if (isExternalIdentifierOidcDiscoveryOpts(opts)) {
47
62
  method = 'oidc-discovery'
48
- }
63
+ }
49
64
  throw Error(`External resolution method ${method} is not yet implemented`)
50
65
  }
51
66
 
@@ -61,7 +76,7 @@ export async function resolveExternalX5cIdentifier(
61
76
  const verify = opts.verify ?? true
62
77
  const x5c = opts.identifier.map((derOrPem) => (derOrPem.includes('CERTIFICATE') ? PEMToDer(derOrPem) : derOrPem))
63
78
  if (x5c.length === 0) {
64
- return Promise.reject('Empty certification chain is now allowed')
79
+ return Promise.reject('Empty certification chain is not allowed')
65
80
  }
66
81
  const certificates = x5c.map(pemOrDerToX509Certificate)
67
82
 
@@ -82,6 +97,7 @@ export async function resolveExternalX5cIdentifier(
82
97
  chain: opts.identifier,
83
98
  trustAnchors: opts.trustAnchors ?? [],
84
99
  verificationTime: opts.verificationTime,
100
+ opts,
85
101
  })
86
102
  }
87
103
  if (verificationResult.certificateChain) {
@@ -90,6 +106,7 @@ export async function resolveExternalX5cIdentifier(
90
106
  jwk: cert.publicKeyJWK,
91
107
  kid: cert.subject.dn.DN,
92
108
  jwkThumbprint: calculateJwkThumbprint({ jwk: cert.publicKeyJWK }),
109
+ publicKeyHex: jwkTtoPublicKeyHex(cert.publicKeyJWK),
93
110
  } satisfies ExternalJwkInfo
94
111
  })
95
112
  }
@@ -108,6 +125,7 @@ export async function resolveExternalX5cIdentifier(
108
125
  jwk,
109
126
  kid: getSubjectDN(cert).DN,
110
127
  jwkThumbprint: calculateJwkThumbprint({ jwk }),
128
+ publicKeyHex: jwkTtoPublicKeyHex(jwk),
111
129
  } satisfies ExternalJwkInfo
112
130
  })
113
131
  )
@@ -129,6 +147,78 @@ export async function resolveExternalX5cIdentifier(
129
147
  }
130
148
  }
131
149
 
150
+ /**
151
+ * Resolves a JWK. Normally this is just returning the JWK, but in case the JWK contains a x5c the chain is validated
152
+ * @param opts
153
+ * @param context
154
+ */
155
+ export async function resolveExternalJwkIdentifier(
156
+ opts: ExternalIdentifierJwkOpts & {
157
+ x5c?: ExternalIdentifierX5cOpts
158
+ },
159
+ context: IAgentContext<any>
160
+ ): Promise<ExternalIdentifierJwkResult> {
161
+ if (!isExternalIdentifierJwkOpts(opts)) {
162
+ return Promise.reject('External JWK Identifier args need to be provided')
163
+ }
164
+ const jwk = opts.identifier
165
+ let x5c: ExternalIdentifierX5cResult | undefined = undefined
166
+ if (jwk.x5c) {
167
+ x5c = await resolveExternalX5cIdentifier({ ...opts.x5c, identifier: jwk.x5c }, context)
168
+ }
169
+ const jwkThumbprint = calculateJwkThumbprint({ jwk })
170
+ return {
171
+ method: 'jwk',
172
+ jwk,
173
+ jwks: [
174
+ {
175
+ jwk,
176
+ jwkThumbprint,
177
+ kid: jwk.kid,
178
+ publicKeyHex: jwkTtoPublicKeyHex(jwk),
179
+ },
180
+ ],
181
+ x5c,
182
+ } satisfies ExternalIdentifierJwkResult
183
+ }
184
+
185
+ /**
186
+ * Resolves a JWK. Normally this is just returning the JWK, but in case the JWK contains a x5c the chain is validated
187
+ * @param opts
188
+ * @param context
189
+ */
190
+ export async function resolveExternalCoseKeyIdentifier(
191
+ opts: ExternalIdentifierCoseKeyOpts & {
192
+ x5c?: ExternalIdentifierX5cOpts
193
+ },
194
+ context: IAgentContext<any>
195
+ ): Promise<ExternalIdentifierCoseKeyResult> {
196
+ if (!isExternalIdentifierCoseKeyOpts(opts)) {
197
+ return Promise.reject('External Cose Key args need to be provided')
198
+ }
199
+ // TODO: We need to do cbor conversion here as well.
200
+ const coseKey = opts.identifier
201
+ let x5c: ExternalIdentifierX5cResult | undefined = undefined
202
+ if (coseKey.x5chain) {
203
+ x5c = await resolveExternalX5cIdentifier({ ...opts.x5c, identifier: coseKey.x5chain }, context)
204
+ }
205
+ const jwk = coseKeyToJwk(coseKey)
206
+ const jwkThumbprint = calculateJwkThumbprint({ jwk })
207
+ return {
208
+ method: 'cose_key',
209
+ coseKey,
210
+ jwks: [
211
+ {
212
+ jwk,
213
+ jwkThumbprint,
214
+ kid: coseKey.kid,
215
+ publicKeyHex: jwkTtoPublicKeyHex(jwk),
216
+ },
217
+ ],
218
+ x5c,
219
+ } satisfies ExternalIdentifierCoseKeyResult
220
+ }
221
+
132
222
  export async function resolveExternalDidIdentifier(
133
223
  opts: ExternalIdentifierDidOpts,
134
224
  context: IAgentContext<IResolver & IDIDManager>
@@ -163,7 +253,12 @@ export async function resolveExternalDidIdentifier(
163
253
  .flatMap((jwks) => jwks)
164
254
  )
165
255
  ).map((jwk) => {
166
- return { jwk, jwkThumbprint: calculateJwkThumbprint({ jwk }), kid: jwk.kid }
256
+ return {
257
+ jwk,
258
+ jwkThumbprint: calculateJwkThumbprint({ jwk }),
259
+ kid: jwk.kid,
260
+ publicKeyHex: jwkTtoPublicKeyHex(jwk),
261
+ }
167
262
  })
168
263
  : []
169
264
 
@@ -0,0 +1,95 @@
1
+ import {
2
+ ErrorMessage,
3
+ ExternalIdentifierOIDFEntityIdOpts,
4
+ ExternalIdentifierOIDFEntityIdResult, ExternalJwkInfo,
5
+ PublicKeyHex,
6
+ TrustedAnchor,
7
+ } from '../types'
8
+ import { IAgentContext } from '@veramo/core'
9
+ import { IOIDFClient } from '@sphereon/ssi-sdk.oidf-client'
10
+ import { contextHasPlugin } from '@sphereon/ssi-sdk.agent-config'
11
+ import { JWK } from '@sphereon/ssi-types'
12
+ import { IJwsValidationResult, VerifyJwsArgs } from '../types/IJwtService'
13
+
14
+ /**
15
+ * Resolves an OIDF Entity ID against multiple trust anchors to establish trusted relationships
16
+ *
17
+ * @param opts Configuration options containing the identifier to resolve and trust anchors to validate against
18
+ * @param context Agent context that must include the OIDF client plugin and JWT verification capabilities
19
+ *
20
+ * @returns Promise resolving to an ExternalIdentifierOIDFEntityIdResult containing:
21
+ * - trustedAnchors: Record mapping trust anchors to their public key hexes
22
+ * - errorList: Optional record of errors encountered per trust anchor
23
+ * - jwks: Array of JWK information from the trust chain
24
+ * - trustEstablished: Boolean indicating if any trust relationships were established
25
+ *
26
+ * @throws Error if trust anchors are missing or JWT verification plugin is not enabled
27
+ */
28
+ export async function resolveExternalOIDFEntityIdIdentifier(
29
+ opts: ExternalIdentifierOIDFEntityIdOpts,
30
+ context: IAgentContext<IOIDFClient>
31
+ ): Promise<ExternalIdentifierOIDFEntityIdResult> {
32
+ let { trustAnchors, identifier } = opts
33
+
34
+ if (!trustAnchors || trustAnchors.length === 0) {
35
+ return Promise.reject(Error('ExternalIdentifierOIDFEntityIdOpts is missing the trustAnchors'))
36
+ }
37
+
38
+ if (!contextHasPlugin(context, 'jwtVerifyJwsSignature')) {
39
+ return Promise.reject(Error('For OIDFEntityId resolving the agent needs to have the JwtService plugin enabled'))
40
+ }
41
+
42
+ const trustedAnchors: Record<TrustedAnchor, PublicKeyHex> = {}
43
+ const errorList: Record<TrustedAnchor, ErrorMessage> = {}
44
+ const jwkInfos: Array<ExternalJwkInfo> = []
45
+
46
+ for (const trustAnchor of trustAnchors) {
47
+ const resolveResult = await context.agent.resolveTrustChain({
48
+ entityIdentifier: identifier,
49
+ trustAnchors: [trustAnchor]
50
+ })
51
+
52
+ if (resolveResult.error || !resolveResult.trustChain) {
53
+ errorList[trustAnchor] = resolveResult.errorMessage ?? 'unspecified'
54
+ } else {
55
+ const trustChain: ReadonlyArray<string> = resolveResult.trustChain.asJsReadonlyArrayView()
56
+ let authorityJWK:JWK | undefined = undefined
57
+ for (const [i, jwt] of [...trustChain].reverse().entries()) {
58
+ const isLast = i === trustChain.length - 1
59
+
60
+ const verifyArgs:VerifyJwsArgs = {jws: jwt}
61
+ if(authorityJWK && !isLast) {
62
+ verifyArgs.jwk = authorityJWK
63
+ }
64
+ const jwtVerifyResult:IJwsValidationResult = await context.agent.jwtVerifyJwsSignature(verifyArgs)
65
+ if(jwtVerifyResult.error || jwtVerifyResult.critical) {
66
+ errorList[trustAnchor] = jwtVerifyResult.message
67
+ break
68
+ }
69
+ if(jwtVerifyResult.jws.signatures.length === 0) {
70
+ errorList[trustAnchor] = 'No signature was present in the trust anchor JWS'
71
+ break
72
+ }
73
+ const signature = jwtVerifyResult.jws.signatures[0]
74
+ if(signature.identifier.jwks.length === 0) {
75
+ errorList[trustAnchor] = 'No JWK was present in the trust anchor signature'
76
+ break
77
+ }
78
+ const jwkInfo:ExternalJwkInfo = signature.identifier.jwks[0]
79
+ if(!authorityJWK) {
80
+ authorityJWK = jwkInfo.jwk
81
+ jwkInfos.push(jwkInfo)
82
+ trustedAnchors[trustAnchor] = signature.publicKeyHex // When we have multiple hits from different trust anchor authorities the caller can infer which signature came from which trust anchor
83
+ }
84
+ }
85
+ }
86
+ }
87
+
88
+ return {
89
+ method: 'entity_id',
90
+ trustedAnchors,
91
+ ...(Object.keys(errorList).length > 0 && { errorList }),
92
+ jwks: jwkInfos,
93
+ trustEstablished: Object.keys(trustedAnchors).length > 0
94
+ }
95
+ }
@@ -1,53 +1,4 @@
1
- import { IIdentifier } from '@veramo/core'
2
- import { ManagedIdentifierDidOpts, ManagedIdentifierOpts } from '../types'
3
-
4
1
  export * from './managedIdentifierFunctions'
5
2
  export * from './externalIdentifierFunctions'
6
-
7
- /**
8
- * Converts legacy id opts key refs to the new ManagedIdentifierOpts
9
- * @param opts
10
- */
11
- export function legacyKeyRefsToIdentifierOpts(opts: {
12
- idOpts?: ManagedIdentifierOpts
13
- iss?: string
14
- keyRef?: string
15
- didOpts?: any
16
- }): ManagedIdentifierOpts {
17
- if (!opts.idOpts) {
18
- console.warn(
19
- `Legacy idOpts being used. Support will be dropped in the future. Consider switching to the idOpts, to have support for DIDs, JWKS, x5c etc. See https://github.com/Sphereon-Opensource/SSI-SDK-crypto-extensions/tree/feature/multi_identifier_support/packages/identifier-resolution`
20
- )
21
- // legacy way
22
- let kmsKeyRef =
23
- opts.keyRef ??
24
- opts.didOpts?.idOpts?.kmsKeyRef ??
25
- (typeof opts.didOpts?.idOpts.identifier === 'object' ? (opts.didOpts?.idOpts.identifier as IIdentifier).keys[0].kid : undefined)
26
- if (!kmsKeyRef) {
27
- throw Error('Key ref is needed for access token signer')
28
- }
29
- return {
30
- kmsKeyRef: opts.keyRef ?? kmsKeyRef,
31
- identifier: kmsKeyRef,
32
- issuer: opts.iss,
33
- } satisfies ManagedIdentifierDidOpts
34
- } else {
35
- const idOpts = opts.idOpts
36
- if (opts.keyRef && !idOpts.kmsKeyRef) {
37
- // legacy way
38
- console.warn(
39
- `Legacy keyRef being used. Support will be dropped in the future. Consider switching to the idOpts, to have support for DIDs, JWKS, x5c etc. See https://github.com/Sphereon-Opensource/SSI-SDK-crypto-extensions/tree/feature/multi_identifier_support/packages/identifier-resolution`
40
- )
41
- idOpts.kmsKeyRef = opts.keyRef
42
- }
43
- if (opts.iss && !idOpts.issuer) {
44
- // legacy way
45
- console.warn(
46
- `Legacy iss being used. Support will be dropped in the future. Consider switching to the idOpts, to have support for DIDs, JWKS, x5c etc. See https://github.com/Sphereon-Opensource/SSI-SDK-crypto-extensions/tree/feature/multi_identifier_support/packages/identifier-resolution`
47
- )
48
- idOpts.issuer = opts.iss
49
- }
50
-
51
- return idOpts
52
- }
53
- }
3
+ export * from './externalOIDFIdentifier'
4
+ export * from './LegacySupport'