示例#1
0
    def decrypt_file(self,
                     input_file,
                     output_file,
                     passphrase=None,
                     verify=True,
                     armor=None):
        """
        Decrypt the ciphertext stored in `input_file` and store the decrypted
        data in `output_file`. The files must be already opened with the correct
        read/write and binary modes.

        Provide a `passphrase` for symmetric decryption.
        """

        with gpg.Data() as ciphertext:
            ciphertext.new_from_fd(input_file)
            with gpg.Data() as plaintext:
                plaintext.new_from_fd(output_file)
                if armor is not None:
                    old_armor = self._gpg.armor
                    self._gpg.armor = armor

                self._decrypt(ciphertext,
                              plaintext,
                              passphrase=passphrase,
                              verify=verify)

                if armor is not None:
                    self._gpg.armor = old_armor
示例#2
0
    def gpg_decrypt(self, message, privkey):
        try:
            # decrypt with GnuPG
            with gpg.Context(
                    armor=True,
                    offline=True,
                    pinentry_mode=gpg.constants.PINENTRY_MODE_LOOPBACK) as c:
                c.set_engine_info(gpg.constants.PROTOCOL_OpenPGP,
                                  home_dir=gnupghome)

                # do we need to import the key?
                try:
                    c.get_key(privkey.fingerprint, True)

                except gpg.errors.KeyNotFound:
                    key_data = gpg.Data(string=str(privkey))
                    gpg.core.gpgme.gpgme_op_import(c.wrapped, key_data)

                pt, _, _ = c.decrypt(gpg.Data(string=str(message)),
                                     verify=False)

            return pt

        except gpg.errors.GPGMEError:
            # if we got here, it's because gpg is screwing with us. The tests seem to pass everywhere except in the buildd.
            # Until I can find a better fix, here's another bypass
            return privkey.decrypt(message).message.encode('utf-8')
示例#3
0
def UIDExport(keydata, uid_i):
    """Export only the UID of a key.
    Unfortunately, GnuPG does not provide smth like
    --export-uid-only in order to obtain a UID and its
    signatures."""
    log.debug("Deletion of UID %r from %r", uid_i, keydata)
    if not uid_i >= 1:
        log.debug("Raising because uid: %r", uid_i)
        raise ValueError("Expected UID to be >= 1, but is %r", uid_i)
    ctx = TempContext()
    ctx.op_import(keydata)
    result = ctx.op_import_result()
    if result.considered != 1 or result.imported != 1:
        raise ValueError("Expected exactly one key in keydata. %r" % result)
    else:
        assert len(result.imports) == 1
        fpr = result.imports[0].fpr
        key = ctx.get_key(fpr)
        uids_to_remove = {i for i in range(1, len(key.uids)+1)}
        uids_to_remove.remove(uid_i)
        if uids_to_remove:
            sink = gpg.Data()
            ctx.interact(key,
                GenEdit(del_uids(uids_to_remove)).edit_cb,
                fnc_value=sink, sink=sink)
            sink.seek(0, 0)
            log.debug("Data after UIDExport: %s", sink.read())
        uid_data = gpg.Data()
        ctx.op_export_keys([key], 0, uid_data)
        uid_data.seek(0, 0)
        uid_bytes = uid_data.read()
        log.debug("UID %r: %r", uid_i, uid_bytes)
        return uid_bytes
