Re: Showing signatures for exported/unimported keys using the Python GPGME bindings

Paul Boddie via Gnupg-devel <[email protected]>
Newsgroups gmane.comp.encryption.gpg.devel
Message-ID <2734939.Fbvv65RQBL@jason>
On Friday, 23 August 2024 10:11:45 CEST Werner Koch wrote:
> 
> you might have noticed that we don't have a real maintainer for the
> Python bindings anymore.  The last maintainer did a lot on the
> documentation front but less on the actual inner workings.

Thanks for the reply! I didn't notice, unfortunately. I did find a discussion 
from a few years back where two competing sets of bindings were discussed, one 
using SWIG and one being constructed using the Python C API directly:

https://lists.gnupg.org/pipermail/gnupg-devel/2016-May/031156.html

> Instead of having used the convient SWIG based bindings we should have
> done a manual binding to make sure that we have a stable API (and less
> compiler warning ;-).  It is more work of course but counting in all the
> problems and the endless hours of fixing stuff this would have been
> better in the end.

I haven't done library binding work for Python in many years, so I can't 
comment on whether SWIG is the most appropriate tool. I suppose there is 
always the hope that a tool can automate the wrapping of the underlying 
library entirely, even if the result is still fairly low-level. I would have 
to reacquaint myself with the current selection of tools to see if that ever 
became remotely feasible.

Many years ago, I made a high-level library for libxml2 based on the low-level 
Python bindings generated by the tool and resources in that library's own 
repository. So, I recognise that starting with low-level bindings and making 
higher-level bindings in a layered approach is entirely satisfactory. Others 
chose to use Pyrex/Cython to wrap libxml2 and to hide the underlying C 
library, but browsing their code suggests that this is also quite an intensive 
job:

https://github.com/lxml/lxml/tree/master/src/lxml

There may be benefits in using Cython instead of the Python C API directly, 
however.

> > P.S. Some kind of quick reference mapping gpg operations to the API would
> > be rather helpful.

> The original SWIG idea was that there is no need for a separate
> documentation.  The higher level and more pythonese API was added latter
> and is indeed not comprehensive.

I didn't find any documentation for the higher-level bindings as provided, 
although I did find documentation for previous incarnations of the bindings 
online. For example:

https://pygpgme.readthedocs.io/en/latest/

> It might be important for your considerations that we plan to split off
> the language bindings into separate repos and tarballs.  The main driver
> for this is that the Qt folks prefer to use cmake and having both build
> systems (cmake and autotools) is not easy for the maintainers.  The
> Python bindings will thus also be split into a separate library and it
> will allow to have a maintainer who does not need to follow the gpgme
> development all the day but instead rely on the stable GPGME API.
> 
> See https://dev.gnupg.org/T7262

That seems like a reasonable approach, given the strong preferences people 
have for (and against) various build systems, plus the nightmare of having to 
integrate them within a common framework.

However, in the specific case involving the lack of signatures for keys that 
are not resident in a keychain, I see that the behaviour is explained by code 
in the GPGME library itself. Looking at src/keylist.c, there are three 
functions, each calling some underlying function:

gpgme_op_keylist_start           -> _gpgme_engine_op_keylist
gpgme_op_keylist_ext_start       -> _gpgme_engine_op_keylist_ext
gpgme_op_keylist_from_data_start -> _gpgme_engine_op_keylist_data

These are described in the documentation, of course:

https://www.gnupg.org/documentation/manuals/gpgme/Listing-Keys.html

However, I see that the data-related function does not propagate keylist_mode 
from the context to the underlying function. In src/engine.c, the 
_gpgme_engine_op_keylist_data function invokes the appropriate engine 
operation without the mode.

And in src/engine-gpg.c, which is the only engine implementing the 
keylist_data operation, I see that the gpg_keylist_data function does not 
support the mode and therefore cannot introduce --with-sig-list to the command 
options.

In contrast, the other keylist operations employ the gpg_keylist_build_options 
function to convert the mode to appropriate command options, although I see 
that --with-sig-check, not --with-sig-list, is actually introduced if 
GPGME_KEYLIST_MODE_SIGS is specified.

So, I think I am mostly left wondering whether this treatment or lack of 
treatment of the mode was intentional in GPGME for keylist_data, or whether it 
was an oversight that can be remedied.

Paul
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.