blob: 638bd4b94404d6d4505f447467d838e5cee1e640 [file] [log] [blame]
Daniel Willmannde07b952020-10-19 10:32:34 +02001#!/usr/bin/env python3
Alexander Chemeris6e589142013-07-04 17:34:06 +04002
3#
4# Utility to display some informations about a SIM card
5#
6#
7# Copyright (C) 2009 Sylvain Munaut <tnt@246tNt.com>
8# Copyright (C) 2010 Harald Welte <laforge@gnumonks.org>
9# Copyright (C) 2013 Alexander Chemeris <alexander.chemeris@gmail.com>
10#
11# This program is free software: you can redistribute it and/or modify
12# it under the terms of the GNU General Public License as published by
13# the Free Software Foundation, either version 2 of the License, or
14# (at your option) any later version.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License
22# along with this program. If not, see <http://www.gnu.org/licenses/>.
23#
24
25import hashlib
26from optparse import OptionParser
27import os
28import random
29import re
30import sys
Vadim Yanitskiydfe3dbb2020-07-28 05:26:02 +070031from pySim.ts_51_011 import EF, DF, EF_SST_map, EF_AD_mode_map
Sebastian Viviani0dc8f692020-05-29 00:14:55 +010032from pySim.ts_31_102 import EF_UST_map, EF_USIM_ADF_map
Supreeth Herle5ad9aec2020-03-24 17:26:40 +010033from pySim.ts_31_103 import EF_IST_map, EF_ISIM_ADF_map
Alexander Chemeris6e589142013-07-04 17:34:06 +040034
Alexander Chemeris6e589142013-07-04 17:34:06 +040035from pySim.commands import SimCardCommands
herlesupreethcebf8b12021-01-21 05:57:06 +010036from pySim.cards import card_detect, Card, UsimCard, IsimCard
Philipp Maierff84c232020-05-12 17:24:18 +020037from pySim.utils import h2b, swap_nibbles, rpad, dec_imsi, dec_iccid, dec_msisdn
Supreeth Herle3b342c22020-03-24 16:15:02 +010038from pySim.utils import format_xplmn_w_act, dec_spn, dec_st, init_reader, dec_addr_tlv
Supreeth Herle99d55552020-03-24 13:03:43 +010039from pySim.utils import h2s, format_ePDGSelection
Alexander Chemeris6e589142013-07-04 17:34:06 +040040
41def parse_options():
42
43 parser = OptionParser(usage="usage: %prog [options]")
44
45 parser.add_option("-d", "--device", dest="device", metavar="DEV",
46 help="Serial Device for SIM access [default: %default]",
47 default="/dev/ttyUSB0",
48 )
49 parser.add_option("-b", "--baud", dest="baudrate", type="int", metavar="BAUD",
50 help="Baudrate used for SIM access [default: %default]",
51 default=9600,
52 )
53 parser.add_option("-p", "--pcsc-device", dest="pcsc_dev", type='int', metavar="PCSC",
54 help="Which PC/SC reader number for SIM access",
55 default=None,
56 )
Vadim Yanitskiy29ca8042020-05-09 21:23:37 +070057 parser.add_option("--modem-device", dest="modem_dev", metavar="DEV",
58 help="Serial port of modem for Generic SIM Access (3GPP TS 27.007)",
59 default=None,
60 )
61 parser.add_option("--modem-baud", dest="modem_baud", type="int", metavar="BAUD",
62 help="Baudrate used for modem's port [default: %default]",
63 default=115200,
64 )
Vadim Yanitskiy9f9f5a62018-10-27 02:10:34 +070065 parser.add_option("--osmocon", dest="osmocon_sock", metavar="PATH",
66 help="Socket path for Calypso (e.g. Motorola C1XX) based reader (via OsmocomBB)",
67 default=None,
68 )
Alexander Chemeris6e589142013-07-04 17:34:06 +040069
70 (options, args) = parser.parse_args()
71
72 if args:
73 parser.error("Extraneous arguments")
74
75 return options
76
77
78if __name__ == '__main__':
79
80 # Parse options
81 opts = parse_options()
82
Vadim Yanitskiy588f3ac2018-10-27 06:30:33 +070083 # Init card reader driver
Philipp Maierff84c232020-05-12 17:24:18 +020084 sl = init_reader(opts)
Philipp Maierc8caec22021-02-22 16:07:53 +010085 if sl is None:
86 exit(1)
Alexander Chemeris6e589142013-07-04 17:34:06 +040087
88 # Create command layer
89 scc = SimCardCommands(transport=sl)
90
91 # Wait for SIM card
92 sl.wait_for_card()
93
Supreeth Herle3e6f16d2020-03-23 10:00:50 +010094 # Assuming UICC SIM
95 scc.cla_byte = "00"
96 scc.sel_ctrl = "0004"
97
98 # Testing for Classic SIM or UICC
99 (res, sw) = sl.send_apdu(scc.cla_byte + "a4" + scc.sel_ctrl + "02" + "3f00")
100 if sw == '6e00':
101 # Just a Classic SIM
102 scc.cla_byte = "a0"
103 scc.sel_ctrl = "0000"
104
Alexander Chemeris6e589142013-07-04 17:34:06 +0400105 # Program the card
106 print("Reading ...")
107
Supreeth Herle4c306ab2020-03-18 11:38:00 +0100108 # Initialize Card object by auto detecting the card
109 card = card_detect("auto", scc) or Card(scc)
110
Supreeth Herle3bf43632020-03-20 20:20:27 +0100111 # Read all AIDs on the UICC
112 card.read_aids()
113
Alexander Chemeris6e589142013-07-04 17:34:06 +0400114 # EF.ICCID
Supreeth Herle3566b8e2020-03-18 12:02:34 +0100115 (res, sw) = card.read_iccid()
Alexander Chemeris6e589142013-07-04 17:34:06 +0400116 if sw == '9000':
Supreeth Herle3566b8e2020-03-18 12:02:34 +0100117 print("ICCID: %s" % (res,))
Alexander Chemeris6e589142013-07-04 17:34:06 +0400118 else:
119 print("ICCID: Can't read, response code = %s" % (sw,))
120
121 # EF.IMSI
Supreeth Herlef9762dc2020-03-18 12:05:06 +0100122 (res, sw) = card.read_imsi()
Alexander Chemeris6e589142013-07-04 17:34:06 +0400123 if sw == '9000':
Supreeth Herlef9762dc2020-03-18 12:05:06 +0100124 print("IMSI: %s" % (res,))
Alexander Chemeris6e589142013-07-04 17:34:06 +0400125 else:
126 print("IMSI: Can't read, response code = %s" % (sw,))
127
Supreeth Herleab46d622020-03-05 15:30:22 +0100128 # EF.GID1
129 try:
Supreeth Herle98a69272020-03-18 12:14:48 +0100130 (res, sw) = card.read_gid1()
Supreeth Herleab46d622020-03-05 15:30:22 +0100131 if sw == '9000':
132 print("GID1: %s" % (res,))
133 else:
134 print("GID1: Can't read, response code = %s" % (sw,))
135 except Exception as e:
136 print("GID1: Can't read file -- %s" % (str(e),))
137
Supreeth Herle0e90e6c2020-03-05 15:33:00 +0100138 # EF.GID2
139 try:
Supreeth Herlee573ccb2020-04-01 09:21:20 +0200140 (res, sw) = card.read_binary('GID2')
Supreeth Herle0e90e6c2020-03-05 15:33:00 +0100141 if sw == '9000':
142 print("GID2: %s" % (res,))
143 else:
144 print("GID2: Can't read, response code = %s" % (sw,))
145 except Exception as e:
146 print("GID2: Can't read file -- %s" % (str(e),))
147
Alexander Chemeris6e589142013-07-04 17:34:06 +0400148 # EF.SMSP
Supreeth Herleebe6dba2020-03-19 12:08:20 +0100149 (res, sw) = card.read_record('SMSP', 1)
Alexander Chemeris6e589142013-07-04 17:34:06 +0400150 if sw == '9000':
151 print("SMSP: %s" % (res,))
152 else:
153 print("SMSP: Can't read, response code = %s" % (sw,))
154
Supreeth Herlef8299452019-06-08 07:49:08 +0200155 # EF.SPN
156 try:
Supreeth Herle846cefb2020-03-19 12:11:25 +0100157 (res, sw) = card.read_spn()
Supreeth Herlef8299452019-06-08 07:49:08 +0200158 if sw == '9000':
Supreeth Herle846cefb2020-03-19 12:11:25 +0100159 print("SPN: %s" % (res[0] or "Not available"))
160 print("Display HPLMN: %s" % (res[1],))
161 print("Display OPLMN: %s" % (res[2],))
Supreeth Herlef8299452019-06-08 07:49:08 +0200162 else:
163 print("SPN: Can't read, response code = %s" % (sw,))
164 except Exception as e:
165 print("SPN: Can't read file -- %s" % (str(e),))
166
Philipp Maiera2650492018-07-11 23:05:58 +0200167 # EF.PLMNsel
168 try:
Supreeth Herle9efd8ef2020-03-19 12:14:10 +0100169 (res, sw) = card.read_binary('PLMNsel')
Denis 'GNUtoo' Carikli84d2cb32019-09-12 01:46:25 +0200170 if sw == '9000':
171 print("PLMNsel: %s" % (res))
172 else:
173 print("PLMNsel: Can't read, response code = %s" % (sw,))
Philipp Maiera2650492018-07-11 23:05:58 +0200174 except Exception as e:
Vadim Yanitskiya3bb3342020-01-25 12:45:37 +0700175 print("PLMNsel: Can't read file -- " + str(e))
Philipp Maiera2650492018-07-11 23:05:58 +0200176
177 # EF.PLMNwAcT
Denis 'GNUtoo' Carikli84d2cb32019-09-12 01:46:25 +0200178 try:
Supreeth Herle14084402020-03-19 12:42:10 +0100179 (res, sw) = card.read_plmn_act()
Denis 'GNUtoo' Carikli84d2cb32019-09-12 01:46:25 +0200180 if sw == '9000':
Supreeth Herle14084402020-03-19 12:42:10 +0100181 print("PLMNwAcT:\n%s" % (res))
Denis 'GNUtoo' Carikli84d2cb32019-09-12 01:46:25 +0200182 else:
183 print("PLMNwAcT: Can't read, response code = %s" % (sw,))
Philipp Maiera2650492018-07-11 23:05:58 +0200184 except Exception as e:
Vadim Yanitskiy6727f0c2020-01-22 23:38:24 +0700185 print("PLMNwAcT: Can't read file -- " + str(e))
Philipp Maiera2650492018-07-11 23:05:58 +0200186
187 # EF.OPLMNwAcT
Denis 'GNUtoo' Carikli84d2cb32019-09-12 01:46:25 +0200188 try:
Supreeth Herle1757b262020-03-19 12:43:11 +0100189 (res, sw) = card.read_oplmn_act()
Denis 'GNUtoo' Carikli84d2cb32019-09-12 01:46:25 +0200190 if sw == '9000':
Supreeth Herle1757b262020-03-19 12:43:11 +0100191 print("OPLMNwAcT:\n%s" % (res))
Denis 'GNUtoo' Carikli84d2cb32019-09-12 01:46:25 +0200192 else:
193 print("OPLMNwAcT: Can't read, response code = %s" % (sw,))
Philipp Maiera2650492018-07-11 23:05:58 +0200194 except Exception as e:
Vadim Yanitskiy6727f0c2020-01-22 23:38:24 +0700195 print("OPLMNwAcT: Can't read file -- " + str(e))
Philipp Maiera2650492018-07-11 23:05:58 +0200196
197 # EF.HPLMNAcT
Denis 'GNUtoo' Carikli84d2cb32019-09-12 01:46:25 +0200198 try:
Supreeth Herlea850a472020-03-19 12:44:11 +0100199 (res, sw) = card.read_hplmn_act()
Denis 'GNUtoo' Carikli84d2cb32019-09-12 01:46:25 +0200200 if sw == '9000':
Supreeth Herlea850a472020-03-19 12:44:11 +0100201 print("HPLMNAcT:\n%s" % (res))
Denis 'GNUtoo' Carikli84d2cb32019-09-12 01:46:25 +0200202 else:
203 print("HPLMNAcT: Can't read, response code = %s" % (sw,))
Philipp Maiera2650492018-07-11 23:05:58 +0200204 except Exception as e:
Vadim Yanitskiy6727f0c2020-01-22 23:38:24 +0700205 print("HPLMNAcT: Can't read file -- " + str(e))
Alexander Chemeris6e589142013-07-04 17:34:06 +0400206
207 # EF.ACC
Supreeth Herled1fb6fc2020-03-19 12:45:45 +0100208 (res, sw) = card.read_binary('ACC')
Alexander Chemeris6e589142013-07-04 17:34:06 +0400209 if sw == '9000':
210 print("ACC: %s" % (res,))
211 else:
212 print("ACC: Can't read, response code = %s" % (sw,))
213
214 # EF.MSISDN
Sylvain Munaut9f138972013-07-18 10:36:51 +0200215 try:
Supreeth Herle6d66af62020-03-19 12:49:16 +0100216 (res, sw) = card.read_msisdn()
Sylvain Munaut9f138972013-07-18 10:36:51 +0200217 if sw == '9000':
Supreeth Herle6d66af62020-03-19 12:49:16 +0100218 # (npi, ton, msisdn) = res
219 if res is not None:
220 print("MSISDN (NPI=%d ToN=%d): %s" % res)
Sylvain Munaut9f138972013-07-18 10:36:51 +0200221 else:
222 print("MSISDN: Not available")
Alexander Chemeris6e589142013-07-04 17:34:06 +0400223 else:
Sylvain Munaut9f138972013-07-18 10:36:51 +0200224 print("MSISDN: Can't read, response code = %s" % (sw,))
Philipp Maierea6bdf02018-07-11 23:02:36 +0200225 except Exception as e:
Vadim Yanitskiy6727f0c2020-01-22 23:38:24 +0700226 print("MSISDN: Can't read file -- " + str(e))
Alexander Chemeris6e589142013-07-04 17:34:06 +0400227
Philipp Maieree908ae2019-03-21 16:21:12 +0100228 # EF.AD
Supreeth Herle52ef6752020-03-19 12:50:27 +0100229 (res, sw) = card.read_binary('AD')
Philipp Maieree908ae2019-03-21 16:21:12 +0100230 if sw == '9000':
Vadim Yanitskiydfe3dbb2020-07-28 05:26:02 +0700231 print("Administrative data: %s" % (res,))
232 if res[:2] in EF_AD_mode_map:
233 print("\tMS operation mode: %s" % (EF_AD_mode_map[res[:2]],))
234 else:
235 print("\tMS operation mode: (unknown 0x%s)" % (res[:2],))
236 if int(res[4:6], 16) & 0x01:
237 print("\tCiphering Indicator: enabled")
238 else:
239 print("\tCiphering Indicator: disabled")
Philipp Maieree908ae2019-03-21 16:21:12 +0100240 else:
241 print("AD: Can't read, response code = %s" % (sw,))
242
Supreeth Herlee26331e2020-03-20 18:50:39 +0100243 # EF.SST
Supreeth Herled3b13d02020-04-20 13:30:34 +0200244 (res, sw) = card.read_binary('SST')
Supreeth Herlee26331e2020-03-20 18:50:39 +0100245 if sw == '9000':
Supreeth Herled3b13d02020-04-20 13:30:34 +0200246 print("SIM Service Table: %s" % res)
Supreeth Herlee26331e2020-03-20 18:50:39 +0100247 # Print those which are available
Supreeth Herled3b13d02020-04-20 13:30:34 +0200248 print("%s" % dec_st(res))
Supreeth Herlee26331e2020-03-20 18:50:39 +0100249 else:
250 print("SIM Service Table: Can't read, response code = %s" % (sw,))
251
Supreeth Herle96412992020-03-22 08:20:11 +0100252 # Check whether we have th AID of USIM, if so select it by its AID
253 # EF.UST - File Id in ADF USIM : 6f38
Philipp Maiercba6dbc2021-03-11 13:03:18 +0100254 data, sw = card.select_adf_by_aid(adf="usim")
255 if sw == '9000':
herlesupreethcebf8b12021-01-21 05:57:06 +0100256 # Select USIM profile
257 usim_card = UsimCard(scc)
258
Harald Welteca673942020-06-03 15:19:40 +0200259 # EF.EHPLMN
herlesupreethcebf8b12021-01-21 05:57:06 +0100260 if usim_card.file_exists(EF_USIM_ADF_map['EHPLMN']):
261 (res, sw) = usim_card.read_ehplmn()
Harald Welteca673942020-06-03 15:19:40 +0200262 if sw == '9000':
263 print("EHPLMN:\n%s" % (res))
264 else:
265 print("EHPLMN: Can't read, response code = %s" % (sw,))
herlesupreeth4a3580b2020-09-29 10:11:36 +0200266
Supreeth Herle96412992020-03-22 08:20:11 +0100267 # EF.UST
herlesupreeth4a3580b2020-09-29 10:11:36 +0200268 try:
herlesupreethcebf8b12021-01-21 05:57:06 +0100269 if usim_card.file_exists(EF_USIM_ADF_map['UST']):
herlesupreeth4a3580b2020-09-29 10:11:36 +0200270 # res[0] - EF content of UST
271 # res[1] - Human readable format of services marked available in UST
herlesupreethcebf8b12021-01-21 05:57:06 +0100272 (res, sw) = usim_card.read_ust()
herlesupreeth4a3580b2020-09-29 10:11:36 +0200273 if sw == '9000':
274 print("USIM Service Table: %s" % res[0])
275 print("%s" % res[1])
276 else:
277 print("USIM Service Table: Can't read, response code = %s" % (sw,))
278 except Exception as e:
279 print("USIM Service Table: Can't read file -- " + str(e))
Supreeth Herle96412992020-03-22 08:20:11 +0100280
Supreeth Herleb1634db2020-03-22 10:00:43 +0100281 #EF.ePDGId - Home ePDG Identifier
282 try:
herlesupreethcebf8b12021-01-21 05:57:06 +0100283 if usim_card.file_exists(EF_USIM_ADF_map['ePDGId']):
284 (res, sw) = usim_card.read_epdgid()
herlesupreethf8232db2020-09-29 10:03:06 +0200285 if sw == '9000':
286 print("ePDGId:\n%s" % (len(res) and res or '\tNot available\n',))
287 else:
288 print("ePDGId: Can't read, response code = %s" % (sw,))
Supreeth Herleb1634db2020-03-22 10:00:43 +0100289 except Exception as e:
290 print("ePDGId: Can't read file -- " + str(e))
291
Supreeth Herle99d55552020-03-24 13:03:43 +0100292 #EF.ePDGSelection - ePDG Selection Information
293 try:
herlesupreethcebf8b12021-01-21 05:57:06 +0100294 if usim_card.file_exists(EF_USIM_ADF_map['ePDGSelection']):
295 (res, sw) = usim_card.read_ePDGSelection()
Supreeth Herle99d55552020-03-24 13:03:43 +0100296 if sw == '9000':
297 print("ePDGSelection:\n%s" % (res,))
298 else:
299 print("ePDGSelection: Can't read, response code = %s" % (sw,))
300 except Exception as e:
301 print("ePDGSelection: Can't read file -- " + str(e))
302
Supreeth Herle5ad9aec2020-03-24 17:26:40 +0100303 # Select ISIM application by its AID
Philipp Maiercba6dbc2021-03-11 13:03:18 +0100304 data, sw = card.select_adf_by_aid(adf="isim")
305 if sw == '9000':
herlesupreethcebf8b12021-01-21 05:57:06 +0100306 # Select USIM profile
307 isim_card = IsimCard(scc)
308
Supreeth Herle5ad9aec2020-03-24 17:26:40 +0100309 #EF.P-CSCF - P-CSCF Address
310 try:
herlesupreethcebf8b12021-01-21 05:57:06 +0100311 if isim_card.file_exists(EF_ISIM_ADF_map['PCSCF']):
312 res = isim_card.read_pcscf()
Supreeth Herle5ad9aec2020-03-24 17:26:40 +0100313 print("P-CSCF:\n%s" % (len(res) and res or '\tNot available\n',))
314 except Exception as e:
315 print("P-CSCF: Can't read file -- " + str(e))
316
Supreeth Herle05b28072020-03-25 10:23:48 +0100317 # EF.DOMAIN - Home Network Domain Name e.g. ims.mncXXX.mccXXX.3gppnetwork.org
318 try:
herlesupreethcebf8b12021-01-21 05:57:06 +0100319 if isim_card.file_exists(EF_ISIM_ADF_map['DOMAIN']):
320 (res, sw) = isim_card.read_domain()
Supreeth Herle05b28072020-03-25 10:23:48 +0100321 if sw == '9000':
322 print("Home Network Domain Name: %s" % (len(res) and res or 'Not available',))
323 else:
324 print("Home Network Domain Name: Can't read, response code = %s" % (sw,))
325 except Exception as e:
326 print("Home Network Domain Name: Can't read file -- " + str(e))
327
Supreeth Herle3f67f9c2020-03-25 15:38:02 +0100328 # EF.IMPI - IMS private user identity
329 try:
herlesupreethcebf8b12021-01-21 05:57:06 +0100330 if isim_card.file_exists(EF_ISIM_ADF_map['IMPI']):
331 (res, sw) = isim_card.read_impi()
Supreeth Herle3f67f9c2020-03-25 15:38:02 +0100332 if sw == '9000':
333 print("IMS private user identity: %s" % (len(res) and res or 'Not available',))
334 else:
335 print("IMS private user identity: Can't read, response code = %s" % (sw,))
336 except Exception as e:
337 print("IMS private user identity: Can't read file -- " + str(e))
338
Supreeth Herle0c02d8a2020-03-26 09:00:06 +0100339 # EF.IMPU - IMS public user identity
340 try:
herlesupreethcebf8b12021-01-21 05:57:06 +0100341 if isim_card.file_exists(EF_ISIM_ADF_map['IMPU']):
342 res = isim_card.read_impu()
Supreeth Herle0c02d8a2020-03-26 09:00:06 +0100343 print("IMS public user identity:\n%s" % (len(res) and res or '\tNot available\n',))
344 except Exception as e:
345 print("IMS public user identity: Can't read file -- " + str(e))
346
Supreeth Herlebe3b6412020-06-01 12:53:57 +0200347 # EF.UICCIARI - UICC IARI
348 try:
herlesupreethcebf8b12021-01-21 05:57:06 +0100349 if isim_card.file_exists(EF_ISIM_ADF_map['UICCIARI']):
350 res = isim_card.read_iari()
Supreeth Herlebe3b6412020-06-01 12:53:57 +0200351 print("UICC IARI:\n%s" % (len(res) and res or '\tNot available\n',))
352 except Exception as e:
353 print("UICC IARI: Can't read file -- " + str(e))
354
Supreeth Herleee15c772020-03-22 08:58:33 +0100355 # Check whether we have th AID of ISIM, if so select it by its AID
356 # EF.IST - File Id in ADF ISIM : 6f07
Philipp Maiercba6dbc2021-03-11 13:03:18 +0100357 data, sw = card.select_adf_by_aid(adf="isim")
358 if sw == '9000':
Supreeth Herleee15c772020-03-22 08:58:33 +0100359 # EF.IST
360 (res, sw) = card.read_binary('6f07')
361 if sw == '9000':
362 print("ISIM Service Table: %s" % res)
363 # Print those which are available
364 print("%s" % dec_st(res, table="isim"))
365 else:
366 print("ISIM Service Table: Can't read, response code = %s" % (sw,))
367
Alexander Chemeris6e589142013-07-04 17:34:06 +0400368 # Done for this card and maybe for everything ?
Vadim Yanitskiy6727f0c2020-01-22 23:38:24 +0700369 print("Done !\n")