2017-12-29 19:30:35 +00:00
|
|
|
#!/usr/bin/env python2
|
2013-07-04 13:34:06 +00:00
|
|
|
|
|
|
|
#
|
|
|
|
# Utility to display some informations about a SIM card
|
|
|
|
#
|
|
|
|
#
|
|
|
|
# Copyright (C) 2009 Sylvain Munaut <tnt@246tNt.com>
|
|
|
|
# Copyright (C) 2010 Harald Welte <laforge@gnumonks.org>
|
|
|
|
# Copyright (C) 2013 Alexander Chemeris <alexander.chemeris@gmail.com>
|
|
|
|
#
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation, either version 2 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#
|
|
|
|
|
|
|
|
import hashlib
|
|
|
|
from optparse import OptionParser
|
|
|
|
import os
|
|
|
|
import random
|
|
|
|
import re
|
|
|
|
import sys
|
2020-03-20 17:50:39 +00:00
|
|
|
from pySim.ts_51_011 import EF, DF, EF_SST_map
|
2020-03-22 07:20:11 +00:00
|
|
|
from pySim.ts_31_102 import EF_UST_map
|
2020-03-22 07:58:33 +00:00
|
|
|
from pySim.ts_31_103 import EF_IST_map
|
2013-07-04 13:34:06 +00:00
|
|
|
|
|
|
|
from pySim.commands import SimCardCommands
|
2020-03-18 10:38:00 +00:00
|
|
|
from pySim.cards import card_detect, Card
|
2020-04-20 11:30:34 +00:00
|
|
|
from pySim.utils import h2b, swap_nibbles, rpad, dec_imsi, dec_iccid, dec_msisdn, format_xplmn_w_act, dec_spn, dec_st
|
2013-07-04 13:34:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
def parse_options():
|
|
|
|
|
|
|
|
parser = OptionParser(usage="usage: %prog [options]")
|
|
|
|
|
|
|
|
parser.add_option("-d", "--device", dest="device", metavar="DEV",
|
|
|
|
help="Serial Device for SIM access [default: %default]",
|
|
|
|
default="/dev/ttyUSB0",
|
|
|
|
)
|
|
|
|
parser.add_option("-b", "--baud", dest="baudrate", type="int", metavar="BAUD",
|
|
|
|
help="Baudrate used for SIM access [default: %default]",
|
|
|
|
default=9600,
|
|
|
|
)
|
|
|
|
parser.add_option("-p", "--pcsc-device", dest="pcsc_dev", type='int', metavar="PCSC",
|
|
|
|
help="Which PC/SC reader number for SIM access",
|
|
|
|
default=None,
|
|
|
|
)
|
2018-10-26 19:10:34 +00:00
|
|
|
parser.add_option("--osmocon", dest="osmocon_sock", metavar="PATH",
|
|
|
|
help="Socket path for Calypso (e.g. Motorola C1XX) based reader (via OsmocomBB)",
|
|
|
|
default=None,
|
|
|
|
)
|
2013-07-04 13:34:06 +00:00
|
|
|
|
|
|
|
(options, args) = parser.parse_args()
|
|
|
|
|
|
|
|
if args:
|
|
|
|
parser.error("Extraneous arguments")
|
|
|
|
|
|
|
|
return options
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
|
|
|
# Parse options
|
|
|
|
opts = parse_options()
|
|
|
|
|
2018-10-26 23:30:33 +00:00
|
|
|
# Init card reader driver
|
|
|
|
if opts.pcsc_dev is not None:
|
2018-10-28 19:02:14 +00:00
|
|
|
print("Using PC/SC reader (dev=%d) interface"
|
|
|
|
% opts.pcsc_dev)
|
2013-07-04 13:34:06 +00:00
|
|
|
from pySim.transport.pcsc import PcscSimLink
|
|
|
|
sl = PcscSimLink(opts.pcsc_dev)
|
2018-10-26 19:10:34 +00:00
|
|
|
elif opts.osmocon_sock is not None:
|
2018-10-28 19:02:14 +00:00
|
|
|
print("Using Calypso-based (OsmocomBB, sock=%s) reader interface"
|
|
|
|
% opts.osmocon_sock)
|
2018-10-26 19:10:34 +00:00
|
|
|
from pySim.transport.calypso import CalypsoSimLink
|
|
|
|
sl = CalypsoSimLink(sock_path=opts.osmocon_sock)
|
2018-10-26 23:30:33 +00:00
|
|
|
else: # Serial reader is default
|
2018-10-28 19:02:14 +00:00
|
|
|
print("Using serial reader (port=%s, baudrate=%d) interface"
|
|
|
|
% (opts.device, opts.baudrate))
|
2018-10-26 23:30:33 +00:00
|
|
|
from pySim.transport.serial import SerialSimLink
|
|
|
|
sl = SerialSimLink(device=opts.device, baudrate=opts.baudrate)
|
2013-07-04 13:34:06 +00:00
|
|
|
|
|
|
|
# Create command layer
|
|
|
|
scc = SimCardCommands(transport=sl)
|
|
|
|
|
|
|
|
# Wait for SIM card
|
|
|
|
sl.wait_for_card()
|
|
|
|
|
2020-03-23 09:00:50 +00:00
|
|
|
# Assuming UICC SIM
|
|
|
|
scc.cla_byte = "00"
|
|
|
|
scc.sel_ctrl = "0004"
|
|
|
|
|
|
|
|
# Testing for Classic SIM or UICC
|
|
|
|
(res, sw) = sl.send_apdu(scc.cla_byte + "a4" + scc.sel_ctrl + "02" + "3f00")
|
|
|
|
if sw == '6e00':
|
|
|
|
# Just a Classic SIM
|
|
|
|
scc.cla_byte = "a0"
|
|
|
|
scc.sel_ctrl = "0000"
|
|
|
|
|
2013-07-04 13:34:06 +00:00
|
|
|
# Program the card
|
|
|
|
print("Reading ...")
|
|
|
|
|
2020-03-18 10:38:00 +00:00
|
|
|
# Initialize Card object by auto detecting the card
|
|
|
|
card = card_detect("auto", scc) or Card(scc)
|
|
|
|
|
2020-03-20 19:20:27 +00:00
|
|
|
# Read all AIDs on the UICC
|
|
|
|
card.read_aids()
|
|
|
|
|
2013-07-04 13:34:06 +00:00
|
|
|
# EF.ICCID
|
2020-03-18 11:02:34 +00:00
|
|
|
(res, sw) = card.read_iccid()
|
2013-07-04 13:34:06 +00:00
|
|
|
if sw == '9000':
|
2020-03-18 11:02:34 +00:00
|
|
|
print("ICCID: %s" % (res,))
|
2013-07-04 13:34:06 +00:00
|
|
|
else:
|
|
|
|
print("ICCID: Can't read, response code = %s" % (sw,))
|
|
|
|
|
|
|
|
# EF.IMSI
|
2020-03-18 11:05:06 +00:00
|
|
|
(res, sw) = card.read_imsi()
|
2013-07-04 13:34:06 +00:00
|
|
|
if sw == '9000':
|
2020-03-18 11:05:06 +00:00
|
|
|
print("IMSI: %s" % (res,))
|
2013-07-04 13:34:06 +00:00
|
|
|
else:
|
|
|
|
print("IMSI: Can't read, response code = %s" % (sw,))
|
|
|
|
|
2020-03-05 14:30:22 +00:00
|
|
|
# EF.GID1
|
|
|
|
try:
|
2020-03-18 11:14:48 +00:00
|
|
|
(res, sw) = card.read_gid1()
|
2020-03-05 14:30:22 +00:00
|
|
|
if sw == '9000':
|
|
|
|
print("GID1: %s" % (res,))
|
|
|
|
else:
|
|
|
|
print("GID1: Can't read, response code = %s" % (sw,))
|
|
|
|
except Exception as e:
|
|
|
|
print("GID1: Can't read file -- %s" % (str(e),))
|
|
|
|
|
2020-03-05 14:33:00 +00:00
|
|
|
# EF.GID2
|
|
|
|
try:
|
2020-04-01 07:21:20 +00:00
|
|
|
(res, sw) = card.read_binary('GID2')
|
2020-03-05 14:33:00 +00:00
|
|
|
if sw == '9000':
|
|
|
|
print("GID2: %s" % (res,))
|
|
|
|
else:
|
|
|
|
print("GID2: Can't read, response code = %s" % (sw,))
|
|
|
|
except Exception as e:
|
|
|
|
print("GID2: Can't read file -- %s" % (str(e),))
|
|
|
|
|
2013-07-04 13:34:06 +00:00
|
|
|
# EF.SMSP
|
2020-03-19 11:08:20 +00:00
|
|
|
(res, sw) = card.read_record('SMSP', 1)
|
2013-07-04 13:34:06 +00:00
|
|
|
if sw == '9000':
|
|
|
|
print("SMSP: %s" % (res,))
|
|
|
|
else:
|
|
|
|
print("SMSP: Can't read, response code = %s" % (sw,))
|
|
|
|
|
2019-06-08 05:49:08 +00:00
|
|
|
# EF.SPN
|
|
|
|
try:
|
2020-03-19 11:11:25 +00:00
|
|
|
(res, sw) = card.read_spn()
|
2019-06-08 05:49:08 +00:00
|
|
|
if sw == '9000':
|
2020-03-19 11:11:25 +00:00
|
|
|
print("SPN: %s" % (res[0] or "Not available"))
|
|
|
|
print("Display HPLMN: %s" % (res[1],))
|
|
|
|
print("Display OPLMN: %s" % (res[2],))
|
2019-06-08 05:49:08 +00:00
|
|
|
else:
|
|
|
|
print("SPN: Can't read, response code = %s" % (sw,))
|
|
|
|
except Exception as e:
|
|
|
|
print("SPN: Can't read file -- %s" % (str(e),))
|
|
|
|
|
2018-07-11 21:05:58 +00:00
|
|
|
# EF.PLMNsel
|
|
|
|
try:
|
2020-03-19 11:14:10 +00:00
|
|
|
(res, sw) = card.read_binary('PLMNsel')
|
2019-09-11 23:46:25 +00:00
|
|
|
if sw == '9000':
|
|
|
|
print("PLMNsel: %s" % (res))
|
|
|
|
else:
|
|
|
|
print("PLMNsel: Can't read, response code = %s" % (sw,))
|
2018-07-11 21:05:58 +00:00
|
|
|
except Exception as e:
|
2020-01-25 05:45:37 +00:00
|
|
|
print("PLMNsel: Can't read file -- " + str(e))
|
2018-07-11 21:05:58 +00:00
|
|
|
|
|
|
|
# EF.PLMNwAcT
|
2019-09-11 23:46:25 +00:00
|
|
|
try:
|
2020-03-19 11:42:10 +00:00
|
|
|
(res, sw) = card.read_plmn_act()
|
2019-09-11 23:46:25 +00:00
|
|
|
if sw == '9000':
|
2020-03-19 11:42:10 +00:00
|
|
|
print("PLMNwAcT:\n%s" % (res))
|
2019-09-11 23:46:25 +00:00
|
|
|
else:
|
|
|
|
print("PLMNwAcT: Can't read, response code = %s" % (sw,))
|
2018-07-11 21:05:58 +00:00
|
|
|
except Exception as e:
|
2020-01-22 16:38:24 +00:00
|
|
|
print("PLMNwAcT: Can't read file -- " + str(e))
|
2018-07-11 21:05:58 +00:00
|
|
|
|
|
|
|
# EF.OPLMNwAcT
|
2019-09-11 23:46:25 +00:00
|
|
|
try:
|
2020-03-19 11:43:11 +00:00
|
|
|
(res, sw) = card.read_oplmn_act()
|
2019-09-11 23:46:25 +00:00
|
|
|
if sw == '9000':
|
2020-03-19 11:43:11 +00:00
|
|
|
print("OPLMNwAcT:\n%s" % (res))
|
2019-09-11 23:46:25 +00:00
|
|
|
else:
|
|
|
|
print("OPLMNwAcT: Can't read, response code = %s" % (sw,))
|
2018-07-11 21:05:58 +00:00
|
|
|
except Exception as e:
|
2020-01-22 16:38:24 +00:00
|
|
|
print("OPLMNwAcT: Can't read file -- " + str(e))
|
2018-07-11 21:05:58 +00:00
|
|
|
|
|
|
|
# EF.HPLMNAcT
|
2019-09-11 23:46:25 +00:00
|
|
|
try:
|
2020-03-19 11:44:11 +00:00
|
|
|
(res, sw) = card.read_hplmn_act()
|
2019-09-11 23:46:25 +00:00
|
|
|
if sw == '9000':
|
2020-03-19 11:44:11 +00:00
|
|
|
print("HPLMNAcT:\n%s" % (res))
|
2019-09-11 23:46:25 +00:00
|
|
|
else:
|
|
|
|
print("HPLMNAcT: Can't read, response code = %s" % (sw,))
|
2018-07-11 21:05:58 +00:00
|
|
|
except Exception as e:
|
2020-01-22 16:38:24 +00:00
|
|
|
print("HPLMNAcT: Can't read file -- " + str(e))
|
2013-07-04 13:34:06 +00:00
|
|
|
|
|
|
|
# EF.ACC
|
2020-03-19 11:45:45 +00:00
|
|
|
(res, sw) = card.read_binary('ACC')
|
2013-07-04 13:34:06 +00:00
|
|
|
if sw == '9000':
|
|
|
|
print("ACC: %s" % (res,))
|
|
|
|
else:
|
|
|
|
print("ACC: Can't read, response code = %s" % (sw,))
|
|
|
|
|
|
|
|
# EF.MSISDN
|
2013-07-18 08:36:51 +00:00
|
|
|
try:
|
2020-03-19 11:49:16 +00:00
|
|
|
(res, sw) = card.read_msisdn()
|
2013-07-18 08:36:51 +00:00
|
|
|
if sw == '9000':
|
2020-03-19 11:49:16 +00:00
|
|
|
# (npi, ton, msisdn) = res
|
|
|
|
if res is not None:
|
|
|
|
print("MSISDN (NPI=%d ToN=%d): %s" % res)
|
2013-07-18 08:36:51 +00:00
|
|
|
else:
|
|
|
|
print("MSISDN: Not available")
|
2013-07-04 13:34:06 +00:00
|
|
|
else:
|
2013-07-18 08:36:51 +00:00
|
|
|
print("MSISDN: Can't read, response code = %s" % (sw,))
|
2018-07-11 21:02:36 +00:00
|
|
|
except Exception as e:
|
2020-01-22 16:38:24 +00:00
|
|
|
print("MSISDN: Can't read file -- " + str(e))
|
2013-07-04 13:34:06 +00:00
|
|
|
|
2019-03-21 15:21:12 +00:00
|
|
|
# EF.AD
|
2020-03-19 11:50:27 +00:00
|
|
|
(res, sw) = card.read_binary('AD')
|
2019-03-21 15:21:12 +00:00
|
|
|
if sw == '9000':
|
|
|
|
print("AD: %s" % (res,))
|
|
|
|
else:
|
|
|
|
print("AD: Can't read, response code = %s" % (sw,))
|
|
|
|
|
2020-03-20 17:50:39 +00:00
|
|
|
# EF.SST
|
2020-04-20 11:30:34 +00:00
|
|
|
(res, sw) = card.read_binary('SST')
|
2020-03-20 17:50:39 +00:00
|
|
|
if sw == '9000':
|
2020-04-20 11:30:34 +00:00
|
|
|
print("SIM Service Table: %s" % res)
|
2020-03-20 17:50:39 +00:00
|
|
|
# Print those which are available
|
2020-04-20 11:30:34 +00:00
|
|
|
print("%s" % dec_st(res))
|
2020-03-20 17:50:39 +00:00
|
|
|
else:
|
|
|
|
print("SIM Service Table: Can't read, response code = %s" % (sw,))
|
|
|
|
|
2020-03-22 07:20:11 +00:00
|
|
|
# Check whether we have th AID of USIM, if so select it by its AID
|
|
|
|
# EF.UST - File Id in ADF USIM : 6f38
|
|
|
|
if '9000' == card.select_adf_by_aid():
|
|
|
|
# EF.UST
|
|
|
|
(res, sw) = card.read_binary('6f38')
|
|
|
|
if sw == '9000':
|
|
|
|
print("USIM Service Table: %s" % res)
|
|
|
|
# Print those which are available
|
|
|
|
print("%s" % dec_st(res, table="usim"))
|
|
|
|
else:
|
|
|
|
print("USIM Service Table: Can't read, response code = %s" % (sw,))
|
|
|
|
|
2020-03-22 07:58:33 +00:00
|
|
|
# Check whether we have th AID of ISIM, if so select it by its AID
|
|
|
|
# EF.IST - File Id in ADF ISIM : 6f07
|
|
|
|
if '9000' == card.select_adf_by_aid(adf="isim"):
|
|
|
|
# EF.IST
|
|
|
|
(res, sw) = card.read_binary('6f07')
|
|
|
|
if sw == '9000':
|
|
|
|
print("ISIM Service Table: %s" % res)
|
|
|
|
# Print those which are available
|
|
|
|
print("%s" % dec_st(res, table="isim"))
|
|
|
|
else:
|
|
|
|
print("ISIM Service Table: Can't read, response code = %s" % (sw,))
|
|
|
|
|
2013-07-04 13:34:06 +00:00
|
|
|
# Done for this card and maybe for everything ?
|
2020-01-22 16:38:24 +00:00
|
|
|
print("Done !\n")
|