@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.
- package/dist/agent/IdentifierResolution.d.ts +3 -1
- package/dist/agent/IdentifierResolution.d.ts.map +1 -1
- package/dist/agent/IdentifierResolution.js +19 -7
- package/dist/agent/IdentifierResolution.js.map +1 -1
- package/dist/functions/LegacySupport.d.ts.map +1 -1
- package/dist/functions/LegacySupport.js +5 -4
- package/dist/functions/LegacySupport.js.map +1 -1
- package/dist/functions/externalIdentifierFunctions.d.ts +17 -1
- package/dist/functions/externalIdentifierFunctions.d.ts.map +1 -1
- package/dist/functions/externalIdentifierFunctions.js +82 -2
- package/dist/functions/externalIdentifierFunctions.js.map +1 -1
- package/dist/functions/managedIdentifierFunctions.d.ts +16 -5
- package/dist/functions/managedIdentifierFunctions.d.ts.map +1 -1
- package/dist/functions/managedIdentifierFunctions.js +66 -6
- package/dist/functions/managedIdentifierFunctions.js.map +1 -1
- package/dist/types/IIdentifierResolution.d.ts +10 -12
- package/dist/types/IIdentifierResolution.d.ts.map +1 -1
- package/dist/types/IIdentifierResolution.js +3 -1
- package/dist/types/IIdentifierResolution.js.map +1 -1
- package/dist/types/common.d.ts +2 -1
- package/dist/types/common.d.ts.map +1 -1
- package/dist/types/common.js +5 -1
- 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 +6 -1
- package/dist/types/externalIdentifierTypes.js.map +1 -1
- package/dist/types/managedIdentifierTypes.d.ts +29 -7
- package/dist/types/managedIdentifierTypes.d.ts.map +1 -1
- package/dist/types/managedIdentifierTypes.js +10 -1
- package/dist/types/managedIdentifierTypes.js.map +1 -1
- package/package.json +12 -12
- package/plugin.schema.json +2149 -264
- package/src/agent/IdentifierResolution.ts +56 -18
- package/src/functions/LegacySupport.ts +5 -1
- package/src/functions/externalIdentifierFunctions.ts +94 -4
- package/src/functions/managedIdentifierFunctions.ts +79 -10
- package/src/types/IIdentifierResolution.ts +22 -12
- package/src/types/common.ts +5 -1
- package/src/types/externalIdentifierTypes.ts +54 -13
- package/src/types/managedIdentifierTypes.ts +47 -8
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import { IAgentContext, IAgentPlugin, IDIDManager, IKeyManager } from '@veramo/core'
|
|
2
|
-
import {
|
|
3
|
-
|
|
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
|
-
|
|
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(
|
|
62
|
-
|
|
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(
|
|
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(
|
|
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
|
|
81
|
-
|
|
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
|
|
85
|
-
|
|
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
|
|
89
|
-
|
|
90
|
-
context: IAgentContext<IIdentifierResolution>
|
|
91
|
-
): Promise<
|
|
92
|
-
return await
|
|
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,
|
|
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 {
|
|
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,
|
|
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
|
-
|
|
79
|
+
identifier: ManagedIdentifierOptsOrResult & {
|
|
80
|
+
crypto?: Crypto
|
|
81
|
+
},
|
|
82
|
+
context: IAgentContext<IKeyManager>
|
|
65
83
|
): Promise<ManagedIdentifierResult> {
|
|
66
|
-
|
|
67
|
-
|
|
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:
|
|
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
|
-
'
|
|
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:
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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
|
}
|
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'
|
|
@@ -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
|
}
|