Files
aios/active-runtime/app/aios_baseline/evidence.py
T

40 lines
1.7 KiB
Python

"""Canonical, domain-separated machine receipts, distinct from Owner grants."""
import base64
import hashlib
import json
from cryptography.exceptions import InvalidSignature
def canonical(value):
return json.dumps(value,sort_keys=True,separators=(',',':'),ensure_ascii=False,allow_nan=False).encode()
def digest(value):
return hashlib.sha256(canonical(value)).hexdigest()
class ReceiptSigner:
def __init__(self, private_key, *, key_id='baseline-machine', trusted_public_keys=None):
self.private_key=private_key
self.public_key=private_key.public_key()
self.key_id=key_id
self.trusted_public_keys=dict(trusted_public_keys or {})
self.trusted_public_keys[key_id]=self.public_key
def sign(self,payload):
raw=canonical({'domain':'aios.operation-receipt.v1','key_id':self.key_id,'payload':payload})
return {'schema':'aios.operation-receipt.v1','key_id':self.key_id,'payload':payload,
'signature':base64.b64encode(self.private_key.sign(raw)).decode()}
def verify(self,envelope):
try:
if type(envelope) is not dict or set(envelope)!={'schema','key_id','payload','signature'} or envelope['schema']!='aios.operation-receipt.v1' or type(envelope['payload']) is not dict:
return False
public=self.trusted_public_keys.get(envelope['key_id'])
if public is None: return False
raw=canonical({'domain':envelope['schema'],'key_id':envelope['key_id'],'payload':envelope['payload']})
public.verify(base64.b64decode(envelope['signature'],validate=True),raw)
return True
except (ValueError,TypeError,InvalidSignature,KeyError):
return False