huaweicloud-encryption-sdk-python 1.2.1__py3-none-any.whl
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.
- examples/file_encryption_example.py +57 -0
- examples/key_capsule_encryption_example.py +240 -0
- examples/kms_discovery_encryption_example.py +56 -0
- examples/local_aes_encryption_example.py +59 -0
- examples/test_rsa.py +42 -0
- examples/test_sm2.py +38 -0
- examples/test_sm4_cbc.py +37 -0
- examples/test_sm4_gcm.py +37 -0
- huaweicloud_encryption_sdk_python-1.2.1.dist-info/METADATA +18 -0
- huaweicloud_encryption_sdk_python-1.2.1.dist-info/RECORD +174 -0
- huaweicloud_encryption_sdk_python-1.2.1.dist-info/WHEEL +5 -0
- huaweicloud_encryption_sdk_python-1.2.1.dist-info/top_level.txt +3 -0
- huaweicloud_encryptionsdk/__init__.py +5 -0
- huaweicloud_encryptionsdk/_apig_sdk/__init__.py +1 -0
- huaweicloud_encryptionsdk/_apig_sdk/signer.py +278 -0
- huaweicloud_encryptionsdk/_apig_sdk/signer_v11.py +70 -0
- huaweicloud_encryptionsdk/_apig_sdk/sm3_hash.py +141 -0
- huaweicloud_encryptionsdk/_lts_sdk/auth/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/auth/signer.py +174 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/client/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/client/consumer_client_adapter.py +59 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/client/http_client.py +211 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/core/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/core/client_consumer_worker.py +106 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/core/consumer_heartbeat.py +73 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/core/log_shard_consumer.py +179 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/interface/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/interface/consumer_check_point_tracker.py +120 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/interface/consumer_processor.py +18 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/interface/consumer_processor_factory.py +3 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/model/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/model/check_point.py +20 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/model/consumer_config.py +27 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/model/log_data.py +18 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/model/task_result.py +40 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/task/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/task/consumer_fetch_task.py +53 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/task/initial_task.py +55 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/task/process_task.py +25 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/task/shutdown_task.py +24 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer_main.py +88 -0
- huaweicloud_encryptionsdk/_lts_sdk/parallel_main.py +64 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/callback/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/callback/call_back.py +7 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/core/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/core/accumulator.py +135 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/core/io_thread_pool.py +107 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/core/io_worker.py +124 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/core/mover.py +69 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/core/producer.py +98 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/lts_http/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/lts_http/http_client.py +63 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/lts_http/simple_request.py +14 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/model/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/model/config.py +50 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/model/error.py +18 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/model/log.py +87 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/model/log_batch.py +154 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/model/lts_store.py +21 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/model/result.py +17 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/model/retry_queue.py +39 -0
- huaweicloud_encryptionsdk/_lts_sdk/serial_main.py +77 -0
- huaweicloud_encryptionsdk/_lts_sdk/utils/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/utils/common.py +57 -0
- huaweicloud_encryptionsdk/_lts_sdk/utils/lts_threading.py +32 -0
- huaweicloud_encryptionsdk/cache/__init__.py +0 -0
- huaweicloud_encryptionsdk/cache/data_key_cache.py +79 -0
- huaweicloud_encryptionsdk/cache/local_data_key_cache.py +161 -0
- huaweicloud_encryptionsdk/common/__init__.py +0 -0
- huaweicloud_encryptionsdk/common/constants.py +15 -0
- huaweicloud_encryptionsdk/common/counting_output_stream.py +18 -0
- huaweicloud_encryptionsdk/common/crypto_factory.py +48 -0
- huaweicloud_encryptionsdk/common/ec_private_key_loader.py +43 -0
- huaweicloud_encryptionsdk/common/ecs_metadata_service.py +42 -0
- huaweicloud_encryptionsdk/common/file_path_for_example_constants.py +4 -0
- huaweicloud_encryptionsdk/common/utils.py +162 -0
- huaweicloud_encryptionsdk/exception/__init__.py +0 -0
- huaweicloud_encryptionsdk/exception/errors.py +109 -0
- huaweicloud_encryptionsdk/handler/__init__.py +0 -0
- huaweicloud_encryptionsdk/handler/cipher_handler.py +294 -0
- huaweicloud_encryptionsdk/handler/crypto_handler.py +24 -0
- huaweicloud_encryptionsdk/handler/default_crypto_handler.py +148 -0
- huaweicloud_encryptionsdk/handler/default_serialize_handler.py +45 -0
- huaweicloud_encryptionsdk/handler/file_decrypt_handler.py +101 -0
- huaweicloud_encryptionsdk/handler/file_encrypt_handler.py +30 -0
- huaweicloud_encryptionsdk/handler/serialize_handler.py +14 -0
- huaweicloud_encryptionsdk/huawei_config.py +49 -0
- huaweicloud_encryptionsdk/huawei_crypto.py +311 -0
- huaweicloud_encryptionsdk/keyrings/__init__.py +0 -0
- huaweicloud_encryptionsdk/keyrings/keyring.py +14 -0
- huaweicloud_encryptionsdk/keyrings/keyring_factory.py +10 -0
- huaweicloud_encryptionsdk/keyrings/kms_keyring_factory.py +21 -0
- huaweicloud_encryptionsdk/keyrings/kmskeyring/__init__.py +0 -0
- huaweicloud_encryptionsdk/keyrings/kmskeyring/kms_discovery_keyring.py +51 -0
- huaweicloud_encryptionsdk/keyrings/kmskeyring/kms_key_capsule_keyring.py +100 -0
- huaweicloud_encryptionsdk/keyrings/kmskeyring/kms_keyring.py +155 -0
- huaweicloud_encryptionsdk/keyrings/kmskeyring/kms_multi_region_keyring.py +8 -0
- huaweicloud_encryptionsdk/keyrings/raw_keyring_factory.py +27 -0
- huaweicloud_encryptionsdk/keyrings/rawkeyring/__init__.py +0 -0
- huaweicloud_encryptionsdk/keyrings/rawkeyring/raw_aes_keyring.py +63 -0
- huaweicloud_encryptionsdk/keyrings/rawkeyring/raw_keyring.py +112 -0
- huaweicloud_encryptionsdk/keyrings/rawkeyring/raw_rsa_keyring.py +55 -0
- huaweicloud_encryptionsdk/keyrings/rawkeyring/raw_sm2_keyring.py +75 -0
- huaweicloud_encryptionsdk/keyrings/rawkeyring/raw_sm4_cbc_keyring.py +66 -0
- huaweicloud_encryptionsdk/keyrings/rawkeyring/raw_sm4_keyring.py +70 -0
- huaweicloud_encryptionsdk/kms/__init__.py +0 -0
- huaweicloud_encryptionsdk/kms/create_key_capsule_request.py +35 -0
- huaweicloud_encryptionsdk/kms/create_key_capsule_response.py +19 -0
- huaweicloud_encryptionsdk/kms/decrypt_key_capsule_request.py +32 -0
- huaweicloud_encryptionsdk/kms/decrypt_key_capsule_response.py +19 -0
- huaweicloud_encryptionsdk/kms/kms_http_client.py +116 -0
- huaweicloud_encryptionsdk/log/__init__.py +0 -0
- huaweicloud_encryptionsdk/log/log_config.py +30 -0
- huaweicloud_encryptionsdk/log/log_file_backup.py +144 -0
- huaweicloud_encryptionsdk/log/log_metrics.py +132 -0
- huaweicloud_encryptionsdk/log/log_reporter_manager.py +163 -0
- huaweicloud_encryptionsdk/log/lts_sdk_producer.py +386 -0
- huaweicloud_encryptionsdk/log/lts_struct_log_builder.py +106 -0
- huaweicloud_encryptionsdk/meterialmanager/__init__.py +0 -0
- huaweicloud_encryptionsdk/meterialmanager/cache_crypto_meterial_manager.py +221 -0
- huaweicloud_encryptionsdk/meterialmanager/crypto_meterial_manager.py +19 -0
- huaweicloud_encryptionsdk/meterialmanager/data_key_generate.py +10 -0
- huaweicloud_encryptionsdk/meterialmanager/data_key_generate_factory.py +20 -0
- huaweicloud_encryptionsdk/meterialmanager/default_crypto_meterials_manager.py +71 -0
- huaweicloud_encryptionsdk/meterialmanager/key_capsule_data_key_generate.py +63 -0
- huaweicloud_encryptionsdk/meterialmanager/kms_data_key_generate.py +65 -0
- huaweicloud_encryptionsdk/meterialmanager/local_data_key_generate.py +13 -0
- huaweicloud_encryptionsdk/model/__init__.py +0 -0
- huaweicloud_encryptionsdk/model/access_point_config.py +9 -0
- huaweicloud_encryptionsdk/model/cipher_body.py +81 -0
- huaweicloud_encryptionsdk/model/cipher_header.py +405 -0
- huaweicloud_encryptionsdk/model/ciphertext_data_key.py +166 -0
- huaweicloud_encryptionsdk/model/crypto_result.py +11 -0
- huaweicloud_encryptionsdk/model/data_key_materials.py +17 -0
- huaweicloud_encryptionsdk/model/data_materials.py +11 -0
- huaweicloud_encryptionsdk/model/enums/__init__.py +0 -0
- huaweicloud_encryptionsdk/model/enums/access_point_type.py +28 -0
- huaweicloud_encryptionsdk/model/enums/crypto_algorithm.py +75 -0
- huaweicloud_encryptionsdk/model/enums/data_key_generate_type.py +20 -0
- huaweicloud_encryptionsdk/model/enums/key_provider_enum.py +19 -0
- huaweicloud_encryptionsdk/model/enums/keyring_type_enum.py +27 -0
- huaweicloud_encryptionsdk/model/key_capsule.py +10 -0
- huaweicloud_encryptionsdk/model/key_capsule_config.py +12 -0
- huaweicloud_encryptionsdk/model/kms_config.py +10 -0
- huaweicloud_encryptionsdk/model/request/__init__.py +0 -0
- huaweicloud_encryptionsdk/model/request/encrypt_request.py +10 -0
- huaweicloud_encryptionsdk/model/request/sign_request.py +2 -0
- huaweicloud_encryptionsdk/model/request/verify_request.py +2 -0
- huaweicloud_encryptionsdk/proof/__init__.py +0 -0
- huaweicloud_encryptionsdk/proof/attestation_document.py +36 -0
- huaweicloud_encryptionsdk/proof/collector/__init__.py +0 -0
- huaweicloud_encryptionsdk/proof/collector/cce_proof_collector.py +24 -0
- huaweicloud_encryptionsdk/proof/collector/ecs_proof_collector.py +11 -0
- huaweicloud_encryptionsdk/proof/collector/key_pair_proof_collector.py +55 -0
- huaweicloud_encryptionsdk/proof/collector/ma_proof_collector.py +51 -0
- huaweicloud_encryptionsdk/proof/private_key_decrypt_callback.py +7 -0
- huaweicloud_encryptionsdk/proof/proof_collector.py +11 -0
- huaweicloud_encryptionsdk/proof/proof_collector_factory.py +53 -0
- huaweicloud_encryptionsdk/proof/proof_info.py +10 -0
- huaweicloud_encryptionsdk/util/__init__.py +0 -0
- huaweicloud_encryptionsdk/util/common_utils.py +12 -0
- tests/__init__.py +0 -0
- tests/test_enums.py +84 -0
- tests/test_exceptions.py +38 -0
- tests/test_factories.py +71 -0
- tests/test_huawei_crypto.py +67 -0
- tests/test_imports.py +46 -0
- tests/test_kms_models.py +95 -0
- tests/test_log_file_backup.py +45 -0
- tests/test_lts_struct_log_builder.py +97 -0
- tests/test_models.py +142 -0
- tests/test_utils.py +111 -0
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from typing import Optional, Union
|
|
5
|
+
|
|
6
|
+
from huaweicloud_encryptionsdk.exception.errors import (
|
|
7
|
+
HuaweicloudException,
|
|
8
|
+
KeyringNotFoundException,
|
|
9
|
+
ErrorMessage,
|
|
10
|
+
)
|
|
11
|
+
from huaweicloud_encryptionsdk.handler.default_crypto_handler import DefaultCryptoHandler
|
|
12
|
+
from huaweicloud_encryptionsdk.keyrings.keyring import Keyring
|
|
13
|
+
from huaweicloud_encryptionsdk.keyrings.kmskeyring.kms_keyring import KMSKeyring
|
|
14
|
+
from huaweicloud_encryptionsdk.log.log_reporter_manager import LogReporterManager
|
|
15
|
+
from huaweicloud_encryptionsdk.meterialmanager.cache_crypto_meterial_manager import CacheCryptoMaterialsManager
|
|
16
|
+
from huaweicloud_encryptionsdk.meterialmanager.crypto_meterial_manager import CryptoMaterialManager
|
|
17
|
+
from huaweicloud_encryptionsdk.meterialmanager.default_crypto_meterials_manager import DefaultCryptoMaterialsManager
|
|
18
|
+
from huaweicloud_encryptionsdk.model.crypto_result import CryptoResult
|
|
19
|
+
from huaweicloud_encryptionsdk.model.data_key_materials import DataKeyMaterials
|
|
20
|
+
from huaweicloud_encryptionsdk.model.enums.access_point_type import AccessPointType
|
|
21
|
+
from huaweicloud_encryptionsdk.model.enums.crypto_algorithm import CryptoAlgorithm
|
|
22
|
+
from huaweicloud_encryptionsdk.model.request.encrypt_request import EncryptRequest
|
|
23
|
+
from huaweicloud_encryptionsdk.common.ecs_metadata_service import EcsMetadataService
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class HuaweiCrypto:
|
|
27
|
+
|
|
28
|
+
def __init__(self, huawei_config):
|
|
29
|
+
self._huawei_config = huawei_config
|
|
30
|
+
if self._huawei_config.crypto_algorithm is None:
|
|
31
|
+
self._huawei_config.crypto_algorithm = CryptoAlgorithm.AES_128_GCM_NOPADDING
|
|
32
|
+
self._crypto_handler = DefaultCryptoHandler()
|
|
33
|
+
self._crypto_materials_manager: CryptoMaterialManager = DefaultCryptoMaterialsManager(huawei_config)
|
|
34
|
+
self._keyring: Optional[Keyring] = None
|
|
35
|
+
self._log_reporter_manager = LogReporterManager()
|
|
36
|
+
|
|
37
|
+
if self._huawei_config.log_config is not None or self._huawei_config.local_log_only:
|
|
38
|
+
self._log_reporter_manager.init(huawei_config)
|
|
39
|
+
|
|
40
|
+
def close(self) -> None:
|
|
41
|
+
self._log_reporter_manager.shutdown()
|
|
42
|
+
|
|
43
|
+
def with_crypto_material_manager(self, manager: CryptoMaterialManager) -> HuaweiCrypto:
|
|
44
|
+
self._crypto_materials_manager = manager
|
|
45
|
+
return self
|
|
46
|
+
|
|
47
|
+
def with_keyring(self, keyring: Keyring) -> HuaweiCrypto:
|
|
48
|
+
self._keyring = keyring
|
|
49
|
+
if isinstance(keyring, KMSKeyring):
|
|
50
|
+
keyring.huawei_config = self._huawei_config
|
|
51
|
+
return self
|
|
52
|
+
|
|
53
|
+
def encrypt(self, plain_text_or_request: Union[bytes, EncryptRequest]) -> CryptoResult[bytes]:
|
|
54
|
+
if isinstance(plain_text_or_request, (bytes, bytearray)):
|
|
55
|
+
request = EncryptRequest(encryption_context={}, plain_text=plain_text_or_request)
|
|
56
|
+
else:
|
|
57
|
+
request = plain_text_or_request
|
|
58
|
+
|
|
59
|
+
if self._keyring is None:
|
|
60
|
+
raise KeyringNotFoundException(ErrorMessage.KEYRING_NULL_EXCEPTION.message)
|
|
61
|
+
|
|
62
|
+
data_key_materials = None
|
|
63
|
+
try:
|
|
64
|
+
data_key_materials = DataKeyMaterials()
|
|
65
|
+
data_key_materials.encryption_contexts = request.encryption_context or {}
|
|
66
|
+
data_key_materials.crypto_algorithm = self._huawei_config.crypto_algorithm
|
|
67
|
+
data_key_materials.policy_id = request.policy_id
|
|
68
|
+
data_key_materials.key_policy = request.key_policy
|
|
69
|
+
|
|
70
|
+
if isinstance(self._crypto_materials_manager, CacheCryptoMaterialsManager):
|
|
71
|
+
if self._crypto_materials_manager.max_byte_limit < len(request.plain_text):
|
|
72
|
+
raise HuaweicloudException(ErrorMessage.DATA_EXCEED_LIMIT.message)
|
|
73
|
+
|
|
74
|
+
data_key_materials = self._crypto_materials_manager.get_materials_for_encrypt(
|
|
75
|
+
self._keyring, data_key_materials, len(request.plain_text)
|
|
76
|
+
)
|
|
77
|
+
result = self._crypto_handler.encrypt(request, data_key_materials)
|
|
78
|
+
|
|
79
|
+
if self._huawei_config.log_config is not None or self._huawei_config.local_log_only:
|
|
80
|
+
if data_key_materials.key_capsule is not None:
|
|
81
|
+
key_id = data_key_materials.key_capsule.key_id
|
|
82
|
+
encrypt_data_bytes = len(request.plain_text)
|
|
83
|
+
encrypt_output_bytes = result.data_length
|
|
84
|
+
access_point_type = AccessPointType.get_display_name_by_code(
|
|
85
|
+
data_key_materials.key_capsule.access_point_type
|
|
86
|
+
)
|
|
87
|
+
instance_id = (
|
|
88
|
+
EcsMetadataService.get_ecs_instance_id()
|
|
89
|
+
if data_key_materials.key_capsule.access_point_type == AccessPointType.ECS.code
|
|
90
|
+
else None
|
|
91
|
+
)
|
|
92
|
+
self._log_reporter_manager.record_encrypt_log(
|
|
93
|
+
None, encrypt_data_bytes, None, encrypt_output_bytes,
|
|
94
|
+
key_id, access_point_type, instance_id
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
return result
|
|
98
|
+
except HuaweicloudException:
|
|
99
|
+
raise
|
|
100
|
+
except Exception as e:
|
|
101
|
+
raise HuaweicloudException(ErrorMessage.CIPHER_EXCEPTION.message) from e
|
|
102
|
+
|
|
103
|
+
def decrypt(self, cipher_text: bytes) -> CryptoResult[bytes]:
|
|
104
|
+
if self._keyring is None:
|
|
105
|
+
raise KeyringNotFoundException(ErrorMessage.KEYRING_NULL_EXCEPTION.message)
|
|
106
|
+
|
|
107
|
+
data_key_materials = None
|
|
108
|
+
try:
|
|
109
|
+
data_key_materials = self._crypto_materials_manager.get_materials_for_decrypt(
|
|
110
|
+
self._keyring, cipher_text
|
|
111
|
+
)
|
|
112
|
+
result = self._crypto_handler.decrypt(cipher_text, data_key_materials)
|
|
113
|
+
|
|
114
|
+
if self._huawei_config.log_config is not None or self._huawei_config.local_log_only:
|
|
115
|
+
if data_key_materials.key_capsule is not None:
|
|
116
|
+
key_id = data_key_materials.key_capsule.key_id
|
|
117
|
+
decrypt_data_bytes = len(cipher_text)
|
|
118
|
+
decrypt_output_bytes = len(result.result) if result.result is not None else 0
|
|
119
|
+
access_point_type = AccessPointType.get_display_name_by_code(
|
|
120
|
+
data_key_materials.key_capsule.access_point_type
|
|
121
|
+
)
|
|
122
|
+
instance_id = data_key_materials.key_capsule.instance_id
|
|
123
|
+
self._log_reporter_manager.record_decrypt_log(
|
|
124
|
+
None, decrypt_data_bytes, None, decrypt_output_bytes,
|
|
125
|
+
key_id, access_point_type, instance_id
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
return result
|
|
129
|
+
except HuaweicloudException:
|
|
130
|
+
raise
|
|
131
|
+
except Exception as e:
|
|
132
|
+
raise HuaweicloudException(ErrorMessage.DECRYPT_EXCEPTION.message) from e
|
|
133
|
+
|
|
134
|
+
def encrypt_stream(self, input_stream, output_stream, encryption_context=None) -> CryptoResult:
|
|
135
|
+
if self._keyring is None:
|
|
136
|
+
raise KeyringNotFoundException(ErrorMessage.KEYRING_NULL_EXCEPTION.message)
|
|
137
|
+
|
|
138
|
+
data_key_materials = None
|
|
139
|
+
try:
|
|
140
|
+
encrypt_data_bytes = 0
|
|
141
|
+
try:
|
|
142
|
+
pos = input_stream.tell()
|
|
143
|
+
input_stream.seek(0, 2)
|
|
144
|
+
encrypt_data_bytes = input_stream.tell()
|
|
145
|
+
input_stream.seek(pos)
|
|
146
|
+
except Exception:
|
|
147
|
+
pass
|
|
148
|
+
|
|
149
|
+
data_key_materials = DataKeyMaterials()
|
|
150
|
+
data_key_materials.encryption_contexts = encryption_context if encryption_context is not None else {}
|
|
151
|
+
data_key_materials.crypto_algorithm = self._huawei_config.crypto_algorithm
|
|
152
|
+
|
|
153
|
+
if isinstance(self._crypto_materials_manager, CacheCryptoMaterialsManager):
|
|
154
|
+
if self._crypto_materials_manager.max_byte_limit < encrypt_data_bytes:
|
|
155
|
+
raise HuaweicloudException(ErrorMessage.DATA_EXCEED_LIMIT.message)
|
|
156
|
+
|
|
157
|
+
data_key_materials = self._crypto_materials_manager.get_materials_for_encrypt(
|
|
158
|
+
self._keyring, data_key_materials, encrypt_data_bytes
|
|
159
|
+
)
|
|
160
|
+
crypto_result = self._crypto_handler.encrypt_stream(
|
|
161
|
+
input_stream, output_stream, data_key_materials, encryption_context
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
if self._huawei_config.log_config is not None or self._huawei_config.local_log_only:
|
|
165
|
+
if data_key_materials.key_capsule is not None:
|
|
166
|
+
key_id = data_key_materials.key_capsule.key_id
|
|
167
|
+
access_point_type = AccessPointType.get_display_name_by_code(
|
|
168
|
+
data_key_materials.key_capsule.access_point_type
|
|
169
|
+
)
|
|
170
|
+
instance_id = (
|
|
171
|
+
EcsMetadataService.get_ecs_instance_id()
|
|
172
|
+
if data_key_materials.key_capsule.access_point_type == AccessPointType.ECS.code
|
|
173
|
+
else None
|
|
174
|
+
)
|
|
175
|
+
self._log_reporter_manager.record_encrypt_log(
|
|
176
|
+
None, encrypt_data_bytes, None, crypto_result.data_length,
|
|
177
|
+
key_id, access_point_type, instance_id
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
return crypto_result
|
|
181
|
+
except HuaweicloudException:
|
|
182
|
+
raise
|
|
183
|
+
except Exception as e:
|
|
184
|
+
raise HuaweicloudException(ErrorMessage.CIPHER_EXCEPTION.message) from e
|
|
185
|
+
|
|
186
|
+
def decrypt_stream(self, input_stream, output_stream) -> CryptoResult:
|
|
187
|
+
if self._keyring is None:
|
|
188
|
+
raise KeyringNotFoundException(ErrorMessage.KEYRING_NULL_EXCEPTION.message)
|
|
189
|
+
|
|
190
|
+
data_key_materials = None
|
|
191
|
+
try:
|
|
192
|
+
decrypt_data_bytes = 0
|
|
193
|
+
try:
|
|
194
|
+
pos = input_stream.tell()
|
|
195
|
+
input_stream.seek(0, 2)
|
|
196
|
+
decrypt_data_bytes = input_stream.tell()
|
|
197
|
+
input_stream.seek(pos)
|
|
198
|
+
except Exception:
|
|
199
|
+
pass
|
|
200
|
+
|
|
201
|
+
data_key_materials = self._crypto_materials_manager.get_materials_for_stream_decrypt(
|
|
202
|
+
self._keyring, input_stream
|
|
203
|
+
)
|
|
204
|
+
crypto_result = self._crypto_handler.decrypt_stream(
|
|
205
|
+
input_stream, output_stream, data_key_materials
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
if self._huawei_config.log_config is not None or self._huawei_config.local_log_only:
|
|
209
|
+
if data_key_materials.key_capsule is not None:
|
|
210
|
+
key_id = data_key_materials.key_capsule.key_id
|
|
211
|
+
access_point_type = AccessPointType.get_display_name_by_code(
|
|
212
|
+
data_key_materials.key_capsule.access_point_type
|
|
213
|
+
)
|
|
214
|
+
instance_id = data_key_materials.key_capsule.instance_id
|
|
215
|
+
self._log_reporter_manager.record_decrypt_log(
|
|
216
|
+
None, decrypt_data_bytes, None, None,
|
|
217
|
+
key_id, access_point_type, instance_id
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
return crypto_result
|
|
221
|
+
except HuaweicloudException:
|
|
222
|
+
raise
|
|
223
|
+
except Exception as e:
|
|
224
|
+
raise HuaweicloudException(ErrorMessage.DECRYPT_EXCEPTION.message) from e
|
|
225
|
+
|
|
226
|
+
def encrypt_file(self, source_file_path: str, target_file_path: str, encryption_context=None) -> CryptoResult:
|
|
227
|
+
if self._keyring is None:
|
|
228
|
+
raise KeyringNotFoundException(ErrorMessage.KEYRING_NULL_EXCEPTION.message)
|
|
229
|
+
|
|
230
|
+
data_key_materials = None
|
|
231
|
+
try:
|
|
232
|
+
encrypt_data_bytes = os.path.getsize(source_file_path)
|
|
233
|
+
|
|
234
|
+
data_key_materials = DataKeyMaterials()
|
|
235
|
+
data_key_materials.encryption_contexts = encryption_context if encryption_context is not None else {}
|
|
236
|
+
data_key_materials.crypto_algorithm = self._huawei_config.crypto_algorithm
|
|
237
|
+
|
|
238
|
+
if isinstance(self._crypto_materials_manager, CacheCryptoMaterialsManager):
|
|
239
|
+
if self._crypto_materials_manager.max_byte_limit < encrypt_data_bytes:
|
|
240
|
+
raise HuaweicloudException(ErrorMessage.DATA_EXCEED_LIMIT.message)
|
|
241
|
+
|
|
242
|
+
data_key_materials = self._crypto_materials_manager.get_materials_for_encrypt(
|
|
243
|
+
self._keyring, data_key_materials, encrypt_data_bytes
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
with open(source_file_path, "rb", buffering=1024 * 1024) as input_stream, \
|
|
247
|
+
open(target_file_path, "wb", buffering=1024 * 1024) as output_stream:
|
|
248
|
+
crypto_result = self._crypto_handler.encrypt_stream(
|
|
249
|
+
input_stream, output_stream, data_key_materials, encryption_context
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
if self._huawei_config.log_config is not None or self._huawei_config.local_log_only:
|
|
253
|
+
if data_key_materials.key_capsule is not None:
|
|
254
|
+
key_id = data_key_materials.key_capsule.key_id
|
|
255
|
+
access_point_type = AccessPointType.get_display_name_by_code(
|
|
256
|
+
data_key_materials.key_capsule.access_point_type
|
|
257
|
+
)
|
|
258
|
+
instance_id = (
|
|
259
|
+
EcsMetadataService.get_ecs_instance_id()
|
|
260
|
+
if data_key_materials.key_capsule.access_point_type == AccessPointType.ECS.code
|
|
261
|
+
else None
|
|
262
|
+
)
|
|
263
|
+
output_size = os.path.getsize(target_file_path)
|
|
264
|
+
self._log_reporter_manager.record_encrypt_log(
|
|
265
|
+
os.path.basename(source_file_path), encrypt_data_bytes,
|
|
266
|
+
os.path.basename(target_file_path), output_size,
|
|
267
|
+
key_id, access_point_type, instance_id
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
return crypto_result
|
|
271
|
+
except HuaweicloudException:
|
|
272
|
+
raise
|
|
273
|
+
except Exception as e:
|
|
274
|
+
raise HuaweicloudException(ErrorMessage.CIPHER_EXCEPTION.message) from e
|
|
275
|
+
|
|
276
|
+
def decrypt_file(self, source_file_path: str, target_file_path: str) -> CryptoResult:
|
|
277
|
+
if self._keyring is None:
|
|
278
|
+
raise KeyringNotFoundException(ErrorMessage.KEYRING_NULL_EXCEPTION.message)
|
|
279
|
+
|
|
280
|
+
data_key_materials = None
|
|
281
|
+
try:
|
|
282
|
+
decrypt_data_bytes = os.path.getsize(source_file_path)
|
|
283
|
+
|
|
284
|
+
with open(source_file_path, "rb", buffering=1024 * 1024) as input_stream:
|
|
285
|
+
data_key_materials = self._crypto_materials_manager.get_materials_for_stream_decrypt(
|
|
286
|
+
self._keyring, input_stream
|
|
287
|
+
)
|
|
288
|
+
with open(target_file_path, "wb", buffering=1024 * 1024) as output_stream:
|
|
289
|
+
crypto_result = self._crypto_handler.decrypt_stream(
|
|
290
|
+
input_stream, output_stream, data_key_materials
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
if self._huawei_config.log_config is not None or self._huawei_config.local_log_only:
|
|
294
|
+
if data_key_materials.key_capsule is not None:
|
|
295
|
+
key_id = data_key_materials.key_capsule.key_id
|
|
296
|
+
access_point_type = AccessPointType.get_display_name_by_code(
|
|
297
|
+
data_key_materials.key_capsule.access_point_type
|
|
298
|
+
)
|
|
299
|
+
instance_id = data_key_materials.key_capsule.instance_id
|
|
300
|
+
output_size = os.path.getsize(target_file_path)
|
|
301
|
+
self._log_reporter_manager.record_decrypt_log(
|
|
302
|
+
os.path.basename(source_file_path), decrypt_data_bytes,
|
|
303
|
+
os.path.basename(target_file_path), output_size,
|
|
304
|
+
key_id, access_point_type, instance_id
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
return crypto_result
|
|
308
|
+
except HuaweicloudException:
|
|
309
|
+
raise
|
|
310
|
+
except Exception as e:
|
|
311
|
+
raise HuaweicloudException(ErrorMessage.DECRYPT_EXCEPTION.message) from e
|
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
|
|
3
|
+
from huaweicloud_encryptionsdk.model.data_key_materials import DataKeyMaterials
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Keyring(ABC):
|
|
7
|
+
|
|
8
|
+
@abstractmethod
|
|
9
|
+
def encrypt_data_key(self, data_key_materials: DataKeyMaterials) -> DataKeyMaterials:
|
|
10
|
+
pass
|
|
11
|
+
|
|
12
|
+
@abstractmethod
|
|
13
|
+
def decrypt_data_key(self, data_key_materials: DataKeyMaterials) -> DataKeyMaterials:
|
|
14
|
+
pass
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from huaweicloud_encryptionsdk.exception.errors import KeyringNotFoundException, ErrorMessage
|
|
2
|
+
from huaweicloud_encryptionsdk.keyrings.keyring_factory import KeyringFactory
|
|
3
|
+
from huaweicloud_encryptionsdk.keyrings.kmskeyring.kms_discovery_keyring import KMSDiscoveryKeyring
|
|
4
|
+
from huaweicloud_encryptionsdk.keyrings.kmskeyring.kms_multi_region_keyring import KMSMultiRegionKeyring
|
|
5
|
+
from huaweicloud_encryptionsdk.keyrings.kmskeyring.kms_key_capsule_keyring import KMSKeyCapsuleKeyring
|
|
6
|
+
from huaweicloud_encryptionsdk.model.enums.keyring_type_enum import KeyringTypeEnum
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class KmsKeyringFactory(KeyringFactory):
|
|
10
|
+
|
|
11
|
+
def get_keyring(self, type: str):
|
|
12
|
+
keyring_type_enum = KeyringTypeEnum.get_raw_keyring_type(type)
|
|
13
|
+
if keyring_type_enum is None:
|
|
14
|
+
raise KeyringNotFoundException(ErrorMessage.KEYRING_NOT_FOUND_EXCEPTION.message)
|
|
15
|
+
if keyring_type_enum == KeyringTypeEnum.KMS_DISCOVERY:
|
|
16
|
+
return KMSDiscoveryKeyring()
|
|
17
|
+
elif keyring_type_enum == KeyringTypeEnum.KMS_MULTI_REGION:
|
|
18
|
+
return KMSMultiRegionKeyring()
|
|
19
|
+
elif keyring_type_enum == KeyringTypeEnum.KMS_KEY_CAPSULE:
|
|
20
|
+
return KMSKeyCapsuleKeyring()
|
|
21
|
+
return None
|
|
File without changes
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
from huaweicloud_encryptionsdk.common.utils import is_empty
|
|
2
|
+
from huaweicloud_encryptionsdk.exception.errors import HuaweicloudException, ErrorMessage
|
|
3
|
+
from huaweicloud_encryptionsdk.keyrings.kmskeyring.kms_keyring import KMSKeyring
|
|
4
|
+
from huaweicloud_encryptionsdk.model.ciphertext_data_key import CiphertextDataKey
|
|
5
|
+
from huaweicloud_encryptionsdk.model.data_key_materials import DataKeyMaterials
|
|
6
|
+
from huaweicloud_encryptionsdk.model.kms_config import KMSConfig
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class KMSDiscoveryKeyring(KMSKeyring):
|
|
10
|
+
|
|
11
|
+
def do_decrypt(self, data_key_materials: DataKeyMaterials):
|
|
12
|
+
self._prepare_key_id(data_key_materials)
|
|
13
|
+
self.real_decrypt(data_key_materials)
|
|
14
|
+
|
|
15
|
+
def _prepare_key_id(self, data_key_materials: DataKeyMaterials):
|
|
16
|
+
kms_config_list = []
|
|
17
|
+
huawei_config = self.huawei_config
|
|
18
|
+
origin_kms_config_list = huawei_config.origin_kms_config_list
|
|
19
|
+
if not origin_kms_config_list:
|
|
20
|
+
huawei_config.origin_kms_config_list = huawei_config.kms_config_list
|
|
21
|
+
origin_kms_config_list = huawei_config.origin_kms_config_list
|
|
22
|
+
for ciphertext_data_key in data_key_materials.ciphertext_data_keys:
|
|
23
|
+
if not self._check_discovery(ciphertext_data_key):
|
|
24
|
+
raise HuaweicloudException(ErrorMessage.NOT_SUPPORT_DISCOVERY_DECRYPT.message)
|
|
25
|
+
current_kms_config = None
|
|
26
|
+
if origin_kms_config_list:
|
|
27
|
+
for kms_config in origin_kms_config_list:
|
|
28
|
+
if ciphertext_data_key.region == kms_config.region:
|
|
29
|
+
current_kms_config = KMSConfig(
|
|
30
|
+
region=ciphertext_data_key.region,
|
|
31
|
+
key_id=ciphertext_data_key.key_id,
|
|
32
|
+
project_id=kms_config.project_id,
|
|
33
|
+
end_point=ciphertext_data_key.end_point
|
|
34
|
+
)
|
|
35
|
+
break
|
|
36
|
+
if current_kms_config is None:
|
|
37
|
+
current_kms_config = KMSConfig(
|
|
38
|
+
region=ciphertext_data_key.region,
|
|
39
|
+
key_id=ciphertext_data_key.key_id,
|
|
40
|
+
project_id=ciphertext_data_key.project_id,
|
|
41
|
+
end_point=ciphertext_data_key.end_point
|
|
42
|
+
)
|
|
43
|
+
kms_config_list.append(current_kms_config)
|
|
44
|
+
huawei_config.kms_config_list = kms_config_list
|
|
45
|
+
|
|
46
|
+
@staticmethod
|
|
47
|
+
def _check_discovery(ciphertext_data_key):
|
|
48
|
+
return (ciphertext_data_key.is_discovery()
|
|
49
|
+
and not is_empty(ciphertext_data_key.key_id)
|
|
50
|
+
and not is_empty(ciphertext_data_key.region)
|
|
51
|
+
and not is_empty(ciphertext_data_key.project_id))
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from huaweicloud_encryptionsdk.common.utils import is_empty, bytes_to_hex, hex_to_bytes, get_capsule_kms_config
|
|
4
|
+
from huaweicloud_encryptionsdk.exception.errors import HuaweicloudException, ErrorMessage
|
|
5
|
+
from huaweicloud_encryptionsdk.keyrings.kmskeyring.kms_keyring import KMSKeyring
|
|
6
|
+
from huaweicloud_encryptionsdk.model.ciphertext_data_key import CiphertextDataKey
|
|
7
|
+
from huaweicloud_encryptionsdk.model.data_key_materials import DataKeyMaterials
|
|
8
|
+
from huaweicloud_encryptionsdk.model.kms_config import KMSConfig
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class KMSKeyCapsuleKeyring(KMSKeyring):
|
|
14
|
+
|
|
15
|
+
def do_decrypt(self, data_key_materials: DataKeyMaterials):
|
|
16
|
+
key_capsule = data_key_materials.key_capsule
|
|
17
|
+
if key_capsule is None:
|
|
18
|
+
raise HuaweicloudException("Key capsule is null")
|
|
19
|
+
|
|
20
|
+
ciphertext_data_keys = data_key_materials.ciphertext_data_keys
|
|
21
|
+
if ciphertext_data_keys is None or len(ciphertext_data_keys) == 0:
|
|
22
|
+
raise HuaweicloudException(ErrorMessage.CIPHER_TEXT_DATA_KEY_NOT_NULL.message)
|
|
23
|
+
ciphertext_data_key = ciphertext_data_keys[0]
|
|
24
|
+
kms_config = self._get_kms_config(ciphertext_data_key)
|
|
25
|
+
key_capsule.datakey_capsule = bytes_to_hex(ciphertext_data_key.data_key)
|
|
26
|
+
|
|
27
|
+
huawei_config = self.huawei_config
|
|
28
|
+
from huaweicloudsdkcore.auth.credentials import BasicCredentials
|
|
29
|
+
auth = BasicCredentials(huawei_config.ak, huawei_config.sk, kms_config.project_id)
|
|
30
|
+
if huawei_config.security_token:
|
|
31
|
+
auth = auth.with_security_token(huawei_config.security_token)
|
|
32
|
+
|
|
33
|
+
access_point_config = huawei_config.key_capsule_config.access_point_config
|
|
34
|
+
from huaweicloud_encryptionsdk.proof.proof_info import ProofInfo
|
|
35
|
+
proof_info = ProofInfo(
|
|
36
|
+
type=key_capsule.access_point_type,
|
|
37
|
+
encrypted_private_key=access_point_config.encrypted_private_key,
|
|
38
|
+
private_key_decrypt_callback=access_point_config.private_key_decrypt_callback,
|
|
39
|
+
key_capsule=key_capsule.datakey_capsule,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
from huaweicloud_encryptionsdk.proof.proof_collector_factory import ProofCollectorFactory
|
|
43
|
+
attestation_document = ProofCollectorFactory.collect(proof_info)
|
|
44
|
+
|
|
45
|
+
plaintext_data_key = self._decrypt_key_capsule_by_kms(key_capsule, attestation_document, kms_config, auth)
|
|
46
|
+
|
|
47
|
+
data_key_materials.plaintext_data_key = plaintext_data_key
|
|
48
|
+
|
|
49
|
+
def _get_kms_config(self, ciphertext_data_key):
|
|
50
|
+
return KMSConfig(
|
|
51
|
+
region=ciphertext_data_key.region,
|
|
52
|
+
key_id=ciphertext_data_key.key_id,
|
|
53
|
+
project_id=ciphertext_data_key.project_id,
|
|
54
|
+
end_point=ciphertext_data_key.end_point
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
def encrypt_data_key(self, data_key_materials: DataKeyMaterials) -> DataKeyMaterials:
|
|
58
|
+
key_capsule_config = self.huawei_config.key_capsule_config
|
|
59
|
+
kms_config = get_capsule_kms_config(self.huawei_config.kms_config_list, key_capsule_config)
|
|
60
|
+
region = key_capsule_config.region
|
|
61
|
+
key_id = kms_config.key_id
|
|
62
|
+
project_id = kms_config.project_id
|
|
63
|
+
endpoint = kms_config.end_point
|
|
64
|
+
if not endpoint:
|
|
65
|
+
try:
|
|
66
|
+
from huaweicloudsdkkms.v2.region.kms_region import KmsRegion
|
|
67
|
+
kms_region = KmsRegion.value_of(key_capsule_config.region)
|
|
68
|
+
endpoint = kms_region.endpoints[0]
|
|
69
|
+
except Exception:
|
|
70
|
+
endpoint = None
|
|
71
|
+
if not endpoint:
|
|
72
|
+
raise HuaweicloudException(ErrorMessage.END_POINT_NOT_NULL.message)
|
|
73
|
+
ciphertext_data_keys = []
|
|
74
|
+
try:
|
|
75
|
+
cipher_data_key_bytes = hex_to_bytes(data_key_materials.key_capsule.datakey_capsule)
|
|
76
|
+
except Exception as e:
|
|
77
|
+
raise HuaweicloudException(ErrorMessage.KMS_CREATE_KEY_CAPSULE_EXCEPTION.message, e)
|
|
78
|
+
ciphertext_data_keys.append(CiphertextDataKey(
|
|
79
|
+
data_key=cipher_data_key_bytes,
|
|
80
|
+
kms_config=KMSConfig(region=region, key_id=key_id, project_id=project_id, end_point=endpoint)
|
|
81
|
+
))
|
|
82
|
+
data_key_materials.ciphertext_data_keys = ciphertext_data_keys
|
|
83
|
+
return data_key_materials
|
|
84
|
+
|
|
85
|
+
def _decrypt_key_capsule_by_kms(self, key_capsule, attestation_document, kms_config, auth):
|
|
86
|
+
try:
|
|
87
|
+
from huaweicloud_encryptionsdk.kms.kms_http_client import KmsHttpClient
|
|
88
|
+
client = KmsHttpClient(self.huawei_config.ak, self.huawei_config.sk, kms_config, self.huawei_config.security_token)
|
|
89
|
+
from huaweicloud_encryptionsdk.kms.decrypt_key_capsule_request import DecryptKeyCapsuleRequest
|
|
90
|
+
request_body = DecryptKeyCapsuleRequest(
|
|
91
|
+
key_id=key_capsule.key_id,
|
|
92
|
+
datakey_capsule=key_capsule.datakey_capsule,
|
|
93
|
+
attestation_document=attestation_document
|
|
94
|
+
)
|
|
95
|
+
from huaweicloud_encryptionsdk.kms.decrypt_key_capsule_response import DecryptKeyCapsuleResponse
|
|
96
|
+
response = client.post("/kms/datakey-capsule/decrypt", request_body, DecryptKeyCapsuleResponse)
|
|
97
|
+
key_capsule.instance_id = response.instance_id
|
|
98
|
+
return hex_to_bytes(response.datakey)
|
|
99
|
+
except Exception as e:
|
|
100
|
+
raise HuaweicloudException("Failed to decrypt key capsule", e)
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from abc import abstractmethod
|
|
3
|
+
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
4
|
+
|
|
5
|
+
from huaweicloud_encryptionsdk.common.utils import is_empty, bytes_to_hex, hex_to_bytes, common_hash
|
|
6
|
+
from huaweicloud_encryptionsdk.exception.errors import EncryptException, HuaweicloudException, ErrorMessage
|
|
7
|
+
from huaweicloud_encryptionsdk.keyrings.keyring import Keyring
|
|
8
|
+
from huaweicloud_encryptionsdk.model.ciphertext_data_key import CiphertextDataKey
|
|
9
|
+
from huaweicloud_encryptionsdk.model.data_key_materials import DataKeyMaterials
|
|
10
|
+
from huaweicloud_encryptionsdk.model.kms_config import KMSConfig
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
SHA256 = "SHA256"
|
|
15
|
+
SM3 = "SM3"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class KMSKeyring(Keyring):
|
|
19
|
+
|
|
20
|
+
kms_client_cache: dict = {}
|
|
21
|
+
|
|
22
|
+
def __init__(self):
|
|
23
|
+
self._huawei_config = None
|
|
24
|
+
|
|
25
|
+
@property
|
|
26
|
+
def huawei_config(self):
|
|
27
|
+
return self._huawei_config
|
|
28
|
+
|
|
29
|
+
@huawei_config.setter
|
|
30
|
+
def huawei_config(self, value):
|
|
31
|
+
self._huawei_config = value
|
|
32
|
+
|
|
33
|
+
@abstractmethod
|
|
34
|
+
def do_decrypt(self, data_key_materials: DataKeyMaterials):
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
def encrypt_data_key(self, data_key_materials: DataKeyMaterials) -> DataKeyMaterials:
|
|
38
|
+
self._do_encrypt(data_key_materials)
|
|
39
|
+
return data_key_materials
|
|
40
|
+
|
|
41
|
+
def decrypt_data_key(self, data_key_materials: DataKeyMaterials) -> DataKeyMaterials:
|
|
42
|
+
self.do_decrypt(data_key_materials)
|
|
43
|
+
return data_key_materials
|
|
44
|
+
|
|
45
|
+
def _do_encrypt(self, data_key_materials: DataKeyMaterials):
|
|
46
|
+
kms_config_list = self.huawei_config.kms_config_list
|
|
47
|
+
ciphertext_data_keys = []
|
|
48
|
+
|
|
49
|
+
def encrypt_for_config(kms_config):
|
|
50
|
+
try:
|
|
51
|
+
from huaweicloudsdkcore.auth.credentials import BasicCredentials
|
|
52
|
+
from huaweicloudsdkkms.v2.region.kms_region import KmsRegion
|
|
53
|
+
from huaweicloudsdkkms.v2 import KmsClient
|
|
54
|
+
from huaweicloudsdkkms.v2.model.encrypt_datakey_request import EncryptDatakeyRequest
|
|
55
|
+
from huaweicloudsdkkms.v2.model.encrypt_datakey_request_body import EncryptDatakeyRequestBody
|
|
56
|
+
|
|
57
|
+
auth = BasicCredentials(self.huawei_config.ak, self.huawei_config.sk, kms_config.project_id)
|
|
58
|
+
if self.huawei_config.security_token:
|
|
59
|
+
auth = auth.with_security_token(self.huawei_config.security_token)
|
|
60
|
+
kms_client = self._get_kms_client(kms_config.region, kms_config.end_point, auth)
|
|
61
|
+
plaintext_data_key = data_key_materials.plaintext_data_key
|
|
62
|
+
data_key_hex = bytes_to_hex(plaintext_data_key)
|
|
63
|
+
length = len(data_key_hex)
|
|
64
|
+
key_spec = self._get_key_spec(kms_client, kms_config.key_id)
|
|
65
|
+
if key_spec == "AES_256":
|
|
66
|
+
digest_alg = SHA256
|
|
67
|
+
else:
|
|
68
|
+
digest_alg = SM3
|
|
69
|
+
tmp_digest = common_hash(plaintext_data_key, digest_alg)
|
|
70
|
+
data_key_with_hash = data_key_hex + bytes_to_hex(tmp_digest)
|
|
71
|
+
body = EncryptDatakeyRequestBody(
|
|
72
|
+
key_id=kms_config.key_id,
|
|
73
|
+
plain_text=data_key_with_hash,
|
|
74
|
+
datakey_plain_length=str(length // 2)
|
|
75
|
+
)
|
|
76
|
+
request = EncryptDatakeyRequest(body=body)
|
|
77
|
+
response = kms_client.encrypt_datakey(request)
|
|
78
|
+
cipher_data_key_bytes = hex_to_bytes(response.cipher_text)
|
|
79
|
+
if self.huawei_config.is_discovery:
|
|
80
|
+
ciphertext_data_key = CiphertextDataKey(data_key=cipher_data_key_bytes, kms_config=kms_config)
|
|
81
|
+
else:
|
|
82
|
+
ciphertext_data_key = CiphertextDataKey(data_key=cipher_data_key_bytes, kms_config=None)
|
|
83
|
+
ciphertext_data_keys.append(ciphertext_data_key)
|
|
84
|
+
except Exception:
|
|
85
|
+
logger.warning(
|
|
86
|
+
"encrypt data key error by kms server,please check the server information is right,region is :%s,keyId is:%s",
|
|
87
|
+
kms_config.region, kms_config.key_id
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
with ThreadPoolExecutor() as executor:
|
|
91
|
+
futures = [executor.submit(encrypt_for_config, kms_config) for kms_config in kms_config_list]
|
|
92
|
+
for future in as_completed(futures):
|
|
93
|
+
future.result()
|
|
94
|
+
|
|
95
|
+
if len(ciphertext_data_keys) <= 0:
|
|
96
|
+
raise EncryptException(ErrorMessage.ENCRYPT_DATA_KEY_EXCEPTION.message)
|
|
97
|
+
data_key_materials.ciphertext_data_keys = ciphertext_data_keys
|
|
98
|
+
|
|
99
|
+
def _get_key_spec(self, kms_client, key_id):
|
|
100
|
+
try:
|
|
101
|
+
from huaweicloudsdkkms.v2.model.list_key_detail_request import ListKeyDetailRequest
|
|
102
|
+
from huaweicloudsdkkms.v2.model.operate_key_request_body import OperateKeyRequestBody
|
|
103
|
+
body = OperateKeyRequestBody(key_id=key_id)
|
|
104
|
+
request = ListKeyDetailRequest(body=body)
|
|
105
|
+
response = kms_client.list_key_detail(request)
|
|
106
|
+
return response.key_info.key_spec
|
|
107
|
+
except Exception:
|
|
108
|
+
return "AES_256"
|
|
109
|
+
|
|
110
|
+
def _get_kms_client(self, region_str, end_point, auth):
|
|
111
|
+
from huaweicloudsdkkms.v2.region.kms_region import KmsRegion
|
|
112
|
+
from huaweicloudsdkkms.v2 import KmsClient
|
|
113
|
+
|
|
114
|
+
cache_key = self.huawei_config.ak + self.huawei_config.sk + region_str
|
|
115
|
+
if cache_key in KMSKeyring.kms_client_cache:
|
|
116
|
+
return KMSKeyring.kms_client_cache[cache_key]
|
|
117
|
+
if is_empty(end_point):
|
|
118
|
+
region = KmsRegion.value_of(region_str)
|
|
119
|
+
else:
|
|
120
|
+
from huaweicloudsdkcore.region.region import Region
|
|
121
|
+
region = Region(region_str, end_point)
|
|
122
|
+
kms_client = KmsClient.new_builder().with_credentials(auth).with_region(region).build()
|
|
123
|
+
KMSKeyring.kms_client_cache[cache_key] = kms_client
|
|
124
|
+
return kms_client
|
|
125
|
+
|
|
126
|
+
def real_decrypt(self, data_key_materials: DataKeyMaterials):
|
|
127
|
+
kms_config_list = self.huawei_config.kms_config_list
|
|
128
|
+
ciphertext_data_keys = data_key_materials.ciphertext_data_keys
|
|
129
|
+
for kms_config in kms_config_list:
|
|
130
|
+
from huaweicloudsdkcore.auth.credentials import BasicCredentials
|
|
131
|
+
auth = BasicCredentials(self.huawei_config.ak, self.huawei_config.sk, kms_config.project_id)
|
|
132
|
+
if self.huawei_config.security_token:
|
|
133
|
+
auth = auth.with_security_token(self.huawei_config.security_token)
|
|
134
|
+
for ciphertext_data_key in ciphertext_data_keys:
|
|
135
|
+
try:
|
|
136
|
+
region_str = kms_config.region
|
|
137
|
+
end_point = kms_config.end_point
|
|
138
|
+
key_id = kms_config.key_id
|
|
139
|
+
kms_client = self._get_kms_client(region_str, end_point, auth)
|
|
140
|
+
encode_data_key = bytes_to_hex(ciphertext_data_key.data_key)
|
|
141
|
+
from huaweicloudsdkkms.v2.model.decrypt_datakey_request import DecryptDatakeyRequest
|
|
142
|
+
from huaweicloudsdkkms.v2.model.decrypt_datakey_request_body import DecryptDatakeyRequestBody
|
|
143
|
+
body = DecryptDatakeyRequestBody(
|
|
144
|
+
key_id=key_id,
|
|
145
|
+
cipher_text=encode_data_key,
|
|
146
|
+
datakey_cipher_length="32"
|
|
147
|
+
)
|
|
148
|
+
request = DecryptDatakeyRequest(body=body)
|
|
149
|
+
response = kms_client.decrypt_datakey(request)
|
|
150
|
+
plaint_bytes = hex_to_bytes(response.data_key)
|
|
151
|
+
algorithm_name = data_key_materials.crypto_algorithm.sec_key_algorithm
|
|
152
|
+
data_key_materials.plaintext_data_key = plaint_bytes
|
|
153
|
+
return
|
|
154
|
+
except Exception as e:
|
|
155
|
+
logger.error("one master key may be not match when decrypt data key in KMSKeyring: %s", e)
|