mirror of
https://github.com/mirkobrombin/raven.git
synced 2026-11-01 21:45:06 +00:00
46 lines
2.1 KiB
Python
46 lines
2.1 KiB
Python
#!/usr/bin/env python3
|
|
"""Download the root certificates Windows trusts for code signing that host certificate bundles leave out.
|
|
|
|
Every Windows installation carries the Microsoft code signing roots in its root store, and installers check the signatures of the
|
|
packages they unpack against them. They come from Microsoft's public certificate repository, each checked against its pinned digest.
|
|
|
|
usage: provision-roots.py --output DIRECTORY
|
|
"""
|
|
|
|
import argparse
|
|
import hashlib
|
|
from pathlib import Path
|
|
import urllib.request
|
|
|
|
# The certificate, where Microsoft publishes it, and the SHA-256 of its DER bytes.
|
|
ROOTS = (
|
|
("MicrosoftRootAuthority.crt", "http://www.microsoft.com/pki/certs/MicrosoftRootAuthority.crt",
|
|
"f38406e540d7a9d90cb4a9479299640ffb6df9e224ecc7a01c0d9558d8dad77d"),
|
|
("MicrosoftRootCert.crt", "http://www.microsoft.com/pki/certs/MicrosoftRootCert.crt",
|
|
"885de64c340e3ea70658f01e1145f957fcda27aabeea1ab9faa9fdb0102d4077"),
|
|
("MicRooCerAut_2010-06-23.crt", "http://www.microsoft.com/pki/certs/MicRooCerAut_2010-06-23.crt",
|
|
"df545bf919a2439c36983b54cdfc903dfa4f37d3996d8d84b4c31eec6f3c163e"),
|
|
("MicRooCerAut2011_2011_03_22.crt", "http://www.microsoft.com/pki/certs/MicRooCerAut2011_2011_03_22.crt",
|
|
"847df6a78497943f27fc72eb93f9a637320a02b561d0a91b09e87a7807ed7c61"),
|
|
)
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Download the Microsoft code signing roots Windows trusts")
|
|
parser.add_argument("--output", type=Path, required=True)
|
|
args = parser.parse_args()
|
|
args.output.mkdir(parents=True, exist_ok=True)
|
|
for name, url, digest in ROOTS:
|
|
target = args.output / name
|
|
if not target.exists() or hashlib.sha256(target.read_bytes()).hexdigest() != digest:
|
|
with urllib.request.urlopen(url) as response:
|
|
data = response.read()
|
|
if hashlib.sha256(data).hexdigest() != digest:
|
|
raise RuntimeError(f"{name} differs from the pinned certificate")
|
|
target.write_bytes(data)
|
|
print(f"roots in {args.output}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|