示例#4
0
def sign_keydata_and_encrypt(keydata, error_cb=None, homedir=None):
    oldctx = DirectoryContext(homedir)
    ctx = TempContextWithAgent(oldctx)
    # We're trying to sign with all available secret keys
    available_secret_keys = [
        key for key in ctx.keylist(secret=True)
        if not key.disabled or key.revoked or key.invalid or key.expired
    ]
    log.debug('Setting available sec keys to: %r', available_secret_keys)
    ctx.signers = available_secret_keys

    ctx.op_import(minimise_key(keydata))
    result = ctx.op_import_result()
    if result.considered != 1 and result.imported != 1:
        raise ValueError("Expected to load exactly one key. %r", result)
    else:
        imports = result.imports
        assert len(imports) == 1
        fpr = result.imports[0].fpr
        key = ctx.get_key(fpr)
        sink = gpg.Data()
        # There is op_keysign, but it's only available with gpg 2.1.12
        ctx.interact(key,
                     GenEdit(sign_key(error_cb=error_cb)).edit_cb,
                     sink=sink)
        sink.seek(0, 0)
        log.debug("Sink after signing: %r", sink.read())

        signed_sink = gpg.Data()
        ctx.set_keylist_mode(gpg.constants.KEYLIST_MODE_SIGS)
        ctx.armor = True
        ctx.op_export_keys([key], 0, signed_sink)
        signed_sink.seek(0, 0)
        signed_keydata = signed_sink.read()
        log.debug("Signed Key: %s", signed_keydata)
        # Do I have to re-get the key to make the signatures known?
        key = ctx.get_key(fpr)

        for i, uid in enumerate(key.uids, start=1):
            if uid.revoked or uid.invalid:
                continue
            else:
                uid_data = UIDExport(signed_keydata, i)
                # FIXME: Check whether this bug is resolved and the remove this conditional
                # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=884900
                if not crashing_gpgme:
                    log.debug("Data for uid %d: %r, sigs: %r %r", i, uid,
                              uid.signatures, uid_data)

                ciphertext, _, _ = ctx.encrypt(
                    plaintext=uid_data,
                    recipients=[key],
                    # We probably have to set owner trust
                    # in order for it to work out of the box
                    always_trust=True,
                    sign=False)
                yield (UID.from_gpgme(uid), ciphertext)
示例#5
0
    def verify(self):
        self.progressbar.set_fraction(0)
        self.progressbar.set_text(_('Verifying Signature'))
        self.progressbar.show()

        def gui_raise_sigerror(self, sigerror='MissingErr'):
            """
            :type sigerror: str
            """
            sigerror = 'SIGNATURE VERIFICATION FAILED!\n\nError Code: {0}\n\nYou might be under attack, there might' \
                       ' be a network\nproblem, or you may be missing a recently added\nTor Browser verification key.' \
                       '\nClick Start to refresh the keyring and try again. If the message persists report the above' \
                       ' error code here:\nhttps://github.com/micahflee/torbrowser-launcher/issues'.format(sigerror)

            self.set_gui('task', sigerror, ['start_over'], False)
            self.clear_ui()
            self.build_ui()

        if gpgme_support:
            with gpg.Context() as c:
                c.set_engine_info(gpg.constants.protocol.OpenPGP,
                                  home_dir=self.common.paths['gnupg_homedir'])

                sig = gpg.Data(file=self.common.paths['sig_file'])
                signed = gpg.Data(file=self.common.paths['tarball_file'])

                try:
                    c.verify(signature=sig, signed_data=signed)
                except gpg.errors.BadSignatures as e:
                    result = str(e).split(": ")
                    if result[1] == 'Bad signature':
                        gui_raise_sigerror(self, str(e))
                    elif result[1] == 'No public key':
                        self.common.refresh_keyring(result[0])
                        gui_raise_sigerror(self, str(e))
                else:
                    self.run_task()
        else:
            FNULL = open(os.devnull, 'w')
            p = subprocess.Popen([
                '/usr/bin/gpg', '--homedir',
                self.common.paths['gnupg_homedir'], '--verify',
                self.common.paths['sig_file'],
                self.common.paths['tarball_file']
            ],
                                 stdout=FNULL,
                                 stderr=subprocess.STDOUT)
            self.pulse_until_process_exits(p)
            if p.returncode == 0:
                self.run_task()
            else:
                self.common.refresh_keyring()
                gui_raise_sigerror(self, 'GENERIC_VERIFY_FAIL')
                if not reactor.running:
                    reactor.run()
