diff --git a/app/appstate.py b/app/appstate.py index c0ddca7..aa85c10 100644 --- a/app/appstate.py +++ b/app/appstate.py @@ -4,6 +4,7 @@ from __future__ import annotations import re +import base64 import uuid import time from functools import cmp_to_key @@ -12,6 +13,7 @@ from typing import List, Set, Dict, Tuple, Optional, Type, Sequence, NamedTuple from .appconfig import REPOSITORIES from .utils import vercmp, version_is_newer_than, extract_upstream_version +from .pgp import parse_signature CygwinVersions = Dict[str, Tuple[str, str, str]] @@ -222,7 +224,7 @@ class Package: makedepends: List[str], md5sum: str, name: str, pgpsig: str, sha256sum: str, arch: str, base_url: str, repo: str, repo_variant: str, provides: List[str], conflicts: List[str], replaces: List[str], version: str, base: str, desc: str, groups: List[str], licenses: List[str], optdepends: List[str], - checkdepends: List[str]) -> None: + checkdepends: List[str], sig_data: str) -> None: self.builddate = int(builddate) self.csize = csize @@ -235,6 +237,7 @@ class Package: r.append((first, second)) return r + self.signature = parse_signature(base64.b64decode(sig_data)) self.depends = split_depends(depends) self.checkdepends = split_depends(checkdepends) self.filename = filename @@ -317,7 +320,7 @@ class Package: d.get("%REPLACES%", []), d["%VERSION%"][0], base, d.get("%DESC%", [""])[0], d.get("%GROUPS%", []), d.get("%LICENSE%", []), d.get("%OPTDEPENDS%", []), - d.get("%CHECKDEPENDS%", [])) + d.get("%CHECKDEPENDS%", []), d.get("%PGPSIG%", [""])[0]) class Source: diff --git a/app/pgp.py b/app/pgp.py new file mode 100644 index 0000000..867cc2a --- /dev/null +++ b/app/pgp.py @@ -0,0 +1,57 @@ +from pgpdump import BinaryData +from pgpdump.utils import PgpdumpException +from datetime import datetime +from typing import NamedTuple +import struct +import binascii + + +KNOWN_KEYS = { + "5F92EFC1A47D45A1": "Alexey Pavlov", + "4DF3B7664CA56930": "Ray Donnelly", + "D595C9AB2C51581E": "Martell Malone", + "974C8BE49078F532": "David Macek", + "FA11531AA0AA7F57": "Christoph Reiter", +} + + +class Signature(NamedTuple): + keyid: str + date: datetime + + @property + def url(self) -> str: + return "http://pool.sks-keyservers.net/pks/lookup?op=vindex&fingerprint=on&search=0x" + self.keyid + + @property + def name(self) -> str: + return KNOWN_KEYS.get(self.keyid.upper(), "Unknown") + + +class SigError(Exception): + pass + + +def parse_signature(sig_data: bytes) -> Signature: + date = None + keyid = None + + try: + parsed = BinaryData(sig_data) + except PgpdumpException as e: + raise SigError(e) + + for x in parsed.packets(): + if x.raw == 2: + for sub in x.subpackets: + if sub.subtype == 2: + date = datetime.utcfromtimestamp(struct.unpack('>I', sub.data)[0]) + if sub.subtype == 16: + keyid = binascii.hexlify(sub.data).decode() + + if keyid is None: + raise SigError("keyid missing") + if date is None: + raise SigError("date missing") + + return Signature(keyid, date) diff --git a/app/templates/package.html b/app/templates/package.html index 8f53c1a..c2c85be 100644 --- a/app/templates/package.html +++ b/app/templates/package.html @@ -43,6 +43,12 @@