jonesmarvin8 24f6f1f8ca fixes
2026-04-26 21:29:54 -04:00

44 lines
1.3 KiB
Python

from hashlib import sha256
from ecdsa import VerifyingKey, SECP256k1, util
from ..exceptions import InvalidResponseError
from ..parsing.tlv import parse_tlv
def parse(challenge: bytes, data: bytes) -> bytes:
tlvs = parse_tlv(data)
inner_tlvs = parse_tlv(tlvs[0xA0][0])
try:
certificate = inner_tlvs[0x8A][0]
signature = inner_tlvs[0x30][0]
except (IndexError, KeyError):
raise InvalidResponseError('Malformed identity response')
signature = b'\x30' + len(signature).to_bytes(1, 'big') + signature
if len(certificate) < 95 or len(signature) < 65:
raise InvalidResponseError('Malformed identity response')
_verify(certificate, signature, challenge)
return _recover_public_key(certificate)
def _verify(certificate: bytes, signature: bytes, challenge: bytes) -> None:
pub_key = certificate[:33]
vk = VerifyingKey.from_string(pub_key, curve=SECP256k1)
vk.verify_digest(signature, challenge, sigdecode=util.sigdecode_der)
def _recover_public_key(certificate: bytes) -> bytes:
signature = certificate[33:]
v = signature[-1]
digest = sha256(certificate).digest()
vk = VerifyingKey.from_public_key_recovery_with_digest(
signature[:-1], digest, SECP256k1)
public_key = vk[v] if isinstance(vk, list) else vk
der: bytes = public_key.to_der('compressed')
return der