mirror of
https://github.com/polhenarejos/pico-hsm.git
synced 2026-01-17 09:28:05 +00:00
When initialized, the device generates a private key in place and stores it encrypted. The publick key is recovered and sent to our PKI, which generates a CV certificate. This CV certificate is stored inside the device, jointly with the DV CVC. Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
63 lines
2.2 KiB
Python
63 lines
2.2 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(command, p1, p2, data):
|
|
lc = [0x00] + list(len(data).to_bytes(2,'big'))
|
|
le = [0x00, 0x00]
|
|
apdu = [0x00] + [command, p1, p2] + lc + data + le
|
|
response, sw1, sw2 = cardservice.connection.transmit(apdu)
|
|
if (sw1 != 0x90):
|
|
raise APDUResponse(sw1,sw2)
|
|
return response
|
|
|
|
cardtype = AnyCardType()
|
|
|
|
try:
|
|
# request card insertion
|
|
cardrequest = CardRequest(timeout=10, cardType=cardtype)
|
|
cardservice = cardrequest.waitforcard()
|
|
|
|
# connect to the card and perform a few transmits
|
|
cardservice.connection.connect()
|
|
|
|
response = send_apdu(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)
|
|
dataef = base64.urlsafe_b64decode(j['cvcert']) + base64.urlsafe_b64decode(j['dvcert'])
|
|
|
|
response = send_apdu(0xa4, 0x00, 0x00, [0x2f,0x02])
|
|
pin = getpass('PIN: ')
|
|
response = send_apdu(0x20, 0x00, 0x81, list(pin.encode()))
|
|
|
|
apdu_data = [0x54, 0x02, 0x00, 0x00] + list(ASN1.make_tag(0x53, dataef))
|
|
response = send_apdu(0xd7, 0x00, 0x00, apdu_data)
|
|
|
|
print('Certificate uploaded successfully!')
|
|
|
|
except CardRequestTimeoutException:
|
|
print('time-out: no card inserted during last 10s')
|