test_encrypt.py
134 lines
| 4.2 KiB
| text/x-python
|
PythonLexer
r5608 | # Copyright (C) 2010-2024 RhodeCode GmbH | |||
r1 | # | |||
# This program is free software: you can redistribute it and/or modify | ||||
# it under the terms of the GNU Affero General Public License, version 3 | ||||
# (only), as published by the Free Software Foundation. | ||||
# | ||||
# This program is distributed in the hope that it will be useful, | ||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
# GNU General Public License for more details. | ||||
# | ||||
# You should have received a copy of the GNU Affero General Public License | ||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
# | ||||
# This program is dual-licensed. If you wish to learn more about the | ||||
# RhodeCode Enterprise Edition, including its added features, Support services, | ||||
# and proprietary license terms, please see https://rhodecode.com/licenses/ | ||||
import pytest | ||||
r281 | from rhodecode.lib.encrypt import ( | |||
r4994 | AESCipher, InvalidDecryptedValue) | |||
from rhodecode.lib import enc_utils | ||||
from rhodecode.lib.str_utils import safe_str | ||||
from rhodecode.lib.exceptions import SignatureVerificationError | ||||
@pytest.mark.parametrize( | ||||
"algo", ['fernet', 'aes'], | ||||
) | ||||
@pytest.mark.parametrize( | ||||
"key, text", | ||||
[ | ||||
(b'a', 'short'), | ||||
(b'a' * 64, 'too long(trimmed to 32)'), | ||||
(b'a' * 32, 'just enough'), | ||||
('ąćęćę', 'non asci'), | ||||
('$asa$asa', 'special $ used'), | ||||
] | ||||
) | ||||
@pytest.mark.parametrize( | ||||
"strict_mode", [True, False], | ||||
) | ||||
def test_common_encryption_module(algo, key, text, strict_mode): | ||||
encrypted = enc_utils.encrypt_value(text, algo=algo, enc_key=key) | ||||
decrypted = enc_utils.decrypt_value(encrypted, algo=algo, enc_key=key, strict_mode=strict_mode) | ||||
assert text == safe_str(decrypted) | ||||
@pytest.mark.parametrize( | ||||
"algo", ['fernet', 'aes'], | ||||
) | ||||
def test_encryption_with_bad_key(algo): | ||||
key = b'secretstring' | ||||
text = b'ihatemysql' | ||||
encrypted = enc_utils.encrypt_value(text, algo=algo, enc_key=key) | ||||
decrypted = enc_utils.decrypt_value(encrypted, algo=algo, enc_key=b'different-key', strict_mode=False) | ||||
assert decrypted[:22] == '<InvalidDecryptedValue' | ||||
@pytest.mark.parametrize( | ||||
"algo", ['fernet', 'aes'], | ||||
) | ||||
def test_encryption_with_bad_key_raises(algo): | ||||
key = b'secretstring' | ||||
text = b'ihatemysql' | ||||
encrypted = enc_utils.encrypt_value(text, algo=algo, enc_key=key) | ||||
with pytest.raises(SignatureVerificationError) as e: | ||||
enc_utils.decrypt_value(encrypted, algo=algo, enc_key=b'different-key', strict_mode=True) | ||||
assert 'InvalidDecryptedValue' in str(e) | ||||
r1 | ||||
r4994 | @pytest.mark.parametrize( | |||
"algo", ['fernet', 'aes'], | ||||
) | ||||
def test_encryption_with_bad_format_data(algo): | ||||
key = b'secret' | ||||
text = b'ihatemysql' | ||||
encrypted = enc_utils.encrypt_value(text, algo=algo, enc_key=key) | ||||
encrypted = b'$xyz' + encrypted[3:] | ||||
r281 | ||||
r4994 | with pytest.raises(ValueError) as e: | |||
enc_utils.decrypt_value(encrypted, algo=algo, enc_key=key, strict_mode=True) | ||||
r281 | ||||
r4994 | assert 'Encrypted Data has invalid format' in str(e) | |||
r3522 | ||||
r4994 | @pytest.mark.parametrize( | |||
"algo", ['fernet', 'aes'], | ||||
) | ||||
def test_encryption_with_bad_data(algo): | ||||
key = b'secret' | ||||
text = b'ihatemysql' | ||||
encrypted = enc_utils.encrypt_value(text, algo=algo, enc_key=key) | ||||
encrypted = encrypted[:-5] | ||||
r3522 | ||||
r4994 | with pytest.raises(SignatureVerificationError) as e: | |||
enc_utils.decrypt_value(encrypted, algo=algo, enc_key=key, strict_mode=True) | ||||
assert 'SignatureVerificationError' in str(e) | ||||
r3522 | ||||
r4994 | def test_encryption_with_hmac(): | |||
key = b'secret' | ||||
text = b'ihatemysql' | ||||
enc = AESCipher(key, hmac=True).encrypt(text) | ||||
assert AESCipher(key, hmac=True).decrypt(enc) == text | ||||
r3522 | ||||
r4994 | def test_encryption_with_hmac_with_bad_data(): | |||
key = b'secret' | ||||
text = b'ihatemysql' | ||||
enc = AESCipher(key, hmac=True).encrypt(text) | ||||
enc = b'xyz' + enc[3:] | ||||
with pytest.raises(SignatureVerificationError) as e: | ||||
assert AESCipher(key, hmac=True).decrypt(enc, safe=False) == text | ||||
r3522 | ||||
r4994 | assert 'SignatureVerificationError' in str(e) | |||
r3522 | ||||
r4994 | def test_encryption_with_hmac_with_bad_key_not_strict(): | |||
key = b'secretstring' | ||||
text = b'ihatemysql' | ||||
enc = AESCipher(key, hmac=True).encrypt(text) | ||||
r3522 | ||||
r4994 | decrypted = AESCipher( | |||
b'differentsecret', hmac=True, strict_verification=False | ||||
).decrypt(enc) | ||||
r3522 | ||||
r4994 | assert isinstance(decrypted, InvalidDecryptedValue) | |||