示例#6
0
def can_unseal(args, init_keys):
    # If keys provided and not gpg
    if len(args.get("gpgs", [])) == 0 and len(args.get("keys",[])) > 0:
        return True
    # If keys not provided but init and no gpg
    if len(args.get("gpgs", [])) == 0 and len(init_keys) > 0:
        return True
    # If gpg keys provided and init
    return_value = len(init_keys) > 0
    for k in args.get("gpgs", []):
        if isinstance(k, str):
            k = k.encode()
        with gpg.Context(armor=False) as c:
            c.op_import(gpg.Data(k))
            import_result =  c.op_import_result()
            if not import_result:
                return False
            key_id = c.get_key(import_result.imports[0].fpr)
            try:
                ciphertext, _, _ = c.encrypt(b"_", always_trust=True, sign=False, recipients=[key_id])
                plaintext, _, _ = c.decrypt(ciphertext)
                return_value &= plaintext == b"_"
            except gpg.errors.GPGMEError:
                return False
    return return_value
示例#7
0
    def _encrypt_payload(self, payload, key_ids):
        """Encrypts the payload with the given keys"""
        global legacy_gpg
        payload = encode_string(payload)

        self.gpg.armor = True

        recipient = [self.gpg.get_key(key_id) for key_id in key_ids]

        for key in recipient:
            if key.expired:
                if legacy_gpg:
                    raise gpgme.GpgmeError("Key with user email %s "
                                           "is expired!".format(
                                               key.uids[0].email))
                else:
                    raise gpg.errors.GPGMEError("Key with user email %s "
                                                "is expired!".format(
                                                    key.uids[0].email))

        if legacy_gpg:
            plaintext = BytesIO(payload)
            ciphertext = BytesIO()

            self.gpg.encrypt(recipient, gpgme.ENCRYPT_ALWAYS_TRUST, plaintext,
                             ciphertext)

            return ciphertext.getvalue()
        else:
            (ciphertext, encresult,
             signresult) = self.gpg.encrypt(gpg.Data(string=payload),
                                            recipients=recipient,
                                            sign=False,
                                            always_trust=True)
            return ciphertext
示例#8
0
    def gpg_verify_key(self, key):
        with gpg.Context(offline=True) as c:
            c.set_engine_info(gpg.constants.PROTOCOL_OpenPGP,
                              home_dir=gnupghome)
            data, vres = c.verify(gpg.Data(string=str(key)))

        assert vres
示例#9
0
文件: gpg.py 项目: breezy-team/breezy
    def sign(self, content, mode):
        try:
            import gpg
        except ImportError as error:
            raise GpgNotInstalled(
                'Set create_signatures=no to disable creating signatures.')

        if isinstance(content, str):
            raise errors.BzrBadParameterUnicode('content')

        plain_text = gpg.Data(content)
        try:
            output, result = self.context.sign(
                plain_text,
                mode={
                    MODE_DETACH: gpg.constants.sig.mode.DETACH,
                    MODE_CLEAR: gpg.constants.sig.mode.CLEAR,
                    MODE_NORMAL: gpg.constants.sig.mode.NORMAL,
                }[mode])
        except gpg.errors.GPGMEError as error:
            raise SigningFailed(str(error))
        except gpg.errors.InvalidSigners as error:
            raise SigningFailed(str(error))

        return output
示例#10
0
        def verify(second_try=False):
            with gpg.Context() as c:
                c.set_engine_info(gpg.constants.protocol.OpenPGP,
                                  home_dir=self.common.paths['gnupg_homedir'])

                sig = gpg.Data(file=self.common.paths['sig_file'])
                signed = gpg.Data(file=self.common.paths['tarball_file'])

                try:
                    c.verify(signature=sig, signed_data=signed)
                except gpg.errors.BadSignatures as e:
                    if second_try:
                        self.error.emit(str(e))
                    else:
                        raise Exception
                else:
                    self.success.emit()
