Skip to content

Commit

Permalink
Add nkpk commands
Browse files Browse the repository at this point in the history
  • Loading branch information
robin-nitrokey committed Jan 26, 2024
1 parent 702821c commit 5a7d2d3
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 0 deletions.
3 changes: 3 additions & 0 deletions pynitrokey/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from pynitrokey.cli.fido2 import fido2
from pynitrokey.cli.nethsm import nethsm
from pynitrokey.cli.nk3 import nk3
from pynitrokey.cli.nkpk import nkpk
from pynitrokey.cli.pro import pro
from pynitrokey.cli.start import start
from pynitrokey.cli.storage import storage
Expand Down Expand Up @@ -87,6 +88,7 @@ def nitropy():
nitropy.add_command(fido2)
nitropy.add_command(nethsm)
nitropy.add_command(nk3)
nitropy.add_command(nkpk)
nitropy.add_command(start)
nitropy.add_command(storage)
nitropy.add_command(pro)
Expand All @@ -105,6 +107,7 @@ def _list():
fido2.commands["list"].callback()
start.commands["list"].callback()
nk3.commands["list"].callback()
nkpk.commands["list"].callback()
# TODO add other handled models


Expand Down
65 changes: 65 additions & 0 deletions pynitrokey/cli/nkpk.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# -*- coding: utf-8 -*-
#
# Copyright 2024 Nitrokey Developers
#
# Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
# http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
# http://opensource.org/licenses/MIT>, at your option. This file may not be
# copied, modified, or distributed except according to those terms.

from typing import Optional, Sequence

import click

from pynitrokey.cli.trussed.test import TestCase
from pynitrokey.helpers import local_print
from pynitrokey.nkpk import NitrokeyPasskeyBootloader, NitrokeyPasskeyDevice
from pynitrokey.trussed.base import NitrokeyTrussedBase
from pynitrokey.trussed.device import NitrokeyTrussedDevice

from . import trussed


class Context(trussed.Context[NitrokeyPasskeyBootloader, NitrokeyPasskeyDevice]):
def __init__(self, path: Optional[str]) -> None:
super().__init__(path, NitrokeyPasskeyBootloader, NitrokeyPasskeyDevice)

@property
def test_cases(self) -> list[TestCase]:
from pynitrokey.cli.trussed import tests

return [
tests.test_uuid_query,
tests.test_firmware_version_query,
tests.test_device_status,
tests.test_bootloader_configuration,
tests.test_firmware_mode,
tests.test_fido2,
]

@property
def device_name(self) -> str:
return "Nitrokey Passkey"

def open(self, path: str) -> Optional[NitrokeyTrussedBase]:
from pynitrokey.nkpk import open

return open(path)

def list_all(self) -> list[NitrokeyTrussedBase]:
from pynitrokey.nkpk import list

return list()


@click.group()
@click.option("-p", "--path", "path", help="The path of the Nitrokey 3 device")
@click.pass_context
def nkpk(ctx: click.Context, path: Optional[str]) -> None:
"""Interact with Nitrokey Passkey devices, see subcommands."""
ctx.obj = Context(path)
trussed.prepare_group()


# shared Trussed commands
trussed.add_commands(nkpk)
70 changes: 70 additions & 0 deletions pynitrokey/nkpk.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-
#
# Copyright 2024 Nitrokey Developers
#
# Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
# http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
# http://opensource.org/licenses/MIT>, at your option. This file may not be
# copied, modified, or distributed except according to those terms.

from typing import List, Optional

from fido2.hid import CtapHidDevice

from pynitrokey.trussed import VID_NITROKEY
from pynitrokey.trussed.base import NitrokeyTrussedBase
from pynitrokey.trussed.bootloader.nrf52 import NitrokeyTrussedBootloaderNrf52
from pynitrokey.trussed.device import NitrokeyTrussedDevice

PID_NITROKEY_PASSKEY_DEVICE = 0x42F3
PID_NITROKEY_PASSKEY_BOOTLOADER = 0x42F4


class NitrokeyPasskeyDevice(NitrokeyTrussedDevice):
def __init__(self, device: CtapHidDevice) -> None:
super().__init__(device)

@property
def pid(self) -> int:
return PID_NITROKEY_PASSKEY_DEVICE

@property
def name(self) -> str:
return "Nitrokey Passkey"


class NitrokeyPasskeyBootloader(NitrokeyTrussedBootloaderNrf52):
@property
def name(self) -> str:
return "Nitrokey Passkey Bootloader"

@property
def pid(self) -> int:
return PID_NITROKEY_PASSKEY_BOOTLOADER

@classmethod
def list(cls) -> List["NitrokeyPasskeyBootloader"]:
return cls.list_vid_pid(VID_NITROKEY, PID_NITROKEY_PASSKEY_BOOTLOADER)

@classmethod
def open(cls, path: str) -> Optional["NitrokeyPasskeyBootloader"]:
return cls.open_vid_pid(VID_NITROKEY, PID_NITROKEY_PASSKEY_BOOTLOADER, path)


def list() -> List[NitrokeyTrussedBase]:
devices: List[NitrokeyTrussedBase] = []
devices.extend(NitrokeyPasskeyBootloader.list())
devices.extend(NitrokeyPasskeyDevice.list())
return devices


def open(path: str) -> Optional[NitrokeyTrussedBase]:
device = NitrokeyPasskeyDevice.open(path)
bootloader_device = NitrokeyPasskeyBootloader.open(path)
if device and bootloader_device:
raise Exception(f"Found multiple devices at path {path}")
if device:
return device
if bootloader_device:
return bootloader_device
return None

0 comments on commit 5a7d2d3

Please sign in to comment.