Bug#710923: python-debian: deb822.GpgInfo doesn't handle multiple signatures

Stuart Prescott stuart at debian.org
Mon Jun 3 15:17:23 UTC 2013


Package: python-debian
Version: 0.1.21
Severity: normal

The GpgInfo class has trouble with multiple signatures (as anticipated in the
code). Specifically, parsing gpgv output where there are multiple signatures
results in the last signature output from gpgv overwriting all previous
signature output. For example, with a GpgInfo modified to show the output from
gpgv, we see that the first signature is missing from the GpgInfo dict at the
end.

  In [1]: deb822.GpgInfo.from_file("InRelease")
  [GNUPG:] SIG_ID yrzgfYqxMsicYATRfe4Eb0Y2zTI 2013-06-01 1370075920
  [GNUPG:] GOODSIG AED4B06F473041FA Debian Archive Automatic Signing Key (6.0/squeeze) <ftpmaster at ....>
  [GNUPG:] VALIDSIG 9FED2BCBDCD29CDF762678CBAED4B06F473041FA 2013-06-01 1370075920 0 4 0 1 2 01 9FED2BCBDCD29CDF762678CBAED4B06F473041FA
  [GNUPG:] SIG_ID UHfPUE8iBAo1hWxJ7OJANR1eElw 2013-06-01 1370075920
  [GNUPG:] GOODSIG 8B48AD6246925553 Debian Archive Automatic Signing Key (7.0/wheezy) <ftpmaster at ....>
  [GNUPG:] VALIDSIG A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553 2013-06-01 1370075920 0 4 0 1 2 01 A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553

  Out[1]: 
  {'GOODSIG': ['8B48AD6246925553',
    'Debian Archive Automatic Signing Key (7.0/wheezy) <ftpmaster at ....>'],
   'SIG_ID': ['UHfPUE8iBAo1hWxJ7OJANR1eElw', '2013-06-01', '1370075920'],
   'VALIDSIG': ['A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553',
    '2013-06-01',
    '1370075920',
    '0',
    '4',
    '0',
    '1',
    '2',
    '01',
    'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553']}

or an even weirder situation where one key is in the keyring and the other
isn't:

  In [2]: deb822.GpgInfo.from_file("DummyInRelease")
  [GNUPG:] SIG_ID UyOIE2DGhwjpPEJ0gsqP39gZ4Bo 2013-06-03 1370270543
  [GNUPG:] GOODSIG 9FE8B8CD71C5D1A8 Stuart Prescott <stuart at ....>
  [GNUPG:] VALIDSIG BE65FD1EF4EA08F323D43C6D9FE8B8CD71C5D1A8 2013-06-03 1370270543 0 4 0 17 2 01 BE65FD1EF4EA08F323D43C6D9FE8B8CD71C5D1A8
  [GNUPG:] ERRSIG BBC17EBB1396F2F7 1 8 01 1370270543 9
  [GNUPG:] NO_PUBKEY BBC17EBB1396F2F7

  Out[2]:
  {'ERRSIG': ['BBC17EBB1396F2F7', '1', '8', '01', '1370270543', '9'],
   'GOODSIG': ['9FE8B8CD71C5D1A8', 'Stuart Prescott <stuart at ...>'],
   'NO_PUBKEY': ['BBC17EBB1396F2F7'],
   'SIG_ID': ['UyOIE2DGhwjpPEJ0gsqP39gZ4Bo', '2013-06-03', '1370270543'],
   'VALIDSIG': ['BE65FD1EF4EA08F323D43C6D9FE8B8CD71C5D1A8',
    '2013-06-03',
    '1370270543',
    '0',
    '4',
    '0',
    '17',
    '2',
    '01',
    'BE65FD1EF4EA08F323D43C6D9FE8B8CD71C5D1A8']}

Note that the valid() method would report that this last example was a valid
signature because one of the signatures was VALIDSIG, despite the fact that
the other was ERRSIG (or EXPSIG or KEYEXPIRED or ...).

The uid() method is presumably completely unused as it does nothing so that's
not too much of a problem for multiple signatures, but the fundamental data
structure of GpgInfo being a dict with keys of the gpgv code (i.e the SIG_ID,
GOODSIG, VALIDSIG) above is at odds with supporting multiple signatures.

I can imagine GpgInfo behaving like a dict for compatibility reasons and moving
instead to a GpgInfo.signatures list that is a list of dict objects that look
like the current GpgInfo dict. It's not obvious how to successfully split the
gpgv output into blocks for that sort of list of signatures -- the output above
makes it tempting to assume that SIG_ID is a header for signature information,
but /usr/share/doc/gnupg/DETAILS.gz cautions:

      SIG_ID  <radix64_string>  <sig_creation_date>  <sig-timestamp>
        This is emitted only for signatures of class 0 or 1 which
        have been verified okay.

So any BADSIG or ERRSIG (like NO_PUBKEY) would not emit this separator:

(forcing a BADSIG by changing the signed data)

  [GNUPG:] BADSIG AED4B06F473041FA Debian Archive Automatic Signing Key (6.0/squeeze) <ftpmaster at ....>


(one VALIDSIG and one ERRSIG/NO_PUBKEY)

  [GNUPG:] SIG_ID UyOIE2DGhwjpPEJ0gsqP39gZ4Bo 2013-06-03 1370270543
  [GNUPG:] GOODSIG 9FE8B8CD71C5D1A8 Stuart Prescott <stuart at ....>
  [GNUPG:] VALIDSIG BE65FD1EF4EA08F323D43C6D9FE8B8CD71C5D1A8 2013-06-03 1370270543 0 4 0 17 2 01 BE65FD1EF4EA08F323D43C6D9FE8B8CD71C5D1A8
  [GNUPG:] ERRSIG BBC17EBB1396F2F7 1 8 01 1370270543 9
  [GNUPG:] NO_PUBKEY BBC17EBB1396F2F7

An alternative approach that saves trying to split out which lines relate to
which signature is to interpret the lines from gpgv as currently done but store
them in a list rather than a dict. This makes methods like valid() a little
harder as it would need to iterate the list rather than just look in the dict
keys, but more importantly it would break all current users of GpgInfo that
relied on it being a dict. I assume we can't really do that, but do we really
want a list of parsed gpgv output being stored as well as the mushed-together
dict to maintain compatibility?

Trying to turn semi-structured output into a data structure is always going to
be problematic -- any suggestions on how do so here?

cheers
Stuart


-- System Information:
Debian Release: 7.0
  APT prefers stable-updates
  APT policy: (550, 'stable-updates'), (550, 'proposed-updates'), (550, 'stable'), (70, 'testing'), (60, 'unstable'), (1, 'experimental')
Architecture: i386 (i686)

Kernel: Linux 3.2.0-4-686-pae (SMP w/4 CPU cores)
Locale: LANG=en_AU.UTF-8, LC_CTYPE=en_AU.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages python-debian depends on:
ii  python          2.7.3-4
ii  python-chardet  2.0.1-2
ii  python2.6       2.6.8-1.1
ii  python2.7       2.7.3-6

Versions of packages python-debian recommends:
ii  python-apt  0.8.8.2

Versions of packages python-debian suggests:
ii  gpgv  1.4.12-7

-- no debconf information



More information about the pkg-python-debian-maint mailing list