@sphereon/ssi-sdk-ext.identifier-resolution 0.24.1-unstable.92 → 0.25.0
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.
- package/dist/agent/IdentifierResolution.d.ts +4 -0
- package/dist/agent/IdentifierResolution.d.ts.map +1 -1
- package/dist/agent/IdentifierResolution.js +25 -1
- package/dist/agent/IdentifierResolution.js.map +1 -1
- package/dist/functions/LegacySupport.d.ts +12 -0
- package/dist/functions/LegacySupport.d.ts.map +1 -0
- package/dist/functions/LegacySupport.js +39 -0
- package/dist/functions/LegacySupport.js.map +1 -0
- package/dist/functions/externalIdentifierFunctions.d.ts +17 -1
- package/dist/functions/externalIdentifierFunctions.d.ts.map +1 -1
- package/dist/functions/externalIdentifierFunctions.js +85 -6
- package/dist/functions/externalIdentifierFunctions.js.map +1 -1
- package/dist/functions/index.d.ts +1 -11
- package/dist/functions/index.d.ts.map +1 -1
- package/dist/functions/index.js +1 -36
- package/dist/functions/index.js.map +1 -1
- package/dist/functions/managedIdentifierFunctions.d.ts +17 -4
- package/dist/functions/managedIdentifierFunctions.d.ts.map +1 -1
- package/dist/functions/managedIdentifierFunctions.js +134 -12
- package/dist/functions/managedIdentifierFunctions.js.map +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/dist/types/IIdentifierResolution.d.ts +12 -3
- package/dist/types/IIdentifierResolution.d.ts.map +1 -1
- package/dist/types/IIdentifierResolution.js +17 -0
- package/dist/types/IIdentifierResolution.js.map +1 -1
- package/dist/types/common.d.ts +3 -1
- package/dist/types/common.d.ts.map +1 -1
- package/dist/types/common.js +17 -10
- package/dist/types/common.js.map +1 -1
- package/dist/types/externalIdentifierTypes.d.ts +23 -6
- package/dist/types/externalIdentifierTypes.d.ts.map +1 -1
- package/dist/types/externalIdentifierTypes.js +11 -7
- package/dist/types/externalIdentifierTypes.js.map +1 -1
- package/dist/types/managedIdentifierTypes.d.ts +43 -15
- package/dist/types/managedIdentifierTypes.d.ts.map +1 -1
- package/dist/types/managedIdentifierTypes.js +24 -11
- package/dist/types/managedIdentifierTypes.js.map +1 -1
- package/package.json +12 -12
- package/plugin.schema.json +2555 -313
- package/src/agent/IdentifierResolution.ts +63 -10
- package/src/functions/LegacySupport.ts +54 -0
- package/src/functions/externalIdentifierFunctions.ts +95 -5
- package/src/functions/index.ts +1 -51
- package/src/functions/managedIdentifierFunctions.ts +158 -10
- package/src/types/IIdentifierResolution.ts +42 -2
- package/src/types/common.ts +10 -2
- package/src/types/externalIdentifierTypes.ts +54 -13
- package/src/types/managedIdentifierTypes.ts +78 -16
|
@@ -1,26 +1,34 @@
|
|
|
1
|
-
import { IRequiredContext } from '@sphereon/ssi-sdk-ext.did-provider-jwk'
|
|
2
1
|
import { getFirstKeyWithRelation } from '@sphereon/ssi-sdk-ext.did-utils'
|
|
3
|
-
import { calculateJwkThumbprint,
|
|
2
|
+
import { calculateJwkThumbprint, coseKeyToJwk, toJwk } from '@sphereon/ssi-sdk-ext.key-utils'
|
|
4
3
|
import { pemOrDerToX509Certificate } from '@sphereon/ssi-sdk-ext.x509-utils'
|
|
5
4
|
import { contextHasDidManager, contextHasKeyManager } from '@sphereon/ssi-sdk.agent-config'
|
|
5
|
+
import { ICoseKeyJson, JWK } from '@sphereon/ssi-types'
|
|
6
6
|
import { IAgentContext, IIdentifier, IKey, IKeyManager } from '@veramo/core'
|
|
7
7
|
import { CryptoEngine, setEngine } from 'pkijs'
|
|
8
8
|
import {
|
|
9
|
+
IIdentifierResolution,
|
|
10
|
+
isManagedIdentifierCoseKeyOpts,
|
|
9
11
|
isManagedIdentifierDidOpts,
|
|
10
12
|
isManagedIdentifierDidResult,
|
|
13
|
+
isManagedIdentifierOID4VCIssuerOpts,
|
|
11
14
|
isManagedIdentifierJwkOpts,
|
|
15
|
+
isManagedIdentifierJwkResult,
|
|
12
16
|
isManagedIdentifierKeyOpts,
|
|
17
|
+
isManagedIdentifierKeyResult,
|
|
13
18
|
isManagedIdentifierKidOpts,
|
|
14
19
|
isManagedIdentifierX5cOpts,
|
|
20
|
+
ManagedIdentifierCoseKeyOpts,
|
|
21
|
+
ManagedIdentifierCoseKeyResult,
|
|
15
22
|
ManagedIdentifierDidOpts,
|
|
16
23
|
ManagedIdentifierDidResult,
|
|
24
|
+
ManagedIdentifierOID4VCIssuerOpts,
|
|
25
|
+
ManagedIdentifierOID4VCIssuerResult,
|
|
17
26
|
ManagedIdentifierJwkOpts,
|
|
18
27
|
ManagedIdentifierJwkResult,
|
|
19
28
|
ManagedIdentifierKeyOpts,
|
|
20
29
|
ManagedIdentifierKeyResult,
|
|
21
30
|
ManagedIdentifierKidOpts,
|
|
22
31
|
ManagedIdentifierKidResult,
|
|
23
|
-
ManagedIdentifierOpts,
|
|
24
32
|
ManagedIdentifierOptsOrResult,
|
|
25
33
|
ManagedIdentifierResult,
|
|
26
34
|
ManagedIdentifierX5cOpts,
|
|
@@ -34,6 +42,8 @@ export async function getManagedKidIdentifier(
|
|
|
34
42
|
const method = 'kid'
|
|
35
43
|
if (!contextHasKeyManager(context)) {
|
|
36
44
|
return Promise.reject(Error(`Cannot get Key/JWK identifier if KeyManager plugin is not enabled!`))
|
|
45
|
+
} else if (opts.identifier.startsWith('did:')) {
|
|
46
|
+
return Promise.reject(Error(`managed kid resolution called but a did url was passed in. Please call the did resolution method`))
|
|
37
47
|
}
|
|
38
48
|
const key = await context.agent.keyManagerGet({ kid: opts.kmsKeyRef ?? opts.identifier })
|
|
39
49
|
const jwk = toJwk(key.publicKeyHex, key.type, { key })
|
|
@@ -43,27 +53,39 @@ export async function getManagedKidIdentifier(
|
|
|
43
53
|
return {
|
|
44
54
|
method,
|
|
45
55
|
key,
|
|
56
|
+
identifier: opts.identifier,
|
|
46
57
|
jwk,
|
|
47
58
|
jwkThumbprint,
|
|
48
59
|
kid,
|
|
60
|
+
clientId: opts.clientId,
|
|
61
|
+
clientIdScheme: opts.clientIdScheme,
|
|
49
62
|
issuer,
|
|
50
63
|
kmsKeyRef: key.kid,
|
|
51
64
|
opts,
|
|
52
65
|
} satisfies ManagedIdentifierKidResult
|
|
53
66
|
}
|
|
54
67
|
|
|
68
|
+
export function isManagedIdentifierResult(
|
|
69
|
+
identifier: ManagedIdentifierOptsOrResult & {
|
|
70
|
+
crypto?: Crypto
|
|
71
|
+
}
|
|
72
|
+
): identifier is ManagedIdentifierResult {
|
|
73
|
+
return 'key' in identifier && 'kmsKeyRef' in identifier && 'method' in identifier && 'opts' in identifier && 'jwkThumbprint' in identifier
|
|
74
|
+
}
|
|
75
|
+
|
|
55
76
|
/**
|
|
56
77
|
* 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
|
|
57
78
|
* @param identifier
|
|
58
79
|
* @param context
|
|
59
80
|
*/
|
|
60
81
|
export async function ensureManagedIdentifierResult(
|
|
61
|
-
identifier: ManagedIdentifierOptsOrResult
|
|
62
|
-
|
|
82
|
+
identifier: ManagedIdentifierOptsOrResult & {
|
|
83
|
+
crypto?: Crypto
|
|
84
|
+
},
|
|
85
|
+
context: IAgentContext<IKeyManager>
|
|
63
86
|
): Promise<ManagedIdentifierResult> {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
: await context.agent.identifierManagedGet(identifier)
|
|
87
|
+
const { lazyDisabled = false } = identifier
|
|
88
|
+
return !lazyDisabled && isManagedIdentifierResult(identifier) ? identifier : await getManagedIdentifier(identifier, context)
|
|
67
89
|
}
|
|
68
90
|
|
|
69
91
|
/**
|
|
@@ -84,15 +106,52 @@ export async function getManagedKeyIdentifier(opts: ManagedIdentifierKeyOpts, _c
|
|
|
84
106
|
return {
|
|
85
107
|
method,
|
|
86
108
|
key,
|
|
109
|
+
identifier: key,
|
|
87
110
|
jwk,
|
|
88
111
|
jwkThumbprint,
|
|
89
112
|
kid,
|
|
90
113
|
issuer,
|
|
91
114
|
kmsKeyRef: key.kid,
|
|
115
|
+
clientId: opts.clientId,
|
|
116
|
+
clientIdScheme: opts.clientIdScheme,
|
|
92
117
|
opts,
|
|
93
118
|
} satisfies ManagedIdentifierKeyResult
|
|
94
119
|
}
|
|
95
120
|
|
|
121
|
+
/**
|
|
122
|
+
* 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
|
|
123
|
+
* @param opts
|
|
124
|
+
* @param context
|
|
125
|
+
*/
|
|
126
|
+
export async function getManagedCoseKeyIdentifier(
|
|
127
|
+
opts: ManagedIdentifierCoseKeyOpts,
|
|
128
|
+
context: IAgentContext<any>
|
|
129
|
+
): Promise<ManagedIdentifierCoseKeyResult> {
|
|
130
|
+
const method = 'cose_key'
|
|
131
|
+
const coseKey: ICoseKeyJson = opts.identifier
|
|
132
|
+
if (!contextHasKeyManager(context)) {
|
|
133
|
+
return Promise.reject(Error(`Cannot get Cose Key identifier if KeyManager plugin is not enabled!`))
|
|
134
|
+
}
|
|
135
|
+
const jwk = coseKeyToJwk(coseKey)
|
|
136
|
+
const jwkThumbprint = calculateJwkThumbprint({ jwk })
|
|
137
|
+
const key = await context.agent.keyManagerGet({ kid: opts.kmsKeyRef ?? jwkThumbprint })
|
|
138
|
+
const kid = opts.kid ?? coseKey.kid ?? jwkThumbprint
|
|
139
|
+
const issuer = opts.issuer
|
|
140
|
+
return {
|
|
141
|
+
method,
|
|
142
|
+
key,
|
|
143
|
+
identifier: opts.identifier,
|
|
144
|
+
jwk,
|
|
145
|
+
jwkThumbprint,
|
|
146
|
+
kid,
|
|
147
|
+
issuer,
|
|
148
|
+
kmsKeyRef: key.kid,
|
|
149
|
+
clientId: opts.clientId,
|
|
150
|
+
clientIdScheme: opts.clientIdScheme,
|
|
151
|
+
opts,
|
|
152
|
+
} satisfies ManagedIdentifierCoseKeyResult
|
|
153
|
+
}
|
|
154
|
+
|
|
96
155
|
export async function getManagedDidIdentifier(opts: ManagedIdentifierDidOpts, context: IAgentContext<any>): Promise<ManagedIdentifierDidResult> {
|
|
97
156
|
const method = 'did'
|
|
98
157
|
if (!contextHasDidManager(context)) {
|
|
@@ -139,6 +198,8 @@ export async function getManagedDidIdentifier(opts: ManagedIdentifierDidOpts, co
|
|
|
139
198
|
keys,
|
|
140
199
|
issuer,
|
|
141
200
|
identifier,
|
|
201
|
+
clientId: opts.clientId,
|
|
202
|
+
clientIdScheme: opts.clientIdScheme,
|
|
142
203
|
opts,
|
|
143
204
|
}
|
|
144
205
|
}
|
|
@@ -160,10 +221,13 @@ export async function getManagedJwkIdentifier(
|
|
|
160
221
|
method,
|
|
161
222
|
key,
|
|
162
223
|
kmsKeyRef: key.kid,
|
|
224
|
+
identifier: jwk,
|
|
163
225
|
jwk,
|
|
164
226
|
jwkThumbprint,
|
|
165
227
|
kid,
|
|
166
228
|
issuer,
|
|
229
|
+
clientId: opts.clientId,
|
|
230
|
+
clientIdScheme: opts.clientIdScheme,
|
|
167
231
|
opts,
|
|
168
232
|
} satisfies ManagedIdentifierJwkResult
|
|
169
233
|
}
|
|
@@ -195,6 +259,7 @@ export async function getManagedX5cIdentifier(
|
|
|
195
259
|
return {
|
|
196
260
|
method,
|
|
197
261
|
x5c,
|
|
262
|
+
identifier: x5c,
|
|
198
263
|
certificate,
|
|
199
264
|
jwk,
|
|
200
265
|
jwkThumbprint,
|
|
@@ -202,17 +267,65 @@ export async function getManagedX5cIdentifier(
|
|
|
202
267
|
kmsKeyRef: key.kid,
|
|
203
268
|
kid,
|
|
204
269
|
issuer,
|
|
270
|
+
clientId: opts.clientId,
|
|
271
|
+
clientIdScheme: opts.clientIdScheme,
|
|
205
272
|
opts,
|
|
206
273
|
} satisfies ManagedIdentifierX5cResult
|
|
207
274
|
}
|
|
208
275
|
|
|
276
|
+
export async function getManagedOID4VCIssuerIdentifier(
|
|
277
|
+
opts: ManagedIdentifierOID4VCIssuerOpts,
|
|
278
|
+
context: IAgentContext<IKeyManager>
|
|
279
|
+
): Promise<ManagedIdentifierOID4VCIssuerResult> {
|
|
280
|
+
const { identifier } = opts
|
|
281
|
+
const method = 'oid4vci-issuer'
|
|
282
|
+
// FIXME: We need to eventually determine the JWK based on the issuer. Using a dummy JWK for now
|
|
283
|
+
const jwk = {
|
|
284
|
+
"kty" : "RSA",
|
|
285
|
+
"kid" : "dummy-jwk-for-vci-issuer-signing",
|
|
286
|
+
"use" : "sig",
|
|
287
|
+
"n" : "pjdss8ZaDfEH6K6U7GeW2nxDqR4IP049fk1fK0lndimbMMVBdPv_hSpm8T8EtBDxrUdi1OHZfMhUixGaut-3nQ4GG9nM249oxhCtxqqNvEXrmQRGqczyLxuh-fKn9Fg--hS9UpazHpfVAFnB5aCfXoNhPuI8oByyFKMKaOVgHNqP5NBEqabiLftZD3W_lsFCPGuzr4Vp0YS7zS2hDYScC2oOMu4rGU1LcMZf39p3153Cq7bS2Xh6Y-vw5pwzFYZdjQxDn8x8BG3fJ6j8TGLXQsbKH1218_HcUJRvMwdpbUQG5nvA2GXVqLqdwp054Lzk9_B_f1lVrmOKuHjTNHq48w",
|
|
288
|
+
"e" : "AQAB",
|
|
289
|
+
"d" : "ksDmucdMJXkFGZxiomNHnroOZxe8AmDLDGO1vhs-POa5PZM7mtUPonxwjVmthmpbZzla-kg55OFfO7YcXhg-Hm2OWTKwm73_rLh3JavaHjvBqsVKuorX3V3RYkSro6HyYIzFJ1Ek7sLxbjDRcDOj4ievSX0oN9l-JZhaDYlPlci5uJsoqro_YrE0PRRWVhtGynd-_aWgQv1YzkfZuMD-hJtDi1Im2humOWxA4eZrFs9eG-whXcOvaSwO4sSGbS99ecQZHM2TcdXeAs1PvjVgQ_dKnZlGN3lTWoWfQP55Z7Tgt8Nf1q4ZAKd-NlMe-7iqCFfsnFwXjSiaOa2CRGZn-Q",
|
|
290
|
+
"p" : "4A5nU4ahEww7B65yuzmGeCUUi8ikWzv1C81pSyUKvKzu8CX41hp9J6oRaLGesKImYiuVQK47FhZ--wwfpRwHvSxtNU9qXb8ewo-BvadyO1eVrIk4tNV543QlSe7pQAoJGkxCia5rfznAE3InKF4JvIlchyqs0RQ8wx7lULqwnn0",
|
|
291
|
+
"q" : "ven83GM6SfrmO-TBHbjTk6JhP_3CMsIvmSdo4KrbQNvp4vHO3w1_0zJ3URkmkYGhz2tgPlfd7v1l2I6QkIh4Bumdj6FyFZEBpxjE4MpfdNVcNINvVj87cLyTRmIcaGxmfylY7QErP8GFA-k4UoH_eQmGKGK44TRzYj5hZYGWIC8",
|
|
292
|
+
"dp" : "lmmU_AG5SGxBhJqb8wxfNXDPJjf__i92BgJT2Vp4pskBbr5PGoyV0HbfUQVMnw977RONEurkR6O6gxZUeCclGt4kQlGZ-m0_XSWx13v9t9DIbheAtgVJ2mQyVDvK4m7aRYlEceFh0PsX8vYDS5o1txgPwb3oXkPTtrmbAGMUBpE",
|
|
293
|
+
"dq" : "mxRTU3QDyR2EnCv0Nl0TCF90oliJGAHR9HJmBe__EjuCBbwHfcT8OG3hWOv8vpzokQPRl5cQt3NckzX3fs6xlJN4Ai2Hh2zduKFVQ2p-AF2p6Yfahscjtq-GY9cB85NxLy2IXCC0PF--Sq9LOrTE9QV988SJy_yUrAjcZ5MmECk",
|
|
294
|
+
"qi" : "ldHXIrEmMZVaNwGzDF9WG8sHj2mOZmQpw9yrjLK9hAsmsNr5LTyqWAqJIYZSwPTYWhY4nu2O0EY9G9uYiqewXfCKw_UngrJt8Xwfq1Zruz0YY869zPN4GiE9-9rzdZB33RBw8kIOquY3MK74FMwCihYx_LiU2YTHkaoJ3ncvtvg"
|
|
295
|
+
} as JWK
|
|
296
|
+
const jwkThumbprint = calculateJwkThumbprint({ jwk })
|
|
297
|
+
|
|
298
|
+
const key = {
|
|
299
|
+
kid: 'dummy-key-for-vci-issuer-signing',
|
|
300
|
+
kms: 'local',
|
|
301
|
+
type: "RSA",
|
|
302
|
+
publicKeyHex: '9a3f75b2e4d8b91128fc6e9a8f6782e5a4f1cba3718e58b5d0a789d6e5f52b3a'
|
|
303
|
+
} as IKey
|
|
304
|
+
|
|
305
|
+
return {
|
|
306
|
+
method,
|
|
307
|
+
identifier,
|
|
308
|
+
jwk,
|
|
309
|
+
jwkThumbprint,
|
|
310
|
+
key, // FIXME: We need construct a key as soon as we have the external VCI Issuer resolution
|
|
311
|
+
kmsKeyRef: identifier, // FIXME: We need use kmsKeyRef as soon as we have the external VCI Issuer resolution
|
|
312
|
+
issuer: identifier.replace('/.well-known/openid-credential-issuer', ''),
|
|
313
|
+
clientId: opts.clientId,
|
|
314
|
+
clientIdScheme: opts.clientIdScheme,
|
|
315
|
+
opts,
|
|
316
|
+
} satisfies ManagedIdentifierOID4VCIssuerResult
|
|
317
|
+
}
|
|
318
|
+
|
|
209
319
|
export async function getManagedIdentifier(
|
|
210
|
-
opts:
|
|
320
|
+
opts: ManagedIdentifierOptsOrResult & {
|
|
211
321
|
crypto?: Crypto
|
|
212
322
|
},
|
|
213
323
|
context: IAgentContext<IKeyManager>
|
|
214
324
|
): Promise<ManagedIdentifierResult> {
|
|
215
325
|
let resolutionResult: ManagedIdentifierResult
|
|
326
|
+
if (isManagedIdentifierResult(opts)) {
|
|
327
|
+
opts
|
|
328
|
+
}
|
|
216
329
|
if (isManagedIdentifierKidOpts(opts)) {
|
|
217
330
|
resolutionResult = await getManagedKidIdentifier(opts, context)
|
|
218
331
|
} else if (isManagedIdentifierDidOpts(opts)) {
|
|
@@ -223,13 +336,48 @@ export async function getManagedIdentifier(
|
|
|
223
336
|
resolutionResult = await getManagedX5cIdentifier(opts, context)
|
|
224
337
|
} else if (isManagedIdentifierKeyOpts(opts)) {
|
|
225
338
|
resolutionResult = await getManagedKeyIdentifier(opts, context)
|
|
339
|
+
} else if (isManagedIdentifierCoseKeyOpts(opts)) {
|
|
340
|
+
resolutionResult = await getManagedCoseKeyIdentifier(opts, context)
|
|
341
|
+
} else if (isManagedIdentifierOID4VCIssuerOpts(opts)) {
|
|
342
|
+
resolutionResult = await getManagedOID4VCIssuerIdentifier(opts, context)
|
|
226
343
|
} else {
|
|
227
344
|
return Promise.reject(Error(`Could not determine identifier method. Please provide explicitly`))
|
|
228
345
|
}
|
|
229
346
|
const { key } = resolutionResult
|
|
230
|
-
if (!key || (isManagedIdentifierDidOpts(opts) && isManagedIdentifierDidResult(resolutionResult) && !resolutionResult.identifier)) {
|
|
347
|
+
if ((!key && !isManagedIdentifierOID4VCIssuerOpts(opts)) || (isManagedIdentifierDidOpts(opts) && isManagedIdentifierDidResult(resolutionResult) && !resolutionResult.identifier)) {
|
|
231
348
|
console.log(`Cannot find identifier`, opts.identifier)
|
|
232
349
|
return Promise.reject(`Cannot find identifier ${opts.identifier}`)
|
|
233
350
|
}
|
|
234
351
|
return resolutionResult
|
|
235
352
|
}
|
|
353
|
+
|
|
354
|
+
export async function managedIdentifierToKeyResult(
|
|
355
|
+
identifier: ManagedIdentifierOptsOrResult,
|
|
356
|
+
context: IAgentContext<IIdentifierResolution & IKeyManager>
|
|
357
|
+
): Promise<ManagedIdentifierKeyResult> {
|
|
358
|
+
const resolved = await ensureManagedIdentifierResult(identifier, context)
|
|
359
|
+
if (isManagedIdentifierKeyResult(resolved)) {
|
|
360
|
+
return resolved
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
return {
|
|
364
|
+
...resolved,
|
|
365
|
+
method: 'key',
|
|
366
|
+
identifier: resolved.key,
|
|
367
|
+
} satisfies ManagedIdentifierKeyResult
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
export async function managedIdentifierToJwk(
|
|
371
|
+
identifier: ManagedIdentifierOptsOrResult,
|
|
372
|
+
context: IAgentContext<IIdentifierResolution & IKeyManager>
|
|
373
|
+
): Promise<ManagedIdentifierJwkResult> {
|
|
374
|
+
const resolved = await ensureManagedIdentifierResult(identifier, context)
|
|
375
|
+
if (isManagedIdentifierJwkResult(resolved)) {
|
|
376
|
+
return resolved
|
|
377
|
+
}
|
|
378
|
+
return {
|
|
379
|
+
...resolved,
|
|
380
|
+
method: 'jwk',
|
|
381
|
+
identifier: resolved.jwk,
|
|
382
|
+
} satisfies ManagedIdentifierJwkResult
|
|
383
|
+
}
|
|
@@ -1,27 +1,52 @@
|
|
|
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,
|
|
19
|
+
ManagedIdentifierOID4VCIssuerOpts,
|
|
20
|
+
ManagedIdentifierOID4VCIssuerResult,
|
|
13
21
|
ManagedIdentifierJwkOpts,
|
|
14
22
|
ManagedIdentifierJwkResult,
|
|
15
23
|
ManagedIdentifierKeyOpts,
|
|
16
24
|
ManagedIdentifierKeyResult,
|
|
17
25
|
ManagedIdentifierKidOpts,
|
|
18
26
|
ManagedIdentifierKidResult,
|
|
19
|
-
|
|
27
|
+
ManagedIdentifierOptsOrResult,
|
|
20
28
|
ManagedIdentifierResult,
|
|
21
29
|
ManagedIdentifierX5cOpts,
|
|
22
30
|
ManagedIdentifierX5cResult,
|
|
23
31
|
} from './managedIdentifierTypes'
|
|
24
32
|
|
|
33
|
+
// Exposing the methods here for any REST implementation
|
|
34
|
+
export const identifierResolutionContextMethods: Array<string> = [
|
|
35
|
+
'identifierManagedGet',
|
|
36
|
+
'identifierManagedGetByDid',
|
|
37
|
+
'identifierManagedGetByKid',
|
|
38
|
+
'identifierManagedGetByJwk',
|
|
39
|
+
'identifierManagedGetByX5c',
|
|
40
|
+
'identifierManagedGetByKey',
|
|
41
|
+
'identifierManagedGetByOID4VCIssuer',
|
|
42
|
+
'identifierGetManagedByCoseKey',
|
|
43
|
+
'identifierExternalResolve',
|
|
44
|
+
'identifierExternalResolveByDid',
|
|
45
|
+
'identifierExternalResolveByX5c',
|
|
46
|
+
'identifierExternalResolveByJwk',
|
|
47
|
+
'identifierExternalResolveByCoseKey',
|
|
48
|
+
]
|
|
49
|
+
|
|
25
50
|
/**
|
|
26
51
|
* @public
|
|
27
52
|
*/
|
|
@@ -30,11 +55,15 @@ export interface IIdentifierResolution extends IPluginMethodMap {
|
|
|
30
55
|
* 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
|
|
31
56
|
*
|
|
32
57
|
* 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
|
|
58
|
+
* 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
|
+
*
|
|
60
|
+
* 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.
|
|
61
|
+
* 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
|
|
33
62
|
* @param args
|
|
34
63
|
* @param context
|
|
35
64
|
* @public
|
|
36
65
|
*/
|
|
37
|
-
identifierManagedGet(args:
|
|
66
|
+
identifierManagedGet(args: ManagedIdentifierOptsOrResult, context: IAgentContext<IKeyManager>): Promise<ManagedIdentifierResult>
|
|
38
67
|
|
|
39
68
|
identifierManagedGetByDid(args: ManagedIdentifierDidOpts, context: IAgentContext<IKeyManager & IDIDManager>): Promise<ManagedIdentifierDidResult>
|
|
40
69
|
|
|
@@ -46,6 +75,13 @@ export interface IIdentifierResolution extends IPluginMethodMap {
|
|
|
46
75
|
|
|
47
76
|
identifierManagedGetByKey(args: ManagedIdentifierKeyOpts, context: IAgentContext<IKeyManager>): Promise<ManagedIdentifierKeyResult>
|
|
48
77
|
|
|
78
|
+
identifierManagedGetByCoseKey(
|
|
79
|
+
args: ManagedIdentifierCoseKeyOpts,
|
|
80
|
+
context: IAgentContext<IKeyManager & IIdentifierResolution>
|
|
81
|
+
): Promise<ManagedIdentifierCoseKeyResult>
|
|
82
|
+
|
|
83
|
+
identifierManagedGetByOID4VCIssuer(args: ManagedIdentifierOID4VCIssuerOpts, context: IAgentContext<any>): Promise<ManagedIdentifierOID4VCIssuerResult>
|
|
84
|
+
|
|
49
85
|
// 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
|
|
50
86
|
|
|
51
87
|
/**
|
|
@@ -58,5 +94,9 @@ export interface IIdentifierResolution extends IPluginMethodMap {
|
|
|
58
94
|
|
|
59
95
|
identifierExternalResolveByDid(args: ExternalIdentifierDidOpts, context: IAgentContext<any>): Promise<ExternalIdentifierDidResult>
|
|
60
96
|
|
|
97
|
+
identifierExternalResolveByJwk(args: ExternalIdentifierJwkOpts, context: IAgentContext<any>): Promise<ExternalIdentifierJwkResult>
|
|
98
|
+
|
|
99
|
+
identifierExternalResolveByCoseKey(args: ExternalIdentifierCoseKeyOpts, context: IAgentContext<any>): Promise<ExternalIdentifierCoseKeyResult>
|
|
100
|
+
|
|
61
101
|
identifierExternalResolveByX5c(args: ExternalIdentifierX5cOpts, context: IAgentContext<any>): Promise<ExternalIdentifierX5cResult>
|
|
62
102
|
}
|
package/src/types/common.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { JWK } from '@sphereon/ssi-
|
|
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'
|
|
@@ -29,7 +29,11 @@ export function isJwksUrlIdentifier(identifier: ManagedIdentifierType | External
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
export function isKidIdentifier(identifier: ManagedIdentifierType | ExternalIdentifierType): identifier is string {
|
|
32
|
-
return typeof identifier === 'string' && !identifier.startsWith('did:')
|
|
32
|
+
return typeof identifier === 'string' && !identifier.startsWith('did:') && !identifier.startsWith('http')
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function isOID4VCIssuerIdentifier(identifier: ManagedIdentifierType | ExternalIdentifierType): identifier is string {
|
|
36
|
+
return typeof identifier === 'string' && identifier.startsWith('http') && identifier.endsWith('/.well-known/openid-credential-issuer')
|
|
33
37
|
}
|
|
34
38
|
|
|
35
39
|
export function isKeyIdentifier(identifier: ManagedIdentifierType): identifier is IKey {
|
|
@@ -42,6 +46,10 @@ export function isKeyIdentifier(identifier: ManagedIdentifierType): identifier i
|
|
|
42
46
|
)
|
|
43
47
|
}
|
|
44
48
|
|
|
49
|
+
export function isCoseKeyIdentifier(identifier: ManagedIdentifierType): identifier is ICoseKeyJson {
|
|
50
|
+
return typeof identifier === 'object' && `kty` in identifier && ('baseIV' in identifier || 'x5chain' in identifier) && !('x5c' in identifier)
|
|
51
|
+
}
|
|
52
|
+
|
|
45
53
|
export function isX5cIdentifier(identifier: ManagedIdentifierType | ExternalIdentifierType): identifier is string[] {
|
|
46
54
|
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
55
|
}
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import { DidDocumentJwks } from '@sphereon/ssi-sdk-ext.did-utils'
|
|
2
|
-
import { JWK } from '@sphereon/ssi-
|
|
3
|
-
import { X509ValidationResult } from '@sphereon/ssi-sdk-ext.x509-utils'
|
|
2
|
+
import { ICoseKeyJson, JWK } from '@sphereon/ssi-types'
|
|
3
|
+
import { X509CertificateChainValidationOpts, X509ValidationResult } from '@sphereon/ssi-sdk-ext.x509-utils'
|
|
4
4
|
import { IParsedDID } from '@sphereon/ssi-types'
|
|
5
5
|
import { DIDDocument, DIDDocumentSection, DIDResolutionResult } from '@veramo/core'
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
isCoseKeyIdentifier,
|
|
8
|
+
isDidIdentifier,
|
|
9
|
+
isJwkIdentifier,
|
|
10
|
+
isJwksUrlIdentifier,
|
|
11
|
+
isKidIdentifier,
|
|
12
|
+
isOidcDiscoveryIdentifier,
|
|
13
|
+
isX5cIdentifier,
|
|
14
|
+
JwkInfo,
|
|
15
|
+
} from './common'
|
|
7
16
|
|
|
8
17
|
/**
|
|
9
18
|
* Use whenever we need to resolve an external identifier. We can pass in kids, DIDs, and x5chains
|
|
@@ -32,7 +41,13 @@ export function isExternalIdentifierDidOpts(opts: ExternalIdentifierOptsBase): o
|
|
|
32
41
|
return ('method' in opts && opts.method === 'did') || isDidIdentifier(identifier)
|
|
33
42
|
}
|
|
34
43
|
|
|
35
|
-
export type ExternalIdentifierOpts = (
|
|
44
|
+
export type ExternalIdentifierOpts = (
|
|
45
|
+
| ExternalIdentifierJwkOpts
|
|
46
|
+
| ExternalIdentifierX5cOpts
|
|
47
|
+
| ExternalIdentifierDidOpts
|
|
48
|
+
| ExternalIdentifierKidOpts
|
|
49
|
+
| ExternalIdentifierCoseKeyOpts
|
|
50
|
+
) &
|
|
36
51
|
ExternalIdentifierOptsBase
|
|
37
52
|
|
|
38
53
|
export type ExternalIdentifierKidOpts = Omit<ExternalIdentifierOptsBase, 'method'> & {
|
|
@@ -48,6 +63,7 @@ export function isExternalIdentifierKidOpts(opts: ExternalIdentifierOptsBase): o
|
|
|
48
63
|
export type ExternalIdentifierJwkOpts = Omit<ExternalIdentifierOptsBase, 'method'> & {
|
|
49
64
|
method?: 'jwk'
|
|
50
65
|
identifier: JWK
|
|
66
|
+
x5c?: ExternalIdentifierX5cOpts
|
|
51
67
|
}
|
|
52
68
|
|
|
53
69
|
export function isExternalIdentifierJwkOpts(opts: ExternalIdentifierOptsBase): opts is ExternalIdentifierJwkOpts {
|
|
@@ -55,6 +71,16 @@ export function isExternalIdentifierJwkOpts(opts: ExternalIdentifierOptsBase): o
|
|
|
55
71
|
return ('method' in opts && opts.method === 'jwk') || isJwkIdentifier(identifier)
|
|
56
72
|
}
|
|
57
73
|
|
|
74
|
+
export type ExternalIdentifierCoseKeyOpts = Omit<ExternalIdentifierOptsBase, 'method'> & {
|
|
75
|
+
method?: 'cose_key'
|
|
76
|
+
identifier: ICoseKeyJson
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function isExternalIdentifierCoseKeyOpts(opts: ExternalIdentifierOptsBase): opts is ExternalIdentifierCoseKeyOpts {
|
|
80
|
+
const { identifier } = opts
|
|
81
|
+
return ('method' in opts && opts.method === 'cose_key') || isCoseKeyIdentifier(identifier)
|
|
82
|
+
}
|
|
83
|
+
|
|
58
84
|
export type ExternalIdentifierOidcDiscoveryOpts = Omit<ExternalIdentifierOptsBase, 'method'> & {
|
|
59
85
|
method?: 'oidc-discovery'
|
|
60
86
|
identifier: string
|
|
@@ -75,28 +101,42 @@ export function isExternalIdentifierJwksUrlOpts(opts: ExternalIdentifierOptsBase
|
|
|
75
101
|
return ('method' in opts && opts.method === 'oidc-discovery') || isJwksUrlIdentifier(identifier)
|
|
76
102
|
}
|
|
77
103
|
|
|
78
|
-
export type ExternalIdentifierX5cOpts = Omit<ExternalIdentifierOptsBase, 'method'> &
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
104
|
+
export type ExternalIdentifierX5cOpts = Omit<ExternalIdentifierOptsBase, 'method'> &
|
|
105
|
+
X509CertificateChainValidationOpts & {
|
|
106
|
+
method?: 'x5c'
|
|
107
|
+
identifier: string[]
|
|
108
|
+
verify?: boolean // defaults to true
|
|
109
|
+
verificationTime?: Date
|
|
110
|
+
trustAnchors?: string[]
|
|
111
|
+
}
|
|
85
112
|
|
|
86
113
|
export function isExternalIdentifierX5cOpts(opts: ExternalIdentifierOptsBase): opts is ExternalIdentifierX5cOpts {
|
|
87
114
|
const { identifier } = opts
|
|
88
115
|
return ('method' in opts && opts.method === 'x5c') || isX5cIdentifier(identifier)
|
|
89
116
|
}
|
|
90
117
|
|
|
91
|
-
export type ExternalIdentifierMethod = 'did' | 'jwk' | 'x5c' | 'kid' | 'oidc-discovery' | 'jwks-url' | 'oid4vci-issuer'
|
|
118
|
+
export type ExternalIdentifierMethod = 'did' | 'jwk' | 'x5c' | 'kid' | 'cose_key' | 'oidc-discovery' | 'jwks-url' | 'oid4vci-issuer'
|
|
92
119
|
|
|
93
|
-
export type ExternalIdentifierResult =
|
|
120
|
+
export type ExternalIdentifierResult = IExternalIdentifierResultBase &
|
|
121
|
+
(ExternalIdentifierDidResult | ExternalIdentifierX5cResult | ExternalIdentifierJwkResult | ExternalIdentifierCoseKeyResult)
|
|
94
122
|
|
|
95
123
|
export interface IExternalIdentifierResultBase {
|
|
96
124
|
method: ExternalIdentifierMethod
|
|
97
125
|
jwks: Array<ExternalJwkInfo>
|
|
98
126
|
}
|
|
99
127
|
|
|
128
|
+
export interface ExternalIdentifierJwkResult extends IExternalIdentifierResultBase {
|
|
129
|
+
method: 'jwk'
|
|
130
|
+
jwk: JWK
|
|
131
|
+
x5c?: ExternalIdentifierX5cResult
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export interface ExternalIdentifierCoseKeyResult extends IExternalIdentifierResultBase {
|
|
135
|
+
method: 'cose_key'
|
|
136
|
+
coseKey: ICoseKeyJson
|
|
137
|
+
x5c?: ExternalIdentifierX5cResult
|
|
138
|
+
}
|
|
139
|
+
|
|
100
140
|
export interface ExternalIdentifierX5cResult extends IExternalIdentifierResultBase {
|
|
101
141
|
method: 'x5c'
|
|
102
142
|
x5c: string[]
|
|
@@ -107,6 +147,7 @@ export interface ExternalIdentifierX5cResult extends IExternalIdentifierResultBa
|
|
|
107
147
|
|
|
108
148
|
export interface ExternalJwkInfo extends JwkInfo {
|
|
109
149
|
kid?: string
|
|
150
|
+
publicKeyHex: string
|
|
110
151
|
}
|
|
111
152
|
|
|
112
153
|
export interface ExternalIdentifierDidResult extends IExternalIdentifierResultBase {
|