Skip to content

Commit 0fcfba4

Browse files
committed
fixed oaep algorithm length issue
moved decorator to 'call_api' function
1 parent 06747ef commit 0fcfba4

File tree

8 files changed

+56
-29
lines changed

8 files changed

+56
-29
lines changed

client_encryption/api_encryption.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,24 @@ def __init__(self, encryption_conf_file):
1818
self._encryption_conf = FieldLevelEncryptionConfig(json_file.read())
1919

2020
def field_encryption(self, func):
21-
"""Decorator for API request. func is APIClient.request"""
21+
"""Decorator for API call_api. func is APIClient.call_api"""
2222

2323
@wraps(func)
24-
def request_function(*args, **kwargs):
25-
"""Wrap request and add field encryption layer to it."""
24+
def call_api_function(*args, **kwargs):
25+
"""Wrap call_api and add field encryption layer to it."""
2626

2727
in_body = kwargs.get("body", None)
2828
kwargs["body"] = self._encrypt_payload(kwargs.get("headers", None), in_body) if in_body else in_body
29+
kwargs["_preload_content"] = False
2930

3031
response = func(*args, **kwargs)
3132

32-
if type(response.data) is not str:
33-
response_body = self._decrypt_payload(response.getheaders(), response.json())
34-
response._content = json.dumps(response_body, indent=4).encode('utf-8')
33+
response_body = self._decrypt_payload(response.getheaders(), response.data)
3534

36-
return response
35+
return response_body
3736

38-
request_function.__fle__ = True
39-
return request_function
37+
call_api_function.__fle__ = True
38+
return call_api_function
4039

4140
def _encrypt_payload(self, headers, body):
4241
"""Encryption enforcement based on configuration - encrypt and add session key params to header or body"""
@@ -86,10 +85,10 @@ def _decrypt_payload(self, headers, body):
8685

8786

8887
def add_encryption_layer(api_client, encryption_conf_file):
89-
"""Decorate APIClient.request with field level encryption"""
88+
"""Decorate APIClient.call_api with field level encryption"""
9089

9190
api_encryption = ApiEncryption(encryption_conf_file)
92-
api_client.request = api_encryption.field_encryption(api_client.request)
91+
api_client.call_api = api_encryption.field_encryption(api_client.call_api)
9392

9493
__check_oauth(api_client) # warn the user if authentication layer is missing/not set
9594

client_encryption/encryption_utils.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,21 @@ def __get_crypto_file_type(file_content):
5454
return FILETYPE_ASN1
5555

5656

57-
def load_hash_algorithm(algo_str):
58-
"""Load a hash algorithm object of Crypto.Hash from a list of supported ones."""
57+
def validate_hash_algorithm(algo_str):
58+
"""Validate a hash algorithm against a list of supported ones."""
5959

6060
if algo_str:
6161
algo_key = algo_str.replace("-", "").upper()
6262

6363
if algo_key in _SUPPORTED_HASH:
64-
return _SUPPORTED_HASH[algo_key]
64+
return algo_key
6565
else:
6666
raise HashAlgorithmError("Hash algorithm invalid or not supported.")
6767
else:
6868
raise HashAlgorithmError("No hash algorithm provided.")
69+
70+
71+
def load_hash_algorithm(algo_str):
72+
"""Load a hash algorithm object of Crypto.Hash from a list of supported ones."""
73+
74+
return _SUPPORTED_HASH[validate_hash_algorithm(algo_str)]

client_encryption/field_level_encryption.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ def encrypt_payload(payload, config, _params=None):
1212
"""Encrypt some fields of a JSON payload using the given configuration."""
1313

1414
try:
15-
if type(payload) is str:
16-
json_payload = json.loads(payload)
17-
else:
15+
if type(payload) is dict:
1816
json_payload = copy.deepcopy(payload)
17+
else:
18+
json_payload = json.loads(payload)
1919

2020
for elem, target in config.paths["$"].to_encrypt.items():
2121
if not _params:
@@ -50,10 +50,10 @@ def decrypt_payload(payload, config, _params=None):
5050
"""Decrypt some fields of a JSON payload using the given configuration."""
5151

5252
try:
53-
if type(payload) is str:
54-
json_payload = json.loads(payload)
55-
else:
53+
if type(payload) is dict:
5654
json_payload = payload
55+
else:
56+
json_payload = json.loads(payload)
5757

5858
for elem, target in config.paths["$"].to_decrypt.items():
5959
try:

