Skip to content

Commit 80956fc

Browse files
feat(key_manager): add sign and verify methods (scaleway#979)
Co-authored-by: Laure-di <[email protected]>
1 parent 9c670ee commit 80956fc

File tree

8 files changed

+606
-16
lines changed

8 files changed

+606
-16
lines changed

scaleway-async/scaleway_async/key_manager/v1alpha1/__init__.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# This file was automatically generated. DO NOT EDIT.
22
# If you have any remark or suggestion do not hesitate to open an issue.
33
from .types import DataKeyAlgorithmSymmetricEncryption
4+
from .types import KeyAlgorithmAsymmetricEncryption
5+
from .types import KeyAlgorithmAsymmetricSigning
46
from .types import KeyAlgorithmSymmetricEncryption
57
from .types import KeyOrigin
68
from .types import KeyState
@@ -27,12 +29,18 @@
2729
from .types import ProtectKeyRequest
2830
from .types import PublicKey
2931
from .types import RotateKeyRequest
32+
from .types import SignRequest
33+
from .types import SignResponse
3034
from .types import UnprotectKeyRequest
3135
from .types import UpdateKeyRequest
36+
from .types import VerifyRequest
37+
from .types import VerifyResponse
3238
from .api import KeyManagerV1Alpha1API
3339

3440
__all__ = [
3541
"DataKeyAlgorithmSymmetricEncryption",
42+
"KeyAlgorithmAsymmetricEncryption",
43+
"KeyAlgorithmAsymmetricSigning",
3644
"KeyAlgorithmSymmetricEncryption",
3745
"KeyOrigin",
3846
"KeyState",
@@ -59,7 +67,11 @@
5967
"ProtectKeyRequest",
6068
"PublicKey",
6169
"RotateKeyRequest",
70+
"SignRequest",
71+
"SignResponse",
6272
"UnprotectKeyRequest",
6373
"UpdateKeyRequest",
74+
"VerifyRequest",
75+
"VerifyResponse",
6476
"KeyManagerV1Alpha1API",
6577
]

scaleway-async/scaleway_async/key_manager/v1alpha1/api.py

Lines changed: 106 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@
2828
KeyUsage,
2929
ListKeysResponse,
3030
PublicKey,
31+
SignRequest,
32+
SignResponse,
3133
UpdateKeyRequest,
34+
VerifyRequest,
35+
VerifyResponse,
3236
)
3337
from .marshalling import (
3438
unmarshal_Key,
@@ -37,12 +41,16 @@
3741
unmarshal_EncryptResponse,
3842
unmarshal_ListKeysResponse,
3943
unmarshal_PublicKey,
44+
unmarshal_SignResponse,
45+
unmarshal_VerifyResponse,
4046
marshal_CreateKeyRequest,
4147
marshal_DecryptRequest,
4248
marshal_EncryptRequest,
4349
marshal_GenerateDataKeyRequest,
4450
marshal_ImportKeyMaterialRequest,
51+
marshal_SignRequest,
4552
marshal_UpdateKeyRequest,
53+
marshal_VerifyRequest,
4654
)
4755

4856

