42 lines
2.4 KiB
Python
42 lines
2.4 KiB
Python
"""Read-only primary provenance capture. Never invokes a compiler or application."""
|
|
from pathlib import Path
|
|
import hashlib, json, urllib.request, zipfile, re
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
OUT = Path(__file__).resolve().parent
|
|
def sha(b): return hashlib.sha256(b).hexdigest()
|
|
def new(name, b):
|
|
with (OUT / name).open('xb') as f: f.write(b)
|
|
def fetch(url, name):
|
|
req = urllib.request.Request(url, headers={'User-Agent':'Arcadia-runtime-provenance/1'})
|
|
with urllib.request.urlopen(req, timeout=45) as r:
|
|
b = r.read()
|
|
info = {'url':url, 'final_url':r.url, 'status':r.status, 'bytes':len(b), 'sha256':sha(b)}
|
|
new(name,b)
|
|
return b, info
|
|
|
|
release_b, release_info = fetch('https://api.github.com/repos/mstorsjo/llvm-mingw/releases/tags/20260908', 'official-release.json')
|
|
release = json.loads(release_b)
|
|
asset = next(a for a in release['assets'] if a['name']=='llvm-mingw-20260908-ucrt-x86_64.zip')
|
|
archive = ROOT / '.local/toolchain/llvm-mingw.zip'
|
|
archive_hash = sha(archive.read_bytes())
|
|
assert archive.stat().st_size == asset['size']
|
|
assert asset['digest'] == 'sha256:' + archive_hash
|
|
rows=[]
|
|
with zipfile.ZipFile(archive) as z:
|
|
for suffix in ['x86_64-w64-mingw32/bin/libunwind.dll','bin/libunwind.dll','LICENSE.TXT']:
|
|
name='llvm-mingw-20260908-ucrt-x86_64/'+suffix
|
|
b=z.read(name)
|
|
local=ROOT/'.local/toolchain'/name
|
|
assert b==local.read_bytes()
|
|
rows.append({'member':name,'bytes':len(b),'sha256':sha(b),'crc':z.getinfo(name).CRC,'local_path':str(local)})
|
|
if suffix=='LICENSE.TXT':new('distribution-LICENSE.TXT',b)
|
|
# Compiler binary strings are corroborative metadata only; do not execute it.
|
|
b=z.read('llvm-mingw-20260908-ucrt-x86_64/bin/clang.exe')
|
|
strings=[x.decode('ascii') for x in re.findall(rb'[ -~]{16,}',b) if b'github.com/llvm/llvm-project' in x or b'clang version 23' in x]
|
|
new('compiler-embedded-version-strings.json',json.dumps(strings,indent=2).encode())
|
|
tag_b, tag_info=fetch('https://api.github.com/repos/mstorsjo/llvm-mingw/git/ref/tags/20260908','official-tag.json')
|
|
tag=json.loads(tag_b)
|
|
new('initial-evidence.json',json.dumps({'release':release_info,'asset':asset,'archive':{'path':str(archive),'bytes':archive.stat().st_size,'sha256':archive_hash},'archive_members':rows,'tag':tag_info,'tag_object':tag['object']},indent=2).encode())
|
|
print(json.dumps({'asset':asset,'archive_sha256':archive_hash,'members':rows,'tag':tag['object'],'compiler_strings':strings},indent=2))
|