Skip to content
This repository has been archived by the owner on Jan 2, 2020. It is now read-only.

PyGPGME-based library #47

Open
wants to merge 106 commits into
base: master
Choose a base branch
from

Conversation

andreimacavei
Copy link

The work I've did for the new GPG library

…__master-muelli

Conflicts:
	keysign/Keyserver.py
	keysign/MainWindow.py
	keysign/Sections.py
The gpg.py file contains some use cases of monkeysign gpg wrapper that we need to replace with pygpgme.
We need to gradually replace all functionality of monkeysign' gpg wrapper. In example.py you can find a basic use of pygpgme to encrypt a file, taken from the original pygpgme repository.
I have set up a simple scenario to test current and future replacement functions for the old monkeysign gpg wrapper. Also added a sample keys/key1.pub key.
I am still now sure how to do the transition from monekeysign' gpg wrapper to pygpgme. There are so many calls to gpg from almost every class in Section.py, SignPages.py modules, and many are using the monkeysign.gpg.Keyring class methods or monkeysign.gpg.Context.
For now, I have moved the gpgme implementation from gpg.py to examply.py file.
There is still work to be done to separate the gpg calls from whithin core classes in Sections.py.
For now, only Sections.py module interacts with gpg through gpg.py file.
We now import a GetNewKeyring function from gpg.py module.
… key2.

Most of the functionality that we need for gpg interraction is demonstrated through the functions in example.py. Now all is left implement the actual needed functions that are in gpg.py module.
We are calling UIDExport from GetKeySection.sign_key_async method and we do that for every UID of a key that we want to sign. Therefore , for each UID, the call to UIDExport does the following:
 * imports the key into a temp keyring
 * removes all other UIDs except the current one passed
 * returns the exported keydata with the UIDs removed
This is how we sign all UIDs and email back the key with its corresponding UID.
Unfortunately PyGPGME API doesn't seem to offer an easy way to delete an UID (or I don't know yet) so for know we don't use the UIDExport_gpgme implementation.
It seems that gpgme.Context.import_ call can throw a gpgm.GpgmeError when the data to import is not keydata.
The gpg API can change again in the future depending on how we'll replace the current gpg wrapper.
Removed unnecesary asserts from UIDExport_gpgm.
This replaces the keyring functionalities offered by Keyring class.
Most of the functionalities of a keyring is done in gpgme.Context class in PyGPGME.
This is good because it removes a layer of abstraction.
It does that by passing a context (gpgme.Context) which should contain the desired key.
It does that by calling import_key_to_tmp for each secret key found for user.
This needs more testing because because gpgme doesn't have a way to set additional argument '--homedir' but instead relies to where 'GNUPGHOME' points to.
muelli and others added 6 commits September 4, 2015 09:57
For now, the keylist seems to be empty. So we print the contents out.
We could not sign anyones key, because the downloaded key was deleted
too early.  Now, we don't delete the key so that we can sign it.  I
added a FIXME to think about removing the directory later.
Not hard code the number. It was 0 and 1 for me, so the test failed.
I think that if we are asserting that we have more signatures after
signing than before, we're good to go.
fixed non-working signing of other keys
@@ -406,7 +309,8 @@ def download_key_http(self, address, port):
params='',
query='',
fragment='')
return requests.get(url.geturl()).text
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the encode? I think you can access the raw bytes of the response via the content property.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to return bytes through the content field (commit 67195f2)

If set to True the function will return expired keys also,
else it won't. This is how we can implement the check for
expiration, because the gpgme module that we use doesn't recognize
the expired keys (aka the key.expired is always set to False).

Also, the 'expiration date' can only be retrieved from the
key.subkeys[0].expires field ... wierdly!
@@ -116,12 +117,18 @@ def gpg_import_keydata(gpgmeContext, keydata):
return result


def gpg_get_keylist(gpgmeContext, keyid=None, secret=False):
def gpg_get_keylist(gpgmeContext, keyid=None, secret=False, expired=False):
"""Returns the keys found in @gpgmeContext
If @keyid is None then all geys will be returned.
If @secret=True then it will return the secret keys.
"""
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very good so far!
can we have the expired attribute documented, too? :o)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks :-) , I've fixed it with this commit 32902ae .
The documentation needs more work though

The gpg module is instended to be imported and used as a namespace
for calling the module functions, that's why it is unnecessary
to have a gpg_ prefix.
imported_key_fpr = self.tmpkeyring.get_keys().keys()[0]
res = gpg.import_keydata(self.ctx, downloaded_data)
if res and len(res.imports):
(imported_key_fpr, null, null) = res.imports[0]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this I don't like.
If, in the future, res.imports[0] will return something else than a three-tuple, this will break.
Would smth like imported_key_fprv = res.imports[0][0] do?

Copy link
Author

@andreimacavei andreimacavei Jun 2, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in andreimacavei@faa997c where I'm getting the first element of the result tuple.
I woould like to create a lib/util function that we receives an import result and returns the fingerprint...something like get_fpr_from_import_result . This way, in the future the result will change, we can only modify the code in one place.

The function `get_personal_keys` will return the personal keys from
User's defaul keyring. It can return the secret part or the public part
of the key. More logic (for key validaiton) can be done at the caller.

This commit also fixes issue #16.
The get_keylist lib function will now receive a `pair` argument.
This is used to differentiate between public keys that are
imported from other users/keyrings, and public keys that have
a secret part existent inside that keyring.
This separates the logic between importing and exporting private
keys.
The `export_secret_keys` function will return a string with all the
private keys found in the current gpg homedir. This is usefull for
when we want to sign a key, and we need to import our secret key
into a temporary keyring.
return public_keys

def get_personal_keys(keyid=None, secret=False):
"""Returns the personal keys found in User's own keyring.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's a "personal" key?

What's the difference to get_keylist?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a key more "personal" than other keys :-).
I may have thought about a key that the user has generated, such as a key for which he owns the private part.
You're right, the get_keylist function can replace this if the gpgmeContext ,received as arg, represents the User's default keyring (not a temporary keyring set by the app itself).

@muelli
Copy link
Owner

muelli commented Dec 6, 2016

FWIW: There is a gpgmeh branch right now which looks like something I might merge.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants