mirror of https://gerrit.osmocom.org/pysim
cards: Add support for sysmo-isim-sja2
The sysmo-isim-sja2 cards are not yet supported by pysim. Lets add support for writing KI and OPC in ADF.USIM and ADF.ISIM as well as the remaining common simcard parameters. Related: SYS#4466 Change-Id: I23e2b46eac0e0dbc2b271983d448999f6a459ecf
This commit is contained in:
parent
07cd481954
commit
0ad5bcfbc1
136
pySim/cards.py
136
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,120 @@ 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):
|
||||
# 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']))
|
||||
|
||||
# This type of card does not allow to reprogram the ICCID.
|
||||
# Reprogramming the ICCID would mess up the card os software
|
||||
# license management, so the ICCID must be kept at its factory
|
||||
# setting!
|
||||
if p.get('iccid'):
|
||||
print("Warning: Programming of the ICCID is not implemented for this type of card.")
|
||||
|
||||
# select DF_GSM
|
||||
self._scc.select_file(['7f20'])
|
||||
|
||||
# write EF.IMSI
|
||||
if p.get('imsi'):
|
||||
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)
|
||||
|
||||
# update EF-SIM_AUTH_KEY (and EF-USIM_AUTH_KEY_2G, which is
|
||||
# hard linked to EF-USIM_AUTH_KEY)
|
||||
self._scc.select_file(['3f00'])
|
||||
self._scc.select_file(['a515'])
|
||||
if p.get('ki'):
|
||||
self._scc.update_binary('6f20', p['ki'], 1)
|
||||
if p.get('opc'):
|
||||
self._scc.update_binary('6f20', p['opc'], 17)
|
||||
|
||||
# update EF-USIM_AUTH_KEY in ADF.ISIM
|
||||
self._scc.select_file(['3f00'])
|
||||
aid = self.read_aid(isim = True)
|
||||
self._scc.select_adf(aid)
|
||||
if p.get('ki'):
|
||||
self._scc.update_binary('af20', p['ki'], 1)
|
||||
if p.get('opc'):
|
||||
self._scc.update_binary('af20', p['opc'], 17)
|
||||
|
||||
# update EF-USIM_AUTH_KEY in ADF.USIM
|
||||
self._scc.select_file(['3f00'])
|
||||
aid = self.read_aid()
|
||||
self._scc.select_adf(aid)
|
||||
if p.get('ki'):
|
||||
self._scc.update_binary('af20', p['ki'], 1)
|
||||
if p.get('opc'):
|
||||
self._scc.update_binary('af20', p['opc'], 17)
|
||||
|
||||
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:
|
||||
|
|
|
@ -107,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]
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
MCC=001
|
||||
MNC=01
|
||||
ICCID=1122334455667788990
|
||||
KI=AABBCCDDEEFFAABBCCDDEEFFAABBCCDD
|
||||
OPC=12345678901234567890123456789012
|
||||
IMSI=001010000000102
|
||||
ADM=72273953
|
|
@ -0,0 +1,53 @@
|
|||
Using PC/SC reader (dev=0) interface
|
||||
Reading ...
|
||||
ICCID: 8988211900000000004
|
||||
IMSI: 001010000000102
|
||||
SMSP: ffffffffffffffffffffffffffffffffffffffffffffffffe1ffffffffffffffffffffffff0581005155f5ffffffffffff000000
|
||||
PLMNsel: fff11fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
PLMNwAcT:
|
||||
fff11fffff # MCC: 1651 MNC: 151 AcT: UTRAN, E-UTRAN, GSM, GSM COMPACT, cdma2000 HRPD, cdma2000 1xRTT
|
||||
ffffff0000 # unused
|
||||
ffffff0000 # unused
|
||||
ffffff0000 # unused
|
||||
ffffff0000 # unused
|
||||
ffffff0000 # unused
|
||||
ffffff0000 # unused
|
||||
ffffff0000 # unused
|
||||
ffffff0000 # unused
|
||||
ffffff0000 # unused
|
||||
ffffff0000 # unused
|
||||
ffffff0000 # unused
|
||||
|
||||
OPLMNwAcT:
|
||||
fff11fffff # MCC: 1651 MNC: 151 AcT: UTRAN, E-UTRAN, GSM, GSM COMPACT, cdma2000 HRPD, cdma2000 1xRTT
|
||||
ffffff0000 # unused
|
||||
ffffff0000 # unused
|
||||
ffffff0000 # unused
|
||||
ffffff0000 # unused
|
||||
ffffff0000 # unused
|
||||
ffffff0000 # unused
|
||||
ffffff0000 # unused
|
||||
ffffff0000 # unused
|
||||
ffffff0000 # unused
|
||||
ffffff0000 # unused
|
||||
ffffff0000 # unused
|
||||
|
||||
HPLMNAcT:
|
||||
ffffff0000 # unused
|
||||
ffffff0000 # unused
|
||||
ffffffffff # unused
|
||||
ffffffffff # unused
|
||||
ffffffffff # unused
|
||||
ffffffffff # unused
|
||||
ffffffffff # unused
|
||||
ffffffffff # unused
|
||||
ffffffffff # unused
|
||||
ffffffffff # unused
|
||||
ffffffffff # unused
|
||||
ffffff0000 # unused
|
||||
|
||||
ACC: 0001
|
||||
MSISDN: Not available
|
||||
AD: 00000002
|
||||
Done !
|
||||
|
Loading…
Reference in New Issue