@sphereon/ssi-sdk-ext.identifier-resolution 0.24.1-next.98 → 0.24.1-unstable.112

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 (41) hide show
  1. package/dist/agent/IdentifierResolution.d.ts +3 -1
  2. package/dist/agent/IdentifierResolution.d.ts.map +1 -1
  3. package/dist/agent/IdentifierResolution.js +19 -7
  4. package/dist/agent/IdentifierResolution.js.map +1 -1
  5. package/dist/functions/LegacySupport.d.ts.map +1 -1
  6. package/dist/functions/LegacySupport.js +5 -4
  7. package/dist/functions/LegacySupport.js.map +1 -1
  8. package/dist/functions/externalIdentifierFunctions.d.ts +17 -1
  9. package/dist/functions/externalIdentifierFunctions.d.ts.map +1 -1
  10. package/dist/functions/externalIdentifierFunctions.js +82 -2
  11. package/dist/functions/externalIdentifierFunctions.js.map +1 -1
  12. package/dist/functions/managedIdentifierFunctions.d.ts +16 -5
  13. package/dist/functions/managedIdentifierFunctions.d.ts.map +1 -1
  14. package/dist/functions/managedIdentifierFunctions.js +66 -6
  15. package/dist/functions/managedIdentifierFunctions.js.map +1 -1
  16. package/dist/types/IIdentifierResolution.d.ts +10 -12
  17. package/dist/types/IIdentifierResolution.d.ts.map +1 -1
  18. package/dist/types/IIdentifierResolution.js +3 -1
  19. package/dist/types/IIdentifierResolution.js.map +1 -1
  20. package/dist/types/common.d.ts +2 -1
  21. package/dist/types/common.d.ts.map +1 -1
  22. package/dist/types/common.js +5 -1
  23. package/dist/types/common.js.map +1 -1
  24. package/dist/types/externalIdentifierTypes.d.ts +23 -6
  25. package/dist/types/externalIdentifierTypes.d.ts.map +1 -1
  26. package/dist/types/externalIdentifierTypes.js +6 -1
  27. package/dist/types/externalIdentifierTypes.js.map +1 -1
  28. package/dist/types/managedIdentifierTypes.d.ts +29 -7
  29. package/dist/types/managedIdentifierTypes.d.ts.map +1 -1
  30. package/dist/types/managedIdentifierTypes.js +10 -1
  31. package/dist/types/managedIdentifierTypes.js.map +1 -1
  32. package/package.json +12 -12
  33. package/plugin.schema.json +2149 -264
  34. package/src/agent/IdentifierResolution.ts +56 -18
  35. package/src/functions/LegacySupport.ts +5 -1
  36. package/src/functions/externalIdentifierFunctions.ts +94 -4
  37. package/src/functions/managedIdentifierFunctions.ts +79 -10
  38. package/src/types/IIdentifierResolution.ts +22 -12
  39. package/src/types/common.ts +5 -1
  40. package/src/types/externalIdentifierTypes.ts +54 -13
  41. package/src/types/managedIdentifierTypes.ts +47 -8
@@ -1,6 +1,16 @@
1
1
  import { IAgentContext, IAgentPlugin, IDIDManager, IKeyManager } from '@veramo/core'
2
- import { ensureManagedIdentifierResult, ManagedIdentifierKeyOpts, ManagedIdentifierKeyResult, ManagedIdentifierOptsOrResult, schema } from '..'
3
- import { getManagedIdentifier, resolveExternalIdentifier } from '../functions'
2
+ import {
3
+ ensureManagedIdentifierResult,
4
+ ExternalIdentifierCoseKeyOpts,
5
+ ExternalIdentifierCoseKeyResult,
6
+ ExternalIdentifierJwkOpts,
7
+ ExternalIdentifierJwkResult,
8
+ ManagedIdentifierKeyOpts,
9
+ ManagedIdentifierKeyResult,
10
+ ManagedIdentifierOptsOrResult,
11
+ schema,
12
+ } from '..'
13
+ import { resolveExternalIdentifier } from '../functions'
4
14
  import {
5
15
  ExternalIdentifierDidOpts,
6
16
  ExternalIdentifierDidResult,
@@ -9,13 +19,14 @@ import {
9
19
  ExternalIdentifierX5cOpts,
10
20
  ExternalIdentifierX5cResult,
11
21
  IIdentifierResolution,
22
+ ManagedIdentifierCoseKeyOpts,
23
+ ManagedIdentifierCoseKeyResult,
12
24
  ManagedIdentifierDidOpts,
13
25
  ManagedIdentifierDidResult,
14
26
  ManagedIdentifierJwkOpts,
15
27
  ManagedIdentifierJwkResult,
16
28
  ManagedIdentifierKidOpts,
17
29
  ManagedIdentifierKidResult,
18
- ManagedIdentifierOpts,
19
30
  ManagedIdentifierResult,
20
31
  ManagedIdentifierX5cOpts,
21
32
  ManagedIdentifierX5cResult,
@@ -35,11 +46,13 @@ 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),
38
- identifierManagedLazyResult: this.identifierManagedLazyResult.bind(this),
49
+ identifierManagedGetByCoseKey: this.identifierGetManagedByCoseKey.bind(this),
39
50
 
40
51
  identifierExternalResolve: this.identifierResolveExternal.bind(this),
41
52
  identifierExternalResolveByDid: this.identifierExternalResolveByDid.bind(this),
42
53
  identifierExternalResolveByX5c: this.identifierExternalResolveByX5c.bind(this),
54
+ identifierExternalResolveByJwk: this.identifierExternalResolveByJwk.bind(this),
55
+ identifierExternalResolveByCoseKey: this.identifierExternalResolveByCoseKey.bind(this),
43
56
 
44
57
  // todo: JWKSet, oidc-discovery, oid4vci-issuer etc. Anything we already can resolve and need keys of
45
58
  }
