I saw a request for Koji to use a stronger cryptographic hash function such as SHA256 ( https://fedorahosted.org/koji/ticket/119 ) on RPM packages. I took some time in reading how the RPMTAG_SIGMD5 is calculated and implemented some Python code to hash the same RPM data using hashlib's SHA256 module. The outputted SHA256 digest can be stored in Koji's DB and also retrieved/calculated/checked with any new packages that are being submitted.
$ rpm -q --queryformat '%{RPMTAG_SIGMD5}' -p "gcc-4.6.2-1.fc17.1.src.rpm" c88e96685e7eb3a124a5707b1bc41333 $ python sha2pay.py gcc-4.6.2-1.fc17.1.src.rpm ['c88e96685e7eb3a124a5707b1bc41333', 'c729d818d5468f8b1147cb70b266992f92f58c9dace218417c7582427d1e5561']
Source code:
import hashlib import os import struct import subprocess import sys
def sha2pay(fn): # http://www.iagora.com/~espel/rpm2cpio nel = 0 f = open(fn, "r") rpm = f.read(96) if (len(rpm) != 96): #print("error reading lead 96.0") return None nel += len(rpm) # http://perldoc.perl.org/functions/pack.html # http://docs.python.org/library/struct.html (magic, major, minor, rest) = struct.unpack(">LBB90s", rpm) if (magic != 0xedabeedb): #print("incorrect lead magic") return None if ((major != 3) and (major != 4)): #print("incorrect lead major") return None # http://docs.python.org/library/stdtypes.html while (1): pos = nel rpm = f.read(16) if (len(rpm) != 16): #print("error reading header 16.0") return None nel += len(rpm) (smagic, rest) = struct.unpack(">H14s", rpm) if ((smagic == 0x1f8b) or (smagic == 0x425a)): break if (pos & 0x7): pos += 7 pos &= (~0x7) f.seek(pos, 0) nel = pos rpm = f.read(16) if (len(rpm) != 16): #print("error reading header 16.1") return None nel += len(rpm) left = (len(rpm) - 16) (magic, data, sections, bytes, rest) = struct.unpack(">4L" + str(left) + "s", rpm) if (magic != 0x8eade801): #print("incorrect header magic") return None # beg custom f.seek(pos + 16, 0) tmp = f.read((16 * sections) + bytes) head = (rpm + tmp) # end custom pos += 16 pos += (16 * sections) pos += bytes f.seek(pos, 0) nel = pos if ((smagic != 0x1f8b) and (smagic != 0x425a)): #print("unknown compression format") return None while (1): tmp = f.read(16384) if (not tmp): break rpm += tmp f.close() return [hashlib.md5(head + rpm).hexdigest(), hashlib.sha256(head + rpm).hexdigest()]
buildsys@lists.fedoraproject.org