Added datetime and options menu to manipulate the RTC and options (press-to-confirm button and optional counter for each key).

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos 2022-08-25 13:38:09 +02:00
parent e8cc6a169e
commit c366c1d1a3
No known key found for this signature in database
GPG key ID: C0095B7870A4CCD3

View file

@ -34,6 +34,8 @@ from binascii import hexlify
import sys
import argparse
import os
from datetime import datetime
from argparse import RawTextHelpFormatter
class APDUResponse(Exception):
def __init__(self, sw1, sw2):
@ -42,15 +44,19 @@ class APDUResponse(Exception):
super().__init__(f'SW:{sw1:02X}{sw2:02X}')
def send_apdu(card, command, p1, p2, data):
lc = [0x00] + list(len(data).to_bytes(2, 'big'))
def send_apdu(card, command, p1, p2, data=None):
lc = []
dataf = []
if (data):
lc = [0x00] + list(len(data).to_bytes(2, 'big'))
dataf = data
le = [0x00, 0x00]
if (isinstance(command, list) and len(command) > 1):
apdu = command
else:
apdu = [0x00, command]
apdu = apdu + [p1, p2] + lc + data + le
apdu = apdu + [p1, p2] + lc + dataf + le
response, sw1, sw2 = card.connection.transmit(apdu)
if (sw1 != 0x90):
raise APDUResponse(sw1, sw2)
@ -73,6 +79,15 @@ def parse_args():
parser_pki_init.add_argument('--certs-dir', help='Store the PKI certificates into this directory.', default='certs')
parser_pki_init.add_argument('--default', help='Setups the default public PKI from public Pico HSM PKI.', action='store_true')
parser_pki_init.add_argument('--force', help='Forces the download of certificates.', action='store_true')
parser_rtc = subparser.add_parser('datetime', help='Datetime operations with the integrated Real Time Clock (RTC).')
parser_rtc.add_argument('subcommand', choices=['set', 'get'], help='Sets or gets current datetime.')
parser_opts = subparser.add_parser('options', help='Manage extra options.', formatter_class=RawTextHelpFormatter)
parser_opts.add_argument('subcommand', choices=['set', 'get'], help='Sets or gets option OPT.')
parser_opts.add_argument('opt', choices=['button', 'counter'], help='Button: press-to-confirm button.\nCounter: every generated key has an internal counter.')
parser_opts.add_argument('onoff', choices=['on', 'off'], help='Toggles state ON or OFF', metavar='ON/OFF', nargs='?')
args = parser.parse_args()
return args
@ -213,6 +228,31 @@ def attestate(card, args):
else:
print(f'Key {kid} is NOT generated by device {chr.decode()}')
def rtc(card, args):
if (args.subcommand == 'set'):
now = datetime.now()
_ = send_apdu(card, [0x80, 0x64], 0x0A, 0x00, list(now.year.to_bytes(2, 'big')) + [now.month, now.day, now.weekday(), now.hour, now.minute, now.second ])
elif (args.subcommand == 'get'):
response = send_apdu(card, [0x80, 0x64], 0x0A, 0x00)
dt = datetime(int.from_bytes(response[:2], 'big'), response[2], response[3], response[5], response[6], response[7])
print(f'Current date and time is: {dt.ctime()}')
def opts(card, args):
opt = 0x0
if (args.opt == 'button'):
opt = 0x1
elif (args.opt == 'counter'):
opt = 0x2
current = send_apdu(card, [0x80, 0x64], 0x6, 0x0)[0]
if (args.subcommand == 'set'):
if (args.onoff == 'on'):
newopt = current | opt
else:
newopt = current & ~opt
send_apdu(card, [0x80, 0x64], 0x6, 0x0, [newopt])
elif (args.subcommand == 'get'):
print(f'Option {args.opt.upper()} is {"ON" if current & opt else "OFF"}')
def main(args):
print('Pico HSM Tool v1.2')
print('Author: Pol Henarejos')
@ -238,6 +278,10 @@ def main(args):
attestate(card, args)
elif (args.command == 'pki'):
pki(card, args)
elif (args.command == 'datetime'):
rtc(card, args)
elif (args.command == 'options'):
opts(card, args)
def run():
args = parse_args()