示例#11
0
 def gpg_message(msg):
     ret = None
     with gpg.Context(offline=True) as c:
         c.set_engine_info(gpg.constants.PROTOCOL_OpenPGP,
                           home_dir=gnupghome)
         msg, _ = c.verify(gpg.Data(string=str(msg)))
         ret = bytes(msg)
     return ret
示例#12
0
def single_temp_key(random_userid):
    with gpg.Context(armor=True) as gpg_context:
        with gpg.Data() as expkey:
            dmkey = gpg_context.create_key(algorithm="rsa1024",
                                           userid=next(random_userid),
                                           encrypt=True)
            gpg_context.op_export(dmkey.fpr, 0, expkey)
            expkey.seek(0, os.SEEK_SET)
            yield expkey.read()
示例#13
0
 def wrapped(*args, **kwargs):
     with tempfile.TemporaryDirectory() as tmpdir:
         shutil.copytree(context.home_dir,
                         f"{tmpdir}/gnupg",
                         ignore=dirs_files_only)
         kwargs["context"] = gpg.Context(armor=context.armor,
                                         home_dir=f"{tmpdir}/gnupg")
         kwargs["buffer"] = gpg.Data()
         return f(*args, **kwargs)
示例#14
0
def generate_gpg_hvac_vault(gpg_value):
    with gpg.Context(armor=False) as c, gpg.Data() as expkey:
        c.op_import(gpg_value)
        import_result =  c.op_import_result()
        if import_result:
            c.op_export(import_result.imports[0].fpr, 0, expkey)
            expkey.seek(0, os.SEEK_SET)
            return base64.b64encode(expkey.read()).decode()
        else:
            return base64.b64encode(b'').decode()
示例#15
0
    def export_key(self, pattern):
        """
        Export the public key part of the matching the pattern provided in the
        string `pattern`.

        The key is returned as a string.
        """

        with gpg.Data() as export_key:
            self._gpg.op_export(pattern, 0, export_key)
            return self._read_data(export_key)
示例#16
0
    def test_sign_and_encrypt(self):
        # This might be a secret key, too, so we import and export to
        # get hold of the public portion.
        keydata = open(self.key_sender_key, "rb").read()
        # We get the public portion of the key
        sender = TempContext()
        sender.op_import(keydata)
        result = sender.op_import_result()
        fpr = result.imports[0].fpr
        sink = gpg.Data()
        sender.op_export(fpr, 0, sink)
        sink.seek(0, 0)
        # This is the key that we will sign
        public_sender_key = sink.read()

        keys = get_usable_keys(homedir=self.key_sender_homedir)
        assert_equal(1, len(keys))
        key = keys[0]
        uids = key.uidslist
        # Now finally call the function under test
        uid_encrypted = list(sign_keydata_and_encrypt(public_sender_key,
                             error_cb=None, homedir=self.key_receiver_homedir))
        assert_equal(len(uids), len(uid_encrypted))

        # We need to explicitly request signatures
        uids_before = uids
        assert_equal(len(uids_before), len(sender.get_key(fpr).uids))

        sigs_before = [s for l in get_signatures_for_uids_on_key(sender,
                                    key).values() for s in l]
        # FIXME: Refactor this a little bit.
        # We have duplication of code with the other test below.
        for uid, uid_enc in zip(uids_before, uid_encrypted):
            uid_enc_str = uid_enc[0].uid
            # The test doesn't work so well, because comments
            # are not rendered :-/
            # assert_equal(uid, uid_enc[0])
            assert_in(uid.name, uid_enc_str)
            assert_in(uid.email, uid_enc_str)
            ciphertext = uid_enc[1]
            log.debug("Decrypting %r", ciphertext)
            plaintext, result, vrfy = sender.decrypt(ciphertext)
            log.debug("Decrypt Result: %r", result)
            sender.op_import(plaintext)
            import_result = sender.op_import_result()
            log.debug("Import Result: %r", import_result)
            assert_equal(1, import_result.new_signatures)
            updated_key = sender.get_key(fpr)
            log.debug("updated key: %r", updated_key)
            log.debug("updated key sigs: %r", [(uid, uid.signatures) for uid in updated_key.uids])

        sigs_after = [s for l in get_signatures_for_uids_on_key(sender,
                                    key).values() for s in l]
        assert_greater(len(sigs_after), len(sigs_before))
