Mailing List Archive

GPGME python bindings query
Hi,

I want to generate revocation certificate for a key using GPGME python
bindings.
I couldn't find example/docs which explain this. Can someone suggest a way
to do so.
I am not sure if there is a way, I tried to achieve this by the
gpg.Context().interact functionality but couldn't find appropriate commands
for certificate generation.

Thanks and Regards

Divesh Uttamchandani
GitHub <https://github.com/diveshuttam> | Linkedin
<https://www.linkedin.com/in/diveshuttam/> | University Profile
<http://www.bits-pilani.ac.in/spp/f2016045>
Re: GPGME python bindings query [ In reply to ]
On Sun, Jul 08, 2018 at 09:52:23AM +0530, Divesh Uttamchandani wrote:
> Hi,
>
> I want to generate revocation certificate for a key using GPGME
> python bindings.

The only way that GPGME can directly generate a revocation certificate
is when one is automatically generated using GnuPG 2.1 or above (you
should already be on 2.2 now anyway). This is no different from
running either the "gpg --gen-key" or "gpg --full-gen-key" commands
and the revocation certificate is generated at the same time as the
key itself is.

You can, however, revoke user IDs with GPGME and there is an example
of that in the later sections of the Python Bindings HOWTO. It's in
the sections using this guy for the example instead of Alice or Bob:

http://web1.east1.us.adversary.org/wp/wp-content/uploads/2018/07/danger-mouse-20180709-01.jpg

> I couldn't find example/docs which explain this. Can someone suggest a way
> to do so.

No. Some things are intended to be done manually and revoking an
entire key is one of them. If it must be automated then current key
generation will produce a revocation certificate by default and the
solution would be to apply that to a key store and/or any relevant
distribution channel (e.g. uploading it to the keyservers).

> I am not sure if there is a way, I tried to achieve this by the
> gpg.Context().interact functionality but couldn't find appropriate
> commands for certificate generation.

The gpg.Context().interact function is not intended for interacting
with all keys in the same way you might use "gpg --edit-key", it's
intended for interacting with cards and tokens which store secret key
material.

While there are some low level functions present which were necessary
for GPGME, and consequently the bindings to it, to do what it does,
these functions are not intended to be used directly and are not
documented as a result. These are functions which are actually
*lower* level than the gpgme_op_* functions.

In your case since this is an exploratory project for GSoC, the best
approach is that if something you're trying to do is both not
immediately apparent and if it were to be performed manually on the
command line would produce a whole bunch of warnings to the user to
confirm that they're sure and if they really want to do whatever it
is; then chances are good that not only is there no way to automate
it, but we will also advise against trying to do so by circumventing
those warnings.

In anticipation of the inevitable question, there's also no function
for deleting UIDs or subkeys in GPGME. Normally the window of
opportunity for doing anything like that is very narrow and it would
be expected to be performed manually and not automated. Instead one
would revoke any UID which is no longer valid and there's plenty of
examples of that on keys currently in use. Indeed, I've got one on
mine right now (it's the fourth one). The following code will display
it on any key interactively:

c = gpg.Context()
fpr = input("Enter key ID or fingerprint: ")
key = c.get_key(fpr, secret=False)
for i in range(len(key.uids)):
if key.uids[i].revoked == 1:
print(key.uids[i].uid)
else:
pass


Regards,
Ben
Re: GPGME python bindings query [ In reply to ]
On 07/09/2018 03:42 AM, Ben McGinnes wrote:
> On Sun, Jul 08, 2018 at 09:52:23AM +0530, Divesh Uttamchandani wrote:
>> Hi,
>>
>> I want to generate revocation certificate for a key using GPGME
>> python bindings.
>
> The only way that GPGME can directly generate a revocation certificate
> is when one is automatically generated using GnuPG 2.1 or above (you
> should already be on 2.2 now anyway). This is no different from
> running either the "gpg --gen-key" or "gpg --full-gen-key" commands
> and the revocation certificate is generated at the same time as the
> key itself is.
>
> You can, however, revoke user IDs with GPGME and there is an example
> of that in the later sections of the Python Bindings HOWTO. It's in
> the sections using this guy for the example instead of Alice or Bob:
>
> http://web1.east1.us.adversary.org/wp/wp-content/uploads/2018/07/danger-mouse-20180709-01.jpg
>
>> I couldn't find example/docs which explain this. Can someone suggest a way
>> to do so.
>
> No. Some things are intended to be done manually and revoking an
> entire key is one of them. If it must be automated then current key
> generation will produce a revocation certificate by default and the
> solution would be to apply that to a key store and/or any relevant
> distribution channel (e.g. uploading it to the keyservers).

I'm actually manually generating a GPG revocation certificate in my own
project (by calling gpg from subprocess). I know I shouldn't be doing
this, but I didn't see another way (and based on the above there isn't
one).

