diff options
| -rw-r--r-- | src/leap/common/keymanager/__init__.py | 37 | ||||
| -rw-r--r-- | src/leap/common/keymanager/keys.py | 64 | ||||
| -rw-r--r-- | src/leap/common/keymanager/openpgp.py | 26 | ||||
| -rw-r--r-- | src/leap/common/tests/test_crypto.py | 12 | ||||
| -rw-r--r-- | src/leap/common/tests/test_keymanager.py | 17 | 
5 files changed, 69 insertions, 87 deletions
| diff --git a/src/leap/common/keymanager/__init__.py b/src/leap/common/keymanager/__init__.py index f5c5f5e..9435cea 100644 --- a/src/leap/common/keymanager/__init__.py +++ b/src/leap/common/keymanager/__init__.py @@ -35,6 +35,7 @@ from leap.common.keymanager.errors import (  from leap.common.keymanager.keys import (      build_key_from_dict,      KEYMANAGER_KEY_TAG, +    TAGS_PRIVATE_INDEX,  )  from leap.common.keymanager.openpgp import (      OpenPGPKey, @@ -43,18 +44,6 @@ from leap.common.keymanager.openpgp import (  # -# key indexing constants. -# - -TAGS_INDEX = 'by-tags' -TAGS_AND_PRIVATE_INDEX = 'by-tags-and-private' -INDEXES = { -    TAGS_INDEX: ['tags'], -    TAGS_AND_PRIVATE_INDEX: ['tags', 'bool(private)'], -} - - -#  # The Key Manager  # @@ -103,8 +92,6 @@ class KeyManager(object):              OpenPGPKey: OpenPGPScheme(soledad),              # other types of key will be added to this mapper.          } -        # initialize the indexes needed to query the database -        self._init_indexes()          # the following are used to perform https requests          self._fetcher = requests          self._session = self._fetcher.session() @@ -121,26 +108,6 @@ class KeyManager(object):              lambda klass: str(klass) == ktype,              self._wrapper_map).pop() -    def _init_indexes(self): -        """ -        Initialize the database indexes. -        """ -        # Ask the database for currently existing indexes. -        db_indexes = dict(self._soledad.list_indexes()) -        # Loop through the indexes we expect to find. -        for name, expression in INDEXES.items(): -            if name not in db_indexes: -                # The index does not yet exist. -                self._soledad.create_index(name, *expression) -                continue -            if expression == db_indexes[name]: -                # The index exists and is up to date. -                continue -            # The index exists but the definition is not what expected, so we -            # delete it and add the proper index expression. -            self._soledad.delete_index(name) -            self._soledad.create_index(name, *expression) -      def _get(self, uri, data=None):          """          Send a GET request to C{uri} containing C{data}. @@ -294,7 +261,7 @@ class KeyManager(object):                  doc.content['address'],                  doc.content),              self._soledad.get_from_index( -                TAGS_AND_PRIVATE_INDEX, +                TAGS_PRIVATE_INDEX,                  KEYMANAGER_KEY_TAG,                  '1' if private else '0')) diff --git a/src/leap/common/keymanager/keys.py b/src/leap/common/keymanager/keys.py index f2c1beb..a3c8537 100644 --- a/src/leap/common/keymanager/keys.py +++ b/src/leap/common/keymanager/keys.py @@ -28,7 +28,6 @@ except ImportError:  import re -from hashlib import sha256  from abc import ABCMeta, abstractmethod  from leap.common.check import leap_assert @@ -57,6 +56,26 @@ KEY_TAGS_KEY = 'tags'  KEYMANAGER_KEY_TAG = 'keymanager-key' + +# +# key indexing constants. +# + +TAGS_PRIVATE_INDEX = 'by-tags-private' +TAGS_ADDRESS_PRIVATE_INDEX = 'by-tags-address-private' +INDEXES = { +    TAGS_PRIVATE_INDEX: [ +        KEY_TAGS_KEY, +        'bool(%s)' % KEY_PRIVATE_KEY, +    ], +    TAGS_ADDRESS_PRIVATE_INDEX: [ +        KEY_TAGS_KEY, +        KEY_ADDRESS_KEY, +        'bool(%s)' % KEY_PRIVATE_KEY, +    ] +} + +  #  # Key handling utilities  # @@ -100,28 +119,6 @@ def build_key_from_dict(kClass, address, kdict):          validation=kdict[KEY_VALIDATION_KEY],  # TODO: verify for validation.      ) - -def keymanager_doc_id(ktype, address, private=False): -    """ -    Return the document id for the document containing a key for -    C{address}. - -    :param address: The type of the key. -    :type address: KeyType -    :param address: The address bound to the key. -    :type address: str -    :param private: Whether the key is private or not. -    :type private: bool -    :return: The document id for the document that stores a key bound to -        C{address}. -    :rtype: str -    """ -    leap_assert(is_address(address), "Wrong address format: %s" % address) -    ktype = str(ktype) -    visibility = KEY_PRIVATE_KEY if private else 'public' -    return sha256('keymanager-'+address+'-'+ktype+'-'+visibility).hexdigest() - -  #  # Abstraction for encryption keys  # @@ -215,6 +212,27 @@ class EncryptionScheme(object):          :type soledad: leap.soledad.Soledad          """          self._soledad = soledad +        self._init_indexes() + +    def _init_indexes(self): +        """ +        Initialize the database indexes. +        """ +        # Ask the database for currently existing indexes. +        db_indexes = dict(self._soledad.list_indexes()) +        # Loop through the indexes we expect to find. +        for name, expression in INDEXES.items(): +            if name not in db_indexes: +                # The index does not yet exist. +                self._soledad.create_index(name, *expression) +                continue +            if expression == db_indexes[name]: +                # The index exists and is up to date. +                continue +            # The index exists but the definition is not what expected, so we +            # delete it and add the proper index expression. +            self._soledad.delete_index(name) +            self._soledad.create_index(name, *expression)      @abstractmethod      def get_key(self, address, private=False): diff --git a/src/leap/common/keymanager/openpgp.py b/src/leap/common/keymanager/openpgp.py index b08bff6..dd11157 100644 --- a/src/leap/common/keymanager/openpgp.py +++ b/src/leap/common/keymanager/openpgp.py @@ -26,13 +26,13 @@ import tempfile  from leap.common.check import leap_assert, leap_assert_type  from leap.common.keymanager import errors -  from leap.common.keymanager.keys import (      EncryptionKey,      EncryptionScheme,      is_address, -    keymanager_doc_id,      build_key_from_dict, +    KEYMANAGER_KEY_TAG, +    TAGS_ADDRESS_PRIVATE_INDEX,  )  from leap.common.keymanager.gpg import GPGWrapper @@ -588,10 +588,7 @@ class OpenPGPScheme(EncryptionScheme):          """          doc = self._get_key_doc(key.address, private=key.private)          if doc is None: -            self._soledad.create_doc_from_json( -                key.get_json(), -                doc_id=keymanager_doc_id( -                    OpenPGPKey, key.address, key.private)) +            self._soledad.create_doc_from_json(key.get_json())          else:              doc.set_json(key.get_json())              self._soledad.put_doc(doc) @@ -609,8 +606,18 @@ class OpenPGPScheme(EncryptionScheme):          :return: The document with the key or None if it does not exist.          :rtype: leap.soledad.backends.leap_backend.LeapDocument          """ -        return self._soledad.get_doc( -            keymanager_doc_id(OpenPGPKey, address, private)) +        doclist = self._soledad.get_from_index( +            TAGS_ADDRESS_PRIVATE_INDEX, +            KEYMANAGER_KEY_TAG, +            address, +            '1' if private else '0') +        if len(doclist) is 0: +            return None +        leap_assert( +            len(doclist) is 1, +            'Found more than one %s key for address!' % +            'private' if private else 'public') +        return doclist.pop()      def delete_key(self, key):          """ @@ -625,6 +632,5 @@ class OpenPGPScheme(EncryptionScheme):              raise errors.KeyNotFound(key)          if stored_key.__dict__ != key.__dict__:              raise errors.KeyAttributesDiffer(key) -        doc = self._soledad.get_doc( -            keymanager_doc_id(OpenPGPKey, key.address, key.private)) +        doc = self._get_key_doc(key.address, key.private)          self._soledad.delete_doc(doc) diff --git a/src/leap/common/tests/test_crypto.py b/src/leap/common/tests/test_crypto.py index b704c05..ae7dc71 100644 --- a/src/leap/common/tests/test_crypto.py +++ b/src/leap/common/tests/test_crypto.py @@ -21,6 +21,10 @@ Tests for the crypto submodule.  """ +import os +import binascii + +  from leap.common.testing.basetest import BaseLeapTest  from leap.common import crypto  from Crypto import Random @@ -56,9 +60,13 @@ class CryptoTestCase(BaseLeapTest):          self.assertTrue(cyphertext is not None)          self.assertTrue(cyphertext != '')          self.assertTrue(cyphertext != 'data') -        iv += 1 +        # get a different iv by changing the first byte +        rawiv = binascii.a2b_base64(iv) +        wrongiv = rawiv +        while wrongiv == rawiv: +            wrongiv = os.urandom(1) + rawiv[1:]          plaintext = crypto.decrypt_sym( -            cyphertext, key, iv=iv, +            cyphertext, key, iv=binascii.b2a_base64(wrongiv),              method=crypto.EncryptionMethods.AES_256_CTR)          self.assertNotEqual('data', plaintext) diff --git a/src/leap/common/tests/test_keymanager.py b/src/leap/common/tests/test_keymanager.py index cffa073..73611b6 100644 --- a/src/leap/common/tests/test_keymanager.py +++ b/src/leap/common/tests/test_keymanager.py @@ -44,7 +44,6 @@ from leap.common.keymanager.openpgp import OpenPGPKey  from leap.common.keymanager.keys import (      is_address,      build_key_from_dict, -    keymanager_doc_id,  )  from leap.common.keymanager import errors @@ -120,22 +119,6 @@ class KeyManagerUtilTestCase(BaseLeapTest):              kdict['validation'], key.validation,              'Wrong data in key.') -    def test_keymanager_doc_id(self): -        doc_id1 = keymanager_doc_id( -            OpenPGPKey, ADDRESS, private=False) -        doc_id2 = keymanager_doc_id( -            OpenPGPKey, ADDRESS, private=True) -        doc_id3 = keymanager_doc_id( -            OpenPGPKey, 'user@leap.se', private=False) -        doc_id4 = keymanager_doc_id( -            OpenPGPKey, 'user@leap.se', private=True) -        self.assertFalse(doc_id1 == doc_id2, 'Doc ids are equal!') -        self.assertFalse(doc_id1 == doc_id3, 'Doc ids are equal!') -        self.assertFalse(doc_id1 == doc_id4, 'Doc ids are equal!') -        self.assertFalse(doc_id2 == doc_id3, 'Doc ids are equal!') -        self.assertFalse(doc_id2 == doc_id4, 'Doc ids are equal!') -        self.assertFalse(doc_id3 == doc_id4, 'Doc ids are equal!') -  class KeyManagerWithSoledadTestCase(BaseLeapTest): | 
