This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
laforge gerrit-no-reply at lists.osmocom.orglaforge has submitted this change. ( https://gerrit.osmocom.org/c/pysim/+/23541 ) Change subject: pySim-shell: complete CHV/PIN management tools ...................................................................... pySim-shell: complete CHV/PIN management tools At the moment we only have a basic version of a verify_chv commnad, but in order to handle any CHV/PIN related situation we also need commands to enable, disable, change and unblock CHV. - fix verify_chv commnad: more distinct parameter names, better help strings, correct pin code encoding and add external source lookup - Add unblock_chv, change_chv, enable_chv and disable_chv commands - add/fix related functions in commands.py Change-Id: Ic89446e6bd2021095e579fb6b20458df48ba6413 Related: OS#4963 --- M pySim-shell.py M pySim/card_data.py M pySim/commands.py 3 files changed, 108 insertions(+), 13 deletions(-) Approvals: laforge: Looks good to me, approved Jenkins Builder: Verified diff --git a/pySim-shell.py b/pySim-shell.py index 68896cb..11953eb 100755 --- a/pySim-shell.py +++ b/pySim-shell.py @@ -39,7 +39,7 @@ from pySim.commands import SimCardCommands from pySim.cards import card_detect, Card from pySim.utils import h2b, swap_nibbles, rpad, h2s -from pySim.utils import dec_st, init_reader, sanitize_pin_adm, tabulate_str_list +from pySim.utils import dec_st, init_reader, sanitize_pin_adm, tabulate_str_list, is_hex from pySim.card_handler import card_handler from pySim.filesystem import CardMF, RuntimeState, CardDF, CardADF @@ -141,15 +141,79 @@ index_dict = { 1: self._cmd.rs.selected_file.get_selectable_names() } return self._cmd.index_based_complete(text, line, begidx, endidx, index_dict=index_dict) + def get_code(self, code): + """Use code either directly or try to get it from external data source""" + auto = ('PIN1', 'PIN2', 'PUK1', 'PUK2') + + if str(code).upper() not in auto: + return sanitize_pin_adm(code) + + result = card_data_get_field(str(code), key='ICCID', value=self._cmd.iccid) + result = sanitize_pin_adm(result) + if result: + self._cmd.poutput("found %s '%s' for ICCID '%s'" % (code.upper(), result, self._cmd.iccid)) + else: + self._cmd.poutput("cannot find %s for ICCID '%s'" % (code.upper(), self._cmd.iccid)) + return result + verify_chv_parser = argparse.ArgumentParser() - verify_chv_parser.add_argument('--chv-nr', type=int, default=1, help='CHV Number') - verify_chv_parser.add_argument('code', help='CODE/PIN/PUK') + verify_chv_parser.add_argument('--pin-nr', type=int, default=1, help='PIN Number, 1=PIN1, 2=PIN2 or custom value (decimal)') + verify_chv_parser.add_argument('pin_code', type=str, help='PIN code digits, \"PIN1\" or \"PIN2\" to get PIN code from external data source') @cmd2.with_argparser(verify_chv_parser) def do_verify_chv(self, opts): - """Verify (authenticate) using specified CHV (PIN)""" - (data, sw) = self._cmd.card._scc.verify_chv(opts.chv_nr, opts.code) - self._cmd.poutput(data) + """Verify (authenticate) using specified PIN code""" + pin = self.get_code(opts.pin_code) + (data, sw) = self._cmd.card._scc.verify_chv(opts.pin_nr, h2b(pin)) + self._cmd.poutput("CHV verfication successful") + + unblock_chv_parser = argparse.ArgumentParser() + unblock_chv_parser.add_argument('--pin-nr', type=int, default=1, help='PUK Number, 1=PIN1, 2=PIN2 or custom value (decimal)') + unblock_chv_parser.add_argument('puk_code', type=str, help='PUK code digits \"PUK1\" or \"PUK2\" to get PUK code from external data source') + unblock_chv_parser.add_argument('new_pin_code', type=str, help='PIN code digits \"PIN1\" or \"PIN2\" to get PIN code from external data source') + + @cmd2.with_argparser(unblock_chv_parser) + def do_unblock_chv(self, opts): + """Unblock PIN code using specified PUK code""" + new_pin = self.get_code(opts.new_pin_code) + puk = self.get_code(opts.puk_code) + (data, sw) = self._cmd.card._scc.unblock_chv(opts.pin_nr, h2b(puk), h2b(new_pin)) + self._cmd.poutput("CHV unblock successful") + + change_chv_parser = argparse.ArgumentParser() + change_chv_parser.add_argument('--pin-nr', type=int, default=1, help='PUK Number, 1=PIN1, 2=PIN2 or custom value (decimal)') + change_chv_parser.add_argument('pin_code', type=str, help='PIN code digits \"PIN1\" or \"PIN2\" to get PIN code from external data source') + change_chv_parser.add_argument('new_pin_code', type=str, help='PIN code digits \"PIN1\" or \"PIN2\" to get PIN code from external data source') + + @cmd2.with_argparser(change_chv_parser) + def do_change_chv(self, opts): + """Change PIN code to a new PIN code""" + new_pin = self.get_code(opts.new_pin_code) + pin = self.get_code(opts.pin_code) + (data, sw) = self._cmd.card._scc.change_chv(opts.pin_nr, h2b(pin), h2b(new_pin)) + self._cmd.poutput("CHV change successful") + + disable_chv_parser = argparse.ArgumentParser() + disable_chv_parser.add_argument('--pin-nr', type=int, default=1, help='PIN Number, 1=PIN1, 2=PIN2 or custom value (decimal)') + disable_chv_parser.add_argument('pin_code', type=str, help='PIN code digits, \"PIN1\" or \"PIN2\" to get PIN code from external data source') + + @cmd2.with_argparser(disable_chv_parser) + def do_disable_chv(self, opts): + """Disable PIN code using specified PIN code""" + pin = self.get_code(opts.pin_code) + (data, sw) = self._cmd.card._scc.disable_chv(opts.pin_nr, h2b(pin)) + self._cmd.poutput("CHV disable successful") + + enable_chv_parser = argparse.ArgumentParser() + enable_chv_parser.add_argument('--pin-nr', type=int, default=1, help='PIN Number, 1=PIN1, 2=PIN2 or custom value (decimal)') + enable_chv_parser.add_argument('pin_code', type=str, help='PIN code digits, \"PIN1\" or \"PIN2\" to get PIN code from external data source') + + @cmd2.with_argparser(enable_chv_parser) + def do_enable_chv(self, opts): + """Enable PIN code using specified PIN code""" + pin = self.get_code(opts.pin_code) + (data, sw) = self._cmd.card._scc.enable_chv(opts.pin_nr, h2b(pin)) + self._cmd.poutput("CHV enable successful") dir_parser = argparse.ArgumentParser() dir_parser.add_argument('--fids', help='Show file identifiers', action='store_true') diff --git a/pySim/card_data.py b/pySim/card_data.py index 495c1f3..ebc63a6 100644 --- a/pySim/card_data.py +++ b/pySim/card_data.py @@ -26,7 +26,7 @@ class CardData(object): - VALID_FIELD_NAMES = ['ICCID', 'ADM1', 'IMSI'] + VALID_FIELD_NAMES = ['ICCID', 'ADM1', 'IMSI', 'PIN1', 'PIN2', 'PUK1', 'PUK2'] # check input parameters, but do nothing concrete yet def get_data(self, fields=[], key='ICCID', value=""): diff --git a/pySim/commands.py b/pySim/commands.py index 65c3891..5184a77 100644 --- a/pySim/commands.py +++ b/pySim/commands.py @@ -21,7 +21,8 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -from pySim.utils import rpad, b2h +from pySim.utils import rpad, b2h, sw_match +from pySim.exceptions import SwMatchError class SimCardCommands(object): def __init__(self, transport): @@ -219,9 +220,39 @@ def reset_card(self): return self._tp.reset_card() - def verify_chv(self, chv_no, code): - fc = rpad(b2h(code), 16) + def _chv_process_sw(self, op_name, chv_no, pin_code, sw): + if sw_match(sw, '63cx'): + raise RuntimeError('Failed to %s chv_no 0x%02X with code 0x%s, %i tries left.' % + (op_name, chv_no, b2h(pin_code).upper(), int(sw[3]))) + elif (sw != '9000'): + raise SwMatchError(sw, '9000') + + def verify_chv(self, chv_no, pin_code): + fc = rpad(b2h(pin_code), 16) data, sw = self._tp.send_apdu(self.cla_byte + '2000' + ('%02X' % chv_no) + '08' + fc) - if (sw != '9000'): - raise RuntimeError('Failed to authenticate with ADM key %s, %i tries left.' % (code, int(sw[3]))) - return (data,sw) + self._chv_process_sw('verify', chv_no, pin_code, sw) + return (data, sw) + + def unblock_chv(self, chv_no, puk_code, pin_code): + fc = rpad(b2h(puk_code), 16) + rpad(b2h(pin_code), 16) + data, sw = self._tp.send_apdu(self.cla_byte + '2C00' + ('%02X' % chv_no) + '10' + fc) + self._chv_process_sw('unblock', chv_no, pin_code, sw) + return (data, sw) + + def change_chv(self, chv_no, pin_code, new_pin_code): + fc = rpad(b2h(pin_code), 16) + rpad(b2h(new_pin_code), 16) + data, sw = self._tp.send_apdu(self.cla_byte + '2400' + ('%02X' % chv_no) + '10' + fc) + self._chv_process_sw('change', chv_no, pin_code, sw) + return (data, sw) + + def disable_chv(self, chv_no, pin_code): + fc = rpad(b2h(pin_code), 16) + data, sw = self._tp.send_apdu(self.cla_byte + '2600' + ('%02X' % chv_no) + '08' + fc) + self._chv_process_sw('disable', chv_no, pin_code, sw) + return (data, sw) + + def enable_chv(self, chv_no, pin_code): + fc = rpad(b2h(pin_code), 16) + data, sw = self._tp.send_apdu(self.cla_byte + '2800' + ('%02X' % chv_no) + '08' + fc) + self._chv_process_sw('enable', chv_no, pin_code, sw) + return (data, sw) -- To view, visit https://gerrit.osmocom.org/c/pysim/+/23541 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: pysim Gerrit-Branch: master Gerrit-Change-Id: Ic89446e6bd2021095e579fb6b20458df48ba6413 Gerrit-Change-Number: 23541 Gerrit-PatchSet: 6 Gerrit-Owner: dexter <pmaier at sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel <dwillmann at sysmocom.de> Gerrit-Reviewer: laforge <laforge at osmocom.org> Gerrit-CC: fixeria <vyanitskiy at sysmocom.de> Gerrit-MessageType: merged -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210402/f2956014/attachment.htm>