@sphereon/ssi-sdk-ext.identifier-resolution 0.24.1-unstable.93 → 0.25.1-feature.OIDF.69.39

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 +79 -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 +13 -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 +2650 -279
  44. package/src/agent/IdentifierResolution.ts +72 -11
  45. package/src/functions/LegacySupport.ts +54 -0
  46. package/src/functions/externalIdentifierFunctions.ts +101 -6
  47. package/src/functions/externalOIDFIdentifier.ts +93 -0
  48. package/src/functions/index.ts +2 -51
  49. package/src/functions/managedIdentifierFunctions.ts +162 -14
  50. package/src/types/IIdentifierResolution.ts +47 -2
  51. package/src/types/IJwtService.d.ts +225 -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,7 @@
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 } from '../types'
3
+ import { schema } from '..'
4
+ import { resolveExternalIdentifier, ensureManagedIdentifierResult } from '../functions'
4
5
  import {
5
6
  ExternalIdentifierDidOpts,
6
7
  ExternalIdentifierDidResult,
@@ -8,18 +9,29 @@ import {
8
9
  ExternalIdentifierResult,
9
10
  ExternalIdentifierX5cOpts,
10
11
  ExternalIdentifierX5cResult,
12
+ ExternalIdentifierCoseKeyOpts,
13
+ ExternalIdentifierCoseKeyResult,
14
+ ExternalIdentifierJwkOpts,
15
+ ExternalIdentifierJwkResult,
11
16
  IIdentifierResolution,
17
+ ManagedIdentifierCoseKeyOpts,
18
+ ManagedIdentifierCoseKeyResult,
12
19
  ManagedIdentifierDidOpts,
13
20
  ManagedIdentifierDidResult,
14
21
  ManagedIdentifierJwkOpts,
15
22
  ManagedIdentifierJwkResult,
16
23
  ManagedIdentifierKidOpts,
17
24
  ManagedIdentifierKidResult,
18
- ManagedIdentifierOpts,
19
25
  ManagedIdentifierResult,
20
26
  ManagedIdentifierX5cOpts,
21
27
  ManagedIdentifierX5cResult,
28
+ ManagedIdentifierOID4VCIssuerResult,
29
+ ManagedIdentifierKeyOpts,
30
+ ManagedIdentifierKeyResult,
31
+ ManagedIdentifierOptsOrResult,
32
+ ManagedIdentifierOID4VCIssuerOpts
22
33
  } from '../types'
34
+ import { IOIDFClient } from '@sphereon/ssi-sdk.oidf-client'
23
35
 
24
36
  /**
25
37
  * @public
@@ -35,10 +47,15 @@ export class IdentifierResolution implements IAgentPlugin {
35
47
  identifierManagedGetByJwk: this.identifierGetManagedByJwk.bind(this),
36
48
  identifierManagedGetByX5c: this.identifierGetManagedByX5c.bind(this),
37
49
  identifierManagedGetByKey: this.identifierGetManagedByKey.bind(this),
50
+ identifierManagedGetByCoseKey: this.identifierGetManagedByCoseKey.bind(this),
51
+ identifierManagedGetByOID4VCIssuer: this.identifierGetManagedByOID4VCIssuer.bind(this),
38
52
 
39
53
  identifierExternalResolve: this.identifierResolveExternal.bind(this),
40
54
  identifierExternalResolveByDid: this.identifierExternalResolveByDid.bind(this),
41
55
  identifierExternalResolveByX5c: this.identifierExternalResolveByX5c.bind(this),
56
+ identifierExternalResolveByJwk: this.identifierExternalResolveByJwk.bind(this),
57
+ identifierExternalResolveByCoseKey: this.identifierExternalResolveByCoseKey.bind(this),
58
+ identifierExternalResolveByOIDFEntityId: this.identifierExternalResolveByOIDFEntityId.bind(this),
42
59
 
43
60
  // todo: JWKSet, oidc-discovery, oid4vci-issuer etc. Anything we already can resolve and need keys of
44
61
  }
@@ -57,34 +74,63 @@ export class IdentifierResolution implements IAgentPlugin {
57
74
  * @param context
58
75
  * @private
59
76
  */
60
- private async identifierGetManaged(args: ManagedIdentifierOpts, context: IAgentContext<IKeyManager>): Promise<ManagedIdentifierResult> {
61
- return await getManagedIdentifier({ ...args, crypto: this._crypto }, context)
77
+ private async identifierGetManaged(
78
+ args: ManagedIdentifierOptsOrResult,
79
+ context: IAgentContext<IKeyManager & IIdentifierResolution>
80
+ ): Promise<ManagedIdentifierResult> {
81
+ return await ensureManagedIdentifierResult({ ...args, crypto: this._crypto }, context)
62
82
  }
63
83
 
64
84
  private async identifierGetManagedByDid(
65
85
  args: ManagedIdentifierDidOpts,
66
- context: IAgentContext<IKeyManager & IDIDManager>
86
+ context: IAgentContext<IKeyManager & IDIDManager & IIdentifierResolution>
67
87
  ): Promise<ManagedIdentifierDidResult> {
68
88
  return (await this.identifierGetManaged({ ...args, method: 'did' }, context)) as ManagedIdentifierDidResult
69
89
  }
70
90
 
71
- private async identifierGetManagedByKid(args: ManagedIdentifierKidOpts, context: IAgentContext<IKeyManager>): Promise<ManagedIdentifierKidResult> {
91
+ private async identifierGetManagedByKid(
92
+ args: ManagedIdentifierKidOpts,
93
+ context: IAgentContext<IKeyManager & IIdentifierResolution>
94
+ ): Promise<ManagedIdentifierKidResult> {
72
95
  return (await this.identifierGetManaged({ ...args, method: 'kid' }, context)) as ManagedIdentifierKidResult
73
96
  }
74
97
 
75
- private async identifierGetManagedByKey(args: ManagedIdentifierKeyOpts, context: IAgentContext<IKeyManager>): Promise<ManagedIdentifierKeyResult> {
98
+ private async identifierGetManagedByKey(
99
+ args: ManagedIdentifierKeyOpts,
100
+ context: IAgentContext<IKeyManager & IIdentifierResolution>
101
+ ): Promise<ManagedIdentifierKeyResult> {
76
102
  return (await this.identifierGetManaged({ ...args, method: 'key' }, context)) as ManagedIdentifierKeyResult
77
103
  }
78
104
 
79
- private async identifierGetManagedByJwk(args: ManagedIdentifierJwkOpts, context: IAgentContext<IKeyManager>): Promise<ManagedIdentifierJwkResult> {
105
+ private async identifierGetManagedByCoseKey(
106
+ args: ManagedIdentifierCoseKeyOpts,
107
+ context: IAgentContext<IKeyManager & IIdentifierResolution>
108
+ ): Promise<ManagedIdentifierCoseKeyResult> {
109
+ return (await this.identifierGetManaged({ ...args, method: 'cose_key' }, context)) as ManagedIdentifierCoseKeyResult
110
+ }
111
+
112
+ private async identifierGetManagedByOID4VCIssuer(
113
+ args: ManagedIdentifierOID4VCIssuerOpts,
114
+ context: IAgentContext<IKeyManager & IIdentifierResolution>
115
+ ): Promise<ManagedIdentifierOID4VCIssuerResult> {
116
+ return (await this.identifierGetManaged({ ...args, method: 'oid4vci-issuer' }, context)) as ManagedIdentifierOID4VCIssuerResult
117
+ }
118
+
119
+ private async identifierGetManagedByJwk(
120
+ args: ManagedIdentifierJwkOpts,
121
+ context: IAgentContext<IKeyManager & IIdentifierResolution>
122
+ ): Promise<ManagedIdentifierJwkResult> {
80
123
  return (await this.identifierGetManaged({ ...args, method: 'jwk' }, context)) as ManagedIdentifierJwkResult
81
124
  }
82
125
 
83
- private async identifierGetManagedByX5c(args: ManagedIdentifierX5cOpts, context: IAgentContext<IKeyManager>): Promise<ManagedIdentifierX5cResult> {
126
+ private async identifierGetManagedByX5c(
127
+ args: ManagedIdentifierX5cOpts,
128
+ context: IAgentContext<IKeyManager & IIdentifierResolution>
129
+ ): Promise<ManagedIdentifierX5cResult> {
84
130
  return (await this.identifierGetManaged({ ...args, method: 'x5c' }, context)) as ManagedIdentifierX5cResult
85
131
  }
86
132
 
87
- private async identifierResolveExternal(args: ExternalIdentifierOpts, context: IAgentContext<IKeyManager>): Promise<ExternalIdentifierResult> {
133
+ private async identifierResolveExternal(args: ExternalIdentifierOpts, context: IAgentContext<IKeyManager | IOIDFClient>): Promise<ExternalIdentifierResult> {
88
134
  return await resolveExternalIdentifier({ ...args, crypto: this._crypto }, context)
89
135
  }
90
136
 
@@ -95,4 +141,19 @@ export class IdentifierResolution implements IAgentPlugin {
95
141
  private async identifierExternalResolveByX5c(args: ExternalIdentifierX5cOpts, context: IAgentContext<any>): Promise<ExternalIdentifierX5cResult> {
96
142
  return (await this.identifierResolveExternal({ ...args, method: 'x5c' }, context)) as ExternalIdentifierX5cResult
97
143
  }
144
+
145
+ private async identifierExternalResolveByCoseKey(
146
+ args: ExternalIdentifierCoseKeyOpts,
147
+ context: IAgentContext<any>
148
+ ): Promise<ExternalIdentifierCoseKeyResult> {
149
+ return (await this.identifierResolveExternal({ ...args, method: 'cose_key' }, context)) as ExternalIdentifierCoseKeyResult
150
+ }
151
+
152
+ private async identifierExternalResolveByJwk(args: ExternalIdentifierJwkOpts, context: IAgentContext<any>): Promise<ExternalIdentifierJwkResult> {
153
+ return (await this.identifierResolveExternal({ ...args, method: 'jwk' }, context)) as ExternalIdentifierJwkResult
154
+ }
155
+
156
+ private async identifierExternalResolveByOIDFEntityId(args: ExternalIdentifierOIDFEntityIdOpts, context: IAgentContext<any>): Promise<ExternalIdentifierOIDFEntityIdResult> {
157
+ return (await this.identifierResolveExternal({ ...args, method: 'entity_id' }, context)) as ExternalIdentifierOIDFEntityIdResult
158
+ }
98
159
  }
@@ -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,93 @@
1
+ import {
2
+ ErrorMessage,
3
+ ExternalIdentifierOIDFEntityIdOpts,
4
+ ExternalIdentifierOIDFEntityIdResult,
5
+ ExternalJwkInfo,
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 { IJwsValidationResult } from '../types/IJwtService'
12
+
13
+ /**
14
+ * Resolves an OIDF Entity ID against multiple trust anchors to establish trusted relationships
15
+ *
16
+ * @param opts Configuration options containing the identifier to resolve and trust anchors to validate against
17
+ * @param context Agent context that must include the OIDF client plugin and JWT verification capabilities
18
+ *
19
+ * @returns Promise resolving to an ExternalIdentifierOIDFEntityIdResult containing:
20
+ * - trustedAnchors: Record mapping trust anchors to their public key hexes
21
+ * - errorList: Optional record of errors encountered per trust anchor
22
+ * - jwks: Array of JWK information from the trust chain
23
+ * - trustEstablished: Boolean indicating if any trust relationships were established
24
+ *
25
+ * @throws Error if trust anchors are missing or JWT verification plugin is not enabled
26
+ */
27
+ export async function resolveExternalOIDFEntityIdIdentifier(
28
+ opts: ExternalIdentifierOIDFEntityIdOpts,
29
+ context: IAgentContext<IOIDFClient>
30
+ ): Promise<ExternalIdentifierOIDFEntityIdResult> {
31
+ let { trustAnchors, identifier } = opts
32
+
33
+ if (!trustAnchors || trustAnchors.length === 0) {
34
+ return Promise.reject(Error('ExternalIdentifierOIDFEntityIdOpts is missing the trustAnchors'))
35
+ }
36
+
37
+ if (!contextHasPlugin(context, 'jwtVerifyJwsSignature')) {
38
+ return Promise.reject(Error('For OIDFEntityId resolving the agent needs to have the JwtService plugin enabled'))
39
+ }
40
+
41
+ const trustedAnchors: Set<TrustedAnchor> = new Set<TrustedAnchor>()
42
+ const errorList: Record<TrustedAnchor, ErrorMessage> = {}
43
+ const jwkInfos: Array<ExternalJwkInfo> = []
44
+
45
+ for (const trustAnchor of trustAnchors) {
46
+ const resolveResult = await context.agent.resolveTrustChain({
47
+ entityIdentifier: identifier,
48
+ trustAnchors: [trustAnchor]
49
+ })
50
+
51
+ if (resolveResult.error || !resolveResult.trustChain) {
52
+ errorList[trustAnchor] = resolveResult.errorMessage ?? 'unspecified'
53
+ } else {
54
+ const trustChain: ReadonlyArray<string> = resolveResult.trustChain.asJsReadonlyArrayView()
55
+ if (trustChain.length === 0) {
56
+ errorList[trustAnchor] = 'Trust chain is empty'
57
+ continue
58
+ }
59
+
60
+ const jwt = trustChain[0]
61
+ const jwtVerifyResult: IJwsValidationResult = await context.agent.jwtVerifyJwsSignature({ jws: jwt })
62
+
63
+ if (jwtVerifyResult.error || jwtVerifyResult.critical) {
64
+ errorList[trustAnchor] = jwtVerifyResult.message
65
+ continue
66
+ }
67
+
68
+ if (jwtVerifyResult.jws.signatures.length === 0) {
69
+ errorList[trustAnchor] = 'No signature was present in the trust anchor JWS'
70
+ continue
71
+ }
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
+ continue
77
+ }
78
+
79
+ if(jwkInfos.length === 0) { // We need the entity JWK only once
80
+ jwkInfos.push(...signature.identifier.jwks)
81
+ }
82
+ trustedAnchors.add(trustAnchor)
83
+ }
84
+ }
85
+
86
+ return {
87
+ method: 'entity_id',
88
+ trustedAnchors: Array.from(trustedAnchors),
89
+ ...(Object.keys(errorList).length > 0 && { errorList }),
90
+ jwks: jwkInfos,
91
+ trustEstablished: trustedAnchors.size > 0
92
+ }
93
+ }
@@ -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'