Пример #1
0
def get_public_key_data(fpr, keyring=None):
    """Returns keydata for a given fingerprint

    In fact, fpr could be anything that gpg happily exports.
    """
    if not keyring:
        keyring = Keyring()
    keydata = keyring.export_data(fpr)
    return keydata
Пример #2
0
def get_public_key_data(fpr, homedir=None):
    """Returns keydata for a given fingerprint
    
    In fact, fpr could be anything that gpg happily exports.
    """
    keyring = Keyring(homedir=homedir)
    keydata = keyring.export_data(fpr)
    if not keydata:
        s = "No data to export for {} (in {})".format(fpr, homedir)
        raise ValueError(s)
    return keydata
Пример #3
0
def get_public_key_data(fpr, homedir=None):
    """Returns keydata for a given fingerprint
    
    In fact, fpr could be anything that gpg happily exports.
    """
    keyring = Keyring(homedir=homedir)
    keydata = keyring.export_data(fpr)
    if not keydata:
        s = "No data to export for {} (in {})".format(fpr, homedir)
        raise ValueError(s)
    return keydata
Пример #4
0
    def __init__(self, base_keyring=None, *args, **kwargs):
        # Not a new style class...
        if issubclass(self.__class__, object):
            super(TempSigningKeyring, self).__init__(*args, **kwargs)
        else:
            TempKeyring.__init__(self, *args, **kwargs)

        if base_keyring is None:
            base_keyring = Keyring()
        # Copy the public parts of the secret keys to the tmpkeyring
        for fpr, key in base_keyring.get_keys(None, secret=True,
                                              public=False).items():
            self.import_data(base_keyring.export_data(fpr))
Пример #5
0
    def __init__(self, base_keyring=None, *args, **kwargs):
        # Not a new style class...
        if issubclass(self.__class__, object):
            super(TempSigningKeyring, self).__init__(*args, **kwargs)
        else:
            TempSplitKeyring.__init__(self, *args, **kwargs)

        if base_keyring is None:
            base_keyring = Keyring()

        # Copy the public parts of the secret keys to the tmpkeyring
        for fpr, key in base_keyring.get_keys(None,
                                              secret=True,
                                              public=False).items():
            self.import_data (base_keyring.export_data (fpr))
