summaryrefslogtreecommitdiff
path: root/src/leap/keymanager/__init__.py
diff options
context:
space:
mode:
authorTomás Touceda <chiiph@leap.se>2013-07-05 12:20:01 -0300
committerTomás Touceda <chiiph@leap.se>2013-07-05 12:20:01 -0300
commit124e1c2b7c9680ca675a5be223208f4bdfcd7720 (patch)
treeb1eb56bcd7c81c1a05367a1c5ef3802ca91c7cc2 /src/leap/keymanager/__init__.py
parentb5516cc47b887d989690bde102441726927b84f1 (diff)
parente004f3e18a983338c7769ffbde3466843aa69858 (diff)
Merge remote-tracking branch 'drebs/feature/3037-separate-keymanager-into-its-own-package' into develop
Diffstat (limited to 'src/leap/keymanager/__init__.py')
-rw-r--r--src/leap/keymanager/__init__.py341
1 files changed, 0 insertions, 341 deletions
diff --git a/src/leap/keymanager/__init__.py b/src/leap/keymanager/__init__.py
deleted file mode 100644
index 38e23d0e..00000000
--- a/src/leap/keymanager/__init__.py
+++ /dev/null
@@ -1,341 +0,0 @@
-# -*- coding: utf-8 -*-
-# __init__.py
-# Copyright (C) 2013 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/>.
-
-
-"""
-Key Manager is a Nicknym agent for LEAP client.
-"""
-
-import requests
-
-try:
- import simplejson as json
-except ImportError:
- import json # noqa
-
-from leap.common.check import leap_assert
-from leap.keymanager.errors import (
- KeyNotFound,
- NoPasswordGiven,
-)
-from leap.keymanager.keys import (
- build_key_from_dict,
- KEYMANAGER_KEY_TAG,
- TAGS_PRIVATE_INDEX,
-)
-from leap.keymanager.openpgp import (
- OpenPGPKey,
- OpenPGPScheme,
-)
-
-
-#
-# The Key Manager
-#
-
-class KeyManager(object):
-
- #
- # server's key storage constants
- #
-
- OPENPGP_KEY = 'openpgp'
- PUBKEY_KEY = "user[public_key]"
-
- def __init__(self, address, nickserver_uri, soledad, session_id=None,
- ca_cert_path=None, api_uri=None, api_version=None, uid=None):
- """
- Initialize a Key Manager for user's C{address} with provider's
- nickserver reachable in C{url}.
-
- :param address: The address of the user of this Key Manager.
- :type address: str
- :param url: The URL of the nickserver.
- :type url: str
- :param soledad: A Soledad instance for local storage of keys.
- :type soledad: leap.soledad.Soledad
- :param session_id: The session ID for interacting with the webapp API.
- :type session_id: str
- :param ca_cert_path: The path to the CA certificate.
- :type ca_cert_path: str
- :param api_uri: The URI of the webapp API.
- :type api_uri: str
- :param api_version: The version of the webapp API.
- :type api_version: str
- :param uid: The users' UID.
- :type uid: str
- """
- self._address = address
- self._nickserver_uri = nickserver_uri
- self._soledad = soledad
- self._session_id = session_id
- self.ca_cert_path = ca_cert_path
- self.api_uri = api_uri
- self.api_version = api_version
- self.uid = uid
- # a dict to map key types to their handlers
- self._wrapper_map = {
- OpenPGPKey: OpenPGPScheme(soledad),
- # other types of key will be added to this mapper.
- }
- # the following are used to perform https requests
- self._fetcher = requests
- self._session = self._fetcher.session()
-
- #
- # utilities
- #
-
- def _key_class_from_type(self, ktype):
- """
- Return key class from string representation of key type.
- """
- return filter(
- lambda klass: str(klass) == ktype,
- self._wrapper_map).pop()
-
- def _get(self, uri, data=None):
- """
- Send a GET request to C{uri} containing C{data}.
-
- :param uri: The URI of the request.
- :type uri: str
- :param data: The body of the request.
- :type data: dict, str or file
-
- :return: The response to the request.
- :rtype: requests.Response
- """
- leap_assert(
- self._ca_cert_path is not None,
- 'We need the CA certificate path!')
- res = self._fetcher.get(uri, data=data, verify=self._ca_cert_path)
- # assert that the response is valid
- res.raise_for_status()
- leap_assert(
- res.headers['content-type'].startswith('application/json'),
- 'Content-type is not JSON.')
- return res
-
- def _put(self, uri, data=None):
- """
- Send a PUT request to C{uri} containing C{data}.
-
- The request will be sent using the configured CA certificate path to
- verify the server certificate and the configured session id for
- authentication.
-
- :param uri: The URI of the request.
- :type uri: str
- :param data: The body of the request.
- :type data: dict, str or file
-
- :return: The response to the request.
- :rtype: requests.Response
- """
- leap_assert(
- self._ca_cert_path is not None,
- 'We need the CA certificate path!')
- leap_assert(
- self._session_id is not None,
- 'We need a session_id to interact with webapp!')
- res = self._fetcher.put(
- uri, data=data, verify=self._ca_cert_path,
- cookies={'_session_id': self._session_id})
- # assert that the response is valid
- res.raise_for_status()
- return res
-
- def _fetch_keys_from_server(self, address):
- """
- Fetch keys bound to C{address} from nickserver and insert them in
- local database.
-
- :param address: The address bound to the keys.
- :type address: str
-
- @raise KeyNotFound: If the key was not found on nickserver.
- """
- # request keys from the nickserver
- server_keys = self._get(
- self._nickserver_uri, {'address': address}).json()
- # insert keys in local database
- if self.OPENPGP_KEY in server_keys:
- self._wrapper_map[OpenPGPKey].put_ascii_key(
- server_keys['openpgp'])
-
- #
- # key management
- #
-
- def send_key(self, ktype):
- """
- Send user's key of type C{ktype} to provider.
-
- Public key bound to user's is sent to provider, which will sign it and
- replace any prior keys for the same address in its database.
-
- If C{send_private} is True, then the private key is encrypted with
- C{password} and sent to server in the same request, together with a
- hash string of user's address and password. The encrypted private key
- will be saved in the server in a way it is publicly retrievable
- through the hash string.
-
- :param ktype: The type of the key.
- :type ktype: KeyType
-
- @raise KeyNotFound: If the key was not found in local database.
- """
- leap_assert(
- ktype is OpenPGPKey,
- 'For now we only know how to send OpenPGP public keys.')
- # prepare the public key bound to address
- pubkey = self.get_key(
- self._address, ktype, private=False, fetch_remote=False)
- data = {
- self.PUBKEY_KEY: pubkey.key_data
- }
- uri = "%s/%s/users/%s.json" % (
- self._api_uri,
- self._api_version,
- self._uid)
- self._put(uri, data)
-
- def get_key(self, address, ktype, private=False, fetch_remote=True):
- """
- Return a key of type C{ktype} bound to C{address}.
-
- First, search for the key in local storage. If it is not available,
- then try to fetch from nickserver.
-
- :param address: The address bound to the key.
- :type address: str
- :param ktype: The type of the key.
- :type ktype: KeyType
- :param private: Look for a private key instead of a public one?
- :type private: bool
-
- :return: A key of type C{ktype} bound to C{address}.
- :rtype: EncryptionKey
- @raise KeyNotFound: If the key was not found both locally and in
- keyserver.
- """
- leap_assert(
- ktype in self._wrapper_map,
- 'Unkown key type: %s.' % str(ktype))
- try:
- # return key if it exists in local database
- return self._wrapper_map[ktype].get_key(address, private=private)
- except KeyNotFound:
- # we will only try to fetch a key from nickserver if fetch_remote
- # is True and the key is not private.
- if fetch_remote is False or private is True:
- raise
- self._fetch_keys_from_server(address)
- return self._wrapper_map[ktype].get_key(address, private=False)
-
- def get_all_keys_in_local_db(self, private=False):
- """
- Return all keys stored in local database.
-
- :return: A list with all keys in local db.
- :rtype: list
- """
- return map(
- lambda doc: build_key_from_dict(
- self._key_class_from_type(doc.content['type']),
- doc.content['address'],
- doc.content),
- self._soledad.get_from_index(
- TAGS_PRIVATE_INDEX,
- KEYMANAGER_KEY_TAG,
- '1' if private else '0'))
-
- def refresh_keys(self):
- """
- Fetch keys from nickserver and update them locally.
- """
- addresses = set(map(
- lambda doc: doc.address,
- self.get_all_keys_in_local_db(private=False)))
- for address in addresses:
- # do not attempt to refresh our own key
- if address == self._address:
- continue
- self._fetch_keys_from_server(address)
-
- def gen_key(self, ktype):
- """
- Generate a key of type C{ktype} bound to the user's address.
-
- :param ktype: The type of the key.
- :type ktype: KeyType
-
- :return: The generated key.
- :rtype: EncryptionKey
- """
- return self._wrapper_map[ktype].gen_key(self._address)
-
- #
- # Setters/getters
- #
-
- def _get_session_id(self):
- return self._session_id
-
- def _set_session_id(self, session_id):
- self._session_id = session_id
-
- session_id = property(
- _get_session_id, _set_session_id, doc='The session id.')
-
- def _get_ca_cert_path(self):
- return self._ca_cert_path
-
- def _set_ca_cert_path(self, ca_cert_path):
- self._ca_cert_path = ca_cert_path
-
- ca_cert_path = property(
- _get_ca_cert_path, _set_ca_cert_path,
- doc='The path to the CA certificate.')
-
- def _get_api_uri(self):
- return self._api_uri
-
- def _set_api_uri(self, api_uri):
- self._api_uri = api_uri
-
- api_uri = property(
- _get_api_uri, _set_api_uri, doc='The webapp API URI.')
-
- def _get_api_version(self):
- return self._api_version
-
- def _set_api_version(self, api_version):
- self._api_version = api_version
-
- api_version = property(
- _get_api_version, _set_api_version, doc='The webapp API version.')
-
- def _get_uid(self):
- return self._uid
-
- def _set_uid(self, uid):
- self._uid = uid
-
- uid = property(
- _get_uid, _set_uid, doc='The uid of the user.')