isislovecruft / python-gnupg

A modified version of python-gnupg, including security patches, extensive documentation, and extra features.
Other
424 stars 172 forks source link

Verification of messages signed with multiple keys #78

Open extempore opened 9 years ago

extempore commented 9 years ago

Some examples here: https://bitbucket.org/vinay.sajip/python-gnupg/issue/21/gpg-message-with-multiple-signatures

isislovecruft commented 9 years ago

@extempore Thanks for pointing that out! I'd definitely take that feature if someone were to implement it (or attempt to port the patches from Vinay Sajip's version of python-gnupg to my version).

It shouldn't be too difficult to tell the data signature parser (gnupg.parsers.Verify) to continue parsing and collect a list/dict of signatures. It also shouldn't be too difficult to tell both gnupg.GPG.sign() and gnupg.GPG.verify() to take a list of keys/fingerprints for signing and verification.

isislovecruft commented 9 years ago

I was just reading over the gnupg-devel mailing list post from Werner Koch, linked to from that ticket you pointed out. Supporting the case where multiple signatures on the same data were all made on separate boxes is "not too difficult" according to Werner, whereby "not too difficult" what is actually meant is a tiny bit of a crazy sed + grep + gpgsplit command:

Let's see how we can combine them into one signature block:

  $ sed -n '/SIGNATURE/,$ p' x1 | gpg2 --dearmor | gpgsplit --no-split >y1
  $ sed -n '/SIGNATURE/,$ p' x2 | gpg2 --dearmor | gpgsplit --no-split >y2
  $ cat y1 y2 | gpg --enarmor | sed -n '5,$ p' | grep -v -- ----- >y
  $ (sed -n '1,/SIGNATURE/ p' x1 ; echo ; cat y; \
     echo '-----END PGP SIGNATURE-----') >x

That was not too complicated.

That is pretty cool, I'll admit. But I'd be a bit worried about promising the reliability of that functionality in this Python library in an automated manner, given that some of those commands could fail and it would start to become a lot of work to do it safely.

That said, I'm still happy to take patches to python-gnupg to add multiple keys to sign() and verify(). :)

I'd also be happy to take a patch which adds an "experimental" script to the examples/ directory to do Werner's crazy sed + grep + gpgsplit command (along with using python-gnupg to create/verify multiparty signatures).

extempore commented 9 years ago

I see Verify._handle_status() receives line-by-line input. How can we detect at which point we've started parsing the second signature?

I haven't tested it, by assume the current version keeps parsing after the first signature, replacing collected data as it goes. Could that lead to inconsistent data in the gpg.verify() result?

extempore commented 9 years ago

I made a signature combiner PoC: https://gist.github.com/extempore/b374fc9793643bb7563f

isislovecruft commented 9 years ago

@extempore Awesome! Do you think we should add methods gnupg.GPG.enarmor() and gnupg.GPG.dearmor() to make this easier?

And, to answer your earlier question about getting Verify._handle_status() to understand multiple signatures, the best way to not break everything using python-gnupg would probably be to add a signatures attribute to Verify which is a container storing some new Signature class which should hold all the attributes a signature may have.

Although, I just tried to use Werner Koch's instructions for creating multisigs, i.e. merging multiple clearsign signatures, several times, and I was unable to get the signatures to ever verify. Instead I got the following errors:

gpg: WARNING: unsafe permissions on homedir `TICKET-78-homedir'
gpg: CRC error; 8CF789 - 9C4A3F
gpg: [don't know]: invalid packet (ctb=29)
gpg: no signature found
gpg: the signature could not be verified.
Please remember that the signature file (.sig or .asc)
should be the first file given on the command line.

Is anyone else actually able to produce these multisigs which verify correctly?

isislovecruft commented 9 years ago

Moving the milestone to 1.4.x because I want to release 1.4.0 right now (which will be equivalent to 1.3.3, but I feel that too many features and changes got added for it to be a micro-release).