Пример #6
0
class KeySignSection(Gtk.VBox):
    def __init__(self):
        '''Initialises the section which lets the user
        choose a key to be signed by other person.
        '''
        super(KeySignSection, self).__init__()

        self.log = logging.getLogger(__name__)
        self.keyring = Keyring()

        # these are needed later when we need to get details about
        # a selected key
        self.keysPage = KeysPage()
        self.keysPage.connect('key-selection-changed',
                              self.on_key_selection_changed)
        self.keysPage.connect('key-selected', self.on_key_selected)
        self.keyDetailsPage = KeyDetailsPage()
        self.keyPresentPage = KeyPresentPage()

        # create back button
        self.backButton = Gtk.Button('Back')
        self.backButton.set_image(
            Gtk.Image.new_from_icon_name("go-previous", Gtk.IconSize.BUTTON))
        self.backButton.set_always_show_image(True)
        self.backButton.connect('clicked', self.on_button_clicked)

        # set up notebook container
        self.notebook = Gtk.Notebook()
        self.notebook.append_page(self.keysPage, None)
        vbox = Gtk.VBox()
        # We place the button at the top, but that might not be the
        # smartest thing to do. Feel free to rearrange
        # FIXME: Consider a GtkHeaderBar for the application
        vbox.pack_start(self.backButton, False, False, 0)
        vbox.pack_start(self.keyPresentPage, True, True, 10)
        self.notebook.append_page(vbox, None)
        self.notebook.set_show_tabs(False)

        self.pack_start(self.notebook, True, True, 0)

        # this will hold a reference to the last key selected
        self.last_selected_key = None

        # When obtaining a key is successful,
        # it will save the key data in this field
        self.received_key_data = None

        self.keyserver = None

    def on_key_selection_changed(self, pane, keyid):
        '''This callback is attached to the signal which is emitted
        when the user changes their selection in the list of keys
        '''
        pass

    def on_key_selected(self, pane, keyid):
        '''This is the callback for when the user has committed
        to a key, i.e. the user has made a selection and wants to
        advance the program.
        '''
        log.debug('User selected key %s', keyid)

        key = list(self.keyring.get_keys(keyid).values())[0]

        keyid = key.keyid()
        fpr = key.fpr
        self.keyring.export_data(fpr, secret=False)
        keydata = self.keyring.context.stdout

        self.log.debug("Keyserver switched on! Serving key with fpr: %s", fpr)
        self.setup_server(keydata, fpr)

        self.switch_to_key_present_page(key)

    def switch_to_key_present_page(self, key):
        '''This switches the notebook to the page which
        presents the information that is needed to securely
        transfer the keydata, i.e. the fingerprint and its barcode.
        '''
        self.keyPresentPage.display_fingerprint_qr_page(key)
        self.notebook.next_page()
        # This is more of a crude hack. Once the next page is presented,
        # the back button has the focus. This is not desirable because
        # you will go back when accidentally pressing space or enter.
        self.keyPresentPage.fingerprintLabel.grab_focus()
        # FIXME: we better use set_current_page, but that requires
        # knowing which page our desired widget is on.
        # FWIW: A headerbar has named pages.

    def on_next_button_clicked(self, button):
        '''A helper for legacy reasons to enable a next button
        
        All it does is retrieve the selection from the TreeView and
        call the signal handler for when the user committed to a key
        '''
        name, email, keyid = self.keysPage.get_items_from_selection()
        return self.on_key_selected(button, keyid)

    def on_button_clicked(self, button):

        page_index = self.notebook.get_current_page()

        if button == self.backButton:

            if page_index == 1:
                self.log.debug("Keyserver switched off")
                self.stop_server()

            self.notebook.prev_page()

    def setup_server(self, keydata, fingerprint):
        """
        Starts the key-server which serves the provided keydata and
        announces the fingerprint as TXT record using Avahi
        """
        self.log.info('Serving now')
        self.log.debug('About to call %r', Keyserver.ServeKeyThread)
        self.keyserver = Keyserver.ServeKeyThread(str(keydata), fingerprint)
        self.log.info('Starting thread %r', self.keyserver)
        self.keyserver.start()
        self.log.info('Finsihed serving')
        return False

    def stop_server(self):
        self.keyserver.shutdown()
