Example
The code below is a basic example of how the wire format of a byte string can be unmarshaled into a Python object.
The byte string used is the modstatesig
field of the first example provided in the Key attestation format example.
class M_CipherText:
def __init__(self, mech, data, iv):
self.mech = mech
self.data = data
self.iv = iv
known_mechs = {170: "DSAhSHA256", 187: "ECDSAhSHA512"}
self.mech_name = known_mechs.get(mech, "Undefined")
def __str__(self):
description = ""
description += f"CipherText.mech= {self.mech_name}\n"
description += f" .data.r= {self.data.r}\n"
description += f" .s= {self.data.s}"
if self.iv:
description += f"\n .iv= {self.iv}"
return description
class M_Mech_DSA_Cipher:
def __init__(self, r, s):
self.r = r
self.s = s
class M_Mech_ECDSA_Cipher:
def __init__(self, r, s):
self.r = r
self.s = s
class M_Bignum(int):
def __new__(cls, content):
return super().__new__(cls, int.from_bytes(content, byteorder='little'))
def __str__(self):
return hex(self)
def unmarshal(bytes_, t):
if t == M_Bignum:
length = int.from_bytes(bytes_[:4], byteorder='little')
return t(bytes_[4:4+length]), bytes_[4+length:]
elif t == M_Mech_DSA_Cipher:
r, bytes_ = unmarshal(bytes_, M_Bignum)
s, bytes_ = unmarshal(bytes_, M_Bignum)
return t(r, s), bytes_
elif t == M_Mech_ECDSA_Cipher:
r, bytes_ = unmarshal(bytes_, M_Bignum)
s, bytes_ = unmarshal(bytes_, M_Bignum)
return t(r, s), bytes_
elif t == M_CipherText:
mech = int.from_bytes(bytes_[:4], byteorder='little')
bytes_ = bytes_[4:]
iv = None # none of the defined variants populate iv
if mech == 170:
data, bytes_ = unmarshal(bytes_, M_Mech_DSA_Cipher)
elif mech == 187:
data, bytes_ = unmarshal(bytes_, M_Mech_ECDSA_Cipher)
else:
print(f"Mech {mech} not yet implemented")
data = None
return t(mech, data, iv), bytes_
else:
print(f"Type {t.__name__} not yet implemented")
return None, bytes_
sig = base64.urlsafe_b64decode("uwAAAEQAAABIF582_Xr16pI3UgQnbJ6BVC_qkiHGmIqnidVnXo2eFxSl5iKKTRCaIbHzB9LADNKwNygbldB7Idbn6BUP4bpayQEAAEQAAACv8Z4kRqTNrxXdiZTyyBDWRFVY9Tm0Qq2Pm6EHbSgZyCxjH_XpKVZHxlTVnNW75DE7PT_vMKgDgU5joCLtuzrUigAAAA==")
print(unmarshal(sig, M_CipherText)[0])
print("---")
print(nfkm.unmarshal(sig, nfkm.CipherText)[0])
CipherText.mech= ECDSAhSHA512
.data.r= 0x1c95abae10f15e8e7d6217bd0951b2837b0d20cc0d207f3b1219a104d8a22e6a514179e8d5e67d589a78a98c62192ea2f54819e6c2704523792eaf57afd369f1748
.s= 0x8ad43abbed22a0634e8103a830ef3f3d3b31e4bbd59cd554c6475629e9f51f632cc819286d07a19b8fad42b439f5585544d610c8f29489dd15afcda446249ef1af
---
CipherText.mech= ECDSAhSHA512
.data.r= 0x1c95abae10f15e8e7d6217bd0951b2837b0d20cc0d207f3b1219a104d8a22e6a514179e8d5e67d589a78a98c62192ea2f54819e6c2704523792eaf57afd369f1748
.s= 0x8ad43abbed22a0634e8103a830ef3f3d3b31e4bbd59cd554c6475629e9f51f632cc819286d07a19b8fad42b439f5585544d610c8f29489dd15afcda446249ef1af