@@ -602,10 +610,10 @@ async def encrypt(
602610
"""
603611
Encrypt a payload.
604612
Encrypt a payload using an existing key, specified by the `key_id` parameter. Only keys with a usage set to `symmetric_encryption` are supported by this method. The maximum payload size that can be encrypted is 64 KB of plaintext.
605-
:param key_id: ID of the key to encrypt.
613+
:param key_id: The key must have an usage set to `symmetric_encryption` or `asymmetric_encryption`.
606614
:param plaintext: Data size must be between 1 and 65535 bytes.
607615
:param region: Region to target. If none is passed will use default region from the config.
608-
:param associated_data: Additional data which will not be encrypted, but authenticated and appended to the encrypted payload.
616+
:param associated_data: 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`.
609617
:return: :class:`EncryptResponse <EncryptResponse>`
610618
611619
Usage:
@@ -650,10 +658,10 @@ async def decrypt(
650658
"""
651659
Decrypt an encrypted payload.
652660
Decrypt an encrypted payload using an existing key, specified by the `key_id` parameter. The maximum payload size that can be decrypted is equivalent to the encrypted output of 64 KB of data (around 131 KB).
653-
:param key_id: ID of the key to decrypt.
661+
:param key_id: The key must have an usage set to `symmetric_encryption` or `asymmetric_encryption`.
654662
:param ciphertext: Data size must be between 1 and 131071 bytes.
655663
:param region: Region to target. If none is passed will use default region from the config.
656-
:param associated_data: The additional data must match the value passed in the encryption request.
664+
:param associated_data: The additional data must match the value passed in the encryption request. Only supported by keys with a usage set to `symmetric_encryption`.
657665
:return: :class:`DecryptResponse <DecryptResponse>`
658666
659667
Usage:
@@ -687,6 +695,100 @@ async def decrypt(
687695
self._throw_on_error(res)
688696
return unmarshal_DecryptResponse(res.json())
689697

698+
async def sign(
699+
self,
700+
*,
701+
key_id: str,
702+
digest: str,
703+
region: Optional[ScwRegion] = None,
704+
) -> SignResponse:
705+
"""
706+
Sign a message digest.
707+
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.
708+
:param key_id: ID of the key to use for signing.
709+
:param digest: The digest must be generated using the same algorithm defined in the key’s algorithm settings.
710+
:param region: Region to target. If none is passed will use default region from the config.
711+
:return: :class:`SignResponse <SignResponse>`
712+
713+
Usage:
714+
::
715+
716+
result = await api.sign(
717+
key_id="example",
718+
digest="example",
719+
)
720+
"""
721+
722+
param_region = validate_path_param(
723+
"region", region or self.client.default_region
724+
)
725+
param_key_id = validate_path_param("key_id", key_id)
726+
727+
res = self._request(
728+
"POST",
729+
f"/key-manager/v1alpha1/regions/{param_region}/keys/{param_key_id}/sign",
730+
body=marshal_SignRequest(
731+
SignRequest(
732+
key_id=key_id,
733+
digest=digest,
734+
region=region,
735+
),
736+
self.client,
737+
),
738+
)
739+
740+
self._throw_on_error(res)
741+
return unmarshal_SignResponse(res.json())
742+
743+
async def verify(
744+
self,
745+
*,
746+
key_id: str,
747+
digest: str,
748+
signature: str,
749+
region: Optional[ScwRegion] = None,
750+
) -> VerifyResponse:
751+
"""
752+
Verify a message signature.
753+
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.
754+
:param key_id: ID of the key to use for signature verification.
755+
:param digest: Must be generated using the same algorithm specified in the key’s configuration.
756+
:param signature: The message signature to verify.
757+
:param region: Region to target. If none is passed will use default region from the config.
758+
:return: :class:`VerifyResponse <VerifyResponse>`
759+
760+
Usage:
761+
::
762+
763+
result = await api.verify(
764+
key_id="example",
765+
digest="example",
766+
signature="example",
767+
)
768+
"""
769+
770+
param_region = validate_path_param(
771+
"region", region or self.client.default_region
772+
)
773+
param_key_id = validate_path_param("key_id", key_id)
774+
775+
res = self._request(
776+
"POST",
777+
f"/key-manager/v1alpha1/regions/{param_region}/keys/{param_key_id}/verify",
778+
body=marshal_VerifyRequest(
779+
VerifyRequest(
780+
key_id=key_id,
781+
digest=digest,
782+
signature=signature,
783+
region=region,
784+
),
785+
self.client,
786+
),
787+
)
788+
789+
self._throw_on_error(res)
790+
return unmarshal_VerifyResponse(res.json())
791+
690792
async def import_key_material(
691793
self,
692794
*,

scaleway-async/scaleway_async/key_manager/v1alpha1/marshalling.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,16 @@
1818
EncryptResponse,
1919
ListKeysResponse,
2020
PublicKey,
21+
SignResponse,
22+
VerifyResponse,
2123
CreateKeyRequest,
2224
DecryptRequest,
2325
EncryptRequest,
2426
GenerateDataKeyRequest,
2527
ImportKeyMaterialRequest,
28+
SignRequest,
2629
UpdateKeyRequest,
30+
VerifyRequest,
2731
)
2832

2933

@@ -66,6 +70,18 @@ def unmarshal_KeyUsage(data: Any) -> KeyUsage:
6670
else:
6771
args["symmetric_encryption"] = None
6872

73+
field = data.get("asymmetric_encryption", None)
74+
if field is not None:
75+
args["asymmetric_encryption"] = field
76+
else:
77+
args["asymmetric_encryption"] = None
78+
79+
field = data.get("asymmetric_signing", None)
80+
if field is not None:
81+
args["asymmetric_signing"] = field
82+
else:
83+
args["asymmetric_signing"] = None
84+
6985
return KeyUsage(**args)
7086

7187

@@ -269,6 +285,44 @@ def unmarshal_PublicKey(data: Any) -> PublicKey:
269285
return PublicKey(**args)
270286

271287

288+
def unmarshal_SignResponse(data: Any) -> SignResponse:
289+
if not isinstance(data, dict):
290+
raise TypeError(
291+
"Unmarshalling the type 'SignResponse' failed as data isn't a dictionary."
292+
)
293+
294+
args: Dict[str, Any] = {}
295+
296+
field = data.get("key_id", None)
297+
if field is not None:
298+
args["key_id"] = field
299+
300+
field = data.get("signature", None)
301+
if field is not None:
302+
args["signature"] = field
303+
304+
return SignResponse(**args)
305+
306+
307+
def unmarshal_VerifyResponse(data: Any) -> VerifyResponse:
308+
if not isinstance(data, dict):
309+
raise TypeError(
310+
"Unmarshalling the type 'VerifyResponse' failed as data isn't a dictionary."
311+
)
312+
313+
args: Dict[str, Any] = {}
314+
315+
field = data.get("key_id", None)
316+
if field is not None:
317+
args["key_id"] = field
318+
319+
field = data.get("valid", None)
320+
if field is not None:
321+
args["valid"] = field
322+
323+
return VerifyResponse(**args)
324+
325+
272326
def marshal_KeyRotationPolicy(
273327
request: KeyRotationPolicy,
274328
defaults: ProfileDefaults,
@@ -293,6 +347,10 @@ def marshal_KeyUsage(
293347
resolve_one_of(
294348
[
295349
OneOfPossibility("symmetric_encryption", request.symmetric_encryption),
350+
OneOfPossibility(
351+
"asymmetric_encryption", request.asymmetric_encryption
352+
),
353+
OneOfPossibility("asymmetric_signing", request.asymmetric_signing),
296354
]
297355
),
298356
)
@@ -395,6 +453,18 @@ def marshal_ImportKeyMaterialRequest(
395453
return output
396454

397455

456+
def marshal_SignRequest(
457+
request: SignRequest,
458+
defaults: ProfileDefaults,
459+
) -> Dict[str, Any]:
460+
output: Dict[str, Any] = {}
461+
462+
if request.digest is not None:
463+
output["digest"] = request.digest
464+
465+
return output
466+
467+
398468
def marshal_UpdateKeyRequest(
399469
request: UpdateKeyRequest,
400470
defaults: ProfileDefaults,
@@ -416,3 +486,18 @@ def marshal_UpdateKeyRequest(
416486
)
417487

418488
return output
489+
490+
491+
def marshal_VerifyRequest(
492+
request: VerifyRequest,
493+
defaults: ProfileDefaults,
494+
) -> Dict[str, Any]:
495+
output: Dict[str, Any] = {}
496+
497+
if request.digest is not None:
498+
output["digest"] = request.digest
499+
500+
if request.signature is not None:
501+
output["signature"] = request.signature
502+
503+
return output

0 commit comments

Comments
 (0)