allows silent certificate checks (#410)

This commit is contained in:
kaczmarczyck
2021-11-18 17:09:40 +01:00
committed by GitHub
parent ae4e32ba4a
commit 5cf988c7fa
3 changed files with 72 additions and 27 deletions

View File

@@ -26,6 +26,7 @@ import os
import shutil
import subprocess
import sys
import time
from typing import Dict, List, Tuple
import colorama
@@ -36,6 +37,7 @@ from tockloader import tbfh
from tockloader import tockloader as loader
from tockloader.exceptions import TockLoaderException
import tools.configure
from tools.deploy_partition import create_metadata, pad_to
PROGRAMMERS = frozenset(("jlink", "openocd", "pyocd", "nordicdfu", "none"))
@@ -706,6 +708,19 @@ class OpenSKInstaller:
if self.args.programmer == "none":
assert_python_library("intelhex")
def configure_device(self):
"""Checks the device configuration, and sets it according to args."""
configure_response = tools.configure.main(
argparse.Namespace(
batch=False,
certificate=self.args.config_cert,
priv_key=self.args.config_pkey,
lock=self.args.lock_device,
))
if not configure_response:
return None
return configure_response[0]
def run(self) -> int:
"""Reads args to decide and run all required tasks."""
self.check_prerequisites()
@@ -746,17 +761,13 @@ class OpenSKInstaller:
self.install_padding()
self.install_tab_file(f"target/tab/{self.args.application}.tab")
self.install_metadata()
if self.verify_flashed_app(self.args.application):
info("You're all set!")
return 0
error(
("It seems that something went wrong. App/example not found "
"on your board. Ensure the connections between the programmer and "
"the board are correct."))
if not self.verify_flashed_app(self.args.application):
error(("It seems that something went wrong. App/example not found "
"on your board. Ensure the connections between the programmer "
"and the board are correct."))
return 1
return 0
if self.args.programmer in ("pyocd", "nordicdfu", "none"):
elif self.args.programmer in ("pyocd", "nordicdfu", "none"):
dest_file = f"target/{self.args.board}_merged.hex"
os.makedirs("target", exist_ok=True)
self.create_hex_file(dest_file)
@@ -793,7 +804,7 @@ class OpenSKInstaller:
fatal("Multiple DFU devices are detected. Please only connect one.")
# Run the command without capturing stdout so that we show progress
info("Flashing device using DFU...")
return subprocess.run(
dfu_return_code = subprocess.run(
[
"nrfutil", "dfu", "usb-serial", f"--package={dfu_pkg_file}",
f"--serial-number={serial_number[0]}"
@@ -801,22 +812,49 @@ class OpenSKInstaller:
check=False,
timeout=None,
).returncode
if dfu_return_code != 0:
return dfu_return_code
# Configure OpenSK through vendor specific command if needed
if self.args.programmer == "none":
if any([
self.args.lock_device,
self.args.config_cert,
self.args.config_pkey,
]):
# pylint: disable=g-import-not-at-top,import-outside-toplevel
import tools.configure
tools.configure.main(
argparse.Namespace(
batch=False,
certificate=self.args.config_cert,
priv_key=self.args.config_pkey,
lock=self.args.lock_device,
))
fatal("Unexpected arguments to configure your device. Since you "
"selected the programmer \"none\", the device is not ready to be "
"configured yet.")
return 0
# Perform checks if OpenSK was flashed.
if self.args.application != "ctap2":
return 0
# Trying to check or configure the device. Booting might take some time.
for i in range(5):
# Increasing wait time, total of 10 seconds.
time.sleep(i)
devices = tools.configure.get_opensk_devices(False)
if devices:
break
if not devices:
fatal("No device to configure found.")
status = self.configure_device()
if not status:
fatal("Could not read device configuration.")
if status["cert"] and status["pkey"]:
info("You're all set!")
else:
info("Your device is not yet configured, and lacks some functionality. "
"If you run into issues, this command might help:\n\n"
"./tools/configure.py \\\n"
" --certificate=crypto_data/opensk_cert.pem \\\n"
" --private-key=crypto_data/opensk.key\n\n"
"Please read the Certificate considerations in docs/customization.md"
" to understand the privacy trade-off.")
return 0

View File

@@ -1192,7 +1192,9 @@ where
params: AuthenticatorVendorConfigureParameters,
cid: ChannelID,
) -> Result<ResponseData, Ctap2StatusCode> {
if params.attestation_material.is_some() || params.lockdown {
(self.check_user_presence)(cid)?;
}
// Sanity checks
let current_priv_key = self.persistent_store.attestation_private_key()?;

View File

@@ -125,6 +125,7 @@ def main(args):
}
devices = get_opensk_devices(args.batch)
responses = []
if not devices:
fatal("No devices found.")
for authenticator in tqdm(devices):
@@ -134,12 +135,15 @@ def main(args):
authenticator.device.wink()
aaguid = uuid.UUID(bytes=authenticator.get_info().aaguid)
info(f"Programming OpenSK device AAGUID {aaguid} ({authenticator.device}).")
if args.lock or args.priv_key:
info("Please touch the device to confirm...")
try:
result = authenticator.send_cbor(
OPENSK_VENDOR_CONFIGURE,
data=cbor_data,
)
status = {"cert": result[1], "pkey": result[2]}
responses.append(status)
info(f"Certificate: {'Present' if result[1] else 'Missing'}")
info(f"Private Key: {'Present' if result[2] else 'Missing'}")
if args.lock:
@@ -156,6 +160,7 @@ def main(args):
"the given cert/key don't match the ones currently programmed)."))
else:
error(f"Failed to configure OpenSK (unknown error: {ex}")
return responses
if __name__ == "__main__":