Added Windows & Linux backend for backup/restore.

Fixes #21

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos
2023-11-02 09:32:19 +01:00
parent ba57cc4527
commit 01a6c9f77f
2 changed files with 67 additions and 9 deletions

View File

@@ -23,7 +23,6 @@ import sys
import argparse import argparse
import platform import platform
from binascii import hexlify from binascii import hexlify
from words import words
from threading import Event from threading import Event
from typing import Mapping, Any, Optional, Callable from typing import Mapping, Any, Optional, Callable
import struct import struct
@@ -58,14 +57,6 @@ except:
from enum import IntEnum from enum import IntEnum
from binascii import hexlify from binascii import hexlify
if (platform.system() == 'Windows' or platform.system() == 'Linux'):
from secure_key import windows as skey
elif (platform.system() == 'Darwin'):
from secure_key import macos as skey
else:
print('ERROR: platform not supported')
sys.exit(-1)
def get_pki_data(url, data=None, method='GET'): def get_pki_data(url, data=None, method='GET'):
user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; ' user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; '
'rv:1.9.0.7) Gecko/2009021910 Firefox/3.0.7' 'rv:1.9.0.7) Gecko/2009021910 Firefox/3.0.7'
@@ -252,6 +243,14 @@ class Vendor:
return self.ctap.vendor(cmd, sub_cmd, params, pin_uv_protocol, pin_uv_param) return self.ctap.vendor(cmd, sub_cmd, params, pin_uv_protocol, pin_uv_param)
def backup_save(self, filename): def backup_save(self, filename):
if (platform.system() == 'Windows' or platform.system() == 'Linux'):
from secure_key import windows as skey
elif (platform.system() == 'Darwin'):
from secure_key import macos as skey
else:
print('ERROR: platform not supported')
sys.exit(-1)
from words import words
ret = self._call( ret = self._call(
Vendor.CMD.VENDOR_BACKUP, Vendor.CMD.VENDOR_BACKUP,
Vendor.SUBCMD.ENABLE, Vendor.SUBCMD.ENABLE,
@@ -270,6 +269,14 @@ class Vendor:
print(f'{(c+1):02d} - {words[coef]}') print(f'{(c+1):02d} - {words[coef]}')
def backup_load(self, filename): def backup_load(self, filename):
if (platform.system() == 'Windows' or platform.system() == 'Linux'):
from secure_key import windows as skey
elif (platform.system() == 'Darwin'):
from secure_key import macos as skey
else:
print('ERROR: platform not supported')
sys.exit(-1)
from words import words
d = 0 d = 0
if (d == 0): if (d == 0):
for c in range(24): for c in range(24):
@@ -349,6 +356,13 @@ class Vendor:
) )
def _get_key_device(self): def _get_key_device(self):
if (platform.system() == 'Windows' or platform.system() == 'Linux'):
from secure_key import windows as skey
elif (platform.system() == 'Darwin'):
from secure_key import macos as skey
else:
print('ERROR: platform not supported')
sys.exit(-1)
return skey.get_secure_key() return skey.get_secure_key()
def get_skey(self): def get_skey(self):

View File

@@ -0,0 +1,44 @@
import sys
import os
import base64
DOMAIN = "PicoKeys.com"
USERNAME = "Pico-Fido"
try:
import keyring
except:
print('ERROR: keyring module not found! Install keyring package.\nTry with `pip install keyring`')
sys.exit(-1)
try:
from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption, load_pem_private_key
from cryptography.hazmat.primitives.asymmetric import ec
except:
print('ERROR: cryptography module not found! Install cryptography package.\nTry with `pip install cryptography`')
sys.exit(-1)
def generate_secure_key():
pkey = ec.generate_private_key(ec.SECP256R1())
set_secure_key(pkey)
return keyring.get_password(DOMAIN, USERNAME)
def get_d(key):
return load_pem_private_key(key, password=None).private_numbers().private_value.to_bytes(32, 'big')
def set_secure_key(pk):
try:
keyring.delete_password(DOMAIN, USERNAME)
except:
pass
keyring.set_password(DOMAIN, USERNAME, pk.private_bytes(Encoding.PEM, PrivateFormat.PKCS8, NoEncryption()).decode())
def get_secure_key():
key = None
try:
key = keyring.get_password(DOMAIN, USERNAME)
except keyring.errors.KeyringError:
key = generate_secure_key()
return get_d(key.encode())