Skip to content

Instantly share code, notes, and snippets.

@jigpu
Last active December 19, 2022 18:32
Show Gist options
  • Save jigpu/463f1a8cab2014fc230a4b8722f294c7 to your computer and use it in GitHub Desktop.
Save jigpu/463f1a8cab2014fc230a4b8722f294c7 to your computer and use it in GitHub Desktop.
Calculate Manifest lines for Chrome OS fwupd package
#!/usr/bin/env python
"""
manifest-calculator.py
Calculate the string which must be added to the Chrome OS Manifest file
as part of the firmware submission process.
Usage:
$ ./manifest-calculator.py <lvfs-cabfile>
Example:
$ ./manifest-calculator.py a7ec6fb710d020ab2589e67935c83f507908ecce32ada5e8a773df02518efed6-DellDockFirmwareUpdateLinux_01.00.09.cab
The 'lvfs-cabfile' should be the name of a CAB file already uploaded to
LVFS. (It is **not** a path to a file on your disk!) For example, log
in to LVFS, select the "Details" for a particular firmware, and then
navigate to the "Target" tab. The filename for that CAB file should be
found at the bottom of the page in the "Revisions" category.
The output from this program should be appended to the "Manifest"
file found in the Chrome os "sys-firmware/fwupd-peripherals" PACKAGE.
(See https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/main/sys-firmware/fwupd-peripherals)
"""
import hashlib
import requests
import sys
import urllib.parse
LVFS_BASEURL = "https://fwupd.org/downloads"
def download(filename):
url = f"{LVFS_BASEURL}/{urllib.parse.quote(filename, safe='')}"
headers = { "user-agent": "manifest-calculator.py" }
result = requests.get(url, headers=headers)
if result.status_code != requests.codes.ok:
raise Exception("Unable to download file")
return result.content
def calculate_hashes(filename, data):
if "blake2b" not in hashlib.algorithms_available:
raise Exception("Required hash algorithm not available")
if "sha512" not in hashlib.algorithms_available:
raise Exception("Required hash algorithm not available")
result = [
filename,
str(len(data)),
"BLAKE2B", hashlib.blake2b(data).hexdigest(),
"SHA512", hashlib.sha512(data).hexdigest(),
]
return " ".join(result)
def generate_manifest_line(filename):
data = download(filename)
hashes = calculate_hashes(filename, data)
line = f"DIST {hashes}"
return line
def help():
print(__doc__, file=sys.stderr)
def selftest():
EXPECT = "DIST a7ec6fb710d020ab2589e67935c83f507908ecce32ada5e8a773df02518efed6-DellDockFirmwareUpdateLinux_01.00.09.cab 2860872 BLAKE2B d98d79e9612ef20065902f19c82348325ddb29e665e80ef2d6dfe61b181d28831f424ec9427ed58f969aba9569c1c15bd14dd43bfde45a1f3cee9e32c54c8f51 SHA512 7d98dfd02d4e7a6d598db108f6a9f9201939dad36e969bab97cd95765b806a08b027731bc9b1bd74ba248dda1de977339835871cb64cd330dc3842fff770d935"
print("Performing self-test...", file=sys.stderr)
result = generate_manifest_line("a7ec6fb710d020ab2589e67935c83f507908ecce32ada5e8a773df02518efed6-DellDockFirmwareUpdateLinux_01.00.09.cab")
assert EXPECT == result
print("Passed!", file=sys.stderr)
def main():
if len(sys.argv) != 2:
help()
#selftest()
else:
line = generate_manifest_line(sys.argv[1])
print(line)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment