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