import zlib, sys, hashlib, base64, subprocess, tarfile, io def members(b): out=[]; pos=0 while pos < len(b): d=zlib.decompressobj(31); data=d.decompress(b[pos:]); used=len(b)-pos-len(d.unused_data) out.append((b[pos:pos+used], data)); pos+=used return out def verify(path, key): b=open(path,'rb').read(); m=members(b) sigtar=tarfile.open(fileobj=io.BytesIO(m[0][1])); sm=[x for x in sigtar.getmembers() if x.name.startswith('.SIGN.RSA')][0] sig=sigtar.extractfile(sm).read(); open('sig.bin','wb').write(sig); open('signed.bin','wb').write(m[1][0]) r=subprocess.run(['openssl','dgst','-sha1','-verify',key,'-signature','sig.bin','signed.bin'],capture_output=True,text=True) print(path, sm.name, r.stdout.strip() or r.stderr.strip()) return m idx=verify('APKINDEX.tar.gz','keys/alpine-devel@lists.alpinelinux.org-616ae350.rsa.pub') m=verify(sys.argv[1],'keys/alpine-devel@lists.alpinelinux.org-616ae350.rsa.pub') print('control Q1:', 'Q1'+base64.b64encode(hashlib.sha1(m[1][0]).digest()).decode()) pk=tarfile.open(fileobj=io.BytesIO(m[1][1])).extractfile('.PKGINFO').read().decode() dh=[l for l in pk.splitlines() if l.startswith('datahash')][0].split('=')[1].strip() print('datahash pkginfo', dh, 'actual', hashlib.sha256(m[2][0] if len(m)==3 else b''.join(x[0] for x in m[2:])).hexdigest()) tarfile.open(fileobj=io.BytesIO(b''.join(x[1] for x in m[2:]))).extractall('alp', filter='tar') if False else None