I would prefer to use the automatically generated certificate as it also
comes with some useful explanation text, but the problem I'm having is
that there is no way to trigger this generation from GPGME and it
appears to happen whenever you generate your first subkey (or perhaps
your first signing subkey, haven't dug that much into it). I'd like to
inform the user every time they will be prompted for their password and
a random extra password prompt for the revocation certificate that I
can't control doesn't really help there. If there's some way I could
manually trigger this process that would be great.


> In your case since this is an exploratory project for GSoC, the best
> approach is that if something you're trying to do is both not
> immediately apparent and if it were to be performed manually on the
> command line would produce a whole bunch of warnings to the user to
> confirm that they're sure and if they really want to do whatever it
> is; then chances are good that not only is there no way to automate
> it, but we will also advise against trying to do so by circumventing
> those warnings.

I definitely need to keep this in mind.

Thanks,
Jacob
Re: GPGME python bindings query [ In reply to ]
On Tue, Jul 10, 2018 at 01:01:10PM -0400, Jacob Adams wrote:
> On 07/09/2018 03:42 AM, Ben McGinnes wrote:
>> On Sun, Jul 08, 2018 at 09:52:23AM +0530, Divesh Uttamchandani wrote:
>>
>>> I couldn't find example/docs which explain this. Can someone
>>> suggest a way to do so.
>>
>> No. Some things are intended to be done manually and revoking an
>> entire key is one of them. If it must be automated then current key
>> generation will produce a revocation certificate by default and the
>> solution would be to apply that to a key store and/or any relevant
>> distribution channel (e.g. uploading it to the keyservers).
>
> I'm actually manually generating a GPG revocation certificate in my
> own project (by calling gpg from subprocess). I know I shouldn't be
> doing this,

It's a good thing you said that.

> but I didn't see another way (and based on the above there isn't
> one).

Correct.

> I would prefer to use the automatically generated certificate as it
> also comes with some useful explanation text, but the problem I'm
> having is that there is no way to trigger this generation from GPGME
> and it appears to happen whenever you generate your first subkey (or
> perhaps your first signing subkey, haven't dug that much into it).

It's generated with the certification key and this comment indicates
there may be a little misunderstanding about the revocation
certificate. It's used to revoke an entire key, including subkeys and
it does this by the simple expedient of revoking the certification
key. Once the certification key is revoked, the certification
signatures can't be validated without throwing the disabled key errors
which prevent the subkeys from being used.

So even if subkeys are added later, there are no additional revocation
certificates generated for the subkeys. Which is why you'll find .rev
files in $GNUPGHOME/openpgp-revocs.d/ directory matching the
fingerprint of the primary key, but nothing for the subkeys; while the
$GNUPGHOME/private-keys-v1.d/ is populated with multiple .key files
matching the keygrips for all the keys and subkeys generated.

> I'd like to inform the user every time they will be prompted for
> their password

Fair enough, it's good practice to get them used to the idea of it
being necessary and reiterating the importance of it without laying it
on too thickly.

> and a random extra password prompt

There are no random extra password prompts, they're all necessary for
a secure system.

> for the revocation certificate that I can't control doesn't really
> help there. If there's some way I could manually trigger this
> process that would be great.

It should have already occurred when the key was first generated. The
only time it needs to be done manually is when issuing a specific
revocation certificate with a less generic revocation reason or if the
key was generated with an older version of GPG that did not generate
such a certificate by default.

>> In your case since this is an exploratory project for GSoC, the
>> best approach is that if something you're trying to do is both not
>> immediately apparent and if it were to be performed manually on the
>> command line would produce a whole bunch of warnings to the user to
>> confirm that they're sure and if they really want to do whatever it
>> is; then chances are good that not only is there no way to automate
>> it, but we will also advise against trying to do so by
>> circumventing those warnings.
>
> I definitely need to keep this in mind.

Not just you, a lot of people should; the warnings are there for valid
reasons and we saw recently with the EFFail situation what happens
when MUAs ignore warnings and errors.


Regards,
Ben