11from chef .exceptions import ChefUnsupportedEncryptionVersionError , ChefDecryptionError
2- from chef .aes import AES256Cipher
2+ from chef .aes import AES256Cipher , EVP_MAX_IV_LENGTH
33from chef .utils import json
44from chef .data_bag import DataBagItem
55
66import os
7+ import sys
78import hmac
89import base64
910import chef
1011import hashlib
12+ import binascii
1113import itertools
14+ import six
15+ from six .moves import filterfalse , zip_longest
16+
1217
1318class EncryptedDataBagItem (DataBagItem ):
1419 SUPPORTED_ENCRYPTION_VERSIONS = (1 ,2 )
@@ -39,10 +44,10 @@ class EncryptorVersion1(object):
3944 VERSION = 1
4045
4146 def __init__ (self , key , data ):
42- self .plain_key = key
43- self .key = hashlib .sha256 (key ).digest ()
47+ self .plain_key = key . encode ( 'utf8' )
48+ self .key = hashlib .sha256 (key . encode ( 'utf8' ) ).digest ()
4449 self .data = data
45- self .iv = os .urandom (8 ). encode ( 'hex' )
50+ self .iv = binascii . hexlify ( os .urandom (int ( EVP_MAX_IV_LENGTH / 2 )) )
4651 self .encryptor = AES256Cipher (key = self .key , iv = self .iv )
4752 self .encrypted_data = None
4853
@@ -54,8 +59,8 @@ def encrypt(self):
5459
5560 def to_dict (self ):
5661 return {
57- "encrypted_data" : base64 .standard_b64encode (self .encrypt ()),
58- "iv" : base64 .standard_b64encode (self .iv ),
62+ "encrypted_data" : base64 .standard_b64encode (self .encrypt ()). decode ( 'utf8' ) ,
63+ "iv" : base64 .standard_b64encode (self .iv ). decode ( 'utf8' ) ,
5964 "version" : self .VERSION ,
6065 "cipher" : "aes-256-cbc"
6166 }
@@ -78,11 +83,11 @@ def _generate_hmac(self):
7883
7984 def to_dict (self ):
8085 result = super (EncryptorVersion2 , self ).to_dict ()
81- result ['hmac' ] = base64 .standard_b64encode (self .hmac )
86+ result ['hmac' ] = base64 .standard_b64encode (self .hmac ). decode ( 'utf8' )
8287 return result
8388
8489def get_decryption_version (data ):
85- if data . has_key ( 'version' ) :
90+ if 'version' in data :
8691 if str (data ['version' ]) in map (str , EncryptedDataBagItem .SUPPORTED_ENCRYPTION_VERSIONS ):
8792 return data ['version' ]
8893 else :
@@ -99,7 +104,7 @@ def create_decryptor(key, data):
99104
100105class DecryptorVersion1 (object ):
101106 def __init__ (self , key , data , iv ):
102- self .key = hashlib .sha256 (key ).digest ()
107+ self .key = hashlib .sha256 (key . encode ( 'utf8' ) ).digest ()
103108 self .data = base64 .standard_b64decode (data )
104109 self .iv = base64 .standard_b64decode (iv )
105110 self .decryptor = AES256Cipher (key = self .key , iv = self .iv )
@@ -120,10 +125,16 @@ def __init__(self, key, data, iv, hmac):
120125 self .encoded_data = data
121126
122127 def _validate_hmac (self ):
123- expected_hmac = hmac .new (self .key , self .encoded_data , hashlib .sha256 ).digest ()
128+ encoded_data = self .encoded_data .encode ('utf8' )
129+
130+ expected_hmac = hmac .new (self .key , encoded_data , hashlib .sha256 ).digest ()
124131 valid = len (expected_hmac ) ^ len (self .hmac )
125- for expected_char , candidate_char in itertools .izip_longest (expected_hmac , self .hmac ):
126- valid |= ord (expected_char ) ^ ord (candidate_char )
132+ for expected_char , candidate_char in zip_longest (expected_hmac , self .hmac ):
133+ if sys .version_info [0 ] > 2 :
134+ valid |= expected_char ^ candidate_char
135+ else :
136+ valid |= ord (expected_char ) ^ ord (candidate_char )
137+
127138 return valid == 0
128139
129140 def decrypt (self ):
0 commit comments