--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/keystonemiddleware/patches/nopycrypto.patch Thu Mar 19 14:41:20 2015 -0700
@@ -0,0 +1,95 @@
+In-house removal of PyCrypto dependency in keystonemiddleware. This
+patch is Solaris-specific and not suitable for upstream.
+
+--- keystonemiddleware-1.3.1/keystonemiddleware/_memcache_crypt.py.~1~ 2014-12-22 12:40:35.000000000 -0800
++++ keystonemiddleware-1.3.1/keystonemiddleware/_memcache_crypt.py 2015-01-31 23:52:53.543098553 -0800
+@@ -17,7 +17,7 @@
+ Utilities for memcache encryption and integrity check.
+
+ Data should be serialized before entering these functions. Encryption
+-has a dependency on the pycrypto. If pycrypto is not available,
++has a dependency on M2Crypto. If M2Crypto is not available,
+ CryptoUnavailableError will be raised.
+
+ This module will not be called unless signing or encryption is enabled
+@@ -38,9 +38,10 @@ import sys
+
+ from keystonemiddleware.i18n import _
+
+-# make sure pycrypto is available
++# make sure M2Crypto is available
+ try:
+- from Crypto.Cipher import AES
++ from M2Crypto.EVP import Cipher
++ AES = Cipher
+ except ImportError:
+ AES = None
+
+@@ -73,6 +74,13 @@ class CryptoUnavailableError(Exception):
+ pass
+
+
++class InvalidKeyLength(Exception):
++ """raise when AES key length is an invalid value.
++
++ """
++ pass
++
++
+ def assert_crypto_availability(f):
+ """Ensure Crypto module is available."""
+
+@@ -132,31 +140,44 @@ def sign_data(key, data):
+ return base64.b64encode(mac)
+
+
++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 InvalidKeyLength(msg)
++ return aes_algs[keylen]
++
++
+ @assert_crypto_availability
+ def encrypt_data(key, data):
+ """Encrypt the data with the given secret key.
+
+- Padding is n bytes of the value n, where 1 <= n <= blocksize.
+ """
+ iv = os.urandom(16)
+- cipher = AES.new(key, AES.MODE_CBC, iv)
+- padding = 16 - len(data) % 16
+- return iv + cipher.encrypt(data + six.int2byte(padding) * padding)
++ cipher = Cipher(alg=_key_to_alg(key), key=key, iv=iv, op=1)
++ result = cipher.update(data)
++ return iv + result + cipher.final()
+
+
+ @assert_crypto_availability
+ def decrypt_data(key, data):
+ """Decrypt the data with the given secret key."""
+ iv = data[:16]
+- cipher = AES.new(key, AES.MODE_CBC, iv)
++ cipher = Cipher(alg=_key_to_alg(key), key=key, iv=iv, op=0)
+ try:
+- result = cipher.decrypt(data[16:])
++ result = cipher.update(data[16:])
++ result = result + cipher.final()
+ except Exception:
+ raise DecryptError(_('Encrypted data appears to be corrupted.'))
+
+- # Strip the last n padding bytes where n is the last value in
+- # the plaintext
+- return result[:-1 * six.byte2int([result[-1]])]
++ return result
+
+
+ def protect_data(keys, data):