@sphereon/ssi-sdk-ext.identifier-resolution 0.24.1-next.97 → 0.24.1-unstable.111
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 -0
- package/dist/agent/IdentifierResolution.d.ts.map +1 -1
- package/dist/agent/IdentifierResolution.js +19 -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 +40 -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 +82 -2
- 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 +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 -3
- package/dist/types/IIdentifierResolution.d.ts.map +1 -1
- package/dist/types/IIdentifierResolution.js +3 -0
- 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 +2126 -222
- package/src/agent/IdentifierResolution.ts +56 -10
- package/src/functions/LegacySupport.ts +54 -0
- package/src/functions/externalIdentifierFunctions.ts +94 -4
- package/src/functions/index.ts +1 -51
- package/src/functions/managedIdentifierFunctions.ts +79 -10
- package/src/types/IIdentifierResolution.ts +24 -2
- 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,10 +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),
|
|
49
|
+
identifierManagedGetByCoseKey: this.identifierGetManagedByCoseKey.bind(this),
|
|
38
50
|
|
|
39
51
|
identifierExternalResolve: this.identifierResolveExternal.bind(this),
|
|
40
52
|
identifierExternalResolveByDid: this.identifierExternalResolveByDid.bind(this),
|
|
41
53
|
identifierExternalResolveByX5c: this.identifierExternalResolveByX5c.bind(this),
|
|
54
|
+
identifierExternalResolveByJwk: this.identifierExternalResolveByJwk.bind(this),
|
|
55
|
+
identifierExternalResolveByCoseKey: this.identifierExternalResolveByCoseKey.bind(this),
|
|
42
56
|
|
|
43
57
|
// todo: JWKSet, oidc-discovery, oid4vci-issuer etc. Anything we already can resolve and need keys of
|
|
44
58
|
}
|
|
@@ -57,30 +71,52 @@ export class IdentifierResolution implements IAgentPlugin {
|
|
|
57
71
|
* @param context
|
|
58
72
|
* @private
|
|
59
73
|
*/
|
|
60
|
-
private async identifierGetManaged(
|
|
61
|
-
|
|
74
|
+
private async identifierGetManaged(
|
|
75
|
+
args: ManagedIdentifierOptsOrResult,
|
|
76
|
+
context: IAgentContext<IKeyManager & IIdentifierResolution>
|
|
77
|
+
): Promise<ManagedIdentifierResult> {
|
|
78
|
+
return await ensureManagedIdentifierResult({ ...args, crypto: this._crypto }, context)
|
|
62
79
|
}
|
|
63
80
|
|
|
64
81
|
private async identifierGetManagedByDid(
|
|
65
82
|
args: ManagedIdentifierDidOpts,
|
|
66
|
-
context: IAgentContext<IKeyManager & IDIDManager>
|
|
83
|
+
context: IAgentContext<IKeyManager & IDIDManager & IIdentifierResolution>
|
|
67
84
|
): Promise<ManagedIdentifierDidResult> {
|
|
68
85
|
return (await this.identifierGetManaged({ ...args, method: 'did' }, context)) as ManagedIdentifierDidResult
|
|
69
86
|
}
|
|
70
87
|
|
|
71
|
-
private async identifierGetManagedByKid(
|
|
88
|
+
private async identifierGetManagedByKid(
|
|
89
|
+
args: ManagedIdentifierKidOpts,
|
|
90
|
+
context: IAgentContext<IKeyManager & IIdentifierResolution>
|
|
91
|
+
): Promise<ManagedIdentifierKidResult> {
|
|
72
92
|
return (await this.identifierGetManaged({ ...args, method: 'kid' }, context)) as ManagedIdentifierKidResult
|
|
73
93
|
}
|
|
74
94
|
|
|
75
|
-
private async identifierGetManagedByKey(
|
|
95
|
+
private async identifierGetManagedByKey(
|
|
96
|
+
args: ManagedIdentifierKeyOpts,
|
|
97
|
+
context: IAgentContext<IKeyManager & IIdentifierResolution>
|
|
98
|
+
): Promise<ManagedIdentifierKeyResult> {
|
|
76
99
|
return (await this.identifierGetManaged({ ...args, method: 'key' }, context)) as ManagedIdentifierKeyResult
|
|
77
100
|
}
|
|
78
101
|
|
|
79
|
-
private async
|
|
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
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private async identifierGetManagedByJwk(
|
|
110
|
+
args: ManagedIdentifierJwkOpts,
|
|
111
|
+
context: IAgentContext<IKeyManager & IIdentifierResolution>
|
|
112
|
+
): Promise<ManagedIdentifierJwkResult> {
|
|
80
113
|
return (await this.identifierGetManaged({ ...args, method: 'jwk' }, context)) as ManagedIdentifierJwkResult
|
|
81
114
|
}
|
|
82
115
|
|
|
83
|
-
private async identifierGetManagedByX5c(
|
|
116
|
+
private async identifierGetManagedByX5c(
|
|
117
|
+
args: ManagedIdentifierX5cOpts,
|
|
118
|
+
context: IAgentContext<IKeyManager & IIdentifierResolution>
|
|
119
|
+
): Promise<ManagedIdentifierX5cResult> {
|
|
84
120
|
return (await this.identifierGetManaged({ ...args, method: 'x5c' }, context)) as ManagedIdentifierX5cResult
|
|
85
121
|
}
|
|
86
122
|
|
|
@@ -95,4 +131,14 @@ export class IdentifierResolution implements IAgentPlugin {
|
|
|
95
131
|
private async identifierExternalResolveByX5c(args: ExternalIdentifierX5cOpts, context: IAgentContext<any>): Promise<ExternalIdentifierX5cResult> {
|
|
96
132
|
return (await this.identifierResolveExternal({ ...args, method: 'x5c' }, context)) as ExternalIdentifierX5cResult
|
|
97
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
|
+
}
|
|
98
144
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { IIdentifier } from '@veramo/core'
|
|
2
|
+
import { ManagedIdentifierDidOpts, ManagedIdentifierOptsOrResult } from '../types'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Converts legacy id opts key refs to the new ManagedIdentifierOpts
|
|
6
|
+
* @param opts
|
|
7
|
+
*/
|
|
8
|
+
export function legacyKeyRefsToIdentifierOpts(opts: {
|
|
9
|
+
idOpts?: ManagedIdentifierOptsOrResult
|
|
10
|
+
iss?: string
|
|
11
|
+
keyRef?: string
|
|
12
|
+
didOpts?: any
|
|
13
|
+
}): ManagedIdentifierOptsOrResult {
|
|
14
|
+
if (!opts.idOpts) {
|
|
15
|
+
console.warn(
|
|
16
|
+
`Legacy idOpts being used. Support will be dropped in the future. Consider switching to the idOpts, to have support for DIDs, JWKS, x5c etc. See https://github.com/Sphereon-Opensource/SSI-SDK-crypto-extensions/tree/feature/multi_identifier_support/packages/identifier-resolution`
|
|
17
|
+
)
|
|
18
|
+
// legacy way
|
|
19
|
+
let kmsKeyRef =
|
|
20
|
+
opts.keyRef ??
|
|
21
|
+
opts.didOpts?.idOpts?.kmsKeyRef ??
|
|
22
|
+
opts.didOpts?.kid ??
|
|
23
|
+
opts.didOpts.idOpts?.kid ??
|
|
24
|
+
(typeof opts.didOpts?.idOpts.identifier === 'object' ? (opts.didOpts?.idOpts.identifier as IIdentifier).keys[0].kid : undefined)
|
|
25
|
+
if (!kmsKeyRef) {
|
|
26
|
+
throw Error('Key ref is needed for access token signer')
|
|
27
|
+
}
|
|
28
|
+
let identifier = (opts.didOpts?.identifier ?? opts.didOpts?.idOpts?.identifier) as IIdentifier | undefined
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
kmsKeyRef: opts.keyRef ?? kmsKeyRef,
|
|
32
|
+
identifier: identifier ?? kmsKeyRef,
|
|
33
|
+
issuer: opts.iss,
|
|
34
|
+
} satisfies ManagedIdentifierDidOpts
|
|
35
|
+
} else {
|
|
36
|
+
const idOpts = opts.idOpts
|
|
37
|
+
if (opts.keyRef && !idOpts.kmsKeyRef) {
|
|
38
|
+
// legacy way
|
|
39
|
+
console.warn(
|
|
40
|
+
`Legacy keyRef being used. Support will be dropped in the future. Consider switching to the idOpts, to have support for DIDs, JWKS, x5c etc. See https://github.com/Sphereon-Opensource/SSI-SDK-crypto-extensions/tree/feature/multi_identifier_support/packages/identifier-resolution`
|
|
41
|
+
)
|
|
42
|
+
idOpts.kmsKeyRef = opts.keyRef
|
|
43
|
+
}
|
|
44
|
+
if (opts.iss && !idOpts.issuer) {
|
|
45
|
+
// legacy way
|
|
46
|
+
console.warn(
|
|
47
|
+
`Legacy iss being used. Support will be dropped in the future. Consider switching to the idOpts, to have support for DIDs, JWKS, x5c etc. See https://github.com/Sphereon-Opensource/SSI-SDK-crypto-extensions/tree/feature/multi_identifier_support/packages/identifier-resolution`
|
|
48
|
+
)
|
|
49
|
+
idOpts.issuer = opts.iss
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return idOpts
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { didDocumentToJwks, getAgentResolver } from '@sphereon/ssi-sdk-ext.did-utils'
|
|
2
|
-
import { calculateJwkThumbprint,
|
|
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
|
|
package/src/functions/index.ts
CHANGED
|
@@ -1,53 +1,3 @@
|
|
|
1
|
-
import { IIdentifier } from '@veramo/core'
|
|
2
|
-
import { ManagedIdentifierDidOpts, ManagedIdentifierOpts } from '../types'
|
|
3
|
-
|
|
4
1
|
export * from './managedIdentifierFunctions'
|
|
5
2
|
export * from './externalIdentifierFunctions'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Converts legacy id opts key refs to the new ManagedIdentifierOpts
|
|
9
|
-
* @param opts
|
|
10
|
-
*/
|
|
11
|
-
export function legacyKeyRefsToIdentifierOpts(opts: {
|
|
12
|
-
idOpts?: ManagedIdentifierOpts
|
|
13
|
-
iss?: string
|
|
14
|
-
keyRef?: string
|
|
15
|
-
didOpts?: any
|
|
16
|
-
}): ManagedIdentifierOpts {
|
|
17
|
-
if (!opts.idOpts) {
|
|
18
|
-
console.warn(
|
|
19
|
-
`Legacy idOpts being used. Support will be dropped in the future. Consider switching to the idOpts, to have support for DIDs, JWKS, x5c etc. See https://github.com/Sphereon-Opensource/SSI-SDK-crypto-extensions/tree/feature/multi_identifier_support/packages/identifier-resolution`
|
|
20
|
-
)
|
|
21
|
-
// legacy way
|
|
22
|
-
let kmsKeyRef =
|
|
23
|
-
opts.keyRef ??
|
|
24
|
-
opts.didOpts?.idOpts?.kmsKeyRef ??
|
|
25
|
-
(typeof opts.didOpts?.idOpts.identifier === 'object' ? (opts.didOpts?.idOpts.identifier as IIdentifier).keys[0].kid : undefined)
|
|
26
|
-
if (!kmsKeyRef) {
|
|
27
|
-
throw Error('Key ref is needed for access token signer')
|
|
28
|
-
}
|
|
29
|
-
return {
|
|
30
|
-
kmsKeyRef: opts.keyRef ?? kmsKeyRef,
|
|
31
|
-
identifier: kmsKeyRef,
|
|
32
|
-
issuer: opts.iss,
|
|
33
|
-
} satisfies ManagedIdentifierDidOpts
|
|
34
|
-
} else {
|
|
35
|
-
const idOpts = opts.idOpts
|
|
36
|
-
if (opts.keyRef && !idOpts.kmsKeyRef) {
|
|
37
|
-
// legacy way
|
|
38
|
-
console.warn(
|
|
39
|
-
`Legacy keyRef being used. Support will be dropped in the future. Consider switching to the idOpts, to have support for DIDs, JWKS, x5c etc. See https://github.com/Sphereon-Opensource/SSI-SDK-crypto-extensions/tree/feature/multi_identifier_support/packages/identifier-resolution`
|
|
40
|
-
)
|
|
41
|
-
idOpts.kmsKeyRef = opts.keyRef
|
|
42
|
-
}
|
|
43
|
-
if (opts.iss && !idOpts.issuer) {
|
|
44
|
-
// legacy way
|
|
45
|
-
console.warn(
|
|
46
|
-
`Legacy iss being used. Support will be dropped in the future. Consider switching to the idOpts, to have support for DIDs, JWKS, x5c etc. See https://github.com/Sphereon-Opensource/SSI-SDK-crypto-extensions/tree/feature/multi_identifier_support/packages/identifier-resolution`
|
|
47
|
-
)
|
|
48
|
-
idOpts.issuer = opts.iss
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return idOpts
|
|
52
|
-
}
|
|
53
|
-
}
|
|
3
|
+
export * from './LegacySupport'
|
|
@@ -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
|
}
|