1
1
from chef .exceptions import ChefUnsupportedEncryptionVersionError , ChefDecryptionError
2
- from chef .aes import AES256Cipher
2
+ from chef .aes import AES256Cipher , EVP_MAX_IV_LENGTH
3
3
from chef .utils import json
4
4
from chef .data_bag import DataBagItem
5
5
6
6
import os
7
+ import sys
7
8
import hmac
8
9
import base64
9
10
import chef
10
11
import hashlib
12
+ import binascii
11
13
import itertools
14
+ import six
15
+ from six .moves import filterfalse , zip_longest
16
+
12
17
13
18
class EncryptedDataBagItem (DataBagItem ):
14
19
SUPPORTED_ENCRYPTION_VERSIONS = (1 ,2 )
@@ -39,10 +44,10 @@ class EncryptorVersion1(object):
39
44
VERSION = 1
40
45
41
46
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 ()
44
49
self .data = data
45
- self .iv = os .urandom (8 ). encode ( 'hex' )
50
+ self .iv = binascii . hexlify ( os .urandom (int ( EVP_MAX_IV_LENGTH / 2 )) )
46
51
self .encryptor = AES256Cipher (key = self .key , iv = self .iv )
47
52
self .encrypted_data = None
48
53
@@ -54,8 +59,8 @@ def encrypt(self):
54
59
55
60
def to_dict (self ):
56
61
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' ) ,
59
64
"version" : self .VERSION ,
60
65
"cipher" : "aes-256-cbc"
61
66
}
@@ -78,11 +83,11 @@ def _generate_hmac(self):
78
83
79
84
def to_dict (self ):
80
85
result = super (EncryptorVersion2 , self ).to_dict ()
81
- result ['hmac' ] = base64 .standard_b64encode (self .hmac )
86
+ result ['hmac' ] = base64 .standard_b64encode (self .hmac ). decode ( 'utf8' )
82
87
return result
83
88
84
89
def get_decryption_version (data ):
85
- if data . has_key ( 'version' ) :
90
+ if 'version' in data :
86
91
if str (data ['version' ]) in map (str , EncryptedDataBagItem .SUPPORTED_ENCRYPTION_VERSIONS ):
87
92
return data ['version' ]
88
93
else :
@@ -99,7 +104,7 @@ def create_decryptor(key, data):
99
104
100
105
class DecryptorVersion1 (object ):
101
106
def __init__ (self , key , data , iv ):
102
- self .key = hashlib .sha256 (key ).digest ()
107
+ self .key = hashlib .sha256 (key . encode ( 'utf8' ) ).digest ()
103
108
self .data = base64 .standard_b64decode (data )
104
109
self .iv = base64 .standard_b64decode (iv )
105
110
self .decryptor = AES256Cipher (key = self .key , iv = self .iv )
@@ -120,10 +125,16 @@ def __init__(self, key, data, iv, hmac):
120
125
self .encoded_data = data
121
126
122
127
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 ()
124
131
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
+
127
138
return valid == 0
128
139
129
140
def decrypt (self ):
0 commit comments