Compare commits
13 Commits
pmaier/ota
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d8f3c78135 | ||
|
|
6b9b46a5a4 | ||
|
|
b6b4501e37 | ||
|
|
54658fa3a9 | ||
|
|
eb04bb1082 | ||
|
|
453fde5a3a | ||
|
|
57237b650e | ||
|
|
1f94791240 | ||
|
|
1a28575327 | ||
|
|
e7016b5b57 | ||
|
|
e80f3160a9 | ||
|
|
917ad7f9f5 | ||
|
|
8b2a49aa8e |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,5 +1,5 @@
|
||||
*.pyc
|
||||
.*.swp
|
||||
.*.sw?
|
||||
|
||||
/docs/_*
|
||||
/docs/generated
|
||||
|
||||
@@ -141,7 +141,7 @@ class SmppHandler:
|
||||
tuple containing the last response data and the last status word as byte strings
|
||||
"""
|
||||
|
||||
logger.info("C-APDU sending: %s..." % b2h(apdu))
|
||||
logger.info("C-APDU sending: %s...", b2h(apdu))
|
||||
|
||||
# translate to Secured OTA RFM
|
||||
secured = self.ota_dialect.encode_cmd(self.ota_keyset, self.tar, self.spi, apdu=apdu)
|
||||
@@ -194,19 +194,19 @@ if __name__ == '__main__':
|
||||
option_parser.add_argument('--tar', required=True, type=is_hexstr, help='Toolkit Application Reference')
|
||||
option_parser.add_argument("--cntr_req", choices=CNTR_REQ.decmapping.values(), default='no_counter',
|
||||
help="Counter requirement")
|
||||
option_parser.add_argument('--ciphering', default=True, type=bool, help='Enable ciphering')
|
||||
option_parser.add_argument('--no-ciphering', action='store_true', default=False, help='Disable ciphering')
|
||||
option_parser.add_argument("--rc-cc-ds", choices=RC_CC_DS.decmapping.values(), default='cc',
|
||||
help="message check (rc=redundency check, cc=crypt. checksum, ds=digital signature)")
|
||||
option_parser.add_argument('--por-in-submit', default=False, type=bool,
|
||||
option_parser.add_argument('--por-in-submit', action='store_true', default=False,
|
||||
help='require PoR to be sent via SMS-SUBMIT')
|
||||
option_parser.add_argument('--por-shall-be-ciphered', default=True, type=bool, help='require encrypted PoR')
|
||||
option_parser.add_argument('--por-no-ciphering', action='store_true', default=False, help='Disable ciphering (PoR)')
|
||||
option_parser.add_argument("--por-rc-cc-ds", choices=RC_CC_DS.decmapping.values(), default='cc',
|
||||
help="PoR check (rc=redundency check, cc=crypt. checksum, ds=digital signature)")
|
||||
option_parser.add_argument("--por_req", choices=POR_REQ.decmapping.values(), default='por_required',
|
||||
help="Proof of Receipt requirements")
|
||||
option_parser.add_argument('--src-addr', default='12', type=str, help='TODO')
|
||||
option_parser.add_argument('--dest-addr', default='23', type=str, help='TODO')
|
||||
option_parser.add_argument('--timeout', default=10, type=int, help='TODO')
|
||||
option_parser.add_argument('--src-addr', default='12', type=str, help='SMS source address (MSISDN)')
|
||||
option_parser.add_argument('--dest-addr', default='23', type=str, help='SMS destination address (MSISDN)')
|
||||
option_parser.add_argument('--timeout', default=10, type=int, help='Maximum response waiting time')
|
||||
option_parser.add_argument('-a', '--apdu', action='append', required=True, type=is_hexstr, help='C-APDU to send')
|
||||
opts = option_parser.parse_args()
|
||||
|
||||
@@ -214,18 +214,22 @@ if __name__ == '__main__':
|
||||
format='%(asctime)s %(levelname)s %(message)s',
|
||||
datefmt='%Y-%m-%d %H:%M:%S')
|
||||
|
||||
if opts.kic_idx != opts.kid_idx:
|
||||
logger.warning("KIC index (%s) and KID index (%s) are different (security violation, card should reject message)",
|
||||
opts.kic_idx, opts.kid_idx)
|
||||
|
||||
ota_keyset = OtaKeyset(algo_crypt=opts.algo_crypt,
|
||||
kic_idx=opts.kic_idx,
|
||||
kic=h2b(opts.kic),
|
||||
algo_auth=opts.algo_auth,
|
||||
kid_idx=opts.kic_idx,
|
||||
kid_idx=opts.kid_idx,
|
||||
kid=h2b(opts.kid),
|
||||
cntr=opts.cntr)
|
||||
spi = {'counter' : opts.cntr_req,
|
||||
'ciphering' : opts.ciphering,
|
||||
'ciphering' : not opts.no_ciphering,
|
||||
'rc_cc_ds': opts.rc_cc_ds,
|
||||
'por_in_submit':opts.por_in_submit,
|
||||
'por_shall_be_ciphered':opts.por_shall_be_ciphered,
|
||||
'por_in_submit': opts.por_in_submit,
|
||||
'por_shall_be_ciphered': not opts.por_no_ciphering,
|
||||
'por_rc_cc_ds': opts.por_rc_cc_ds,
|
||||
'por': opts.por_req}
|
||||
apdu = h2b("".join(opts.apdu))
|
||||
|
||||
@@ -54,6 +54,8 @@ def compile_asn1_subdir(subdir_name:str, codec='der'):
|
||||
__ver = sys.version_info
|
||||
if (__ver.major, __ver.minor) >= (3, 9):
|
||||
for i in resources.files('pySim.esim').joinpath('asn1').joinpath(subdir_name).iterdir():
|
||||
if not i.name.endswith('.asn'):
|
||||
continue
|
||||
asn_txt += i.read_text()
|
||||
asn_txt += "\n"
|
||||
#else:
|
||||
|
||||
@@ -19,7 +19,6 @@ import abc
|
||||
import requests
|
||||
import logging
|
||||
import json
|
||||
from re import match
|
||||
from typing import Optional
|
||||
import base64
|
||||
from twisted.web.server import Request
|
||||
@@ -211,7 +210,7 @@ class JsonHttpApiFunction(abc.ABC):
|
||||
# additional custom HTTP headers (server responses)
|
||||
extra_http_res_headers = {}
|
||||
|
||||
def __new__(cls, *args, role = None, **kwargs):
|
||||
def __new__(cls, *args, role = 'legacy_client', **kwargs):
|
||||
"""
|
||||
Args:
|
||||
args: (see JsonHttpApiClient and JsonHttpApiServer)
|
||||
@@ -221,14 +220,13 @@ class JsonHttpApiFunction(abc.ABC):
|
||||
|
||||
# Create a dictionary with the class attributes of this class (the properties listed above and the encode_
|
||||
# decode_ methods below). The dictionary will not include any dunder/magic methods
|
||||
cls_attr = { attr_name: getattr(cls, attr_name) for attr_name in dir(cls) if not match("__.*__", attr_name) }
|
||||
cls_attr = {attr_name: getattr(cls, attr_name) for attr_name in dir(cls) if not attr_name.startswith('__')}
|
||||
|
||||
# Normal instantiation as JsonHttpApiFunction:
|
||||
if len(args) == 0:
|
||||
if len(args) == 0 and len(kwargs) == 0:
|
||||
return type(cls.__name__, (abc.ABC,), cls_attr)()
|
||||
|
||||
# Instantiation as as JsonHttpApiFunction with a JsonHttpApiClient or JsonHttpApiServer base
|
||||
role = kwargs.get('role', 'legacy_client')
|
||||
if role == 'legacy_client':
|
||||
# Deprecated: With the advent of the server role (JsonHttpApiServer) the API had to be changed. To maintain
|
||||
# compatibility with existing code (out-of-tree) the original behaviour and API interface and behaviour had
|
||||
|
||||
@@ -352,6 +352,7 @@ class SmspTpScAddr(ConfigurableParameter):
|
||||
strip_chars = ' \t\r\n'
|
||||
max_len = 21 # '+' and 20 digits
|
||||
min_len = 1
|
||||
example_input = '+49301234567'
|
||||
|
||||
@classmethod
|
||||
def validate_val(cls, val):
|
||||
@@ -627,7 +628,7 @@ class MilenageRotationConstants(BinaryParam, AlgoConfig):
|
||||
name = 'MilenageRotation'
|
||||
algo_config_key = 'rotationConstants'
|
||||
allow_len = 5 # length in bytes (from BinaryParam)
|
||||
example_input = '0a 0b 0c 0d 0e'
|
||||
example_input = '40 00 20 40 60'
|
||||
|
||||
@classmethod
|
||||
def validate_val(cls, val):
|
||||
|
||||
@@ -181,7 +181,7 @@ class SeqNumber(BER_TLV_IE, tag=0x80):
|
||||
class NotificationAddress(BER_TLV_IE, tag=0x0c):
|
||||
_construct = Utf8Adapter(GreedyBytes)
|
||||
class Iccid(BER_TLV_IE, tag=0x5a):
|
||||
_construct = BcdAdapter(GreedyBytes)
|
||||
_construct = PaddedBcdAdapter(GreedyBytes)
|
||||
class NotificationMetadata(BER_TLV_IE, tag=0xbf2f, nested=[SeqNumber, ProfileMgmtOperation,
|
||||
NotificationAddress, Iccid]):
|
||||
pass
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
},
|
||||
{
|
||||
"profile_info": {
|
||||
"iccid": "8949449999999990031f",
|
||||
"iccid": "8949449999999990031",
|
||||
"isdp_aid": "a0000005591010ffffffff8900001200",
|
||||
"profile_state": "disabled",
|
||||
"service_provider_name": "OsmocomSPN",
|
||||
|
||||
@@ -23,7 +23,7 @@ import os
|
||||
import json
|
||||
from utils import *
|
||||
|
||||
# This testcase requires a sysmoEUICC1-C2T with the test prfile TS48V1-B-UNIQUE (ICCID 8949449999999990031f)
|
||||
# This testcase requires a sysmoEUICC1-C2T with the test prfile TS48V1-B-UNIQUE (ICCID 8949449999999990031)
|
||||
# installed, and in disabled state. Also the profile must be installed in such a way that notifications are
|
||||
# generated when the profile is disabled or enabled (ProfileMetadata)
|
||||
|
||||
|
||||
@@ -3,6 +3,9 @@ set echo true
|
||||
|
||||
select ADF.ISD-R
|
||||
|
||||
# Ensure that the test-profile we intend to test with is actually enabled
|
||||
enable_profile --iccid 89000123456789012341
|
||||
|
||||
# by ICCID (pre-installed test profile on sysmoEUICC1-C2T)
|
||||
disable_profile --iccid 89000123456789012341 > enable_disable_profile.tmp
|
||||
enable_profile --iccid 89000123456789012341 >> enable_disable_profile.tmp
|
||||
|
||||
@@ -3,6 +3,11 @@ set echo true
|
||||
|
||||
select ADF.ISD-R
|
||||
|
||||
# Generate two (additional) notifications by quickly enabeling the test profile
|
||||
enable_profile --iccid 8949449999999990031f
|
||||
# Ensure that the test-profile is actually enabled. (In case te test-profile
|
||||
# was disabled, a notification may be generated. The testcase should tolerate
|
||||
# that)
|
||||
enable_profile --iccid 89000123456789012341
|
||||
|
||||
# Generate two (additional) notifications by quickly enabeling the test profile
|
||||
enable_profile --iccid 8949449999999990031
|
||||
enable_profile --iccid 89000123456789012341
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
set debug true
|
||||
set echo true
|
||||
|
||||
# The output of get_profiles_info will also include the "profile_state", which
|
||||
# can be either "enabled" or "disabled". Ensure that the correct profile is
|
||||
# enabled.
|
||||
enable_profile --iccid 89000123456789012341
|
||||
|
||||
select ADF.ISD-R
|
||||
get_profiles_info > get_profiles_info.tmp
|
||||
|
||||
Reference in New Issue
Block a user