From ccc2102bf98c09755daee263d2a7568385ea27fc Mon Sep 17 00:00:00 2001 From: mertemr <48881002+mertemr@users.noreply.github.com> Date: Wed, 7 May 2025 22:22:09 +0300 Subject: [PATCH 1/2] feat: add signing and verification methods to KMS class (cherry picked from commit 2e375e7f41c6a3f6d1c3baaad4809e5e2126faf9) --- infisical_sdk/api_types.py | 38 ++++++++++++++- infisical_sdk/resources/kms.py | 88 ++++++++++++++++++++++++++++++++-- 2 files changed, 120 insertions(+), 6 deletions(-) diff --git a/infisical_sdk/api_types.py b/infisical_sdk/api_types.py index 467673e..5a06828 100644 --- a/infisical_sdk/api_types.py +++ b/infisical_sdk/api_types.py @@ -1,7 +1,7 @@ +import json from dataclasses import dataclass, field, fields -from typing import Optional, List, Any, Dict from enum import Enum -import json +from typing import Any, Dict, List, Optional, Union class ApprovalStatus(str, Enum): @@ -133,6 +133,26 @@ class SymmetricEncryption(str, Enum): AES_GCM_128 = "aes-128-gcm" +class AsymmetricEncryption(str, Enum): + RSA_4096 = "rsa-4096" + ECC_NIST_P256 = "ecc-nist-p256" + + +class RSASigningAlgorithm(str, Enum): + RSASSA_PSS_SHA_256 = "rsassa-pss-sha-256" + RSASSA_PSS_SHA_384 = "rsassa-pss-sha-384" + RSASSA_PSS_SHA_512 = "rsassa-pss-sha-512" + RSASSA_PKCS1_V1_5_SHA_256 = "rsassa-pkcs1-v1-5-sha-256" + RSASSA_PKCS1_V1_5_SHA_384 = "rsassa-pkcs1-v1-5-sha-384" + RSASSA_PKCS1_V1_5_SHA_512 = "rsassa-pkcs1-v1-5-sha-512" + + +class ECDSASigningAlgorithm(str, Enum): + ECDSA_SHA_256 = "ecdsa-sha-256" + ECDSA_SHA_384 = "ecdsa-sha-384" + ECDSA_SHA_512 = "ecdsa-sha-512" + + class OrderDirection(str, Enum): ASC = "asc" DESC = "desc" @@ -194,3 +214,17 @@ class KmsKeyEncryptDataResponse(BaseModel): class KmsKeyDecryptDataResponse(BaseModel): """Response model for decrypt data API""" plaintext: str + + +@dataclass +class KmsKeySignDataResponse(BaseModel): + signature: str + keyId: str + signingAlgorithm: Union[ECDSASigningAlgorithm | RSASigningAlgorithm] + + +@dataclass +class KmsKeyVerifyDataResponse(BaseModel): + signatureValid: bool + keyId: str + signingAlgorithm: Union[ECDSASigningAlgorithm | RSASigningAlgorithm] diff --git a/infisical_sdk/resources/kms.py b/infisical_sdk/resources/kms.py index 901df3a..c47b928 100644 --- a/infisical_sdk/resources/kms.py +++ b/infisical_sdk/resources/kms.py @@ -1,7 +1,19 @@ -from infisical_sdk.api_types import SymmetricEncryption, KmsKeysOrderBy, OrderDirection -from infisical_sdk.api_types import ListKmsKeysResponse, SingleKmsKeyResponse -from infisical_sdk.api_types import KmsKey, KmsKeyEncryptDataResponse, KmsKeyDecryptDataResponse - +from typing import Union + +from infisical_sdk.api_types import ( + ECDSASigningAlgorithm, + KmsKey, + KmsKeyDecryptDataResponse, + KmsKeyEncryptDataResponse, + KmsKeySignDataResponse, + KmsKeysOrderBy, + KmsKeyVerifyDataResponse, + ListKmsKeysResponse, + OrderDirection, + RSASigningAlgorithm, + SingleKmsKeyResponse, + SymmetricEncryption, +) from infisical_sdk.infisical_requests import InfisicalRequests @@ -175,3 +187,71 @@ def decrypt_data( ) return result.data.plaintext + + def sign_data( + self, + key_id: str, + base64EncodedPlaintext: str, + signingAlgorithm: Union[ECDSASigningAlgorithm | RSASigningAlgorithm], + ) -> str: + """ + Sign the provided base64-encoded plaintext using the specified KMS key and signing algorithm. + + :param key_id: The ID of the key used for signing. + :type key_id: str + :param base64EncodedPlaintext: The base64-encoded plaintext to sign. + :type base64EncodedPlaintext: str + :param signingAlgorithm: The signing algorithm to use (RSA or ECDSA variants). + :type signingAlgorithm: ECDSASigningAlgorithm | RSASigningAlgorithm + + :return: The base64-encoded signature. + :rtype: str + """ + request_body = { + "data": base64EncodedPlaintext, + "signingAlgorithm": signingAlgorithm.value, + } + + result = self.requests.post( + path=f"/api/v1/kms/keys/{key_id}/sign", + json=request_body, + model=KmsKeySignDataResponse, + ) + + return result.data.signature + + def verify_data( + self, + key_id: str, + base64EncodedPlaintext: str, + signingAlgorithm: Union[ECDSASigningAlgorithm | RSASigningAlgorithm], + signature: str, + ) -> bool: + """ + Verify a signature for the given base64-encoded plaintext using the specified KMS key and signing algorithm. + + :param key_id: The ID of the key used to verify the signature. + :type key_id: str + :param base64EncodedPlaintext: The base64-encoded plaintext whose signature is being verified. + :type base64EncodedPlaintext: str + :param signingAlgorithm: The algorithm used to generate the signature. + :type signingAlgorithm: ECDSASigningAlgorithm | RSASigningAlgorithm + :param signature: The base64-encoded signature to verify. + :type signature: str + + :return: True if the signature is valid, False otherwise. + :rtype: bool + """ + request_body = { + "data": base64EncodedPlaintext, + "signingAlgorithm": signingAlgorithm.value, + "signature": signature, + } + + result = self.requests.post( + path=f"/api/v1/kms/keys/{key_id}/verify", + json=request_body, + model=KmsKeyVerifyDataResponse, + ) + + return result.data.signatureValid From 06c7b7e144f3cdd390a652ad1f3413210269619b Mon Sep 17 00:00:00 2001 From: mertemr <48881002+mertemr@users.noreply.github.com> Date: Fri, 9 May 2025 11:51:56 +0300 Subject: [PATCH 2/2] fix: fix casing for signing algorithm constants in api_types.py (cherry picked from commit 819c41829a54dfb3a20bcf09c921280ca87c9b23) --- infisical_sdk/api_types.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/infisical_sdk/api_types.py b/infisical_sdk/api_types.py index 5a06828..1bd8a3e 100644 --- a/infisical_sdk/api_types.py +++ b/infisical_sdk/api_types.py @@ -139,18 +139,18 @@ class AsymmetricEncryption(str, Enum): class RSASigningAlgorithm(str, Enum): - RSASSA_PSS_SHA_256 = "rsassa-pss-sha-256" - RSASSA_PSS_SHA_384 = "rsassa-pss-sha-384" - RSASSA_PSS_SHA_512 = "rsassa-pss-sha-512" - RSASSA_PKCS1_V1_5_SHA_256 = "rsassa-pkcs1-v1-5-sha-256" - RSASSA_PKCS1_V1_5_SHA_384 = "rsassa-pkcs1-v1-5-sha-384" - RSASSA_PKCS1_V1_5_SHA_512 = "rsassa-pkcs1-v1-5-sha-512" + RSASSA_PSS_SHA_256 = "RSASSA_PSS_SHA_256" + RSASSA_PSS_SHA_384 = "RSASSA_PSS_SHA_384" + RSASSA_PSS_SHA_512 = "RSASSA_PSS_SHA_512" + RSASSA_PKCS1_V1_5_SHA_256 = "RSASSA_PKCS1_V1_5_SHA_256" + RSASSA_PKCS1_V1_5_SHA_384 = "RSASSA_PKCS1_V1_5_SHA_384" + RSASSA_PKCS1_V1_5_SHA_512 = "RSASSA_PKCS1_V1_5_SHA_512" class ECDSASigningAlgorithm(str, Enum): - ECDSA_SHA_256 = "ecdsa-sha-256" - ECDSA_SHA_384 = "ecdsa-sha-384" - ECDSA_SHA_512 = "ecdsa-sha-512" + ECDSA_SHA_256 = "ECDSA_SHA_256" + ECDSA_SHA_384 = "ECDSA_SHA_384" + ECDSA_SHA_512 = "ECDSA_SHA_512" class OrderDirection(str, Enum):