gen-miniroon.py (1569B)
1 #!/usr/bin/env python3 2 import sys 3 import hmac 4 5 6 class NetString(bytes): 7 @classmethod 8 def from_any(cls, data): 9 if isinstance(data, NetString): 10 return cls(data) 11 if isinstance(data, bytes): 12 return cls(to_ns(data)) 13 if isinstance(data, str): 14 return cls(to_ns(data.encode('ascii'))) 15 assert not isinstance(data, dict) 16 return cls(to_ns(to_ns_list(data))) 17 18 19 def to_ns(b): 20 assert isinstance(b, bytes) 21 return NetString(b'%d:%s,' % (len(b), b)) 22 23 24 def to_ns_list(data): 25 assert not isinstance(data, (dict, bytes, str)) 26 return b''.join(NetString.from_any(i) for i in data) 27 28 29 def miniroon_hmac(key, msg): 30 print('miniroon_hmac%r' % ((key, msg),), file=sys.stderr) 31 #return hmac.digest(key, msg, 'blake2s') 32 return hmac.digest(key, msg, 'sha256') 33 34 35 def make_miniroon(name, action='invoke-once', secret=b'\0'*32, caveats=(), version='capv0'): 36 hdr = b''.join(NetString.from_any(i) for i in (version, name, action)) 37 caveats_ns = [to_ns_list(c) for c in caveats] 38 sig = miniroon_hmac(secret, hdr) 39 for c in caveats_ns: 40 sig = miniroon_hmac(sig, c) 41 return NetString.from_any([ 42 hdr, 43 caveats_ns, 44 sig, 45 ]) 46 47 48 if __name__ == '__main__': 49 import os 50 # os.write(1, make_miniroon(name='ccx')) 51 os.write(1, make_miniroon(name='ccx', caveats=[ 52 ('env-is', 'var1', 'hello'), 53 ('env-absent', 'var2'), 54 ('env-glob', 'var3', '_*'), 55 # ('x-glob', 'var3', '_*'), 56 ('env-is', 'var3', '_hello'), 57 ]))