changeset 1098:77cd312d32c4

memory: fixes encoding issues during encryption
author souliane <souliane@mailoo.org>
date Sun, 06 Jul 2014 21:13:47 +0200 (2014-07-06)
parents dace0ede919c
children 1baa116501fa
files src/memory/crypto.py src/test/test_memory_crypto.py
diffstat 2 files changed, 17 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/memory/crypto.py	Fri Jun 27 20:05:31 2014 +0200
+++ b/src/memory/crypto.py	Sun Jul 06 21:13:47 2014 +0200
@@ -42,17 +42,18 @@
 
         Based on http://stackoverflow.com/a/12525165
 
-        @param key (str): the encryption key
-        @param text (str): the text to encrypt
+        @param key (unicode): the encryption key
+        @param text (unicode): the text to encrypt
         @param leave_empty (bool): if True, empty text will be returned "as is"
         @return: Deferred: base-64 encoded str
         """
         if leave_empty and text == '':
             return succeed(text)
         iv = BlockCipher.getRandomKey()
+        key = key.encode('utf-8')
         key = key[:BlockCipher.MAX_KEY_SIZE] if len(key) >= BlockCipher.MAX_KEY_SIZE else BlockCipher.pad(key)
         cipher = AES.new(key, AES.MODE_CFB, iv)
-        d = deferToThread(cipher.encrypt, BlockCipher.pad(text))
+        d = deferToThread(cipher.encrypt, BlockCipher.pad(text.encode('utf-8')))
         d.addCallback(lambda ciphertext: b64encode(iv + ciphertext))
         return d
 
@@ -62,7 +63,7 @@
 
         Based on http://stackoverflow.com/a/12525165
 
-        @param key (str): the decryption key
+        @param key (unicode): the decryption key
         @param ciphertext (base-64 encoded str): the text to decrypt
         @param leave_empty (bool): if True, empty ciphertext will be returned "as is"
         @return: Deferred: str or None if the password could not be decrypted
@@ -71,6 +72,7 @@
             return succeed('')
         ciphertext = b64decode(ciphertext)
         iv, ciphertext = ciphertext[:BlockCipher.IV_SIZE], ciphertext[BlockCipher.IV_SIZE:]
+        key = key.encode('utf-8')
         key = key[:BlockCipher.MAX_KEY_SIZE] if len(key) >= BlockCipher.MAX_KEY_SIZE else BlockCipher.pad(key)
         cipher = AES.new(key, AES.MODE_CFB, iv)
         d = deferToThread(cipher.decrypt, ciphertext)
@@ -79,7 +81,7 @@
         # a decrypted empty value and a decryption failure... both return
         # the empty value. Fortunately, we detect empty passwords beforehand
         # thanks to the "leave_empty" parameter which is used by default.
-        d.addCallback(lambda text: text if text else None)
+        d.addCallback(lambda text: text.decode('utf-8') if text else None)
         return d
 
     @classmethod
--- a/src/test/test_memory_crypto.py	Fri Jun 27 20:05:31 2014 +0200
+++ b/src/test/test_memory_crypto.py	Sun Jul 06 21:13:47 2014 +0200
@@ -23,10 +23,16 @@
 
 from sat.test import helpers
 from sat.memory.crypto import BlockCipher, PasswordHasher
-from os import urandom
+import random
+import string
 from twisted.internet import defer
 
 
+def getRandomUnicode(len):
+    """Return a random unicode string"""
+    return u''.join(random.choice(string.letters + u"éáúóâêûôßüöä") for i in xrange(len))
+
+
 class CryptoTest(helpers.SatTestCase):
 
     def setUp(self):
@@ -42,9 +48,9 @@
             d_list.append(d)
 
         for key_len in (0, 2, 8, 10, 16, 24, 30, 32, 40):
-            key = urandom(key_len)
+            key = getRandomUnicode(key_len)
             for message_len in (0, 2, 16, 24, 32, 100):
-                message = urandom(message_len)
+                message = getRandomUnicode(message_len)
                 test(key, message)
         return defer.DeferredList(d_list)
 
@@ -57,7 +63,7 @@
                 d1 = PasswordHasher.verify(password, hashed)
                 d1.addCallback(lambda result: self.assertTrue(result))
                 d_list.append(d1)
-                attempt = urandom(10)
+                attempt = getRandomUnicode(10)
                 d2 = PasswordHasher.verify(attempt, hashed)
                 d2.addCallback(lambda result: self.assertFalse(result))
                 d_list.append(d2)