Пример #7
0
    def sign_key_async(self, fingerprint=None, callback=None, data=None, error_cb=None):
        self.log.debug("I will sign key with fpr {}".format(fingerprint))

        keyring = Keyring()
        keyring.context.set_option('export-options', 'export-minimal')

        tmpkeyring = TempSigningKeyring(keyring)
        # Eventually, we want to let the user select their keys to sign with
        # For now, we just take whatever is there.
        secret_keys = get_usable_secret_keys(tmpkeyring)
        self.log.info('Signing with these keys: %s', secret_keys)

        keydata = data or self.received_key_data
        if keydata:
            stripped_key = MinimalExport(keydata)
            fpr = fingerprint_for_key(stripped_key)
            if fingerprint is None:
                # The user hasn't provided any data to operate on
                fingerprint = fpr

            if not fingerprint == fpr:
                self.log.warning('Something strange is going on. '
                    'We wanted to sign fingerprint "%s", received '
                    'keydata to operate on, but the key has fpr "%s".',
                    fingerprint, fpr)
                
        else: # Do we need this branch at all?
            if fingerprint is None:
                raise ValueError('You need to provide either keydata or a fpr')
            self.log.debug("looking for key %s in your keyring", fingerprint)
            keyring.context.set_option('export-options', 'export-minimal')
            stripped_key = keyring.export_data(fingerprint)

        self.log.debug('Trying to import key\n%s', stripped_key)
        if tmpkeyring.import_data(stripped_key):
            # 3. for every user id (or all, if -a is specified)
            # 3.1. sign the uid, using gpg-agent
            keys = tmpkeyring.get_keys(fingerprint)
            self.log.info("Found keys %s for fp %s", keys, fingerprint)
            assert len(keys) == 1, "We received multiple keys for fp %s: %s" % (fingerprint, keys)
            key = keys[fingerprint]
            uidlist = key.uidslist
            
            for secret_key in secret_keys:
                secret_fpr = secret_key.fpr
                self.log.info('Setting up to sign with %s', secret_fpr)
                # We need to --always-trust, because GnuPG would print
                # warning about the trustdb.  I think this is because
                # we have a newly signed key whose trust GnuPG wants to
                # incorporate into the trust decision.
                tmpkeyring.context.set_option('always-trust')
                tmpkeyring.context.set_option('local-user', secret_fpr)
                # FIXME: For now, we sign all UIDs. This is bad.
                ret = tmpkeyring.sign_key(uidlist[0].uid, signall=True)
                self.log.info("Result of signing %s on key %s: %s", uidlist[0].uid, fingerprint, ret)


            for uid in uidlist:
                uid_str = uid.uid
                self.log.info("Processing uid %s %s", uid, uid_str)

                # 3.2. export and encrypt the signature
                # 3.3. mail the key to the user
                signed_key = UIDExport(uid_str, tmpkeyring.export_data(uid_str))
                self.log.info("Exported %d bytes of signed key", len(signed_key))
                # self.signui.tmpkeyring.context.set_option('armor')
                tmpkeyring.context.set_option('always-trust')
                encrypted_key = tmpkeyring.encrypt_data(data=signed_key, recipient=uid_str)

                keyid = str(key.keyid())
                ctx = {
                    'uid' : uid_str,
                    'fingerprint': fingerprint,
                    'keyid': keyid,
                }
                # We could try to dir=tmpkeyring.dir
                # We do not use the with ... as construct as the
                # tempfile might be deleted before the MUA had the chance
                # to get hold of it.
                # Hence we reference the tmpfile and hope that it will be properly
                # cleaned up when this object will be destroyed...
                tmpfile = NamedTemporaryFile(prefix='gnome-keysign-', suffix='.asc')
                self.tmpfiles.append(tmpfile)
                filename = tmpfile.name
                self.log.info('Writing keydata to %s', filename)
                tmpfile.write(encrypted_key)
                # Interesting, sometimes it would not write the whole thing out,
                # so we better flush here
                tmpfile.flush()
                # As we're done with the file, we close it.
                #tmpfile.close()

                subject = Template(SUBJECT).safe_substitute(ctx)
                body = Template(BODY).safe_substitute(ctx)
                self.email_file (to=uid_str, subject=subject,
                                 body=body, files=[filename])


            # FIXME: Can we get rid of self.tmpfiles here already? Even if the MUA is still running?


            # 3.4. optionnally (-l), create a local signature and import in
            # local keyring
            # 4. trash the temporary keyring


        else:
            self.log.error('data found in barcode does not match a OpenPGP fingerprint pattern: %s', fingerprint)
            if error_cb:
                GLib.idle_add(error_cb, data)

        return False