示例#17
0
    def decrypt_text(self, data, passphrase=None, verify=True):
        """
        Decrypt the ciphertext `data`.

        Provide a `passphrase` for symmetric decryption.

        The decrypted data is returned as a string.
        """

        with gpg.Data() as sink:
            self._decrypt(data, sink, passphrase=passphrase, verify=verify)
            return self._read_data(sink)
示例#18
0
def five_temp_key(random_userid):
    keys = []
    with gpg.Context(armor=True) as gpg_context:
        for _ in range(0, 5):
            with gpg.Data() as expkey:
                dmkey = gpg_context.create_key(algorithm="rsa1024",
                                               userid=next(random_userid),
                                               encrypt=True)
                gpg_context.op_export(dmkey.fpr, 0, expkey)
                expkey.seek(0, os.SEEK_SET)
                keys.append(expkey.read())
    yield keys
示例#19
0
    def test_sign_and_encrypt(self):
        secret_keydata = open(self.key_sender_key, "r").read()
        # We get the public portion of the key
        sender = TempContext()
        sender.op_import(secret_keydata)
        result = sender.op_import_result()
        fpr = result.imports[0].fpr
        sink = gpg.Data()
        sender.op_export(fpr, 0, sink)
        sink.seek(0, 0)
        # This is the key that we will sign
        public_sender_key = sink.read()

        keys = get_usable_secret_keys(homedir=self.key_sender_homedir)
        assert_equals(1, len(keys))
        key = keys[0]
        uids = key.uidslist
        # Now finally call the function under test
        uid_encrypted = list(
            sign_keydata_and_encrypt(public_sender_key,
                                     error_cb=None,
                                     homedir=self.key_receiver_homedir))
        assert_equals(len(uids), len(uid_encrypted))

        # We need to explicitly request signatures
        sender.set_keylist_mode(gpg.constants.KEYLIST_MODE_SIGS)
        uids_before = sender.get_key(fpr).uids
        sigs = [uid.signatures for uid in uids_before]
        sigs_before = [sig for signatures in sigs for sig in signatures]
        for uid, uid_enc in zip(uids_before, uid_encrypted):
            # The test doesn't work so well, because comments
            # are not rendered :-/
            # assert_equals(uid, uid_enc[0])
            assert_in(uid.name, uid_enc[0].uid)
            assert_in(uid.email, uid_enc[0].uid)
            ciphertext = uid_enc[1]
            log.debug("Decrypting %r", ciphertext)
            plaintext, result, vrfy = sender.decrypt(ciphertext)
            log.debug("Decrypt Result: %r", result)
            sender.op_import(plaintext)
            import_result = sender.op_import_result()
            log.debug("Import Result: %r", import_result)
            assert_equals(1, import_result.new_signatures)
            updated_key = sender.get_key(fpr)
            log.debug("updated key: %r", updated_key)
            log.debug("updated key sigs: %r",
                      [(uid, uid.signatures) for uid in updated_key.uids])

        uids_after = sender.get_key(fpr).uids
        sigs = [uid.signatures for uid in uids_after]
        sigs_after = [sig for signatures in sigs for sig in signatures]
        assert_greater(len(sigs_after), len(sigs_before))
示例#20
0
    def gpg_verify(self, subject, sig=None, pubkey=None):
        # verify with GnuPG
        with gpg.Context(armor=True, offline=True) as c:
            c.set_engine_info(gpg.constants.PROTOCOL_OpenPGP,
                              home_dir=gnupghome)

            # do we need to import the key?
            if pubkey:
                try:
                    c.get_key(pubkey.fingerprint)

                except gpg.errors.KeyNotFound:
                    key_data = gpg.Data(string=str(pubkey))
                    gpg.core.gpgme.gpgme_op_import(c.wrapped, key_data)

            vargs = [gpg.Data(string=str(subject))]
            if sig is not None:
                vargs += [gpg.Data(string=str(sig))]

            _, vres = c.verify(*vargs)

        assert vres
