aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Maier <pmaier@sysmocom.de>2019-12-20 13:53:34 +0100
committerPhilipp Maier <pmaier@sysmocom.de>2019-12-20 13:53:34 +0100
commit319c7f003cde3c52fc2008e6e9a9b6482e52aa41 (patch)
tree1079c5ead0f3856d071748ad55ab82edcb665e2e
parent4e724391e042cf8a45bf32b2d069120b749bda40 (diff)
-rw-r--r--pySim/cards.py178
-rw-r--r--pySim/commands.py20
2 files changed, 190 insertions, 8 deletions
diff --git a/pySim/cards.py b/pySim/cards.py
index 758ec0e..c0abcd5 100644
--- a/pySim/cards.py
+++ b/pySim/cards.py
@@ -144,6 +144,30 @@ class Card(object):
data, sw = self._scc.update_binary(EF['SPN'], rpad(content, 32))
return sw
+ # Read the (full) AID for either ISIM or USIM application
+ def read_aid(self, isim = False):
+
+ # First (known) halves of the AID
+ aid_usim = "a0000000871002"
+ aid_isim = "a0000000871004"
+
+ # Select which one to look for
+ if isim:
+ aid = aid_isim
+ else:
+ aid = aid_usim
+
+ # Find out how many records the EF.DIR has, then go through
+ # all records and try to find the AID we are looking for
+ aid_record_count = self._scc.record_count(['2F00'])
+ for i in range(0, aid_record_count):
+ record = self._scc.read_record(['2F00'], i + 1)
+ if aid in record[0]:
+ aid_len = int(record[0][6:8], 16)
+ return record[0][8:8 + aid_len * 2]
+
+ return None
+
class _MagicSimBase(Card):
"""
@@ -911,10 +935,162 @@ class WavemobileSim(Card):
return
+
+
+
+
+
+
+
+
+
+class SysmoISIMSJA2(Card):
+ """
+ sysmocom sysmoISIM-SJA2
+ """
+
+ name = 'sysmoISIM-SJA2'
+
+ def __init__(self, ssc):
+ super(SysmoISIMSJA2, self).__init__(ssc)
+ self._scc.cla_byte = "00"
+ self._scc.sel_ctrl = "0004" #request an FCP
+
+ @classmethod
+ def autodetect(kls, scc):
+ try:
+ # Try card model #1
+ atr = "3B 9F 96 80 1F 87 80 31 E0 73 FE 21 1B 67 4A 4C 75 30 34 05 4B A9"
+ if scc.get_atr() == toBytes(atr):
+ return kls(scc)
+
+ # Try card model #2
+ atr = "3B 9F 96 80 1F 87 80 31 E0 73 FE 21 1B 67 4A 4C 75 31 33 02 51 B2"
+ if scc.get_atr() == toBytes(atr):
+ return kls(scc)
+ except:
+ return None
+ return None
+
+
+
+
+
+
+
+
+
+
+ def program(self, p):
+ print "=================================================="
+
+ # authenticate as ADM using default key (written on the card..)
+ if not p['pin_adm']:
+ raise ValueError("Please provide a PIN-ADM as there is no default one")
+ self._scc.verify_chv(0x0A, h2b(p['pin_adm']))
+
+ if p.get('iccid'):
+ print("Warning: Programming of the ICCID is not implemented for this type of card.")
+
+
+
+
+ # select MF
+ r = self._scc.select_file(['3f00'])
+
+ print "==================== ADF.ISIM ======================="
+ r = self._scc.select_file(['3f00'])
+ aid = self.read_aid(isim = True)
+ r = self._scc.select_adf(aid)
+ print r
+
+
+
+
+ print "==================== ADF.USIM ======================="
+ r = self._scc.select_file(['3f00'])
+ aid = self.read_aid()
+ r = self._scc.select_adf(aid)
+ print r
+
+
+
+
+ print "====================================================="
+
+
+
+ # select DF_SYSTEM
+ r = self._scc.select_file(['3f00'])
+ r = self._scc.select_file(['A515'])
+ data, sw = self._scc.update_binary('6F20', p['ki'], 1)
+
+
+
+
+
+ # select DF_GSM
+ r = self._scc.select_file(['7f20'])
+
+ # write EF.IMSI
+ data, sw = self._scc.update_binary('6f07', enc_imsi(p['imsi']))
+
+ # EF.PLMNsel
+ if p.get('mcc') and p.get('mnc'):
+ sw = self.update_plmnsel(p['mcc'], p['mnc'])
+ if sw != '9000':
+ print("Programming PLMNsel failed with code %s"%sw)
+
+ # EF.PLMNwAcT
+ if p.get('mcc') and p.get('mnc'):
+ sw = self.update_plmn_act(p['mcc'], p['mnc'])
+ if sw != '9000':
+ print("Programming PLMNwAcT failed with code %s"%sw)
+
+ # EF.OPLMNwAcT
+ if p.get('mcc') and p.get('mnc'):
+ sw = self.update_oplmn_act(p['mcc'], p['mnc'])
+ if sw != '9000':
+ print("Programming OPLMNwAcT failed with code %s"%sw)
+
+ # EF.AD
+ if p.get('mcc') and p.get('mnc'):
+ sw = self.update_ad(p['mnc'])
+ if sw != '9000':
+ print("Programming AD failed with code %s"%sw)
+
+ # EF.SMSP
+ if p.get('smsp'):
+ r = self._scc.select_file(['3f00', '7f10'])
+ data, sw = self._scc.update_record('6f42', 1, lpad(p['smsp'], 104), force_len=True)
+
+ return
+
+ def erase(self):
+ return
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# In order for autodetection ...
_cards_classes = [ FakeMagicSim, SuperSim, MagicSim, GrcardSim,
SysmoSIMgr1, SysmoSIMgr2, SysmoUSIMgr1, SysmoUSIMSJS1,
- FairwavesSIM, OpenCellsSim, WavemobileSim ]
+ FairwavesSIM, OpenCellsSim, WavemobileSim, SysmoISIMSJA2 ]
def card_autodetect(scc):
for kls in _cards_classes:
diff --git a/pySim/commands.py b/pySim/commands.py
index 03540b6..385cacf 100644
--- a/pySim/commands.py
+++ b/pySim/commands.py
@@ -30,8 +30,8 @@ class SimCardCommands(object):
self._cla_byte = "a0"
self.sel_ctrl = "0000"
- # Get file size from FCP
- def __get_len_from_tlv(self, fcp):
+ # Extract a single FCP item from TLV
+ def __parse_fcp(self, fcp):
# see also: ETSI TS 102 221, chapter 11.1.1.3.1 Response for MF,
# DF or ADF
from pytlv.TLV import TLV
@@ -58,9 +58,7 @@ class SimCardCommands(object):
# Skip FCP tag and length
tlv = fcp[skip:]
- tlv_parsed = tlvparser.parse(tlv)
-
- return int(tlv_parsed['80'], 16)
+ return tlvparser.parse(tlv)
# Tell the length of a record by the card response
# USIMs respond with an FCP template, which is different
@@ -69,7 +67,10 @@ class SimCardCommands(object):
# SIM: GSM 11.11, chapter 9.2.1 SELECT
def __record_len(self, r):
if self.sel_ctrl == "0004":
- return self.__get_len_from_tlv(r[-1])
+ tlv_parsed = self.__parse_fcp(r[-1])
+ file_descriptor = tlv_parsed['82']
+ # See also ETSI TS 102 221, chapter 11.1.1.4.3 File Descriptor
+ return int(file_descriptor[4:8], 16)
else:
return int(r[-1][28:30], 16)
@@ -77,7 +78,8 @@ class SimCardCommands(object):
# above.
def __len(self, r):
if self.sel_ctrl == "0004":
- return self.__get_len_from_tlv(r[-1])
+ tlv_parsed = self.__parse_fcp(r[-1])
+ return int(tlv_parsed['80'], 16)
else:
return int(r[-1][4:8], 16)
@@ -105,6 +107,10 @@ class SimCardCommands(object):
rv.append(data)
return rv
+ def select_adf(self, aid):
+ aidlen = ("0" + format(len(aid)/2, 'x'))[-2:]
+ return self._tp.send_apdu_checksw(self.cla_byte + "a4" + "0404" + aidlen + aid)
+
def read_binary(self, ef, length=None, offset=0):
if not hasattr(type(ef), '__iter__'):
ef = [ef]