Пример #8
0
    def sign_key_async(self, fingerprint=None, callback=None, data=None, error_cb=None):
        self.log.debug("I will sign key with fpr {}".format(fingerprint))

        keyring = Keyring()
        keyring.context.set_option('export-options', 'export-minimal')

        tmpkeyring = TempSigningKeyring(keyring)
        # Eventually, we want to let the user select their keys to sign with
        # For now, we just take whatever is there.
        secret_keys = get_usable_secret_keys(tmpkeyring)
        self.log.info('Signing with these keys: %s', secret_keys)

        keydata = data or self.received_key_data
        if keydata:
            stripped_key = MinimalExport(keydata)
            fpr = fingerprint_for_key(stripped_key)
            if fingerprint is None:
                # The user hasn't provided any data to operate on
                fingerprint = fpr

            if not fingerprint == fpr:
                self.log.warning('Something strange is going on. '
                    'We wanted to sign fingerprint "%s", received '
                    'keydata to operate on, but the key has fpr "%s".',
                    fingerprint, fpr)
                
        else: # Do we need this branch at all?
            if fingerprint is None:
                raise ValueError('You need to provide either keydata or a fpr')
            self.log.debug("looking for key %s in your keyring", fingerprint)
            keyring.context.set_option('export-options', 'export-minimal')
            stripped_key = keyring.export_data(fingerprint)

        self.log.debug('Trying to import key\n%s', stripped_key)
        if tmpkeyring.import_data(stripped_key):
            # 3. for every user id (or all, if -a is specified)
            # 3.1. sign the uid, using gpg-agent
            keys = tmpkeyring.get_keys(fingerprint)
            self.log.info("Found keys %s for fp %s", keys, fingerprint)
            assert len(keys) == 1, "We received multiple keys for fp %s: %s" % (fingerprint, keys)
            key = keys[fingerprint]
            uidlist = key.uidslist
            
            for secret_key in secret_keys:
                secret_fpr = secret_key.fpr
                self.log.info('Setting up to sign with %s', secret_fpr)
                # We need to --always-trust, because GnuPG would print
                # warning about the trustdb.  I think this is because
                # we have a newly signed key whose trust GnuPG wants to
                # incorporate into the trust decision.
                tmpkeyring.context.set_option('always-trust')
                tmpkeyring.context.set_option('local-user', secret_fpr)
                # FIXME: For now, we sign all UIDs. This is bad.
                ret = tmpkeyring.sign_key(uidlist[0].uid, signall=True)
                self.log.info("Result of signing %s on key %s: %s", uidlist[0].uid, fingerprint, ret)


            for uid in uidlist:
                uid_str = uid.uid
                self.log.info("Processing uid %s %s", uid, uid_str)

                # 3.2. export and encrypt the signature
                # 3.3. mail the key to the user
                signed_key = UIDExport(uid_str, tmpkeyring.export_data(uid_str))
                self.log.info("Exported %d bytes of signed key", len(signed_key))
                # self.signui.tmpkeyring.context.set_option('armor')
                tmpkeyring.context.set_option('always-trust')
                encrypted_key = tmpkeyring.encrypt_data(data=signed_key, recipient=uid_str)

                keyid = str(key.keyid())
                ctx = {
                    'uid' : uid_str,
                    'fingerprint': fingerprint,
                    'keyid': keyid,
                }
                # We could try to dir=tmpkeyring.dir
                # We do not use the with ... as construct as the
                # tempfile might be deleted before the MUA had the chance
                # to get hold of it.
                # Hence we reference the tmpfile and hope that it will be properly
                # cleaned up when this object will be destroyed...
                tmpfile = NamedTemporaryFile(prefix='gnome-keysign-', suffix='.asc')
                self.tmpfiles.append(tmpfile)
                filename = tmpfile.name
                self.log.info('Writing keydata to %s', filename)
                tmpfile.write(encrypted_key)
                # Interesting, sometimes it would not write the whole thing out,
                # so we better flush here
                tmpfile.flush()
                # As we're done with the file, we close it.
                #tmpfile.close()

                subject = Template(SUBJECT).safe_substitute(ctx)
                body = Template(BODY).safe_substitute(ctx)
                self.email_file (to=uid_str, subject=subject,
                                 body=body, files=[filename])


            # FIXME: Can we get rid of self.tmpfiles here already? Even if the MUA is still running?


            # 3.4. optionnally (-l), create a local signature and import in
            # local keyring
            # 4. trash the temporary keyring


        else:
            self.log.error('data found in barcode does not match a OpenPGP fingerprint pattern: %s', fingerprint)
            if error_cb:
                GLib.idle_add(error_cb, data)

        return False