pico-hsm/burn-cvcerts.py
Pol Henarejos fc6c852e09
When used this tool, the device is always reset to default state.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2022-08-18 20:09:23 +02:00

94 lines
3.6 KiB
Python

#! /usr/bin/env python3
from smartcard.CardType import AnyCardType
from smartcard.CardRequest import CardRequest
from smartcard.Exceptions import CardRequestTimeoutException
from cvc.certificates import CVC
from cvc.asn1 import ASN1
import json
import urllib.request
import base64
from getpass import getpass
from binascii import hexlify
class APDUResponse(Exception):
def __init__(self, sw1, sw2):
self.sw1 = sw1
self.sw2 = sw2
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'))
le = [0x00, 0x00]
if (isinstance(command, list) and len(command) > 1):
apdu = command
else:
apdu = [0x00, command]
apdu = apdu + [p1, p2] + lc + data + le
response, sw1, sw2 = card.connection.transmit(apdu)
if (sw1 != 0x90):
raise APDUResponse(sw1,sw2)
return response
def main():
print('Pico HSM burning certificates tool v1.0')
print('Author: Pol Henarejos')
print('Report bugs to https://github.com/polhenarejos/pico-hsm/')
print('')
print('')
print('********************************')
print('* PLEASE READ IT CAREFULLY *')
print('********************************')
print('')
print('This tool will erase and reset your device. It will delete all private and secret keys.')
print('Are you sure?')
_ = input('[Press enter to confirm]')
cardtype = AnyCardType()
try:
# request card insertion
cardrequest = CardRequest(timeout=10, cardType=cardtype)
card = cardrequest.waitforcard()
# connect to the card and perform a few transmits
card.connection.connect()
reset_data = [0x80, 0x02, 0x00, 0x01, 0x81, 0x06, 0x36, 0x34, 0x38, 0x32, 0x31, 0x39, 0x82, 0x08, 0x35, 0x37, 0x36, 0x32, 0x31, 0x38, 0x38, 0x30, 0x91, 0x01, 0x03]
response = send_apdu(card, [0x80, 0x50], 0x00, 0x00, reset_data)
response = send_apdu(card, 0xB1, 0xCE, 0x00, [0x54,0x02,0x00,0x00])
cert = bytearray(response)
Y = CVC().decode(cert).pubkey().find(0x86).data()
print(f'Public Point: {hexlify(Y).decode()}')
user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.7) Gecko/2009021910 Firefox/3.0.7'
pbk = base64.urlsafe_b64encode(Y)
data = urllib.parse.urlencode({'pubkey':pbk}).encode()
req = urllib.request.Request("https://www.henarejos.me/pico-hsm/cvc/", method='POST', data=data, headers={'User-Agent':user_agent,} ) #The assembled request
response = urllib.request.urlopen(req)
resp = response.read().decode('utf-8')
j = json.loads(resp)
print('Device name: '+j['devname'])
dataef = base64.urlsafe_b64decode(j['cvcert']) + base64.urlsafe_b64decode(j['dvcert'])
response = send_apdu(card, 0xa4, 0x00, 0x00, [0x2f,0x02])
pin = b'648219'
response = send_apdu(card, 0x20, 0x00, 0x81, list(pin))
apdu_data = [0x54, 0x02, 0x00, 0x00] + list(ASN1.make_tag(0x53, dataef))
response = send_apdu(card, 0xd7, 0x00, 0x00, apdu_data)
print('Certificate uploaded successfully!')
print('')
print('Note that the device is initialized with a default PIN and configuration.')
print('Now you can initialize the device as usual with you chosen PIN and configuration options.')
except CardRequestTimeoutException:
print('time-out: no card inserted during last 10s')
def run():
main()
if __name__ == "__main__":
run()