X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=daklib%2Fgpg.py;h=94842083125a5633a27c8dd58e6014568f9c1b9f;hb=391f5ec09a119131dc846b796ca791f4cecc69e4;hp=236b4927b29f4a57d396e8b0647b70bd761cbdf5;hpb=ca33f78389ccdf09172f4dd6e32f7fae7ef36443;p=dak.git diff --git a/daklib/gpg.py b/daklib/gpg.py index 236b4927..94842083 100644 --- a/daklib/gpg.py +++ b/daklib/gpg.py @@ -80,12 +80,27 @@ class SignedFile(object): self.valid = False self.expired = False self.invalid = False - self.fingerprint = None - self.primary_fingerprint = None - self.signature_id = None + self.fingerprints = [] + self.primary_fingerprints = [] + self.signature_ids = [] self._verify(data, require_signature) + @property + def fingerprint(self): + assert len(self.fingerprints) == 1 + return self.fingerprints[0] + + @property + def primary_fingerprint(self): + assert len(self.primary_fingerprints) == 1 + return self.primary_fingerprints[0] + + @property + def signature_id(self): + assert len(self.signature_ids) == 1 + return self.signature_ids[0] + def _verify(self, data, require_signature): with _Pipe() as stdin: with _Pipe() as contents: @@ -121,6 +136,9 @@ class SignedFile(object): if require_signature and not self.valid: raise GpgException("No valid signature found. (GPG exited with status code %s)\n%s" % (exit_code, self.stderr)) + assert len(self.fingerprints) == len(self.primary_fingerprints) + assert len(self.fingerprints) == len(self.signature_ids) + def _do_io(self, read, write): for fd in write.keys(): old = fcntl.fcntl(fd, fcntl.F_GETFL) @@ -178,11 +196,14 @@ class SignedFile(object): # # if fields[1] == "VALIDSIG": - if self.fingerprint is not None: - raise GpgException("More than one signature is not (yet) supported.") + # GnuPG accepted MD5 as a hash algorithm until gnupg 1.4.20, + # which Debian 8 does not yet include. We want to make sure + # to not accept uploads covered by a MD5-based signature. + if fields[9] == "1": + raise GpgException("Digest algorithm MD5 is not trusted.") self.valid = True - self.fingerprint = fields[2] - self.primary_fingerprint = fields[11] + self.fingerprints.append(fields[2]) + self.primary_fingerprints.append(fields[11]) self.signature_timestamp = self._parse_timestamp(fields[4], fields[3]) elif fields[1] == "BADARMOR": @@ -198,14 +219,12 @@ class SignedFile(object): raise GpgException("Other error: %s %s" % (fields[2], fields[3])) elif fields[1] == "SIG_ID": - if self.signature_id is not None: - raise GpgException("More than one signature id.") - self.signature_id = fields[2] + self.signature_ids.append(fields[2]) - elif fields[1] in ('PLAINTEXT', 'GOODSIG'): + elif fields[1] in ('PLAINTEXT', 'GOODSIG', 'NOTATION_NAME', 'NOTATION_DATA', 'SIGEXPIRED', 'KEYEXPIRED', 'POLICY_URL'): pass - elif fields[1] in ('EXPSIG', 'EXPKEYSIG', 'KEYEXPIRED'): + elif fields[1] in ('EXPSIG', 'EXPKEYSIG'): self.expired = True self.invalid = True