summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--keymanager/src/leap/keymanager/__init__.py7
-rw-r--r--keymanager/src/leap/keymanager/documents.py101
-rw-r--r--keymanager/src/leap/keymanager/keys.py163
-rw-r--r--keymanager/src/leap/keymanager/migrator.py70
-rw-r--r--keymanager/src/leap/keymanager/openpgp.py4
-rw-r--r--keymanager/src/leap/keymanager/tests/test_migrator.py2
-rw-r--r--keymanager/src/leap/keymanager/tests/test_openpgp.py6
7 files changed, 174 insertions, 179 deletions
diff --git a/keymanager/src/leap/keymanager/__init__.py b/keymanager/src/leap/keymanager/__init__.py
index 32e5581..6420f9a 100644
--- a/keymanager/src/leap/keymanager/__init__.py
+++ b/keymanager/src/leap/keymanager/__init__.py
@@ -76,11 +76,8 @@ from leap.keymanager.errors import (
)
from leap.keymanager.validation import ValidationLevels, can_upgrade
-from leap.keymanager.keys import (
- build_key_from_dict,
- KEYMANAGER_KEY_TAG,
- TAGS_PRIVATE_INDEX,
-)
+from leap.keymanager.keys import build_key_from_dict
+from leap.keymanager.documents import KEYMANAGER_KEY_TAG, TAGS_PRIVATE_INDEX
from leap.keymanager.openpgp import OpenPGPScheme
__version__ = get_versions()['version']
diff --git a/keymanager/src/leap/keymanager/documents.py b/keymanager/src/leap/keymanager/documents.py
new file mode 100644
index 0000000..2ed5376
--- /dev/null
+++ b/keymanager/src/leap/keymanager/documents.py
@@ -0,0 +1,101 @@
+# -*- coding: utf-8 -*-
+# documents.py
+# Copyright (C) 2013-2016 LEAP
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+Soledad documents
+"""
+from twisted.internet import defer
+from leap.common.check import leap_assert
+
+#
+# Dictionary keys used for storing cryptographic keys.
+#
+
+KEY_VERSION_KEY = 'version'
+KEY_UIDS_KEY = 'uids'
+KEY_ADDRESS_KEY = 'address'
+KEY_TYPE_KEY = 'type'
+KEY_FINGERPRINT_KEY = 'fingerprint'
+KEY_DATA_KEY = 'key_data'
+KEY_PRIVATE_KEY = 'private'
+KEY_LENGTH_KEY = 'length'
+KEY_EXPIRY_DATE_KEY = 'expiry_date'
+KEY_LAST_AUDITED_AT_KEY = 'last_audited_at'
+KEY_REFRESHED_AT_KEY = 'refreshed_at'
+KEY_VALIDATION_KEY = 'validation'
+KEY_ENCR_USED_KEY = 'encr_used'
+KEY_SIGN_USED_KEY = 'sign_used'
+KEY_TAGS_KEY = 'tags'
+
+
+#
+# Key storage constants
+#
+
+KEYMANAGER_KEY_TAG = 'keymanager-key'
+KEYMANAGER_ACTIVE_TAG = 'keymanager-active'
+KEYMANAGER_ACTIVE_TYPE = '-active'
+
+# Version of the Soledad Document schema,
+# it should be bumped each time the document format changes
+KEYMANAGER_DOC_VERSION = 1
+
+
+#
+# key indexing constants.
+#
+
+TAGS_PRIVATE_INDEX = 'by-tags-private'
+TYPE_FINGERPRINT_PRIVATE_INDEX = 'by-type-fingerprint-private'
+TYPE_ADDRESS_PRIVATE_INDEX = 'by-type-address-private'
+INDEXES = {
+ TAGS_PRIVATE_INDEX: [
+ KEY_TAGS_KEY,
+ 'bool(%s)' % KEY_PRIVATE_KEY,
+ ],
+ TYPE_FINGERPRINT_PRIVATE_INDEX: [
+ KEY_TYPE_KEY,
+ KEY_FINGERPRINT_KEY,
+ 'bool(%s)' % KEY_PRIVATE_KEY,
+ ],
+ TYPE_ADDRESS_PRIVATE_INDEX: [
+ KEY_TYPE_KEY,
+ KEY_ADDRESS_KEY,
+ 'bool(%s)' % KEY_PRIVATE_KEY,
+ ]
+}
+
+
+@defer.inlineCallbacks
+def init_indexes(soledad):
+ """
+ Initialize the database indexes.
+ """
+ leap_assert(soledad is not None,
+ "Cannot init indexes with null soledad")
+
+ indexes = yield soledad.list_indexes()
+ db_indexes = dict(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.
+ yield soledad.create_index(name, *expression)
+ elif expression != db_indexes[name]:
+ # The index exists but the definition is not what expected,
+ # so we delete it and add the proper index expression.
+ yield soledad.delete_index(name)
+ yield soledad.create_index(name, *expression)
diff --git a/keymanager/src/leap/keymanager/keys.py b/keymanager/src/leap/keymanager/keys.py
index 296ed86..c0ee21b 100644
--- a/keymanager/src/leap/keymanager/keys.py
+++ b/keymanager/src/leap/keymanager/keys.py
@@ -27,78 +27,17 @@ import logging
import re
import time
-
from datetime import datetime
-from leap.common.check import leap_assert
-from twisted.internet import defer
from leap.keymanager import errors
from leap.keymanager.wrapper import TempGPGWrapper
from leap.keymanager.validation import ValidationLevels
+from leap.keymanager import documents as doc
logger = logging.getLogger(__name__)
#
-# Dictionary keys used for storing cryptographic keys.
-#
-
-KEY_VERSION_KEY = 'version'
-KEY_UIDS_KEY = 'uids'
-KEY_ADDRESS_KEY = 'address'
-KEY_TYPE_KEY = 'type'
-KEY_FINGERPRINT_KEY = 'fingerprint'
-KEY_DATA_KEY = 'key_data'
-KEY_PRIVATE_KEY = 'private'
-KEY_LENGTH_KEY = 'length'
-KEY_EXPIRY_DATE_KEY = 'expiry_date'
-KEY_LAST_AUDITED_AT_KEY = 'last_audited_at'
-KEY_REFRESHED_AT_KEY = 'refreshed_at'
-KEY_VALIDATION_KEY = 'validation'
-KEY_ENCR_USED_KEY = 'encr_used'
-KEY_SIGN_USED_KEY = 'sign_used'
-KEY_TAGS_KEY = 'tags'
-
-
-#
-# Key storage constants
-#
-
-KEYMANAGER_KEY_TAG = 'keymanager-key'
-KEYMANAGER_ACTIVE_TAG = 'keymanager-active'
-KEYMANAGER_ACTIVE_TYPE = '-active'
-
-# Version of the Soledad Document schema,
-# it should be bumped each time the document format changes
-KEYMANAGER_DOC_VERSION = 1
-
-
-#
-# key indexing constants.
-#
-
-TAGS_PRIVATE_INDEX = 'by-tags-private'
-TYPE_FINGERPRINT_PRIVATE_INDEX = 'by-type-fingerprint-private'
-TYPE_ADDRESS_PRIVATE_INDEX = 'by-type-address-private'
-INDEXES = {
- TAGS_PRIVATE_INDEX: [
- KEY_TAGS_KEY,
- 'bool(%s)' % KEY_PRIVATE_KEY,
- ],
- TYPE_FINGERPRINT_PRIVATE_INDEX: [
- KEY_TYPE_KEY,
- KEY_FINGERPRINT_KEY,
- 'bool(%s)' % KEY_PRIVATE_KEY,
- ],
- TYPE_ADDRESS_PRIVATE_INDEX: [
- KEY_TYPE_KEY,
- KEY_ADDRESS_KEY,
- 'bool(%s)' % KEY_PRIVATE_KEY,
- ]
-}
-
-
-#
# Key handling utilities
#
@@ -132,27 +71,27 @@ def build_key_from_dict(key, active=None):
sign_used = False
if active:
- address = active[KEY_ADDRESS_KEY]
+ address = active[doc.KEY_ADDRESS_KEY]
try:
- validation = ValidationLevels.get(active[KEY_VALIDATION_KEY])
+ validation = ValidationLevels.get(active[doc.KEY_VALIDATION_KEY])
except ValueError:
logger.error("Not valid validation level (%s) for key %s",
- (active[KEY_VALIDATION_KEY],
- active[KEY_FINGERPRINT_KEY]))
- last_audited_at = _to_datetime(active[KEY_LAST_AUDITED_AT_KEY])
- encr_used = active[KEY_ENCR_USED_KEY]
- sign_used = active[KEY_SIGN_USED_KEY]
+ (active[doc.KEY_VALIDATION_KEY],
+ active[doc.KEY_FINGERPRINT_KEY]))
+ last_audited_at = _to_datetime(active[doc.KEY_LAST_AUDITED_AT_KEY])
+ encr_used = active[doc.KEY_ENCR_USED_KEY]
+ sign_used = active[doc.KEY_SIGN_USED_KEY]
- expiry_date = _to_datetime(key[KEY_EXPIRY_DATE_KEY])
- refreshed_at = _to_datetime(key[KEY_REFRESHED_AT_KEY])
+ expiry_date = _to_datetime(key[doc.KEY_EXPIRY_DATE_KEY])
+ refreshed_at = _to_datetime(key[doc.KEY_REFRESHED_AT_KEY])
return OpenPGPKey(
address=address,
- uids=key[KEY_UIDS_KEY],
- fingerprint=key[KEY_FINGERPRINT_KEY],
- key_data=key[KEY_DATA_KEY],
- private=key[KEY_PRIVATE_KEY],
- length=key[KEY_LENGTH_KEY],
+ uids=key[doc.KEY_UIDS_KEY],
+ fingerprint=key[doc.KEY_FINGERPRINT_KEY],
+ key_data=key[doc.KEY_DATA_KEY],
+ private=key[doc.KEY_PRIVATE_KEY],
+ length=key[doc.KEY_LENGTH_KEY],
expiry_date=expiry_date,
last_audited_at=last_audited_at,
refreshed_at=refreshed_at,
@@ -271,16 +210,16 @@ class OpenPGPKey(object):
refreshed_at = _to_unix_time(self.refreshed_at)
return json.dumps({
- KEY_UIDS_KEY: self.uids,
- KEY_TYPE_KEY: self.__class__.__name__,
- KEY_FINGERPRINT_KEY: self.fingerprint,
- KEY_DATA_KEY: self.key_data,
- KEY_PRIVATE_KEY: self.private,
- KEY_LENGTH_KEY: self.length,
- KEY_EXPIRY_DATE_KEY: expiry_date,
- KEY_REFRESHED_AT_KEY: refreshed_at,
- KEY_VERSION_KEY: KEYMANAGER_DOC_VERSION,
- KEY_TAGS_KEY: [KEYMANAGER_KEY_TAG],
+ doc.KEY_UIDS_KEY: self.uids,
+ doc.KEY_TYPE_KEY: self.__class__.__name__,
+ doc.KEY_FINGERPRINT_KEY: self.fingerprint,
+ doc.KEY_DATA_KEY: self.key_data,
+ doc.KEY_PRIVATE_KEY: self.private,
+ doc.KEY_LENGTH_KEY: self.length,
+ doc.KEY_EXPIRY_DATE_KEY: expiry_date,
+ doc.KEY_REFRESHED_AT_KEY: refreshed_at,
+ doc.KEY_VERSION_KEY: doc.KEYMANAGER_DOC_VERSION,
+ doc.KEY_TAGS_KEY: [doc.KEYMANAGER_KEY_TAG],
})
def get_active_json(self):
@@ -293,16 +232,17 @@ class OpenPGPKey(object):
last_audited_at = _to_unix_time(self.last_audited_at)
return json.dumps({
- KEY_ADDRESS_KEY: self.address,
- KEY_TYPE_KEY: self.__class__.__name__ + KEYMANAGER_ACTIVE_TYPE,
- KEY_FINGERPRINT_KEY: self.fingerprint,
- KEY_PRIVATE_KEY: self.private,
- KEY_VALIDATION_KEY: str(self.validation),
- KEY_LAST_AUDITED_AT_KEY: last_audited_at,
- KEY_ENCR_USED_KEY: self.encr_used,
- KEY_SIGN_USED_KEY: self.sign_used,
- KEY_VERSION_KEY: KEYMANAGER_DOC_VERSION,
- KEY_TAGS_KEY: [KEYMANAGER_ACTIVE_TAG],
+ doc.KEY_ADDRESS_KEY: self.address,
+ doc.KEY_TYPE_KEY: (self.__class__.__name__ +
+ doc.KEYMANAGER_ACTIVE_TYPE),
+ doc.KEY_FINGERPRINT_KEY: self.fingerprint,
+ doc.KEY_PRIVATE_KEY: self.private,
+ doc.KEY_VALIDATION_KEY: str(self.validation),
+ doc.KEY_LAST_AUDITED_AT_KEY: last_audited_at,
+ doc.KEY_ENCR_USED_KEY: self.encr_used,
+ doc.KEY_SIGN_USED_KEY: self.sign_used,
+ doc.KEY_VERSION_KEY: doc.KEYMANAGER_DOC_VERSION,
+ doc.KEY_TAGS_KEY: [doc.KEYMANAGER_ACTIVE_TAG],
})
def next(self):
@@ -351,34 +291,3 @@ def parse_address(address):
if match is None:
return None
return ''.join(match.group(2, 4))
-
-
-def init_indexes(soledad):
- """
- Initialize the database indexes.
- """
- leap_assert(soledad is not None,
- "Cannot init indexes with null soledad")
-
- def create_idexes(indexes):
- deferreds = []
- db_indexes = dict(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.
- d = soledad.create_index(name, *expression)
- deferreds.append(d)
- elif expression != db_indexes[name]:
- # The index exists but the definition is not what expected,
- # so we delete it and add the proper index expression.
- d = soledad.delete_index(name)
- d.addCallback(
- lambda _:
- soledad.create_index(name, *expression))
- deferreds.append(d)
- return defer.gatherResults(deferreds, consumeErrors=True)
-
- d = soledad.list_indexes()
- d.addCallback(create_idexes)
- return d
diff --git a/keymanager/src/leap/keymanager/migrator.py b/keymanager/src/leap/keymanager/migrator.py
index 9e4ae77..c73da2e 100644
--- a/keymanager/src/leap/keymanager/migrator.py
+++ b/keymanager/src/leap/keymanager/migrator.py
@@ -26,21 +26,7 @@ Document migrator
from collections import namedtuple
from twisted.internet.defer import gatherResults, succeed
-from leap.keymanager.keys import (
- TAGS_PRIVATE_INDEX,
- KEYMANAGER_KEY_TAG,
- KEYMANAGER_ACTIVE_TAG,
-
- KEYMANAGER_DOC_VERSION,
- KEY_ADDRESS_KEY,
- KEY_UIDS_KEY,
- KEY_VERSION_KEY,
- KEY_FINGERPRINT_KEY,
- KEY_VALIDATION_KEY,
- KEY_LAST_AUDITED_AT_KEY,
- KEY_ENCR_USED_KEY,
- KEY_SIGN_USED_KEY,
-)
+from leap.keymanager import documents as doc
from leap.keymanager.validation import ValidationLevels
@@ -70,12 +56,12 @@ class KeyDocumentsMigrator(object):
private_value = '1' if private else '0'
deferred_keys = self._soledad.get_from_index(
- TAGS_PRIVATE_INDEX,
- KEYMANAGER_KEY_TAG,
+ doc.TAGS_PRIVATE_INDEX,
+ doc.KEYMANAGER_KEY_TAG,
private_value)
deferred_active = self._soledad.get_from_index(
- TAGS_PRIVATE_INDEX,
- KEYMANAGER_ACTIVE_TAG,
+ doc.TAGS_PRIVATE_INDEX,
+ doc.KEYMANAGER_ACTIVE_TAG,
private_value)
return gatherResults([deferred_keys, deferred_active])
@@ -99,7 +85,7 @@ class KeyDocumentsMigrator(object):
def _buildKeyDict(self, keys, actives):
keydict = {
- fp2id(key.content[KEY_FINGERPRINT_KEY]): KeyDocs(key, [])
+ fp2id(key.content[doc.KEY_FINGERPRINT_KEY]): KeyDocs(key, [])
for key in keys}
deferreds = []
@@ -119,7 +105,7 @@ class KeyDocumentsMigrator(object):
def _filter_outdated(self, keydict):
outdated = {}
for key_id, docs in keydict.items():
- if ((docs.key and KEY_VERSION_KEY not in docs.key.content) or
+ if ((docs.key and doc.KEY_VERSION_KEY not in docs.key.content) or
docs.active):
outdated[key_id] = docs
return outdated
@@ -136,43 +122,43 @@ class KeyDocumentsMigrator(object):
last_audited = 0
encr_used = False
sign_used = False
- fingerprint = key.content[KEY_FINGERPRINT_KEY]
- if len(actives) == 1 and KEY_VERSION_KEY not in key.content:
+ fingerprint = key.content[doc.KEY_FINGERPRINT_KEY]
+ if len(actives) == 1 and doc.KEY_VERSION_KEY not in key.content:
# we can preserve the validation of the key if there is only one
# active address for the key
- validation = key.content[KEY_VALIDATION_KEY]
- last_audited = key.content[KEY_LAST_AUDITED_AT_KEY]
- encr_used = key.content[KEY_ENCR_USED_KEY]
- sign_used = key.content[KEY_SIGN_USED_KEY]
+ validation = key.content[doc.KEY_VALIDATION_KEY]
+ last_audited = key.content[doc.KEY_LAST_AUDITED_AT_KEY]
+ encr_used = key.content[doc.KEY_ENCR_USED_KEY]
+ sign_used = key.content[doc.KEY_SIGN_USED_KEY]
deferreds = []
for active in actives:
- if KEY_VERSION_KEY in active.content:
+ if doc.KEY_VERSION_KEY in active.content:
continue
- active.content[KEY_VERSION_KEY] = KEYMANAGER_DOC_VERSION
- active.content[KEY_FINGERPRINT_KEY] = fingerprint
- active.content[KEY_VALIDATION_KEY] = validation
- active.content[KEY_LAST_AUDITED_AT_KEY] = last_audited
- active.content[KEY_ENCR_USED_KEY] = encr_used
- active.content[KEY_SIGN_USED_KEY] = sign_used
+ active.content[doc.KEY_VERSION_KEY] = doc.KEYMANAGER_DOC_VERSION
+ active.content[doc.KEY_FINGERPRINT_KEY] = fingerprint
+ active.content[doc.KEY_VALIDATION_KEY] = validation
+ active.content[doc.KEY_LAST_AUDITED_AT_KEY] = last_audited
+ active.content[doc.KEY_ENCR_USED_KEY] = encr_used
+ active.content[doc.KEY_SIGN_USED_KEY] = sign_used
del active.content[KEY_ID_KEY]
d = self._soledad.put_doc(active)
deferreds.append(d)
return gatherResults(deferreds)
def _migrate_key(self, key):
- if not key or KEY_VERSION_KEY in key.content:
+ if not key or doc.KEY_VERSION_KEY in key.content:
return succeed(None)
- key.content[KEY_VERSION_KEY] = KEYMANAGER_DOC_VERSION
- key.content[KEY_UIDS_KEY] = key.content[KEY_ADDRESS_KEY]
- del key.content[KEY_ADDRESS_KEY]
+ key.content[doc.KEY_VERSION_KEY] = doc.KEYMANAGER_DOC_VERSION
+ key.content[doc.KEY_UIDS_KEY] = key.content[doc.KEY_ADDRESS_KEY]
+ del key.content[doc.KEY_ADDRESS_KEY]
del key.content[KEY_ID_KEY]
- del key.content[KEY_VALIDATION_KEY]
- del key.content[KEY_LAST_AUDITED_AT_KEY]
- del key.content[KEY_ENCR_USED_KEY]
- del key.content[KEY_SIGN_USED_KEY]
+ del key.content[doc.KEY_VALIDATION_KEY]
+ del key.content[doc.KEY_LAST_AUDITED_AT_KEY]
+ del key.content[doc.KEY_ENCR_USED_KEY]
+ del key.content[doc.KEY_SIGN_USED_KEY]
return self._soledad.put_doc(key)
diff --git a/keymanager/src/leap/keymanager/openpgp.py b/keymanager/src/leap/keymanager/openpgp.py
index fae5600..08b69f7 100644
--- a/keymanager/src/leap/keymanager/openpgp.py
+++ b/keymanager/src/leap/keymanager/openpgp.py
@@ -36,10 +36,12 @@ from leap.keymanager import errors
from leap.keymanager.wrapper import TempGPGWrapper
from leap.keymanager.keys import (
OpenPGPKey,
- init_indexes,
is_address,
parse_address,
build_key_from_dict,
+)
+from leap.keymanager.documents import (
+ init_indexes,
TYPE_FINGERPRINT_PRIVATE_INDEX,
TYPE_ADDRESS_PRIVATE_INDEX,
KEY_UIDS_KEY,
diff --git a/keymanager/src/leap/keymanager/tests/test_migrator.py b/keymanager/src/leap/keymanager/tests/test_migrator.py
index 2d9782b..76323e5 100644
--- a/keymanager/src/leap/keymanager/tests/test_migrator.py
+++ b/keymanager/src/leap/keymanager/tests/test_migrator.py
@@ -26,7 +26,7 @@ from mock import Mock
from twisted.internet.defer import succeed, inlineCallbacks
from leap.keymanager.migrator import KeyDocumentsMigrator, KEY_ID_KEY
-from leap.keymanager.keys import (
+from leap.keymanager.documents import (
TAGS_PRIVATE_INDEX,
KEYMANAGER_ACTIVE_TAG,
KEYMANAGER_KEY_TAG,
diff --git a/keymanager/src/leap/keymanager/tests/test_openpgp.py b/keymanager/src/leap/keymanager/tests/test_openpgp.py
index 0e39dab..47e9005 100644
--- a/keymanager/src/leap/keymanager/tests/test_openpgp.py
+++ b/keymanager/src/leap/keymanager/tests/test_openpgp.py
@@ -29,7 +29,7 @@ from leap.keymanager import (
KeyNotFound,
openpgp,
)
-from leap.keymanager.keys import (
+from leap.keymanager.documents import (
TYPE_FINGERPRINT_PRIVATE_INDEX,
TYPE_ADDRESS_PRIVATE_INDEX,
)
@@ -57,7 +57,7 @@ class OpenPGPCryptoTestCase(KeyManagerWithSoledadTestCase):
self._soledad, gpgbinary=self.gpg_binary_path)
yield self._assert_key_not_found(pgp, 'user@leap.se')
key = yield pgp.gen_key('user@leap.se')
- self.assertIsInstance(key, openpgp.OpenPGPKey)
+ self.assertIsInstance(key, OpenPGPKey)
self.assertEqual(
['user@leap.se'], key.address, 'Wrong address bound to key.')
self.assertEqual(
@@ -80,7 +80,7 @@ class OpenPGPCryptoTestCase(KeyManagerWithSoledadTestCase):
yield self._assert_key_not_found(pgp, ADDRESS)
yield pgp.put_raw_key(PUBLIC_KEY, ADDRESS)
key = yield pgp.get_key(ADDRESS, private=False)
- self.assertIsInstance(key, openpgp.OpenPGPKey)
+ self.assertIsInstance(key, OpenPGPKey)
self.assertTrue(
ADDRESS in key.address, 'Wrong address bound to key.')
self.assertEqual(