示例#21
0
    def encrypt_file(self,
                     input_file,
                     output_file,
                     recipients=None,
                     passphrase=None,
                     always_trust=False,
                     armor=None):
        """
        Encrypt the plain text stored in `input_file` for the given `recipients`
        and store the encrypted data in `output_file`. The files must be already
        opened with the correct read/write (and binary) modes. The recipients
        may be a single Key object, a list of Key objects, or `None` to encrypt
        the data symmetrically. Provide a `passphrase` for symmetric encryption.

        If `always_trust` is `True` then keys in the recipients that are not
        explicitly marked as trusted are still allowed.

        If `armor` is not `None` then it overrides the `armor` property set
        upon construction. This may be useful for encrypting binary data on
        a channel that supports non-text data since it reduces the required
        size and network resources.
        """

        with gpg.Data() as plaintext:
            plaintext.new_from_fd(input_file)
            with gpg.Data() as ciphertext:
                ciphertext.new_from_fd(output_file)
                if armor is not None:
                    old_armor = self._gpg.armor
                    self._gpg.armor = armor

                self._encrypt(plaintext,
                              ciphertext,
                              recipients,
                              passphrase,
                              always_trust=always_trust)

                if armor is not None:
                    self._gpg.armor = old_armor
示例#22
0
def get_public_key_data(fpr, homedir=None):
    c = DirectoryContext(homedir)
    c.armor = True
    sink = gpg.Data()
    # FIXME: There will probably be an export() function
    c.op_export(fpr, 0, sink)
    sink.seek(0, os.SEEK_SET)
    keydata = sink.read()
    log.debug("Exported %r: %r", fpr, keydata)
    if not keydata:
        s = "No data to export for {} (in {})".format(fpr, homedir)
        raise ValueError(s)
    return keydata
示例#23
0
def openpgpkey_from_data(keydata):
    c = TempContext()
    c.op_import(gpg.Data(keydata))
    result = c.op_import_result()
    log.debug("Import Result: %s", result)
    if result.imported != 1:
        raise ValueError("Keydata did not contain exactly one key, but %r" %
            result.imported)
    else:
        imported = result.imports
        import_ = imported[0]
        fpr = import_.fpr
        key = c.get_key(fpr)
        return Key.from_gpgme(key)
示例#24
0
def export_public_key(keydata):
    "Returns the public portion of the key even if you provide a private key"
    # This might be a secret key, too, so we import and export to
    # get hold of the public portion.
    ctx = TempContext()
    ctx.op_import(keydata)
    result = ctx.op_import_result()
    fpr = result.imports[0].fpr
    sink = gpg.Data()
    ctx.op_export(fpr, 0, sink)
    sink.seek(0, 0)
    public_key = sink.read()
    assert len(public_key) > 0
    return public_key
示例#25
0
    def encrypt_text(self,
                     data,
                     recipients=None,
                     passphrase=None,
                     always_trust=False):
        """
        Encrypt the plain text `data` for the given `recipients`, which may be
        a single Key object, a list of Key objects, or `None` to encrypt the
        data symmetrically. Provide a `passphrase` for symmetric encryption.

        If `always_trust` is `True` then keys in the recipients that are not
        explicitly marked as trusted are still allowed.

        The encrypted data is returned as a string.
        """

        with gpg.Data(data) as plaintext:
            with gpg.Data() as ciphertext:
                self._encrypt(plaintext,
                              ciphertext,
                              recipients,
                              passphrase,
                              always_trust=always_trust)
                return self._read_data(ciphertext)
