#!/usr/bin/env python3 # SmartPGP : JavaCard implementation of OpenPGP card v3 specification # https://c0de.dev/c0de/SmartPGP # Copyright (C) 2016 ANSSI # Copyright (C) 2023 Code Fox # 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, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import argparse import os import sys from getpass import getpass from smartpgp.highlevel import * VALID_COMMANDS={ 'list-readers':CardConnectionContext.cmd_list_readers, 'full-reset': CardConnectionContext.cmd_full_reset, 'reset': CardConnectionContext.cmd_reset, 'switch-rsa2048': CardConnectionContext.cmd_switch_rsa2048, 'switch-rsa3072': CardConnectionContext.cmd_switch_rsa3072, 'switch-rsa4096': CardConnectionContext.cmd_switch_rsa4096, 'switch-bp256':CardConnectionContext.cmd_switch_bp256, 'switch-bp384':CardConnectionContext.cmd_switch_bp384, 'switch-bp512':CardConnectionContext.cmd_switch_bp512, 'switch-p256': CardConnectionContext.cmd_switch_p256, 'switch-p384': CardConnectionContext.cmd_switch_p384, 'switch-p521': CardConnectionContext.cmd_switch_p521, 'generate-sm-key': CardConnectionContext.cmd_generate_sm_key, 'get-sm-key': CardConnectionContext.cmd_get_sm_key, 'set-resetting-code': CardConnectionContext.cmd_set_resetting_code, 'unblock-pin': CardConnectionContext.cmd_unblock_pin, 'put-sm-key': CardConnectionContext.cmd_put_sm_key, 'put-sign-certificate': CardConnectionContext.cmd_put_sign_certificate, 'put-auth-certificate': CardConnectionContext.cmd_put_auth_certificate, 'put-sm-certificate': CardConnectionContext.cmd_put_sm_certificate, 'get-sm-certificate': CardConnectionContext.cmd_get_sm_certificate, 'put-aes-key': CardConnectionContext.cmd_put_aes_key, 'encrypt-aes': CardConnectionContext.cmd_encrypt_aes, 'decrypt-aes': CardConnectionContext.cmd_decrypt_aes, 'get-kdf': CardConnectionContext.cmd_get_kdf, 'set-kdf': CardConnectionContext.cmd_set_kdf, 'setup-kdf': CardConnectionContext.cmd_setup_kdf, } def read_pin_interactive(name): pw = getpass("Enter %s PIN: " % name) return pw def parse_args(ctx): parser = argparse.ArgumentParser() parser.add_argument("command", help="The command. Valid commands are: %s" % ', '.join([c for c in VALID_COMMANDS.keys()])) parser.add_argument("-r", "--reader", type=int, help="Select reader index (default: 0)") parser.add_argument("-i", "--input", type=str, help="Input file for commands requiring input data (other than PIN codes)") parser.add_argument("-o", "--output", type=str, help="Output file for commands emitting output data") group = parser.add_mutually_exclusive_group() group.add_argument("-p", "--pin", type=str, help="Admin PIN (default: 12345678). Use ENV:VARNAME to read from an environment variable") group.add_argument("-I", "--interactive", action='store_true', help="Ask Admin PIN interactively") args = parser.parse_args() # option -r ctx.reader_index = args.reader or 0 # option -p if args.pin is not None: if args.pin.startswith('ENV:'): varname = args.pin[4:] try: ctx.admin_pin=os.environ[varname] except KeyError: print("Environment variable %s not found" % varname) sys.exit(1) else: ctx.admin_pin = args.pin # option -I if args.interactive: ctx.set_pin_read_function(read_pin_interactive) # option -i ctx.input = args.input # option -O ctx.output = args.output return ctx,args def main(): ctx = CardConnectionContext() ctx,args = parse_args(ctx) if args.command in VALID_COMMANDS: VALID_COMMANDS[args.command](ctx) else: print("Unknown command '%s'" % args.command) print("Run '%s -h' for help" % sys.argv[0]) sys.exit(1) if __name__=='__main__': main()