|
17 | 17 | from functools import lru_cache
|
18 | 18 | from itertools import islice, cycle, groupby, repeat
|
19 | 19 | import logging
|
20 |
| -import os |
21 | 20 | from random import randint, shuffle
|
22 | 21 | from threading import Lock
|
23 | 22 | import socket
|
24 | 23 | import warnings
|
25 | 24 |
|
26 |
| -from cryptography.hazmat.primitives import padding |
27 |
| -from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes |
| 25 | +log = logging.getLogger(__name__) |
28 | 26 |
|
29 | 27 | from cassandra import WriteType as WT
|
30 |
| -from cassandra.cqltypes import _cqltypes |
31 | 28 |
|
32 | 29 |
|
33 | 30 | # This is done this way because WriteType was originally
|
34 | 31 | # defined here and in order not to break the API.
|
35 | 32 | # It may removed in the next mayor.
|
36 | 33 | WriteType = WT
|
37 | 34 |
|
38 |
| - |
39 | 35 | from cassandra import ConsistencyLevel, OperationTimedOut
|
40 | 36 |
|
41 |
| -log = logging.getLogger(__name__) |
42 |
| - |
43 |
| - |
44 | 37 | class HostDistance(object):
|
45 | 38 | """
|
46 | 39 | A measure of how "distant" a node is from the client, which
|
@@ -1397,7 +1390,6 @@ def _rethrow(self, *args, **kwargs):
|
1397 | 1390 |
|
1398 | 1391 |
|
1399 | 1392 | ColDesc = namedtuple('ColDesc', ['ks', 'table', 'col'])
|
1400 |
| -ColData = namedtuple('ColData', ['key','type']) |
1401 | 1393 |
|
1402 | 1394 | class ColumnEncryptionPolicy(object):
|
1403 | 1395 | """
|
@@ -1454,100 +1446,3 @@ def encode_and_encrypt(self, coldesc, obj):
|
1454 | 1446 | statements.
|
1455 | 1447 | """
|
1456 | 1448 | raise NotImplementedError()
|
1457 |
| - |
1458 |
| -AES256_BLOCK_SIZE = 128 |
1459 |
| -AES256_BLOCK_SIZE_BYTES = int(AES256_BLOCK_SIZE / 8) |
1460 |
| -AES256_KEY_SIZE = 256 |
1461 |
| -AES256_KEY_SIZE_BYTES = int(AES256_KEY_SIZE / 8) |
1462 |
| - |
1463 |
| -class AES256ColumnEncryptionPolicy(ColumnEncryptionPolicy): |
1464 |
| - |
1465 |
| - # CBC uses an IV that's the same size as the block size |
1466 |
| - # |
1467 |
| - # TODO: Need to find some way to expose mode options |
1468 |
| - # (CBC etc.) without leaking classes from the underlying |
1469 |
| - # impl here |
1470 |
| - def __init__(self, mode = modes.CBC, iv = os.urandom(AES256_BLOCK_SIZE_BYTES)): |
1471 |
| - |
1472 |
| - self.mode = mode |
1473 |
| - self.iv = iv |
1474 |
| - |
1475 |
| - # ColData for a given ColDesc is always preserved. We only create a Cipher |
1476 |
| - # when there's an actual need to for a given ColDesc |
1477 |
| - self.coldata = {} |
1478 |
| - self.ciphers = {} |
1479 |
| - |
1480 |
| - def encrypt(self, coldesc, obj_bytes): |
1481 |
| - |
1482 |
| - # AES256 has a 128-bit block size so if the input bytes don't align perfectly on |
1483 |
| - # those blocks we have to pad them. There's plenty of room for optimization here: |
1484 |
| - # |
1485 |
| - # * Instances of the PKCS7 padder should be managed in a bounded pool |
1486 |
| - # * It would be nice if we could get a flag from encrypted data to indicate |
1487 |
| - # whether it was padded or not |
1488 |
| - # * Might be able to make this happen with a leading block of flags in encrypted data |
1489 |
| - padder = padding.PKCS7(AES256_BLOCK_SIZE).padder() |
1490 |
| - padded_bytes = padder.update(obj_bytes) + padder.finalize() |
1491 |
| - |
1492 |
| - cipher = self._get_cipher(coldesc) |
1493 |
| - encryptor = cipher.encryptor() |
1494 |
| - return encryptor.update(padded_bytes) + encryptor.finalize() |
1495 |
| - |
1496 |
| - def decrypt(self, coldesc, encrypted_bytes): |
1497 |
| - |
1498 |
| - cipher = self._get_cipher(coldesc) |
1499 |
| - decryptor = cipher.decryptor() |
1500 |
| - padded_bytes = decryptor.update(encrypted_bytes) + decryptor.finalize() |
1501 |
| - |
1502 |
| - unpadder = padding.PKCS7(AES256_BLOCK_SIZE).unpadder() |
1503 |
| - return unpadder.update(padded_bytes) + unpadder.finalize() |
1504 |
| - |
1505 |
| - def add_column(self, coldesc, key, type): |
1506 |
| - |
1507 |
| - if not coldesc: |
1508 |
| - raise ValueError("ColDesc supplied to add_column cannot be None") |
1509 |
| - if not key: |
1510 |
| - raise ValueError("Key supplied to add_column cannot be None") |
1511 |
| - if not type: |
1512 |
| - raise ValueError("Type supplied to add_column cannot be None") |
1513 |
| - if type not in _cqltypes.keys(): |
1514 |
| - raise ValueError("Type %s is not a supported type".format(type)) |
1515 |
| - if not len(key) == AES256_KEY_SIZE_BYTES: |
1516 |
| - raise ValueError("AES256 column encryption policy expects a 256-bit encryption key") |
1517 |
| - self.coldata[coldesc] = ColData(key, _cqltypes[type]) |
1518 |
| - |
1519 |
| - def contains_column(self, coldesc): |
1520 |
| - return coldesc in self.coldata |
1521 |
| - |
1522 |
| - def encode_and_encrypt(self, coldesc, obj): |
1523 |
| - if not coldesc: |
1524 |
| - raise ValueError("ColDesc supplied to encode_and_encrypt cannot be None") |
1525 |
| - if not obj: |
1526 |
| - raise ValueError("Object supplied to encode_and_encrypt cannot be None") |
1527 |
| - coldata = self.coldata.get(coldesc) |
1528 |
| - if not coldata: |
1529 |
| - raise ValueError("Could not find ColData for ColDesc %s".format(coldesc)) |
1530 |
| - return self.encrypt(coldesc, coldata.type.serialize(obj, None)) |
1531 |
| - |
1532 |
| - def cache_info(self): |
1533 |
| - return AES256ColumnEncryptionPolicy._build_cipher.cache_info() |
1534 |
| - |
1535 |
| - def column_type(self, coldesc): |
1536 |
| - return self.coldata[coldesc].type |
1537 |
| - |
1538 |
| - def _get_cipher(self, coldesc): |
1539 |
| - """ |
1540 |
| - Access relevant state from this instance necessary to create a Cipher and then get one, |
1541 |
| - hopefully returning a cached instance if we've already done so (and it hasn't been evicted) |
1542 |
| - """ |
1543 |
| - |
1544 |
| - try: |
1545 |
| - coldata = self.coldata[coldesc] |
1546 |
| - return AES256ColumnEncryptionPolicy._build_cipher(coldata.key, self.mode, self.iv) |
1547 |
| - except KeyError: |
1548 |
| - raise ValueError("Could not find column {}".format(coldesc)) |
1549 |
| - |
1550 |
| - # Explicitly use a class method here to avoid caching self |
1551 |
| - @lru_cache(maxsize=128) |
1552 |
| - def _build_cipher(key, mode, iv): |
1553 |
| - return Cipher(algorithms.AES256(key), mode(iv)) |
0 commit comments