LCSClientID optional field cannot be set in an EMM message because of error during ber-encoding
Marc-Egli opened this issue · comments
Hello,
I am currently working on generating some NAS packets and I observed some strange behavior when setting the LCSClientID optional field inside an EMMCSServiceNotification
message.
From the below code, I concluded that I needed to generate an LCSClientID message using the ASN.1 specifications.
LCSClientId = wrapper.gen_ber_wrapper(MAP.MAP_LCS_DataTypes.LCS_ClientID,
asn_map_acquire,
asn_map_release)
I obtained the below LCSClientID message which is correctly decoded and encoded. All values are random but conform to the specifications.
{'lcsClientType': 'emergencyServices', 'lcsClientExternalID': {'externalAddress': b'J', 'extensionContainer': {'privateExtensionList': [{'extId': (179, 17, 158, 19), 'extType': ('BOOLEAN', True)}], 'pcs-Extensions': {}}}, 'lcsClientDialedByMS': b'"\xed', 'lcsClientInternalID': 'o-andM-VPLMN', 'lcsClientName': {'dataCodingScheme': b'\x11', 'nameString': b'h\xecQ\xc9\x89@U\x03X\xaf\xda\xcd\\\x8c\xfc\xc3B\xea'}}
I then use this dictionary to set the value of the LCSClientID in the EMMCSServiceNotification
message.
When doing so I get the following error :
File "/usr/local/lib/python3.10/dist-packages/pycrate-0.5.5-py3.10.egg/pycrate_asn1rt/wrapper.py", line 123, in set_val
self._buf = self.OBJ.to_ber()
File "/usr/local/lib/python3.10/dist-packages/pycrate-0.5.5-py3.10.egg/pycrate_asn1rt/asnobj.py", line 1680, in to_ber
return pack_val(*self._to_ber())[0]
File "/usr/local/lib/python3.10/dist-packages/pycrate-0.5.5-py3.10.egg/pycrate_asn1rt/asnobj.py", line 1629, in _to_ber
pc, lval, V = self._encode_ber_cont()
File "/usr/local/lib/python3.10/dist-packages/pycrate-0.5.5-py3.10.egg/pycrate_asn1rt/asnobj_construct.py", line 2205, in _encode_ber_cont
comp_tlv = Comp._to_ber()
File "/usr/local/lib/python3.10/dist-packages/pycrate-0.5.5-py3.10.egg/pycrate_asn1rt/asnobj.py", line 1629, in _to_ber
pc, lval, V = self._encode_ber_cont()
File "/usr/local/lib/python3.10/dist-packages/pycrate-0.5.5-py3.10.egg/pycrate_asn1rt/asnobj_construct.py", line 2205, in _encode_ber_cont
comp_tlv = Comp._to_ber()
File "/usr/local/lib/python3.10/dist-packages/pycrate-0.5.5-py3.10.egg/pycrate_asn1rt/asnobj.py", line 1629, in _to_ber
pc, lval, V = self._encode_ber_cont()
File "/usr/local/lib/python3.10/dist-packages/pycrate-0.5.5-py3.10.egg/pycrate_asn1rt/asnobj_construct.py", line 2205, in _encode_ber_cont
comp_tlv = Comp._to_ber()
File "/usr/local/lib/python3.10/dist-packages/pycrate-0.5.5-py3.10.egg/pycrate_asn1rt/asnobj.py", line 1629, in _to_ber
pc, lval, V = self._encode_ber_cont()
File "/usr/local/lib/python3.10/dist-packages/pycrate-0.5.5-py3.10.egg/pycrate_asn1rt/asnobj_construct.py", line 3156, in _encode_ber_cont
tlv = Comp._to_ber()
File "/usr/local/lib/python3.10/dist-packages/pycrate-0.5.5-py3.10.egg/pycrate_asn1rt/asnobj.py", line 1629, in _to_ber
pc, lval, V = self._encode_ber_cont()
File "/usr/local/lib/python3.10/dist-packages/pycrate-0.5.5-py3.10.egg/pycrate_asn1rt/asnobj_construct.py", line 2205, in _encode_ber_cont
comp_tlv = Comp._to_ber()
File "/usr/local/lib/python3.10/dist-packages/pycrate-0.5.5-py3.10.egg/pycrate_asn1rt/asnobj.py", line 1629, in _to_ber
pc, lval, V = self._encode_ber_cont()
File "/usr/local/lib/python3.10/dist-packages/pycrate-0.5.5-py3.10.egg/pycrate_asn1rt/asnobj_ext.py", line 582, in _encode_ber_cont
TLV = Obj._to_ber()
File "/usr/local/lib/python3.10/dist-packages/pycrate-0.5.5-py3.10.egg/pycrate_asn1rt/asnobj.py", line 1630, in _to_ber
if not self._tagc:
AttributeError: 'BOOL' object has no attribute '_tagc'. Did you mean: '_tag'?
I traced back the error to the privateExtensionList
field that contains an extId
and a extType
. The issue is that the type I provide cannot be ber encoded because of the missing _tagc
attribute. I verified the definition of the extType
, which is an ASN.1 OpenType, I should be able to provide any type to this field. The LCSClientID packet is valid but the encoding to put it into the EMMCSServiceNotification
message fails.
Thank you in advance.
Thanks for the report. Can you share a code snippet to reproduce the issue ?
Sure, here is a small example:
from pycrate_mobile.NAS import *
lcs_packet = MAP.MAP_LCS_DataTypes.LCS_ClientID
lcs_fields = {'lcsClientType': 'lawfulInterceptServices', 'lcsClientExternalID': {'externalAddress': b'\xaa\x8e\xa9\xdaqg', 'extensionContainer': { 'privateExtensionList': [{'extId': (0,1,2,3,4), 'extType' : ('BOOLEAN', True)}],'pcs-Extensions': {}}}, 'lcsClientDialedByMS': b'[\x129\x10\xd47\x02w\x10\xbb\xe0\x1fM\xc8\xc9', 'lcsClientInternalID': 'o-andM-HPLMN', 'lcsClientName': {'dataCodingScheme': b';', 'nameString': b'\x97\xfe6yh<\xbe\\Q\x91\x14\xbaVT\xa3'}}
lcs_packet.set_val(lcs_fields)
# Detect invalid format by encoding and decoding
try:
lcs = MAP.MAP_LCS_DataTypes.LCS_ClientID
lcs.from_uper(lcs_packet.to_uper())
except Exception as err:
print("Decoding failed")
exit(0)
# Set LCSClientID fields in EMMCSServiceNotification message
val = {'LCSClientId' : lcs_fields}
msg = EMMCSServiceNotification(val=val)
This code snippet crashes when the LCSClientID field is set in the EMMCSServiceNotification message.
Here is a shorter code snippet that exhibits the issue:
from pycrate_asn1dir.MAP import *
p = MAP_LCS_DataTypes.LCS_ClientID
v = {'lcsClientType': 'lawfulInterceptServices', 'lcsClientExternalID': {'externalAddress': b'\xaa\x8e\xa9\xdaqg', 'extensionContainer': { 'privateExtensionList': [{'extId': (0,1,2,3,4), 'extType': ('BOOLEAN', True)}],'pcs-Extensions': {}}}, 'lcsClientDialedByMS': b'[\x129\x10\xd47\x02w\x10\xbb\xe0\x1fM\xc8\xc9', 'lcsClientInternalID': 'o-andM-HPLMN', 'lcsClientName': {'dataCodingScheme': b';', 'nameString': b'\x97\xfe6yh<\xbe\\Q\x91\x14\xbaVT\xa3'}}
p.set_val(v)
p.to_ber()
One remark with your code: you use from_uper()
and to_uper()
with the MAP object, which is incorrect, as MAP relies on the BER codec. The issue lies in the use of an arbitrary object (here, a raw boolean) in the privateExtensionList
which contains OPEN objects, together with the BER encoding which requires object tagging. I'll need to check more carefully on how to address the issue properly.
Thank you very much for looking into this issue and also for the explanation about the incorrect function calls from_uper()
and to_uper()
on the MAP object.
I just pushed 581a50f, that should fix the issue you reported. Can you test it on your side and give me a feedback ?
Thanks for your help.
I just tested on my side and the fix works for me.
Thank you very much for having looked into it and finding a patch !