SmartPGP/bin/smartpgp-cli

113 lines
4.6 KiB
Python
Executable File

#!/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 <SmartPGP@c0de.dev>
# 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()