@@ -58,38 +71,53 @@ export class IdentifierResolution implements IAgentPlugin {
58
71
  * @param context
59
72
  * @private
60
73
  */
61
- private async identifierGetManaged(args: ManagedIdentifierOpts, context: IAgentContext<IKeyManager>): Promise<ManagedIdentifierResult> {
62
- return await getManagedIdentifier({ ...args, crypto: this._crypto }, context)
74
+ private async identifierGetManaged(
75
+ args: ManagedIdentifierOptsOrResult,
76
+ context: IAgentContext<IKeyManager & IIdentifierResolution>
77
+ ): Promise<ManagedIdentifierResult> {
78
+ return await ensureManagedIdentifierResult({ ...args, crypto: this._crypto }, context)
63
79
  }
64
80
 
65
81
  private async identifierGetManagedByDid(
66
82
  args: ManagedIdentifierDidOpts,
67
- context: IAgentContext<IKeyManager & IDIDManager>
83
+ context: IAgentContext<IKeyManager & IDIDManager & IIdentifierResolution>
68
84
  ): Promise<ManagedIdentifierDidResult> {
69
85
  return (await this.identifierGetManaged({ ...args, method: 'did' }, context)) as ManagedIdentifierDidResult
70
86
  }
71
87
 
72
- private async identifierGetManagedByKid(args: ManagedIdentifierKidOpts, context: IAgentContext<IKeyManager>): Promise<ManagedIdentifierKidResult> {
88
+ private async identifierGetManagedByKid(
89
+ args: ManagedIdentifierKidOpts,
90
+ context: IAgentContext<IKeyManager & IIdentifierResolution>
91
+ ): Promise<ManagedIdentifierKidResult> {
73
92
  return (await this.identifierGetManaged({ ...args, method: 'kid' }, context)) as ManagedIdentifierKidResult
74
93
  }
75
94
 
76
- private async identifierGetManagedByKey(args: ManagedIdentifierKeyOpts, context: IAgentContext<IKeyManager>): Promise<ManagedIdentifierKeyResult> {
95
+ private async identifierGetManagedByKey(
96
+ args: ManagedIdentifierKeyOpts,
97
+ context: IAgentContext<IKeyManager & IIdentifierResolution>
98
+ ): Promise<ManagedIdentifierKeyResult> {
77
99
  return (await this.identifierGetManaged({ ...args, method: 'key' }, context)) as ManagedIdentifierKeyResult
78
100
  }
79
101
 
80
- private async identifierGetManagedByJwk(args: ManagedIdentifierJwkOpts, context: IAgentContext<IKeyManager>): Promise<ManagedIdentifierJwkResult> {
81
- return (await this.identifierGetManaged({ ...args, method: 'jwk' }, context)) as ManagedIdentifierJwkResult
102
+ private async identifierGetManagedByCoseKey(
103
+ args: ManagedIdentifierCoseKeyOpts,
104
+ context: IAgentContext<IKeyManager & IIdentifierResolution>
105
+ ): Promise<ManagedIdentifierCoseKeyResult> {
106
+ return (await this.identifierGetManaged({ ...args, method: 'cose_key' }, context)) as ManagedIdentifierCoseKeyResult
82
107
  }
83
108
 
84
- private async identifierGetManagedByX5c(args: ManagedIdentifierX5cOpts, context: IAgentContext<IKeyManager>): Promise<ManagedIdentifierX5cResult> {
85
- return (await this.identifierGetManaged({ ...args, method: 'x5c' }, context)) as ManagedIdentifierX5cResult
109
+ private async identifierGetManagedByJwk(
110
+ args: ManagedIdentifierJwkOpts,
111
+ context: IAgentContext<IKeyManager & IIdentifierResolution>
112
+ ): Promise<ManagedIdentifierJwkResult> {
113
+ return (await this.identifierGetManaged({ ...args, method: 'jwk' }, context)) as ManagedIdentifierJwkResult
86
114
  }
87
115
 
88
- private async identifierManagedLazyResult(
89
- identifier: ManagedIdentifierOptsOrResult,
90
- context: IAgentContext<IIdentifierResolution>
91
- ): Promise<ManagedIdentifierResult> {
92
- return await ensureManagedIdentifierResult(identifier, context)
116
+ private async identifierGetManagedByX5c(
117
+ args: ManagedIdentifierX5cOpts,
118
+ context: IAgentContext<IKeyManager & IIdentifierResolution>
119
+ ): Promise<ManagedIdentifierX5cResult> {
120
+ return (await this.identifierGetManaged({ ...args, method: 'x5c' }, context)) as ManagedIdentifierX5cResult
93
121
  }
94
122
 
95
123
  private async identifierResolveExternal(args: ExternalIdentifierOpts, context: IAgentContext<IKeyManager>): Promise<ExternalIdentifierResult> {
@@ -103,4 +131,14 @@ export class IdentifierResolution implements IAgentPlugin {
103
131
  private async identifierExternalResolveByX5c(args: ExternalIdentifierX5cOpts, context: IAgentContext<any>): Promise<ExternalIdentifierX5cResult> {
104
132
  return (await this.identifierResolveExternal({ ...args, method: 'x5c' }, context)) as ExternalIdentifierX5cResult
105
133
  }
134
+
135
+ private async identifierExternalResolveByCoseKey(
136
+ args: ExternalIdentifierCoseKeyOpts,
137
+ context: IAgentContext<any>
138
+ ): Promise<ExternalIdentifierCoseKeyResult> {
139
+ return (await this.identifierResolveExternal({ ...args, method: 'cose_key' }, context)) as ExternalIdentifierCoseKeyResult
140
+ }
141
+ private async identifierExternalResolveByJwk(args: ExternalIdentifierJwkOpts, context: IAgentContext<any>): Promise<ExternalIdentifierJwkResult> {
142
+ return (await this.identifierResolveExternal({ ...args, method: 'jwk' }, context)) as ExternalIdentifierJwkResult
143
+ }
106
144
  }
@@ -19,13 +19,17 @@ export function legacyKeyRefsToIdentifierOpts(opts: {
19
19
  let kmsKeyRef =
20
20
  opts.keyRef ??
21
21
  opts.didOpts?.idOpts?.kmsKeyRef ??
22
+ opts.didOpts?.kid ??
23
+ opts.didOpts.idOpts?.kid ??
22
24
  (typeof opts.didOpts?.idOpts.identifier === 'object' ? (opts.didOpts?.idOpts.identifier as IIdentifier).keys[0].kid : undefined)
23
25
  if (!kmsKeyRef) {
24
26
  throw Error('Key ref is needed for access token signer')
25
27
  }
28
+ let identifier = (opts.didOpts?.identifier ?? opts.didOpts?.idOpts?.identifier) as IIdentifier | undefined
29
+
26
30
  return {
27
31
  kmsKeyRef: opts.keyRef ?? kmsKeyRef,
28
- identifier: kmsKeyRef,
32
+ identifier: identifier ?? kmsKeyRef,
29
33
  issuer: opts.iss,
30
34
  } satisfies ManagedIdentifierDidOpts
31
35
  } else {
@@ -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,20 +8,26 @@ 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,
@@ -39,6 +45,10 @@ export async function resolveExternalIdentifier(
39
45
  return resolveExternalDidIdentifier(opts, context)
40
46
  } else if (isExternalIdentifierX5cOpts(opts)) {
41
47
  return resolveExternalX5cIdentifier(opts, context)
48
+ } else if (isExternalIdentifierJwkOpts(opts)) {
49
+ return resolveExternalJwkIdentifier(opts, context)
50
+ } else if (isExternalIdentifierCoseKeyOpts(opts)) {
51
+ return resolveExternalCoseKeyIdentifier(opts, context)
42
52
  } else if (isExternalIdentifierKidOpts(opts)) {
43
53
  method = 'kid'
44
54
  } else if (isExternalIdentifierJwksUrlOpts(opts)) {
@@ -82,6 +92,7 @@ export async function resolveExternalX5cIdentifier(
82
92
  chain: opts.identifier,
83
93
  trustAnchors: opts.trustAnchors ?? [],
84
94
  verificationTime: opts.verificationTime,
95
+ opts,
85
96
  })
86
97
  }
87
98
  if (verificationResult.certificateChain) {
@@ -90,6 +101,7 @@ export async function resolveExternalX5cIdentifier(
90
101
  jwk: cert.publicKeyJWK,
91
102
  kid: cert.subject.dn.DN,
92
103
  jwkThumbprint: calculateJwkThumbprint({ jwk: cert.publicKeyJWK }),
104
+ publicKeyHex: jwkTtoPublicKeyHex(cert.publicKeyJWK),
93
105
  } satisfies ExternalJwkInfo
94
106
  })
95
107
  }
@@ -108,6 +120,7 @@ export async function resolveExternalX5cIdentifier(
108
120
  jwk,
109
121
  kid: getSubjectDN(cert).DN,
110
122
  jwkThumbprint: calculateJwkThumbprint({ jwk }),
123
+ publicKeyHex: jwkTtoPublicKeyHex(jwk),
111
124
  } satisfies ExternalJwkInfo
112
125
  })
113
126
  )
@@ -129,6 +142,78 @@ export async function resolveExternalX5cIdentifier(
129
142
  }
130
143
  }
131
144
 
145
+ /**
146
+ * Resolves a JWK. Normally this is just returning the JWK, but in case the JWK contains a x5c the chain is validated
147
+ * @param opts
148
+ * @param context
149
+ */
150
+ export async function resolveExternalJwkIdentifier(
151
+ opts: ExternalIdentifierJwkOpts & {
152
+ x5c?: ExternalIdentifierX5cOpts
153
+ },
154
+ context: IAgentContext<any>
155
+ ): Promise<ExternalIdentifierJwkResult> {
156
+ if (!isExternalIdentifierJwkOpts(opts)) {
157
+ return Promise.reject('External JWK Identifier args need to be provided')
158
+ }
159
+ const jwk = opts.identifier
160
+ let x5c: ExternalIdentifierX5cResult | undefined = undefined
161
+ if (jwk.x5c) {
162
+ x5c = await resolveExternalX5cIdentifier({ ...opts.x5c, identifier: jwk.x5c }, context)
163
+ }
164
+ const jwkThumbprint = calculateJwkThumbprint({ jwk })
165
+ return {
166
+ method: 'jwk',
167
+ jwk,
168
+ jwks: [
169
+ {
170
+ jwk,
171
+ jwkThumbprint,
172
+ kid: jwk.kid,
173
+ publicKeyHex: jwkTtoPublicKeyHex(jwk),
174
+ },
175
+ ],
176
+ x5c,
177
+ } satisfies ExternalIdentifierJwkResult
178
+ }
179
+
180
+ /**
181
+ * Resolves a JWK. Normally this is just returning the JWK, but in case the JWK contains a x5c the chain is validated
182
+ * @param opts
183
+ * @param context
184
+ */
185
+ export async function resolveExternalCoseKeyIdentifier(
186
+ opts: ExternalIdentifierCoseKeyOpts & {
187
+ x5c?: ExternalIdentifierX5cOpts
188
+ },
189
+ context: IAgentContext<any>
190
+ ): Promise<ExternalIdentifierCoseKeyResult> {
191
+ if (!isExternalIdentifierCoseKeyOpts(opts)) {
192
+ return Promise.reject('External Cose Key args need to be provided')
193
+ }
194
+ // TODO: We need to do cbor conversion here as well.
195
+ const coseKey = opts.identifier
196
+ let x5c: ExternalIdentifierX5cResult | undefined = undefined
197
+ if (coseKey.x5chain) {
198
+ x5c = await resolveExternalX5cIdentifier({ ...opts.x5c, identifier: coseKey.x5chain }, context)
199
+ }
200
+ const jwk = coseKeyToJwk(coseKey)
201
+ const jwkThumbprint = calculateJwkThumbprint({ jwk })
202
+ return {
203
+ method: 'cose_key',
204
+ coseKey,
205
+ jwks: [
206
+ {
207
+ jwk,
208
+ jwkThumbprint,
209
+ kid: coseKey.kid,
210
+ publicKeyHex: jwkTtoPublicKeyHex(jwk),
211
+ },
212
+ ],
213
+ x5c,
214
+ } satisfies ExternalIdentifierCoseKeyResult
215
+ }
216
+
132
217
  export async function resolveExternalDidIdentifier(
133
218
  opts: ExternalIdentifierDidOpts,
134
219
  context: IAgentContext<IResolver & IDIDManager>
@@ -163,7 +248,12 @@ export async function resolveExternalDidIdentifier(
163
248
  .flatMap((jwks) => jwks)
164
249
  )
165
250
  ).map((jwk) => {
166
- return { jwk, jwkThumbprint: calculateJwkThumbprint({ jwk }), kid: jwk.kid }
251
+ return {
252
+ jwk,
253
+ jwkThumbprint: calculateJwkThumbprint({ jwk }),
254
+ kid: jwk.kid,
255
+ publicKeyHex: jwkTtoPublicKeyHex(jwk),
256
+ }
167
257
  })
168
258
  : []
169
259
 
@@ -1,11 +1,13 @@
1
1
  import { getFirstKeyWithRelation } from '@sphereon/ssi-sdk-ext.did-utils'
2
- import { calculateJwkThumbprint, JWK, toJwk } from '@sphereon/ssi-sdk-ext.key-utils'
2
+ import { calculateJwkThumbprint, coseKeyToJwk, toJwk } from '@sphereon/ssi-sdk-ext.key-utils'
3
3
  import { pemOrDerToX509Certificate } from '@sphereon/ssi-sdk-ext.x509-utils'
4
4
  import { contextHasDidManager, contextHasKeyManager } from '@sphereon/ssi-sdk.agent-config'
5
+ import { ICoseKeyJson, JWK } from '@sphereon/ssi-types'
5
6
  import { IAgentContext, IIdentifier, IKey, IKeyManager } from '@veramo/core'
6
7
  import { CryptoEngine, setEngine } from 'pkijs'
7
8
  import {
8
9
  IIdentifierResolution,
10
+ isManagedIdentifierCoseKeyOpts,
9
11
  isManagedIdentifierDidOpts,
10
12
  isManagedIdentifierDidResult,
11
13
  isManagedIdentifierJwkOpts,
@@ -14,6 +16,8 @@ import {
14
16
  isManagedIdentifierKeyResult,
15
17
  isManagedIdentifierKidOpts,
16
18
  isManagedIdentifierX5cOpts,
19
+ ManagedIdentifierCoseKeyOpts,
20
+ ManagedIdentifierCoseKeyResult,
17
21
  ManagedIdentifierDidOpts,
18
22
  ManagedIdentifierDidResult,
19
23
  ManagedIdentifierJwkOpts,
@@ -22,7 +26,6 @@ import {
22
26
  ManagedIdentifierKeyResult,
23
27
  ManagedIdentifierKidOpts,
24
28
  ManagedIdentifierKidResult,
25
- ManagedIdentifierOpts,
26
29
  ManagedIdentifierOptsOrResult,
27
30
  ManagedIdentifierResult,
28
31
  ManagedIdentifierX5cOpts,
@@ -36,6 +39,8 @@ export async function getManagedKidIdentifier(
36
39
  const method = 'kid'
37
40
  if (!contextHasKeyManager(context)) {
38
41
  return Promise.reject(Error(`Cannot get Key/JWK identifier if KeyManager plugin is not enabled!`))
42
+ } else if (opts.identifier.startsWith('did:')) {
43
+ return Promise.reject(Error(`managed kid resolution called but a did url was passed in. Please call the did resolution method`))
39
44
  }
40
45
  const key = await context.agent.keyManagerGet({ kid: opts.kmsKeyRef ?? opts.identifier })
41
46
  const jwk = toJwk(key.publicKeyHex, key.type, { key })
@@ -45,27 +50,39 @@ export async function getManagedKidIdentifier(
45
50
  return {
46
51
  method,
47
52
  key,
53
+ identifier: opts.identifier,
48
54
  jwk,
49
55
  jwkThumbprint,
50
56
  kid,
57
+ clientId: opts.clientId,
58
+ clientIdScheme: opts.clientIdScheme,
51
59
  issuer,
52
60
  kmsKeyRef: key.kid,
53
61
  opts,
54
62
  } satisfies ManagedIdentifierKidResult
55
63
  }
56
64
 
65
+ export function isManagedIdentifierResult(
66
+ identifier: ManagedIdentifierOptsOrResult & {
67
+ crypto?: Crypto
68
+ }
69
+ ): identifier is ManagedIdentifierResult {
70
+ return 'key' in identifier && 'kmsKeyRef' in identifier && 'method' in identifier && 'opts' in identifier && 'jwkThumbprint' in identifier
71
+ }
72
+
57
73
  /**
58
74
  * Allows to get a managed identifier result in case identifier options are passed in, but returns the identifier directly in case results are passed in. This means resolution can have happened before, or happens in this method
59
75
  * @param identifier
60
76
  * @param context
61
77
  */
62
78
  export async function ensureManagedIdentifierResult(
63
- identifier: ManagedIdentifierOptsOrResult,
64
- context: IAgentContext<IIdentifierResolution>
79
+ identifier: ManagedIdentifierOptsOrResult & {
80
+ crypto?: Crypto
81
+ },
82
+ context: IAgentContext<IKeyManager>
65
83
  ): Promise<ManagedIdentifierResult> {
66
- return 'key' in identifier && 'kmsKeyRef' in identifier && 'method' in identifier && 'opts' in identifier
67
- ? identifier
68
- : await context.agent.identifierManagedGet(identifier)
84
+ const { lazyDisabled = false } = identifier
85
+ return !lazyDisabled && isManagedIdentifierResult(identifier) ? identifier : await getManagedIdentifier(identifier, context)
69
86
  }
70
87
 
71
88
  /**
@@ -86,15 +103,52 @@ export async function getManagedKeyIdentifier(opts: ManagedIdentifierKeyOpts, _c
86
103
  return {
87
104
  method,
88
105
  key,
106
+ identifier: key,
89
107
  jwk,
90
108
  jwkThumbprint,
91
109
  kid,
92
110
  issuer,
93
111
  kmsKeyRef: key.kid,
112
+ clientId: opts.clientId,
113
+ clientIdScheme: opts.clientIdScheme,
94
114
  opts,
95
115
  } satisfies ManagedIdentifierKeyResult
96
116
  }
97
117
 
118
+ /**
119
+ * This function is just a convenience function to get a common result. The user already apparently had a key, so could have called the kid version as well
120
+ * @param opts
121
+ * @param context
122
+ */
123
+ export async function getManagedCoseKeyIdentifier(
124
+ opts: ManagedIdentifierCoseKeyOpts,
125
+ context: IAgentContext<any>
126
+ ): Promise<ManagedIdentifierCoseKeyResult> {
127
+ const method = 'cose_key'
128
+ const coseKey: ICoseKeyJson = opts.identifier
129
+ if (!contextHasKeyManager(context)) {
130
+ return Promise.reject(Error(`Cannot get Cose Key identifier if KeyManager plugin is not enabled!`))
131
+ }
132
+ const jwk = coseKeyToJwk(coseKey)
133
+ const jwkThumbprint = calculateJwkThumbprint({ jwk })
134
+ const key = await context.agent.keyManagerGet({ kid: opts.kmsKeyRef ?? jwkThumbprint })
135
+ const kid = opts.kid ?? coseKey.kid ?? jwkThumbprint
136
+ const issuer = opts.issuer
137
+ return {
138
+ method,
139
+ key,
140
+ identifier: opts.identifier,
141
+ jwk,
142
+ jwkThumbprint,
143
+ kid,
144
+ issuer,
145
+ kmsKeyRef: key.kid,
146
+ clientId: opts.clientId,
147
+ clientIdScheme: opts.clientIdScheme,
148
+ opts,
149
+ } satisfies ManagedIdentifierCoseKeyResult
150
+ }
151
+
98
152
  export async function getManagedDidIdentifier(opts: ManagedIdentifierDidOpts, context: IAgentContext<any>): Promise<ManagedIdentifierDidResult> {
99
153
  const method = 'did'
100
154
  if (!contextHasDidManager(context)) {
@@ -141,6 +195,8 @@ export async function getManagedDidIdentifier(opts: ManagedIdentifierDidOpts, co
141
195
  keys,
142
196
  issuer,
143
197
  identifier,
198
+ clientId: opts.clientId,
199
+ clientIdScheme: opts.clientIdScheme,
144
200
  opts,
145
201
  }
146
202
  }
@@ -162,10 +218,13 @@ export async function getManagedJwkIdentifier(
162
218
  method,
163
219
  key,
164
220
  kmsKeyRef: key.kid,
221
+ identifier: jwk,
165
222
  jwk,
166
223
  jwkThumbprint,
167
224
  kid,
168
225
  issuer,
226
+ clientId: opts.clientId,
227
+ clientIdScheme: opts.clientIdScheme,
169
228
  opts,
170
229
  } satisfies ManagedIdentifierJwkResult
171
230
  }
@@ -197,6 +256,7 @@ export async function getManagedX5cIdentifier(
197
256
  return {
198
257
  method,
199
258
  x5c,
259
+ identifier: x5c,
200
260
  certificate,
201
261
  jwk,
202
262
  jwkThumbprint,
@@ -204,17 +264,22 @@ export async function getManagedX5cIdentifier(
204
264
  kmsKeyRef: key.kid,
205
265
  kid,
206
266
  issuer,
267
+ clientId: opts.clientId,
268
+ clientIdScheme: opts.clientIdScheme,
207
269
  opts,
208
270
  } satisfies ManagedIdentifierX5cResult
209
271
  }
210
272
 
211
273
  export async function getManagedIdentifier(
212
- opts: ManagedIdentifierOpts & {
274
+ opts: ManagedIdentifierOptsOrResult & {
213
275
  crypto?: Crypto
214
276
  },
215
277
  context: IAgentContext<IKeyManager>
216
278
  ): Promise<ManagedIdentifierResult> {
217
279
  let resolutionResult: ManagedIdentifierResult
280
+ if (isManagedIdentifierResult(opts)) {
281
+ opts
282
+ }
218
283
  if (isManagedIdentifierKidOpts(opts)) {
219
284
  resolutionResult = await getManagedKidIdentifier(opts, context)
220
285
  } else if (isManagedIdentifierDidOpts(opts)) {
@@ -225,6 +290,8 @@ export async function getManagedIdentifier(
225
290
  resolutionResult = await getManagedX5cIdentifier(opts, context)
226
291
  } else if (isManagedIdentifierKeyOpts(opts)) {
227
292
  resolutionResult = await getManagedKeyIdentifier(opts, context)
293
+ } else if (isManagedIdentifierCoseKeyOpts(opts)) {
294
+ resolutionResult = await getManagedCoseKeyIdentifier(opts, context)
228
295
  } else {
229
296
  return Promise.reject(Error(`Could not determine identifier method. Please provide explicitly`))
230
297
  }
@@ -238,7 +305,7 @@ export async function getManagedIdentifier(
238
305
 
239
306
  export async function managedIdentifierToKeyResult(
240
307
  identifier: ManagedIdentifierOptsOrResult,
241
- context: IAgentContext<IIdentifierResolution>
308
+ context: IAgentContext<IIdentifierResolution & IKeyManager>
242
309
  ): Promise<ManagedIdentifierKeyResult> {
243
310
  const resolved = await ensureManagedIdentifierResult(identifier, context)
244
311
  if (isManagedIdentifierKeyResult(resolved)) {
@@ -247,12 +314,13 @@ export async function managedIdentifierToKeyResult(
247
314
  return {
248
315
  ...resolved,
249
316
  method: 'key',
317
+ identifier: resolved.key,
250
318
  } satisfies ManagedIdentifierKeyResult
251
319
  }
252
320
 
253
321
  export async function managedIdentifierToJwk(
254
322
  identifier: ManagedIdentifierOptsOrResult,
255
- context: IAgentContext<IIdentifierResolution>
323
+ context: IAgentContext<IIdentifierResolution & IKeyManager>
256
324
  ): Promise<ManagedIdentifierJwkResult> {
257
325
  const resolved = await ensureManagedIdentifierResult(identifier, context)
258
326
  if (isManagedIdentifierJwkResult(resolved)) {
@@ -261,5 +329,6 @@ export async function managedIdentifierToJwk(
261
329
  return {
262
330
  ...resolved,
263
331
  method: 'jwk',
332
+ identifier: resolved.jwk,
264
333
  } satisfies ManagedIdentifierJwkResult
265
334
  }
@@ -1,13 +1,19 @@
1
1
  import { IAgentContext, IDIDManager, IKeyManager, IPluginMethodMap } from '@veramo/core'
2
2
  import {
3
+ ExternalIdentifierCoseKeyOpts,
4
+ ExternalIdentifierCoseKeyResult,
3
5
  ExternalIdentifierDidOpts,
4
6
  ExternalIdentifierDidResult,
7
+ ExternalIdentifierJwkOpts,
8
+ ExternalIdentifierJwkResult,
5
9
  ExternalIdentifierOpts,
6
10
  ExternalIdentifierResult,
7
11
  ExternalIdentifierX5cOpts,
8
12
  ExternalIdentifierX5cResult,
9
13
  } from './externalIdentifierTypes'
10
14
  import {
15
+ ManagedIdentifierCoseKeyOpts,
16
+ ManagedIdentifierCoseKeyResult,
11
17
  ManagedIdentifierDidOpts,
12
18
  ManagedIdentifierDidResult,
13
19
  ManagedIdentifierJwkOpts,
@@ -16,7 +22,6 @@ import {
16
22
  ManagedIdentifierKeyResult,
17
23
  ManagedIdentifierKidOpts,
18
24
  ManagedIdentifierKidResult,
19
- ManagedIdentifierOpts,
20
25
  ManagedIdentifierOptsOrResult,
21
26
  ManagedIdentifierResult,
22
27
  ManagedIdentifierX5cOpts,
@@ -31,10 +36,12 @@ export const identifierResolutionContextMethods: Array<string> = [
31
36
  'identifierManagedGetByJwk',
32
37
  'identifierManagedGetByX5c',
33
38
  'identifierManagedGetByKey',
39
+ 'identifierGetManagedByCoseKey',
34
40
  'identifierExternalResolve',
35
41
  'identifierExternalResolveByDid',
36
42
  'identifierExternalResolveByX5c',
37
- 'identifierManagedLazyResult',
43
+ 'identifierExternalResolveByJwk',
44
+ 'identifierExternalResolveByCoseKey',
38
45
  ]
39
46
 
40
47
  /**
@@ -45,11 +52,15 @@ export interface IIdentifierResolution extends IPluginMethodMap {
45
52
  * Main method for managed identifiers. We always go through this method (also the others) as we want to integrate a plugin for anomaly detection. Having a single method helps
46
53
  *
47
54
  * The end result of all these methods is a common baseline response that allows to use a key from the registered KMS systems. It also provides kid and iss(uer) values that can be used in a JWT/JWS for instance
55
+ * Allows to get a managed identifier result in case identifier options are passed in, but returns the identifier directly in case results are passed in. This means resolution can have happened before, or happens in this method
56
+ *
57
+ * We use the opts or result type almost everywhere, as it allows for just in time resolution whenever this method is called and afterwards we have the result, so resolution doesn't have to hit the DB, or external endpoints.
58
+ * Also use this method in the local agent, not using REST. If case the identifier needs to be resolved, you can always have the above methods using REST
48
59
  * @param args
49
60
  * @param context
50
61
  * @public
51
62
  */
52
- identifierManagedGet(args: ManagedIdentifierOpts, context: IAgentContext<IKeyManager>): Promise<ManagedIdentifierResult>
63
+ identifierManagedGet(args: ManagedIdentifierOptsOrResult, context: IAgentContext<IKeyManager>): Promise<ManagedIdentifierResult>
53
64
 
54
65
  identifierManagedGetByDid(args: ManagedIdentifierDidOpts, context: IAgentContext<IKeyManager & IDIDManager>): Promise<ManagedIdentifierDidResult>
55
66
 
@@ -61,15 +72,10 @@ export interface IIdentifierResolution extends IPluginMethodMap {
61
72
 
62
73
  identifierManagedGetByKey(args: ManagedIdentifierKeyOpts, context: IAgentContext<IKeyManager>): Promise<ManagedIdentifierKeyResult>
63
74
 
64
- /**
65
- * Allows to get a managed identifier result in case identifier options are passed in, but returns the identifier directly in case results are passed in. This means resolution can have happened before, or happens in this method
66
- *
67
- * We use the opts or result type almost everywhere, as it allows for just in time resolution whenever this method is called and afterwards we have the result, so resolution doesn't have to hit the DB, or external endpoints.
68
- * Also use this method in the local agent, not using REST. If case the identifier needs to be resolved, you can always have the above methods using REST
69
- * @param identifier
70
- * @param context
71
- */
72
- identifierManagedLazyResult(identifier: ManagedIdentifierOptsOrResult, context: IAgentContext<IIdentifierResolution>): Promise<ManagedIdentifierResult>
75
+ identifierManagedGetByCoseKey(
76
+ args: ManagedIdentifierCoseKeyOpts,
77
+ context: IAgentContext<IKeyManager & IIdentifierResolution>
78
+ ): Promise<ManagedIdentifierCoseKeyResult>
73
79
 
74
80
  // TODO: We can create a custom managed identifier method allowing developers to register a callback function to get their implementation hooked up. Needs more investigation as it would also impact the KMS
75
81
 
@@ -83,5 +89,9 @@ export interface IIdentifierResolution extends IPluginMethodMap {
83
89
 
84
90
  identifierExternalResolveByDid(args: ExternalIdentifierDidOpts, context: IAgentContext<any>): Promise<ExternalIdentifierDidResult>
85
91
 
92
+ identifierExternalResolveByJwk(args: ExternalIdentifierJwkOpts, context: IAgentContext<any>): Promise<ExternalIdentifierJwkResult>
93
+
94
+ identifierExternalResolveByCoseKey(args: ExternalIdentifierCoseKeyOpts, context: IAgentContext<any>): Promise<ExternalIdentifierCoseKeyResult>
95
+
86
96
  identifierExternalResolveByX5c(args: ExternalIdentifierX5cOpts, context: IAgentContext<any>): Promise<ExternalIdentifierX5cResult>
87
97
  }
@@ -1,4 +1,4 @@
1
- import { JWK } from '@sphereon/ssi-sdk-ext.key-utils'
1
+ import { ICoseKeyJson, JWK } from '@sphereon/ssi-types'
2
2
  import { IIdentifier, IKey } from '@veramo/core'
3
3
  import { ExternalIdentifierType } from './externalIdentifierTypes'
4
4
  import { ManagedIdentifierType } from './managedIdentifierTypes'
@@ -42,6 +42,10 @@ export function isKeyIdentifier(identifier: ManagedIdentifierType): identifier i
42
42
  )
43
43
  }
44
44
 
45
+ export function isCoseKeyIdentifier(identifier: ManagedIdentifierType): identifier is ICoseKeyJson {
46
+ return typeof identifier === 'object' && `kty` in identifier && ('baseIV' in identifier || 'x5chain' in identifier) && !('x5c' in identifier)
47
+ }
48
+
45
49
  export function isX5cIdentifier(identifier: ManagedIdentifierType | ExternalIdentifierType): identifier is string[] {
46
50
  return Array.isArray(identifier) && identifier.length > 0 // todo: Do we want to do additional validation? We know it must be DER and thus hex for instance
47
51
  }