In-house removal of PyCrypto dependency in Glance. This patch is
Solaris-specific and not suitable for upstream.
Convert urlsafe_encrypt() and urlsafe_decrypt() to use M2Crypto instead
of PyCrypto.
--- glance-2015.1.2/glance/common/crypt.py.~1~ 2015-10-13 09:38:23.000000000 -0700
+++ glance-2015.1.2/glance/common/crypt.py 2016-01-24 16:48:24.788282369 -0800
@@ -20,14 +20,30 @@ Routines for URL-safe encrypting/decrypt
"""
import base64
+import os
-from Crypto.Cipher import AES
-from Crypto import Random
-from Crypto.Random import random
+from glance.common import exception
+
+from M2Crypto.EVP import Cipher
# NOTE(jokke): simplified transition to py3, behaves like py2 xrange
from six.moves import range
+def _key_to_alg(key):
+ """Return a M2Crypto-compatible AES-CBC algorithm name given a key."""
+ aes_algs = {
+ 128: 'aes_128_cbc',
+ 192: 'aes_192_cbc',
+ 256: 'aes_256_cbc'
+ }
+
+ keylen = 8 * len(key)
+ if keylen not in aes_algs:
+ msg = ('Invalid AES key length, %d bits') % keylen
+ raise exception.Invalid(msg)
+ return aes_algs[keylen]
+
+
def urlsafe_encrypt(key, plaintext, blocksize=16):
"""
Encrypts plaintext. Resulting ciphertext will contain URL-safe characters
@@ -37,20 +53,12 @@ def urlsafe_encrypt(key, plaintext, bloc
:returns : Resulting ciphertext
"""
- def pad(text):
- """
- Pads text to be encrypted
- """
- pad_length = (blocksize - len(text) % blocksize)
- sr = random.StrongRandom()
- pad = ''.join(chr(sr.randint(1, 0xFF)) for i in range(pad_length - 1))
- # We use chr(0) as a delimiter between text and padding
- return text + chr(0) + pad
# random initial 16 bytes for CBC
- init_vector = Random.get_random_bytes(16)
- cypher = AES.new(key, AES.MODE_CBC, init_vector)
- padded = cypher.encrypt(pad(str(plaintext)))
+ init_vector = os.urandom(16)
+ cipher = Cipher(alg=_key_to_alg(key), key=key, iv=init_vector, op=1)
+ padded = cipher.update(str(plaintext))
+ padded = padded + cipher.final()
return base64.urlsafe_b64encode(init_vector + padded)
@@ -64,6 +72,7 @@ def urlsafe_decrypt(key, ciphertext):
"""
# Cast from unicode
ciphertext = base64.urlsafe_b64decode(str(ciphertext))
- cypher = AES.new(key, AES.MODE_CBC, ciphertext[:16])
- padded = cypher.decrypt(ciphertext[16:])
- return padded[:padded.rfind(chr(0))]
+ cipher = Cipher(alg=_key_to_alg(key), key=key, iv=ciphertext[:16], op=0)
+ padded = cipher.update(ciphertext[16:])
+ padded = padded + cipher.final()
+ return padded