client_encryption/field_level_encryption_config.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from OpenSSL.crypto import dump_certificate, FILETYPE_ASN1, dump_publickey
33
from Crypto.Hash import SHA256
44
from client_encryption.encoding_utils import Encoding
5-
from client_encryption.encryption_utils import load_encryption_certificate, load_decryption_key, load_hash_algorithm
5+
from client_encryption.encryption_utils import load_encryption_certificate, load_decryption_key, validate_hash_algorithm
66

77

88
class FieldLevelEncryptionConfig(object):
@@ -44,9 +44,7 @@ def __init__(self, conf):
4444
else:
4545
self._decryption_key = None
4646

47-
digest_algo = json_config["oaepPaddingDigestAlgorithm"]
48-
if load_hash_algorithm(digest_algo) is not None:
49-
self._oaep_padding_digest_algorithm = digest_algo
47+
self._oaep_padding_digest_algorithm = validate_hash_algorithm(json_config["oaepPaddingDigestAlgorithm"])
5048

5149
data_enc = Encoding(json_config["dataEncoding"].upper())
5250
self._data_encoding = data_enc

client_encryption/session_key_params.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from binascii import Error
22
from Crypto.Cipher import PKCS1_OAEP, AES
3-
from Crypto import Random
3+
from Crypto.Random import get_random_bytes
44
from Crypto.PublicKey import RSA
55
from client_encryption.encoding_utils import encode_bytes, decode_value
66
from client_encryption.encryption_utils import load_hash_algorithm
@@ -62,11 +62,11 @@ def generate(config):
6262
encoding = config.data_encoding
6363

6464
# Generate a random IV
65-
iv = Random.new().read(SessionKeyParams._BLOCK_SIZE)
65+
iv = get_random_bytes(SessionKeyParams._BLOCK_SIZE)
6666
iv_encoded = encode_bytes(iv, encoding)
6767

6868
# Generate an AES secret key
69-
secret_key = Random.new().read(SessionKeyParams._KEY_SIZE)
69+
secret_key = get_random_bytes(SessionKeyParams._KEY_SIZE)
7070

7171
# Encrypt the secret key
7272
secret_key_encrypted = SessionKeyParams.__wrap_secret_key(secret_key, config)

client_encryption/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
#!/usr/bin/env python
22
# -*- coding: utf-8 -*-
3-
__version__ = "1.0.2"
3+
__version__ = "1.0.3-dev"

tests/test_encryption_utils.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,30 @@ def test_load_hash_algorithm_underscore(self):
131131
def test_load_hash_algorithm_none(self):
132132
self.assertRaises(HashAlgorithmError, to_test.load_hash_algorithm, None)
133133

134+
def test_validate_hash_algorithm(self):
135+
hash_algo = to_test.validate_hash_algorithm("SHA224")
136+
137+
self.assertEqual(hash_algo, "SHA224")
138+
139+
def test_validate_hash_algorithm_dash(self):
140+
hash_algo = to_test.validate_hash_algorithm("SHA-512")
141+
142+
self.assertEqual(hash_algo, "SHA512")
143+
144+
def test_validate_hash_algorithm_lowercase(self):
145+
hash_algo = to_test.validate_hash_algorithm("sha384")
146+
147+
self.assertEqual(hash_algo, "SHA384")
148+
149+
def test_validate_hash_algorithm_not_supported(self):
150+
self.assertRaises(HashAlgorithmError, to_test.validate_hash_algorithm, "MD5")
151+
152+
def test_validate_hash_algorithm_underscore(self):
153+
self.assertRaises(HashAlgorithmError, to_test.validate_hash_algorithm, "SHA_512")
154+
155+
def test_validate_hash_algorithm_none(self):
156+
self.assertRaises(HashAlgorithmError, to_test.validate_hash_algorithm, None)
157+
134158
@staticmethod
135159
def __strip_key(rsa_key):
136160
return rsa_key.export_key(pkcs=8).decode('utf-8').replace("\n", "")[27:-25]

tests/test_field_level_encryption_config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ def test_load_config_SHA512_oaep_padding_algorithm(self):
151151
json_conf["oaepPaddingDigestAlgorithm"] = oaep_algo_test
152152

153153
conf = to_test.FieldLevelEncryptionConfig(json_conf)
154-
self.__check_configuration(conf, oaep_algo=oaep_algo_test)
154+
self.__check_configuration(conf, oaep_algo="SHA512")
155155

156156
def test_load_config_wrong_oaep_padding_algorithm(self):
157157
oaep_algo_test = "sha_512"

0 commit comments

Comments
 (0)