@sphereon/ssi-sdk.kms-rest 0.36.1-feature.SSISDK.44.finish.dcql.1 → 0.36.1-feature.SSISDK.70.integrate.digidentity.55
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/index.cjs +137 -83
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -4
- package/dist/index.d.ts +8 -4
- package/dist/index.js +138 -84
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
- package/src/RestKeyManagementSystem.ts +106 -80
- package/src/types/index.ts +2 -0
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
calculateJwkThumbprint,
|
|
3
|
+
isHashString,
|
|
4
|
+
joseAlgorithmToDigest,
|
|
5
|
+
shaHasher,
|
|
6
|
+
signatureAlgorithmFromKeyType,
|
|
7
|
+
signatureAlgorithmToJoseAlgorithm,
|
|
8
|
+
toJwk,
|
|
9
|
+
x25519PublicHexFromPrivateHex,
|
|
10
|
+
type X509Opts,
|
|
11
|
+
} from '@sphereon/ssi-sdk-ext.key-utils'
|
|
2
12
|
import { hexToPEM, jwkToPEM, pemCertChainTox5c, PEMToHex, PEMToJwk } from '@sphereon/ssi-sdk-ext.x509-utils'
|
|
3
13
|
import type { ManagedKeyInfo as RestManagedKeyInfo } from '@sphereon/ssi-sdk.kms-rest-client'
|
|
4
14
|
import {
|
|
@@ -27,13 +37,17 @@ interface KeyManagementSystemOptions {
|
|
|
27
37
|
applicationId: string
|
|
28
38
|
baseUrl: string
|
|
29
39
|
providerId?: string
|
|
40
|
+
tenantId?: string
|
|
41
|
+
userId?: string
|
|
30
42
|
authOpts?: RestClientAuthenticationOpts
|
|
31
43
|
}
|
|
32
44
|
|
|
33
45
|
export class RestKeyManagementSystem extends AbstractKeyManagementSystem {
|
|
34
46
|
private client: KmsRestClient
|
|
35
47
|
private readonly id: string
|
|
36
|
-
private providerId: string | undefined
|
|
48
|
+
private readonly providerId: string | undefined
|
|
49
|
+
private readonly tenantId: string | undefined
|
|
50
|
+
private readonly userId: string | undefined
|
|
37
51
|
|
|
38
52
|
constructor(options: KeyManagementSystemOptions) {
|
|
39
53
|
super()
|
|
@@ -45,18 +59,26 @@ export class RestKeyManagementSystem extends AbstractKeyManagementSystem {
|
|
|
45
59
|
|
|
46
60
|
this.id = options.applicationId
|
|
47
61
|
this.providerId = options.providerId
|
|
62
|
+
this.tenantId = options.tenantId
|
|
63
|
+
this.userId = options.userId
|
|
48
64
|
this.client = new KmsRestClient(config)
|
|
49
65
|
}
|
|
50
66
|
|
|
51
67
|
async createKey(args: CreateKeyArgs): Promise<ManagedKeyInfo> {
|
|
52
68
|
const { type, meta } = args
|
|
53
69
|
|
|
54
|
-
const
|
|
70
|
+
const joseAlg = signatureAlgorithmFromKeyType({
|
|
71
|
+
type,
|
|
72
|
+
algorithms: meta?.algorithms as string[] | undefined,
|
|
73
|
+
})
|
|
74
|
+
const signatureAlgorithm = this.mapJoseToRestSignatureAlgorithm(joseAlg)
|
|
55
75
|
const options = {
|
|
56
76
|
use: meta && 'keyUsage' in meta ? this.mapKeyUsage(meta.keyUsage) : JwkUse.Sig,
|
|
57
77
|
alg: signatureAlgorithm,
|
|
58
78
|
keyOperations: meta && meta.keyOperations ? this.mapKeyOperations(meta.keyOperations as string[]) : [KeyOperations.Sign],
|
|
59
79
|
...(meta && 'keyAlias' in meta && meta.keyAlias ? { alias: meta.keyAlias } : {}),
|
|
80
|
+
...(this.tenantId && { tenantId: this.tenantId }),
|
|
81
|
+
...(this.userId && { userId: this.userId }),
|
|
60
82
|
}
|
|
61
83
|
|
|
62
84
|
const key = this.providerId
|
|
@@ -68,7 +90,7 @@ export class RestKeyManagementSystem extends AbstractKeyManagementSystem {
|
|
|
68
90
|
|
|
69
91
|
const jwk = {
|
|
70
92
|
...key.keyPair.jose.publicJwk,
|
|
71
|
-
alg: key.keyPair.jose.publicJwk.alg ?
|
|
93
|
+
alg: key.keyPair.jose.publicJwk.alg ? signatureAlgorithmToJoseAlgorithm(key.keyPair.jose.publicJwk.alg) : undefined,
|
|
72
94
|
} satisfies JWK
|
|
73
95
|
|
|
74
96
|
const kid = key.keyPair.kid ?? key.keyPair.jose.publicJwk.kid
|
|
@@ -85,7 +107,7 @@ export class RestKeyManagementSystem extends AbstractKeyManagementSystem {
|
|
|
85
107
|
algorithms: [key.keyPair.jose.publicJwk.alg ?? 'PS256'],
|
|
86
108
|
jwkThumbprint: calculateJwkThumbprint({
|
|
87
109
|
jwk,
|
|
88
|
-
digestAlgorithm:
|
|
110
|
+
digestAlgorithm: jwk.alg ? joseAlgorithmToDigest(jwk.alg) : 'sha256',
|
|
89
111
|
}),
|
|
90
112
|
},
|
|
91
113
|
publicKeyHex: Buffer.from(key.keyPair.jose.publicJwk.toString(), 'utf8').toString('base64'),
|
|
@@ -94,15 +116,20 @@ export class RestKeyManagementSystem extends AbstractKeyManagementSystem {
|
|
|
94
116
|
|
|
95
117
|
async importKey(args: ImportKeyArgs): Promise<ManagedKeyInfo> {
|
|
96
118
|
const { type } = args
|
|
97
|
-
const signatureAlgorithm = this.mapKeyTypeToSignatureAlgorithm(type)
|
|
98
119
|
const importKey = this.mapImportKey(args)
|
|
99
120
|
|
|
100
121
|
const result = this.providerId
|
|
101
122
|
? await this.client.methods.kmsClientProviderStoreKey({
|
|
102
123
|
...importKey.key,
|
|
103
124
|
providerId: this.providerId,
|
|
125
|
+
...(this.tenantId && { tenantId: this.tenantId }),
|
|
126
|
+
...(this.userId && { userId: this.userId }),
|
|
127
|
+
})
|
|
128
|
+
: await this.client.methods.kmsClientStoreKey({
|
|
129
|
+
...importKey.key,
|
|
130
|
+
...(this.tenantId && { tenantId: this.tenantId }),
|
|
131
|
+
...(this.userId && { userId: this.userId }),
|
|
104
132
|
})
|
|
105
|
-
: await this.client.methods.kmsClientStoreKey(importKey.key)
|
|
106
133
|
|
|
107
134
|
return {
|
|
108
135
|
kid: importKey.kid,
|
|
@@ -113,7 +140,7 @@ export class RestKeyManagementSystem extends AbstractKeyManagementSystem {
|
|
|
113
140
|
algorithms: [result.keyInfo.key.alg ?? 'PS256'],
|
|
114
141
|
jwkThumbprint: calculateJwkThumbprint({
|
|
115
142
|
jwk: importKey.publicKeyJwk,
|
|
116
|
-
digestAlgorithm:
|
|
143
|
+
digestAlgorithm: importKey.publicKeyJwk.alg ? joseAlgorithmToDigest(importKey.publicKeyJwk.alg) : 'sha256',
|
|
117
144
|
}),
|
|
118
145
|
},
|
|
119
146
|
publicKeyHex: Buffer.from(result.keyInfo.key.toString(), 'utf8').toString('base64'),
|
|
@@ -127,14 +154,27 @@ export class RestKeyManagementSystem extends AbstractKeyManagementSystem {
|
|
|
127
154
|
? await this.client.methods.kmsClientProviderDeleteKey({
|
|
128
155
|
aliasOrKid: kid,
|
|
129
156
|
providerId: this.providerId,
|
|
157
|
+
...(this.tenantId && { tenantId: this.tenantId }),
|
|
158
|
+
...(this.userId && { userId: this.userId }),
|
|
159
|
+
})
|
|
160
|
+
: await this.client.methods.kmsClientDeleteKey({
|
|
161
|
+
aliasOrKid: kid,
|
|
162
|
+
...(this.tenantId && { tenantId: this.tenantId }),
|
|
163
|
+
...(this.userId && { userId: this.userId }),
|
|
130
164
|
})
|
|
131
|
-
: await this.client.methods.kmsClientDeleteKey({ aliasOrKid: kid })
|
|
132
165
|
}
|
|
133
166
|
|
|
134
167
|
async listKeys(): Promise<ManagedKeyInfo[]> {
|
|
135
168
|
const keys = this.providerId
|
|
136
|
-
? await this.client.methods.kmsClientProviderListKeys({
|
|
137
|
-
|
|
169
|
+
? await this.client.methods.kmsClientProviderListKeys({
|
|
170
|
+
providerId: this.providerId,
|
|
171
|
+
...(this.tenantId && { tenantId: this.tenantId }),
|
|
172
|
+
...(this.userId && { userId: this.userId }),
|
|
173
|
+
})
|
|
174
|
+
: await this.client.methods.kmsClientListKeys({
|
|
175
|
+
...(this.tenantId && { tenantId: this.tenantId }),
|
|
176
|
+
...(this.userId && { userId: this.userId }),
|
|
177
|
+
})
|
|
138
178
|
|
|
139
179
|
const restKeys = ListKeysResponseToJSONTyped(keys, false).keyInfos
|
|
140
180
|
|
|
@@ -163,7 +203,7 @@ export class RestKeyManagementSystem extends AbstractKeyManagementSystem {
|
|
|
163
203
|
jwk,
|
|
164
204
|
jwkThumbprint: calculateJwkThumbprint({
|
|
165
205
|
jwk: jwk as JWK,
|
|
166
|
-
digestAlgorithm: restKey.
|
|
206
|
+
digestAlgorithm: restKey.key.alg ? joseAlgorithmToDigest(restKey.key.alg) : 'sha256',
|
|
167
207
|
}),
|
|
168
208
|
alias: restKey.alias,
|
|
169
209
|
providerId: restKey.providerId,
|
|
@@ -195,35 +235,59 @@ export class RestKeyManagementSystem extends AbstractKeyManagementSystem {
|
|
|
195
235
|
}
|
|
196
236
|
|
|
197
237
|
async sign(args: SignArgs): Promise<string> {
|
|
198
|
-
const { keyRef, data } = args
|
|
238
|
+
const { keyRef, data, algorithm = 'SHA-256' } = args
|
|
199
239
|
const key = this.providerId
|
|
200
240
|
? await this.client.methods.kmsClientProviderGetKey({
|
|
201
241
|
aliasOrKid: keyRef.kid,
|
|
202
242
|
providerId: this.providerId,
|
|
243
|
+
...(this.tenantId && { tenantId: this.tenantId }),
|
|
244
|
+
...(this.userId && { userId: this.userId }),
|
|
245
|
+
})
|
|
246
|
+
: await this.client.methods.kmsClientGetKey({
|
|
247
|
+
aliasOrKid: keyRef.kid,
|
|
248
|
+
...(this.tenantId && { tenantId: this.tenantId }),
|
|
249
|
+
...(this.userId && { userId: this.userId }),
|
|
203
250
|
})
|
|
204
|
-
: await this.client.methods.kmsClientGetKey({ aliasOrKid: keyRef.kid })
|
|
205
251
|
|
|
252
|
+
// with remote signing we are not going to send the whole data over the network, we need to hash it (unless we already get a hash
|
|
253
|
+
const dataToBeSigned: Uint8Array = isHashString(data)
|
|
254
|
+
? data
|
|
255
|
+
: shaHasher(data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength), algorithm)
|
|
206
256
|
const signingResult = await this.client.methods.kmsClientCreateRawSignature({
|
|
207
257
|
keyInfo: key.keyInfo,
|
|
208
|
-
input: toString(
|
|
258
|
+
input: toString(dataToBeSigned, 'base64'),
|
|
259
|
+
...(this.tenantId && { tenantId: this.tenantId }),
|
|
260
|
+
...(this.userId && { userId: this.userId }),
|
|
209
261
|
})
|
|
210
262
|
|
|
211
263
|
return signingResult.signature
|
|
212
264
|
}
|
|
213
265
|
|
|
214
266
|
async verify(args: VerifyArgs): Promise<boolean> {
|
|
215
|
-
const { keyRef, data, signature } = args
|
|
267
|
+
const { keyRef, data, signature, algorithm = 'SHA-256' } = args
|
|
216
268
|
const key = this.providerId
|
|
217
269
|
? await this.client.methods.kmsClientProviderGetKey({
|
|
218
270
|
aliasOrKid: keyRef.kid,
|
|
219
271
|
providerId: this.providerId,
|
|
272
|
+
...(this.tenantId && { tenantId: this.tenantId }),
|
|
273
|
+
...(this.userId && { userId: this.userId }),
|
|
274
|
+
})
|
|
275
|
+
: await this.client.methods.kmsClientGetKey({
|
|
276
|
+
aliasOrKid: keyRef.kid,
|
|
277
|
+
...(this.tenantId && { tenantId: this.tenantId }),
|
|
278
|
+
...(this.userId && { userId: this.userId }),
|
|
220
279
|
})
|
|
221
|
-
: await this.client.methods.kmsClientGetKey({ aliasOrKid: keyRef.kid })
|
|
222
280
|
|
|
281
|
+
// with remote signing we are not going to send the whole data over the network, we need to hash it (unless we already get a hash
|
|
282
|
+
const dataToBeVerified: Uint8Array = isHashString(data)
|
|
283
|
+
? data
|
|
284
|
+
: shaHasher(data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength), algorithm)
|
|
223
285
|
const verification = await this.client.methods.kmsClientIsValidRawSignature({
|
|
224
286
|
keyInfo: key.keyInfo,
|
|
225
|
-
input: toString(
|
|
287
|
+
input: toString(dataToBeVerified, 'base64'),
|
|
226
288
|
signature,
|
|
289
|
+
...(this.tenantId && { tenantId: this.tenantId }),
|
|
290
|
+
...(this.userId && { userId: this.userId }),
|
|
227
291
|
})
|
|
228
292
|
|
|
229
293
|
return verification.isValid
|
|
@@ -233,23 +297,6 @@ export class RestKeyManagementSystem extends AbstractKeyManagementSystem {
|
|
|
233
297
|
throw new Error('sharedSecret is not implemented for REST KMS.')
|
|
234
298
|
}
|
|
235
299
|
|
|
236
|
-
private signatureAlgorithmToDigestAlgorithm = (signatureAlgorithm: SignatureAlgorithm): 'sha256' | 'sha512' => {
|
|
237
|
-
switch (signatureAlgorithm) {
|
|
238
|
-
case SignatureAlgorithm.EcdsaSha256:
|
|
239
|
-
case SignatureAlgorithm.RsaSsaPssSha256Mgf1:
|
|
240
|
-
case SignatureAlgorithm.EckaDhSha256:
|
|
241
|
-
case SignatureAlgorithm.HmacSha256:
|
|
242
|
-
case SignatureAlgorithm.Es256K:
|
|
243
|
-
return 'sha256'
|
|
244
|
-
case SignatureAlgorithm.EcdsaSha512:
|
|
245
|
-
case SignatureAlgorithm.HmacSha512:
|
|
246
|
-
case SignatureAlgorithm.RsaSsaPssSha512Mgf1:
|
|
247
|
-
return 'sha512'
|
|
248
|
-
default:
|
|
249
|
-
throw new Error(`Signature algorithm ${signatureAlgorithm} is not supported by REST KMS`)
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
300
|
private mapKeyUsage = (usage: string): JwkUse => {
|
|
254
301
|
switch (usage) {
|
|
255
302
|
case 'sig':
|
|
@@ -261,53 +308,32 @@ export class RestKeyManagementSystem extends AbstractKeyManagementSystem {
|
|
|
261
308
|
}
|
|
262
309
|
}
|
|
263
310
|
|
|
264
|
-
private
|
|
265
|
-
switch (type) {
|
|
266
|
-
case 'Secp256r1':
|
|
267
|
-
return SignatureAlgorithm.EcdsaSha256
|
|
268
|
-
case 'RSA':
|
|
269
|
-
return SignatureAlgorithm.RsaSsaPssSha256Mgf1
|
|
270
|
-
case 'X25519':
|
|
271
|
-
return SignatureAlgorithm.EckaDhSha256
|
|
272
|
-
default:
|
|
273
|
-
throw new Error(`Key type ${type} is not supported by REST KMS`)
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
private mapJoseAlgorithm = (alg: string): JoseSignatureAlgorithm => {
|
|
311
|
+
private mapJoseToRestSignatureAlgorithm = (alg: JoseSignatureAlgorithm): SignatureAlgorithm => {
|
|
278
312
|
switch (alg) {
|
|
279
|
-
case
|
|
280
|
-
return
|
|
281
|
-
case
|
|
282
|
-
return
|
|
283
|
-
case
|
|
284
|
-
return
|
|
285
|
-
case
|
|
286
|
-
return
|
|
287
|
-
case
|
|
288
|
-
return
|
|
289
|
-
case
|
|
290
|
-
return
|
|
291
|
-
case
|
|
292
|
-
return
|
|
293
|
-
case
|
|
294
|
-
return
|
|
295
|
-
case
|
|
296
|
-
return
|
|
297
|
-
case
|
|
298
|
-
return
|
|
299
|
-
case
|
|
300
|
-
return
|
|
301
|
-
case 'PS256':
|
|
302
|
-
return JoseSignatureAlgorithm.PS256
|
|
303
|
-
case 'PS384':
|
|
304
|
-
return JoseSignatureAlgorithm.PS384
|
|
305
|
-
case 'PS512':
|
|
306
|
-
return JoseSignatureAlgorithm.PS512
|
|
307
|
-
case 'none':
|
|
308
|
-
return JoseSignatureAlgorithm.none
|
|
313
|
+
case JoseSignatureAlgorithm.RS256:
|
|
314
|
+
return SignatureAlgorithm.RsaSha256
|
|
315
|
+
case JoseSignatureAlgorithm.RS384:
|
|
316
|
+
return SignatureAlgorithm.RsaSha384
|
|
317
|
+
case JoseSignatureAlgorithm.RS512:
|
|
318
|
+
return SignatureAlgorithm.RsaSha512
|
|
319
|
+
case JoseSignatureAlgorithm.PS256:
|
|
320
|
+
return SignatureAlgorithm.RsaSsaPssSha256Mgf1
|
|
321
|
+
case JoseSignatureAlgorithm.PS384:
|
|
322
|
+
return SignatureAlgorithm.RsaSsaPssSha384Mgf1
|
|
323
|
+
case JoseSignatureAlgorithm.PS512:
|
|
324
|
+
return SignatureAlgorithm.RsaSsaPssSha512Mgf1
|
|
325
|
+
case JoseSignatureAlgorithm.ES256:
|
|
326
|
+
return SignatureAlgorithm.EcdsaSha256
|
|
327
|
+
case JoseSignatureAlgorithm.ES384:
|
|
328
|
+
return SignatureAlgorithm.EcdsaSha384
|
|
329
|
+
case JoseSignatureAlgorithm.ES512:
|
|
330
|
+
return SignatureAlgorithm.EcdsaSha512
|
|
331
|
+
case JoseSignatureAlgorithm.ES256K:
|
|
332
|
+
return SignatureAlgorithm.Es256K
|
|
333
|
+
case JoseSignatureAlgorithm.EdDSA:
|
|
334
|
+
return SignatureAlgorithm.Ed25519
|
|
309
335
|
default:
|
|
310
|
-
throw new Error(`
|
|
336
|
+
throw new Error(`JOSE algorithm ${alg} not supported by REST KMS`)
|
|
311
337
|
}
|
|
312
338
|
}
|
|
313
339
|
|
package/src/types/index.ts
CHANGED
|
@@ -15,6 +15,7 @@ export type CreateKeyArgs = {
|
|
|
15
15
|
export type SignArgs = {
|
|
16
16
|
keyRef: Pick<IKey, 'kid'>
|
|
17
17
|
data: Uint8Array
|
|
18
|
+
algorithm?: string
|
|
18
19
|
[x: string]: any
|
|
19
20
|
}
|
|
20
21
|
|
|
@@ -22,6 +23,7 @@ export type VerifyArgs = {
|
|
|
22
23
|
keyRef: Pick<IKey, 'kid'>
|
|
23
24
|
data: Uint8Array
|
|
24
25
|
signature: string
|
|
26
|
+
algorithm?: string
|
|
25
27
|
[x: string]: any
|
|
26
28
|
}
|
|
27
29
|
|