diff options
Diffstat (limited to 'keymanager/src')
| -rw-r--r-- | keymanager/src/leap/keymanager/errors.py | 12 | ||||
| -rw-r--r-- | keymanager/src/leap/keymanager/openpgp.py | 63 | 
2 files changed, 58 insertions, 17 deletions
| diff --git a/keymanager/src/leap/keymanager/errors.py b/keymanager/src/leap/keymanager/errors.py index 89949d2..27180db 100644 --- a/keymanager/src/leap/keymanager/errors.py +++ b/keymanager/src/leap/keymanager/errors.py @@ -84,3 +84,15 @@ class SignFailed(Exception):      Raised when failed to sign.      """      pass + + +class KeyAddressMismatch(Exception): +    """ +    A mismatch between addresses. +    """ + + +class KeyFingerprintMismatch(Exception): +    """ +    A mismatch between fingerprints. +    """ diff --git a/keymanager/src/leap/keymanager/openpgp.py b/keymanager/src/leap/keymanager/openpgp.py index 1670e1c..78acd6a 100644 --- a/keymanager/src/leap/keymanager/openpgp.py +++ b/keymanager/src/leap/keymanager/openpgp.py @@ -35,7 +35,7 @@ from gnupg import GPG  from gnupg.gnupg import GPGUtilities  from gnupg._util import _make_binary_stream -from leap.common.check import leap_assert, leap_assert_type +from leap.common.check import leap_assert, leap_assert_type, leap_check  from leap.keymanager import errors  from leap.keymanager.keys import (      EncryptionKey, @@ -303,16 +303,22 @@ class OpenPGPScheme(EncryptionScheme):              raise errors.KeyNotFound(address)          return build_key_from_dict(OpenPGPKey, address, doc.content) -    def put_ascii_key(self, key_data): +    def parse_ascii_key(self, key_data):          """ -        Put key contained in ascii-armored C{key_data} in local storage. +        Parses an ascii armored key (or key pair) data and returns +        the OpenPGPKey keys. -        :param key_data: The key data to be stored. +        :param key_data: the key data to be parsed.          :type key_data: str or unicode + +        :returns: the public key and private key (if applies) for that data. +        :rtype: (public, private) -> tuple(OpenPGPKey, OpenPGPKey) +                the tuple may have one or both components None          """          leap_assert_type(key_data, (str, unicode))          # TODO: add more checks for correct key data.          leap_assert(key_data is not None, 'Data does not represent a key.') +        mail_regex = '.*<([\w.-]+@[\w.-]+)>.*'          with self._temporary_gpgwrapper() as gpg:              # TODO: inspect result, or use decorator @@ -325,31 +331,54 @@ class OpenPGPScheme(EncryptionScheme):              except IndexError:                  pass              pubkey = gpg.list_keys(secret=False).pop()  # unitary keyring +              # extract adress from first uid on key -            match = re.match('.*<([\w.-]+@[\w.-]+)>.*', pubkey['uids'].pop()) +            match = re.match(mail_regex, pubkey['uids'].pop())              leap_assert(match is not None, 'No user address in key data.')              address = match.group(1) +              if privkey is not None: -                match = re.match( -                    '.*<([\w.-]+@[\w.-]+)>.*', privkey['uids'].pop()) +                match = re.match(mail_regex, privkey['uids'].pop())                  leap_assert(match is not None, 'No user address in key data.')                  privaddress = match.group(1) -                leap_assert( -                    address == privaddress, -                    'Addresses in pub and priv key differ.') -                leap_assert( -                    pubkey['fingerprint'] == privkey['fingerprint'], -                    'Fingerprints for pub and priv key differ.') -                # insert private key in storage + +                # build private key                  openpgp_privkey = _build_key_from_gpg( -                    address, privkey, +                    privaddress, privkey,                      gpg.export_keys(privkey['fingerprint'], secret=True)) -                self.put_key(openpgp_privkey) -            # insert public key in storage + +                leap_check(address == privaddress, +                           'Addresses in public and private key differ.', +                           errors.KeyAddressMismatch) +                leap_check(pubkey['fingerprint'] == privkey['fingerprint'], +                           'Fingerprints for public and private key differ.', +                           errors.KeyFingerprintMismatch) + +            # build public key              openpgp_pubkey = _build_key_from_gpg(                  address, pubkey,                  gpg.export_keys(pubkey['fingerprint'], secret=False)) + +            return (openpgp_pubkey, openpgp_privkey) + +    def put_ascii_key(self, key_data): +        """ +        Put key contained in ascii-armored C{key_data} in local storage. + +        :param key_data: The key data to be stored. +        :type key_data: str or unicode +        """ +        leap_assert_type(key_data, (str, unicode)) + +        try: +            openpgp_pubkey, openpgp_privkey = self.parse_ascii_key(key_data) +        except (errors.KeyAddressMismatch, errors.KeyFingerprintMismatch) as e: +            leap_assert(False, repr(e)) + +        if openpgp_pubkey is not None:              self.put_key(openpgp_pubkey) +        if openpgp_privkey is not None: +            self.put_key(openpgp_privkey)      def put_key(self, key):          """ | 
