diff --git a/pySim/esim/rsp.py b/pySim/esim/rsp.py index 85dacee4..c2a163ba 100644 --- a/pySim/esim/rsp.py +++ b/pySim/esim/rsp.py @@ -24,7 +24,7 @@ from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives.serialization import Encoding from cryptography import x509 -from pySim.utils import bertlv_parse_one, bertlv_encode_tag, bertlv_encode_len, b2h +from pySim.utils import bertlv_parse_one_rawtag, bertlv_return_one_rawtlv, b2h from pySim.esim import compile_asn1_subdir asn1 = compile_asn1_subdir('rsp') @@ -101,37 +101,31 @@ class RspSessionStore(shelve.DbfilenameShelf): def extract_euiccSigned1(authenticateServerResponse: bytes) -> bytes: """Extract the raw, DER-encoded binary euiccSigned1 field from the given AuthenticateServerResponse. This is needed due to the very peculiar SGP.22 notion of signing sections of DER-encoded ASN.1 objects.""" - tdict, l, v, remainder = bertlv_parse_one(authenticateServerResponse) - rawtag = bertlv_encode_tag(tdict) + rawtag, l, v, remainder = bertlv_parse_one_rawtag(authenticateServerResponse) if len(remainder): raise ValueError('Excess data at end of TLV') - if b2h(rawtag) != 'bf38': + if rawtag != 0xbf38: raise ValueError('Unexpected outer tag: %s' % b2h(rawtag)) - tdict, l, v1, remainder = bertlv_parse_one(v) - rawtag = bertlv_encode_tag(tdict) - if b2h(rawtag) != 'a0': + rawtag, l, v1, remainder = bertlv_parse_one_rawtag(v) + if rawtag != 0xa0: raise ValueError('Unexpected tag where CHOICE was expected') - tdict, l, v2, remainder = bertlv_parse_one(v1) - rawtag = bertlv_encode_tag(tdict) - if b2h(rawtag) != '30': + rawtag, l, tlv2, remainder = bertlv_return_one_rawtlv(v1) + if rawtag != 0x30: raise ValueError('Unexpected tag where SEQUENCE was expected') - return rawtag + bertlv_encode_len(l) + v2 + return tlv2 def extract_euiccSigned2(prepareDownloadResponse: bytes) -> bytes: """Extract the raw, DER-encoded binary euiccSigned2 field from the given prepareDownloadrResponse. This is needed due to the very peculiar SGP.22 notion of signing sections of DER-encoded ASN.1 objects.""" - tdict, l, v, remainder = bertlv_parse_one(prepareDownloadResponse) - rawtag = bertlv_encode_tag(tdict) + rawtag, l, v, remainder = bertlv_parse_one_rawtag(prepareDownloadResponse) if len(remainder): raise ValueError('Excess data at end of TLV') - if b2h(rawtag) != 'bf21': + if rawtag != 0xbf21: raise ValueError('Unexpected outer tag: %s' % b2h(rawtag)) - tdict, l, v1, remainder = bertlv_parse_one(v) - rawtag = bertlv_encode_tag(tdict) - if b2h(rawtag) != 'a0': + rawtag, l, v1, remainder = bertlv_parse_one_rawtag(v) + if rawtag != 0xa0: raise ValueError('Unexpected tag where CHOICE was expected') - tdict, l, v2, remainder = bertlv_parse_one(v1) - rawtag = bertlv_encode_tag(tdict) - if b2h(rawtag) != '30': + rawtag, l, tlv2, remainder = bertlv_return_one_rawtlv(v1) + if rawtag != 0x30: raise ValueError('Unexpected tag where SEQUENCE was expected') - return rawtag + bertlv_encode_len(l) + v2 + return tlv2 diff --git a/pySim/utils.py b/pySim/utils.py index afa476b2..2362b591 100644 --- a/pySim/utils.py +++ b/pySim/utils.py @@ -359,6 +359,32 @@ def bertlv_parse_one(binary: bytes) -> Tuple[dict, int, bytes, bytes]: remainder = remainder[length:] return (tagdict, length, value, remainder) +def bertlv_parse_one_rawtag(binary: bytes) -> Tuple[int, int, bytes, bytes]: + """Parse a single TLV IE at the start of the given binary data; return tag as raw integer. + Args: + binary : binary input data of BER-TLV length field + Returns: + Tuple of (tag:int, len:int, remainder:bytes) + """ + (tag, remainder) = bertlv_parse_tag_raw(binary) + (length, remainder) = bertlv_parse_len(remainder) + value = remainder[:length] + remainder = remainder[length:] + return (tag, length, value, remainder) + +def bertlv_return_one_rawtlv(binary: bytes) -> Tuple[int, int, bytes, bytes]: + """Return one single [encoded] TLV IE at the start of the given binary data. + Args: + binary : binary input data of BER-TLV length field + Returns: + Tuple of (tag:int, len:int, tlv:bytes, remainder:bytes) + """ + (tag, remainder) = bertlv_parse_tag_raw(binary) + (length, remainder) = bertlv_parse_len(remainder) + tl_length = len(binary) - len(remainder) + value = binary[:tl_length] + remainder[:length] + remainder = remainder[length:] + return (tag, length, value, remainder) def dgi_parse_tag_raw(binary: bytes) -> Tuple[int, bytes]: # In absence of any clear spec guidance we assume it's always 16 bit