Compare commits
5 Commits
laforge/sm
...
zecke/tmp2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d56eb30eea | ||
|
|
533a0dce3a | ||
|
|
29474b0d5b | ||
|
|
800c9eb097 | ||
|
|
73b686f7ee |
@@ -62,6 +62,9 @@ def parse_options():
|
||||
help="Card type (user -t list to view) [default: %default]",
|
||||
default="auto",
|
||||
)
|
||||
parser.add_option("-a", "--pin-adm", dest="pin_adm",
|
||||
help="ADM PIN used for provisioning (overwrites default)",
|
||||
)
|
||||
parser.add_option("-e", "--erase", dest="erase", action='store_true',
|
||||
help="Erase beforehand [default: %default]",
|
||||
default=False,
|
||||
@@ -224,7 +227,7 @@ def derive_milenage_opc(ki_hex, op_hex):
|
||||
return b2h(strxor(opc_bytes, h2b(op_hex)))
|
||||
|
||||
def gen_parameters(opts):
|
||||
"""Generates Name, ICCID, MCC, MNC, IMSI, SMSP, Ki from the
|
||||
"""Generates Name, ICCID, MCC, MNC, IMSI, SMSP, Ki, PIN-ADM from the
|
||||
options given by the user"""
|
||||
|
||||
# MCC/MNC
|
||||
@@ -349,6 +352,14 @@ def gen_parameters(opts):
|
||||
else:
|
||||
opc = ''.join(['%02x' % random.randrange(0,256) for i in range(16)])
|
||||
|
||||
if opts.pin_adm is not None:
|
||||
if len(opts.pin_adm) > 8:
|
||||
raise ValueError("PIN-ADM needs to be <=8 digits")
|
||||
pin_adm = ''.join(['%02x'%(ord(x)) for x in opts.pin_adm])
|
||||
pin_adm = rpad(pin_adm, 16)
|
||||
else:
|
||||
pin_adm = None
|
||||
|
||||
|
||||
# Return that
|
||||
return {
|
||||
@@ -361,6 +372,7 @@ def gen_parameters(opts):
|
||||
'ki' : ki,
|
||||
'opc' : opc,
|
||||
'acc' : acc,
|
||||
'pin_adm' : pin_adm,
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -264,7 +264,11 @@ class GrcardSim(Card):
|
||||
#self._scc.verify_chv(4, h2b("4444444444444444"))
|
||||
|
||||
# Authenticate using ADM PIN 5
|
||||
self._scc.verify_chv(5, h2b("4444444444444444"))
|
||||
if p['pin_adm']:
|
||||
pin = p['pin_adm']
|
||||
else:
|
||||
pin = h2b("4444444444444444")
|
||||
self._scc.verify_chv(5, pin)
|
||||
|
||||
# EF.ICCID
|
||||
r = self._scc.select_file(['3f00', '2fe2'])
|
||||
@@ -365,11 +369,17 @@ class SysmoSIMgr2(Card):
|
||||
# P1: 3A for PIN, 3B for PUK
|
||||
# P2: CHV number, as in VERIFY CHV for PIN, and as in UNBLOCK CHV for PUK
|
||||
# P3: 08, CHV length (curiously the PUK is also 08 length, instead of 10)
|
||||
pdu = 'A0D43A0508' + "4444444444444444"
|
||||
if p['pin_adm']:
|
||||
pin = p['pin_adm']
|
||||
else:
|
||||
pin = h2b("4444444444444444")
|
||||
|
||||
pdu = 'A0D43A0508' + b2h(pin)
|
||||
data, sw = self._scc._tp.send_apdu(pdu)
|
||||
|
||||
# authenticate as ADM (enough to write file, and can set PINs)
|
||||
self._scc.verify_chv(0x05, h2b("4444444444444444"))
|
||||
|
||||
self._scc.verify_chv(0x05, pin)
|
||||
|
||||
# write EF.ICCID
|
||||
data, sw = self._scc.update_binary('2fe2', enc_iccid(p['iccid']))
|
||||
@@ -405,7 +415,60 @@ class SysmoSIMgr2(Card):
|
||||
def erase(self):
|
||||
return
|
||||
|
||||
class SysmoUSIMSJS1(Card):
|
||||
"""
|
||||
sysmocom sysmoUSIM-SJS1
|
||||
"""
|
||||
|
||||
name = 'sysmoUSIM-SJS1'
|
||||
|
||||
def __init__(self, ssc):
|
||||
super(SysmoUSIMSJS1, self).__init__(ssc)
|
||||
self._scc.cla_byte = "00"
|
||||
|
||||
@classmethod
|
||||
def autodetect(kls, scc):
|
||||
# TODO: look for ATR 3B 9F 96 80 1F C7 80 31 A0 73 BE 21 13 67 43 20 07 18 00 00 01 A5
|
||||
return None
|
||||
|
||||
def program(self, p):
|
||||
|
||||
|
||||
# select MF
|
||||
r = self._scc.select_file(['3f00'])
|
||||
|
||||
# select DF_GSM
|
||||
r = self._scc.select_file(['7f20'])
|
||||
|
||||
# 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']))
|
||||
|
||||
|
||||
# set Ki in proprietary file
|
||||
data, sw = self._scc.update_binary('00FF', p['ki'])
|
||||
|
||||
# set Ki in proprietary file
|
||||
content = "01" + p['opc']
|
||||
data, sw = self._scc.update_binary('00F7', content)
|
||||
|
||||
# write EF.IMSI
|
||||
data, sw = self._scc.update_binary('6f07', enc_imsi(p['imsi']))
|
||||
|
||||
# write EF.AUTH
|
||||
content = "0101"
|
||||
r = self._scc.select_file(['7FCC', '6f00'])
|
||||
data, sw = self._scc.update_binary('6f00', content)
|
||||
|
||||
|
||||
|
||||
def erase(self):
|
||||
return
|
||||
|
||||
|
||||
|
||||
# In order for autodetection ...
|
||||
_cards_classes = [ FakeMagicSim, SuperSim, MagicSim, GrcardSim,
|
||||
SysmoSIMgr1, SysmoSIMgr2, SysmoUSIMgr1 ]
|
||||
SysmoSIMgr1, SysmoSIMgr2, SysmoUSIMgr1, SysmoUSIMSJS1 ]
|
||||
|
||||
@@ -28,11 +28,20 @@ from pySim.utils import rpad, b2h
|
||||
class SimCardCommands(object):
|
||||
def __init__(self, transport):
|
||||
self._tp = transport;
|
||||
self._cla_byte = "a0"
|
||||
|
||||
@property
|
||||
def cla_byte(self):
|
||||
return self._cla_byte
|
||||
@cla_byte.setter
|
||||
def cla_byte(self, value):
|
||||
self._cla_byte = value
|
||||
|
||||
|
||||
def select_file(self, dir_list):
|
||||
rv = []
|
||||
for i in dir_list:
|
||||
data, sw = self._tp.send_apdu_checksw("a0a4000002" + i)
|
||||
data, sw = self._tp.send_apdu_checksw(self.cla_byte + "a4000C02" + i)
|
||||
rv.append(data)
|
||||
return rv
|
||||
|
||||
@@ -42,14 +51,14 @@ class SimCardCommands(object):
|
||||
r = self.select_file(ef)
|
||||
if length is None:
|
||||
length = int(r[-1][4:8], 16) - offset
|
||||
pdu = 'a0b0%04x%02x' % (offset, (min(256, length) & 0xff))
|
||||
pdu = self.cla_byte + 'b0%04x%02x' % (offset, (min(256, length) & 0xff))
|
||||
return self._tp.send_apdu(pdu)
|
||||
|
||||
def update_binary(self, ef, data, offset=0):
|
||||
if not hasattr(type(ef), '__iter__'):
|
||||
ef = [ef]
|
||||
self.select_file(ef)
|
||||
pdu = 'a0d6%04x%02x' % (offset, len(data)/2) + data
|
||||
pdu = self.cla_byte + 'd6%04x%02x' % (offset, len(data)/2) + data
|
||||
return self._tp.send_apdu_checksw(pdu)
|
||||
|
||||
def read_record(self, ef, rec_no):
|
||||
@@ -57,7 +66,7 @@ class SimCardCommands(object):
|
||||
ef = [ef]
|
||||
r = self.select_file(ef)
|
||||
rec_length = int(r[-1][28:30], 16)
|
||||
pdu = 'a0b2%02x04%02x' % (rec_no, rec_length)
|
||||
pdu = self.cla_byte + 'b2%02x04%02x' % (rec_no, rec_length)
|
||||
return self._tp.send_apdu(pdu)
|
||||
|
||||
def update_record(self, ef, rec_no, data, force_len=False):
|
||||
@@ -70,7 +79,7 @@ class SimCardCommands(object):
|
||||
raise ValueError('Invalid data length (expected %d, got %d)' % (rec_length, len(data)/2))
|
||||
else:
|
||||
rec_length = len(data)/2
|
||||
pdu = ('a0dc%02x04%02x' % (rec_no, rec_length)) + data
|
||||
pdu = (self.cla_byte + 'dc%02x04%02x' % (rec_no, rec_length)) + data
|
||||
return self._tp.send_apdu_checksw(pdu)
|
||||
|
||||
def record_size(self, ef):
|
||||
@@ -85,11 +94,11 @@ class SimCardCommands(object):
|
||||
if len(rand) != 32:
|
||||
raise ValueError('Invalid rand')
|
||||
self.select_file(['3f00', '7f20'])
|
||||
return self._tp.send_apdu('a088000010' + rand)
|
||||
return self._tp.send_apdu(self.cla_byte + '88000010' + rand)
|
||||
|
||||
def reset_card(self):
|
||||
return self._tp.reset_card()
|
||||
|
||||
def verify_chv(self, chv_no, code):
|
||||
fc = rpad(b2h(code), 16)
|
||||
return self._tp.send_apdu_checksw('a02000' + ('%02x' % chv_no) + '08' + fc)
|
||||
return self._tp.send_apdu_checksw(self.cla_byte + '2000' + ('%02X' % chv_no) + '08' + fc)
|
||||
Reference in New Issue
Block a user