Skip to content

Commit b288a5f

Browse files
feat(key_manager): add sign and verify methods (#2116)
Co-authored-by: Jonathan R. <[email protected]>
1 parent f4d494a commit b288a5f

File tree

4 files changed

+191
-5
lines changed

4 files changed

+191
-5
lines changed

packages_generated/key_manager/src/v1alpha1/api.gen.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,17 @@ import {
1313
marshalEncryptRequest,
1414
marshalGenerateDataKeyRequest,
1515
marshalImportKeyMaterialRequest,
16+
marshalSignRequest,
1617
marshalUpdateKeyRequest,
18+
marshalVerifyRequest,
1719
unmarshalDataKey,
1820
unmarshalDecryptResponse,
1921
unmarshalEncryptResponse,
2022
unmarshalKey,
2123
unmarshalListKeysResponse,
2224
unmarshalPublicKey,
25+
unmarshalSignResponse,
26+
unmarshalVerifyResponse,
2327
} from './marshalling.gen'
2428
import type {
2529
CreateKeyRequest,
@@ -42,8 +46,12 @@ import type {
4246
ProtectKeyRequest,
4347
PublicKey,
4448
RotateKeyRequest,
49+
SignRequest,
50+
SignResponse,
4551
UnprotectKeyRequest,
4652
UpdateKeyRequest,
53+
VerifyRequest,
54+
VerifyResponse,
4755
} from './types.gen'
4856

4957
const jsonContentHeaders = {
@@ -316,6 +324,42 @@ The data encryption key is returned in plaintext and ciphertext but it should on
316324
unmarshalDecryptResponse,
317325
)
318326

327+
/**
328+
* Sign a message digest. Use a given key to sign a message digest. The key must have its usage set to `asymmetric_signing`. The digest must be created using the same digest algorithm that is defined in the key's algorithm configuration.
329+
*
330+
* @param request - The request {@link SignRequest}
331+
* @returns A Promise of SignResponse
332+
*/
333+
sign = (request: Readonly<SignRequest>) =>
334+
this.client.fetch<SignResponse>(
335+
{
336+
body: JSON.stringify(marshalSignRequest(request, this.client.settings)),
337+
headers: jsonContentHeaders,
338+
method: 'POST',
339+
path: `/key-manager/v1alpha1/regions/${validatePathParam('region', request.region ?? this.client.settings.defaultRegion)}/keys/${validatePathParam('keyId', request.keyId)}/sign`,
340+
},
341+
unmarshalSignResponse,
342+
)
343+
344+
/**
345+
* Verify a message signature. Use a given key to verify a message signature against a message digest. The key must have its usage set to `asymmetric_signing`. The message digest must be generated using the same digest algorithm that is defined in the key's algorithm configuration.
346+
*
347+
* @param request - The request {@link VerifyRequest}
348+
* @returns A Promise of VerifyResponse
349+
*/
350+
verify = (request: Readonly<VerifyRequest>) =>
351+
this.client.fetch<VerifyResponse>(
352+
{
353+
body: JSON.stringify(
354+
marshalVerifyRequest(request, this.client.settings),
355+
),
356+
headers: jsonContentHeaders,
357+
method: 'POST',
358+
path: `/key-manager/v1alpha1/regions/${validatePathParam('region', request.region ?? this.client.settings.defaultRegion)}/keys/${validatePathParam('keyId', request.keyId)}/verify`,
359+
},
360+
unmarshalVerifyResponse,
361+
)
362+
319363
/**
320364
* Import key material. Import externally generated key material into Key Manager to derive a new cryptographic key. The key's origin must be `external`.
321365
*

packages_generated/key_manager/src/v1alpha1/index.gen.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ export type {
1919
GetPublicKeyRequest,
2020
ImportKeyMaterialRequest,
2121
Key,
22+
KeyAlgorithmAsymmetricEncryption,
23+
KeyAlgorithmAsymmetricSigning,
2224
KeyAlgorithmSymmetricEncryption,
2325
KeyOrigin,
2426
KeyRotationPolicy,
@@ -30,6 +32,10 @@ export type {
3032
ProtectKeyRequest,
3133
PublicKey,
3234
RotateKeyRequest,
35+
SignRequest,
36+
SignResponse,
3337
UnprotectKeyRequest,
3438
UpdateKeyRequest,
39+
VerifyRequest,
40+
VerifyResponse,
3541
} from './types.gen'

packages_generated/key_manager/src/v1alpha1/marshalling.gen.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ import type {
2121
KeyUsage,
2222
ListKeysResponse,
2323
PublicKey,
24+
SignRequest,
25+
SignResponse,
2426
UpdateKeyRequest,
27+
VerifyRequest,
28+
VerifyResponse,
2529
} from './types.gen'
2630

2731
const unmarshalKeyRotationPolicy = (data: unknown): KeyRotationPolicy => {
@@ -45,6 +49,12 @@ const unmarshalKeyUsage = (data: unknown): KeyUsage => {
4549
}
4650

4751
return {
52+
asymmetricEncryption: data.asymmetric_encryption
53+
? data.asymmetric_encryption
54+
: undefined,
55+
asymmetricSigning: data.asymmetric_signing
56+
? data.asymmetric_signing
57+
: undefined,
4858
symmetricEncryption: data.symmetric_encryption
4959
? data.symmetric_encryption
5060
: undefined,
@@ -148,6 +158,32 @@ export const unmarshalPublicKey = (data: unknown): PublicKey => {
148158
} as PublicKey
149159
}
150160

161+
export const unmarshalSignResponse = (data: unknown): SignResponse => {
162+
if (!isJSONObject(data)) {
163+
throw new TypeError(
164+
`Unmarshalling the type 'SignResponse' failed as data isn't a dictionary.`,
165+
)
166+
}
167+
168+
return {
169+
keyId: data.key_id,
170+
signature: data.signature,
171+
} as SignResponse
172+
}
173+
174+
export const unmarshalVerifyResponse = (data: unknown): VerifyResponse => {
175+
if (!isJSONObject(data)) {
176+
throw new TypeError(
177+
`Unmarshalling the type 'VerifyResponse' failed as data isn't a dictionary.`,
178+
)
179+
}
180+
181+
return {
182+
keyId: data.key_id,
183+
valid: data.valid,
184+
} as VerifyResponse
185+
}
186+
151187
const marshalKeyRotationPolicy = (
152188
request: KeyRotationPolicy,
153189
defaults: DefaultValues,
@@ -162,6 +198,8 @@ const marshalKeyUsage = (
162198
): Record<string, unknown> => ({
163199
...resolveOneOf([
164200
{ param: 'symmetric_encryption', value: request.symmetricEncryption },
201+
{ param: 'asymmetric_encryption', value: request.asymmetricEncryption },
202+
{ param: 'asymmetric_signing', value: request.asymmetricSigning },
165203
]),
166204
})
167205

@@ -217,6 +255,13 @@ export const marshalImportKeyMaterialRequest = (
217255
salt: request.salt,
218256
})
219257

258+
export const marshalSignRequest = (
259+
request: SignRequest,
260+
defaults: DefaultValues,
261+
): Record<string, unknown> => ({
262+
digest: request.digest,
263+
})
264+
220265
export const marshalUpdateKeyRequest = (
221266
request: UpdateKeyRequest,
222267
defaults: DefaultValues,
@@ -229,3 +274,11 @@ export const marshalUpdateKeyRequest = (
229274
: undefined,
230275
tags: request.tags,
231276
})
277+
278+
export const marshalVerifyRequest = (
279+
request: VerifyRequest,
280+
defaults: DefaultValues,
281+
): Record<string, unknown> => ({
282+
digest: request.digest,
283+
signature: request.signature,
284+
})

packages_generated/key_manager/src/v1alpha1/types.gen.ts

Lines changed: 88 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,23 @@ export type DataKeyAlgorithmSymmetricEncryption =
66
| 'unknown_symmetric_encryption'
77
| 'aes_256_gcm'
88

9+
export type KeyAlgorithmAsymmetricEncryption =
10+
| 'unknown_asymmetric_encryption'
11+
| 'rsa_oaep_2048_sha256'
12+
| 'rsa_oaep_3072_sha256'
13+
| 'rsa_oaep_4096_sha256'
14+
15+
export type KeyAlgorithmAsymmetricSigning =
16+
| 'unknown_asymmetric_signing'
17+
| 'ec_p256_sha256'
18+
| 'ec_p384_sha384'
19+
| 'rsa_pss_2048_sha256'
20+
| 'rsa_pss_3072_sha256'
21+
| 'rsa_pss_4096_sha256'
22+
| 'rsa_pkcs1_2048_sha256'
23+
| 'rsa_pkcs1_3072_sha256'
24+
| 'rsa_pkcs1_4096_sha256'
25+
926
export type KeyAlgorithmSymmetricEncryption =
1027
| 'unknown_symmetric_encryption'
1128
| 'aes_256_gcm'
@@ -41,9 +58,19 @@ export interface KeyUsage {
4158
/**
4259
* See the `Key.Algorithm.SymmetricEncryption` enum for a description of values.
4360
*
44-
* One-of ('usage'): at most one of 'symmetricEncryption' could be set.
61+
* One-of ('usage'): at most one of 'symmetricEncryption', 'asymmetricEncryption', 'asymmetricSigning' could be set.
4562
*/
4663
symmetricEncryption?: KeyAlgorithmSymmetricEncryption
64+
/**
65+
*
66+
* One-of ('usage'): at most one of 'symmetricEncryption', 'asymmetricEncryption', 'asymmetricSigning' could be set.
67+
*/
68+
asymmetricEncryption?: KeyAlgorithmAsymmetricEncryption
69+
/**
70+
*
71+
* One-of ('usage'): at most one of 'symmetricEncryption', 'asymmetricEncryption', 'asymmetricSigning' could be set.
72+
*/
73+
asymmetricSigning?: KeyAlgorithmAsymmetricSigning
4774
}
4875

4976
export interface Key {
@@ -181,15 +208,15 @@ export type DecryptRequest = {
181208
*/
182209
region?: ScwRegion
183210
/**
184-
* ID of the key to decrypt.
211+
* The key must have an usage set to `symmetric_encryption` or `asymmetric_encryption`.
185212
*/
186213
keyId: string
187214
/**
188215
* Data size must be between 1 and 131071 bytes.
189216
*/
190217
ciphertext: string
191218
/**
192-
* The additional data must match the value passed in the encryption request.
219+
* The additional data must match the value passed in the encryption request. Only supported by keys with a usage set to `symmetric_encryption`.
193220
*/
194221
associatedData?: string
195222
}
@@ -259,15 +286,15 @@ export type EncryptRequest = {
259286
*/
260287
region?: ScwRegion
261288
/**
262-
* ID of the key to encrypt.
289+
* The key must have an usage set to `symmetric_encryption` or `asymmetric_encryption`.
263290
*/
264291
keyId: string
265292
/**
266293
* Data size must be between 1 and 65535 bytes.
267294
*/
268295
plaintext: string
269296
/**
270-
* Additional data which will not be encrypted, but authenticated and appended to the encrypted payload.
297+
* Additional data which will not be encrypted, but authenticated and appended to the encrypted payload. Only supported by keys with a usage set to `symmetric_encryption`.
271298
*/
272299
associatedData?: string
273300
}
@@ -407,6 +434,32 @@ export type RotateKeyRequest = {
407434
keyId: string
408435
}
409436

437+
export type SignRequest = {
438+
/**
439+
* Region to target. If none is passed will use default region from the config.
440+
*/
441+
region?: ScwRegion
442+
/**
443+
* ID of the key to use for signing.
444+
*/
445+
keyId: string
446+
/**
447+
* The digest must be generated using the same algorithm defined in the key’s algorithm settings.
448+
*/
449+
digest: string
450+
}
451+
452+
export interface SignResponse {
453+
/**
454+
* ID of the key used to generate the signature.
455+
*/
456+
keyId: string
457+
/**
458+
* The message signature.
459+
*/
460+
signature: string
461+
}
462+
410463
export type UnprotectKeyRequest = {
411464
/**
412465
* Region to target. If none is passed will use default region from the config.
@@ -444,3 +497,33 @@ export type UpdateKeyRequest = {
444497
*/
445498
rotationPolicy?: KeyRotationPolicy
446499
}
500+
501+
export type VerifyRequest = {
502+
/**
503+
* Region to target. If none is passed will use default region from the config.
504+
*/
505+
region?: ScwRegion
506+
/**
507+
* ID of the key to use for signature verification.
508+
*/
509+
keyId: string
510+
/**
511+
* Must be generated using the same algorithm specified in the key’s configuration.
512+
*/
513+
digest: string
514+
/**
515+
* The message signature to verify.
516+
*/
517+
signature: string
518+
}
519+
520+
export interface VerifyResponse {
521+
/**
522+
* ID of the key used for verification.
523+
*/
524+
keyId: string
525+
/**
526+
* Returns `true` if the signature is valid for the digest and key, `false` otherwise.
527+
*/
528+
valid: boolean
529+
}

0 commit comments

Comments
 (0)