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:
@@ -34,6 +34,8 @@ from binascii import hexlify
|
|||||||
import sys
|
import sys
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
|
from datetime import datetime
|
||||||
|
from argparse import RawTextHelpFormatter
|
||||||
|
|
||||||
class APDUResponse(Exception):
|
class APDUResponse(Exception):
|
||||||
def __init__(self, sw1, sw2):
|
def __init__(self, sw1, sw2):
|
||||||
@@ -42,15 +44,19 @@ class APDUResponse(Exception):
|
|||||||
super().__init__(f'SW:{sw1:02X}{sw2:02X}')
|
super().__init__(f'SW:{sw1:02X}{sw2:02X}')
|
||||||
|
|
||||||
|
|
||||||
def send_apdu(card, command, p1, p2, data):
|
def send_apdu(card, command, p1, p2, data=None):
|
||||||
lc = [0x00] + list(len(data).to_bytes(2, 'big'))
|
lc = []
|
||||||
|
dataf = []
|
||||||
|
if (data):
|
||||||
|
lc = [0x00] + list(len(data).to_bytes(2, 'big'))
|
||||||
|
dataf = data
|
||||||
le = [0x00, 0x00]
|
le = [0x00, 0x00]
|
||||||
if (isinstance(command, list) and len(command) > 1):
|
if (isinstance(command, list) and len(command) > 1):
|
||||||
apdu = command
|
apdu = command
|
||||||
else:
|
else:
|
||||||
apdu = [0x00, command]
|
apdu = [0x00, command]
|
||||||
|
|
||||||
apdu = apdu + [p1, p2] + lc + data + le
|
apdu = apdu + [p1, p2] + lc + dataf + le
|
||||||
response, sw1, sw2 = card.connection.transmit(apdu)
|
response, sw1, sw2 = card.connection.transmit(apdu)
|
||||||
if (sw1 != 0x90):
|
if (sw1 != 0x90):
|
||||||
raise APDUResponse(sw1, sw2)
|
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('--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('--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_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()
|
args = parser.parse_args()
|
||||||
return args
|
return args
|
||||||
|
|
||||||
@@ -213,6 +228,31 @@ def attestate(card, args):
|
|||||||
else:
|
else:
|
||||||
print(f'Key {kid} is NOT generated by device {chr.decode()}')
|
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):
|
def main(args):
|
||||||
print('Pico HSM Tool v1.2')
|
print('Pico HSM Tool v1.2')
|
||||||
print('Author: Pol Henarejos')
|
print('Author: Pol Henarejos')
|
||||||
@@ -238,6 +278,10 @@ def main(args):
|
|||||||
attestate(card, args)
|
attestate(card, args)
|
||||||
elif (args.command == 'pki'):
|
elif (args.command == 'pki'):
|
||||||
pki(card, args)
|
pki(card, args)
|
||||||
|
elif (args.command == 'datetime'):
|
||||||
|
rtc(card, args)
|
||||||
|
elif (args.command == 'options'):
|
||||||
|
opts(card, args)
|
||||||
|
|
||||||
def run():
|
def run():
|
||||||
args = parse_args()
|
args = parse_args()
|
||||||
|
|||||||
Reference in New Issue
Block a user