示例#26
0
    def encrypt_payload(self, payload, gpg_keys):
        global legacy_gpg
        payload = encode_string(payload)
        self._ctx.armor = True

        if legacy_gpg:
            plaintext = BytesIO(payload)
            ciphertext = BytesIO()
            self._ctx.encrypt(gpg_keys, gpgme.ENCRYPT_ALWAYS_TRUST, plaintext,
                              ciphertext)
            return ciphertext.getvalue()
        else:
            (ciphertext, encresult,
             signresult) = self._ctx.encrypt(gpg.Data(string=payload),
                                             recipients=gpg_keys,
                                             sign=False,
                                             always_trust=True)
            return ciphertext
示例#27
0
def rawkey2infos(key_fo):
    pb_dir = tempfile.mkdtemp()
    keyinfos = []
    with pubring_dir(pb_dir), gpg.Context() as ctx:
        ctx.op_import(key_fo)
        for key in ctx.keylist():
            subkey = _extract_signing_subkey(key)
            if subkey is None:
                continue
            keyinfos.append(Key(key, subkey))
        ctx.armor = True
        for info in keyinfos:
            with gpg.Data() as sink:
                ctx.op_export(info.id_, 0, sink)
                sink.seek(0, os.SEEK_SET)
                info.raw_key = sink.read()
    dnf.util.rm_rf(pb_dir)
    return keyinfos
示例#28
0
    def import_key_and_check_status(self, key):
        """Import a GnuPG key and check that the operation was successful.
        :param str key: A string specifying the key's filepath from
            ``Common.paths``
        :rtype: bool
        :returns: ``True`` if the key is now within the keyring (or was
            previously and hasn't changed). ``False`` otherwise.
        """
        if gpgme_support:
            with gpg.Context() as c:
                c.set_engine_info(gpg.constants.protocol.OpenPGP,
                                  home_dir=self.paths['gnupg_homedir'])

                impkey = self.paths['signing_keys'][key]
                try:
                    c.op_import(gpg.Data(file=impkey))
                except:
                    return False
                else:
                    result = c.op_import_result()
                    if result and self.fingerprints[key] in result.imports[
                            0].fpr:
                        return True
                    else:
                        return False
        else:
            success = False

            p = subprocess.Popen([
                '/usr/bin/gpg', '--status-fd', '2', '--homedir',
                self.paths['gnupg_homedir'], '--import',
                self.paths['signing_keys'][key]
            ],
                                 stderr=subprocess.PIPE)
            p.wait()

            for output in p.stderr.readlines():
                match = gnupg_import_ok_pattern.match(output)
                if match:
                    if match.group().find(self.fingerprints[key]) >= 0:
                        success = True
                        break

            return success
示例#29
0
    def import_key(self, pubkey):
        """
        Import a single public key provided in the string `pubkey`.

        Returns a tuple of the imported key object and the import result object.
        If not exactly one key is provided or imported, then a `ValueError` is
        raised with the import result in its arguments.
        """

        with gpg.Data(pubkey) as import_key:
            self._gpg.op_import(import_key)
            result = self._gpg.op_import_result()

        if result.considered != 1:
            raise ValueError('Exactly one public key must be provided', result)
        if result.imported != 1:
            raise ValueError('Given public key must be valid', result)

        return self._get_imported_key(result), result
示例#30
0
def minimise_key(keydata):
    "Returns the public key exported under the MINIMAL mode"
    ctx = TempContext()
    ctx.op_import(keydata)
    result = ctx.op_import_result()
    if result.considered != 1 and result.imported != 1:
        raise ValueError("Expected to load exactly one key. %r", result)
    else:
        imports = [i for i in result.imports
                   if i.status == gpg.constants.IMPORT_NEW]
        log.debug("Import %r", result)
        assert len(imports) == 1
        fpr = result.imports[0].fpr
        key = ctx.get_key(fpr)
        sink = gpg.Data()
        ctx.op_export_keys([key], gpg.constants.EXPORT_MODE_MINIMAL, sink)
        sink.seek(0, 0)
        minimised_key = sink.read()
        return minimised_key