Skip to content

Commit

Permalink
nk3: Add Uuid class
Browse files Browse the repository at this point in the history
  • Loading branch information
robin-nitrokey committed Dec 16, 2022
1 parent 82d966a commit 17f8564
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 16 deletions.
2 changes: 1 addition & 1 deletion pynitrokey/cli/nk3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ def list() -> None:
with device as device:
uuid = device.uuid()
if uuid:
local_print(f"{device.path}: {device.name} {device.uuid():032X}")
local_print(f"{device.path}: {device.name} {uuid}")
else:
local_print(f"{device.path}: {device.name}")

Expand Down
10 changes: 5 additions & 5 deletions pynitrokey/cli/nk3/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from pynitrokey.helpers import local_print
from pynitrokey.nk3.base import Nitrokey3Base
from pynitrokey.nk3.device import Nitrokey3Device
from pynitrokey.nk3.utils import Version
from pynitrokey.nk3.utils import Uuid, Version

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -149,7 +149,7 @@ def log_system() -> None:
@test_case("uuid", "UUID query")
def test_uuid_query(ctx: TestContext, device: Nitrokey3Base) -> TestResult:
uuid = device.uuid()
uuid_str = f"{uuid:032X}" if uuid else "[not supported]"
uuid_str = str(uuid) if uuid else "[not supported]"
return TestResult(TestStatus.SUCCESS, uuid_str)


Expand Down Expand Up @@ -179,7 +179,7 @@ def test_bootloader_configuration(
from smartcard.CardConnection import CardConnection
from smartcard.Exceptions import NoCardException

def find_smartcard(uuid: int) -> CardConnection:
def find_smartcard(uuid: Uuid) -> CardConnection:
for reader in System.readers():
conn = reader.createConnection()
try:
Expand All @@ -193,10 +193,10 @@ def find_smartcard(uuid: int) -> CardConnection:
continue
if len(data) != 16:
continue
if uuid != int.from_bytes(data, "big"):
if uuid != Uuid(int.from_bytes(data, byteorder="big")):
continue
return conn
raise Exception(f"No smartcard with UUID {uuid:032X} found")
raise Exception(f"No smartcard with UUID {uuid} found")

def select(conn: CardConnection, aid: list[int]) -> bool:
apdu = [0x00, 0xA4, 0x04, 0x00]
Expand Down
4 changes: 3 additions & 1 deletion pynitrokey/nk3/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
from abc import ABC, abstractmethod
from typing import Optional, TypeVar

from .utils import Uuid

T = TypeVar("T", bound="Nitrokey3Base")


Expand Down Expand Up @@ -41,5 +43,5 @@ def reboot(self) -> bool:
...

@abstractmethod
def uuid(self) -> Optional[int]:
def uuid(self) -> Optional[Uuid]:
...
6 changes: 3 additions & 3 deletions pynitrokey/nk3/bootloader/lpc55.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from spsdk.sbfile.sb2.images import BootImageV21
from spsdk.utils.usbfilter import USBDeviceFilter

from ..utils import Version
from ..utils import Uuid, Version
from . import FirmwareMetadata, Nitrokey3Bootloader, ProgressCallback, Variant

RKHT = bytes.fromhex("050aad3e77791a81e59c5b2ba5a158937e9460ee325d8ccba09734b8fdebb171")
Expand Down Expand Up @@ -81,7 +81,7 @@ def reboot(self) -> bool:
raise Exception("Failed to reboot Nitrokey 3 bootloader")
return True

def uuid(self) -> Optional[int]:
def uuid(self) -> Optional[Uuid]:
uuid = self.device.get_property(PropertyTag.UNIQUE_DEVICE_IDENT) # type: ignore[arg-type]
if not uuid:
raise ValueError("Missing response for UUID property query")
Expand All @@ -92,7 +92,7 @@ def uuid(self) -> Optional[int]:
# https://github.com/lpc55/lpc55-host/blob/main/src/bootloader/property.rs#L222
wrong_endian = (uuid[3] << 96) + (uuid[2] << 64) + (uuid[1] << 32) + uuid[0]
right_endian = wrong_endian.to_bytes(16, byteorder="little")
return int.from_bytes(right_endian, byteorder="big")
return Uuid(int.from_bytes(right_endian, byteorder="big"))

def update(
self,
Expand Down
6 changes: 3 additions & 3 deletions pynitrokey/nk3/bootloader/nrf52.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from nordicsemi.dfu.package import Package
from nordicsemi.lister.device_lister import DeviceLister

from ..utils import Version
from ..utils import Uuid, Version
from . import FirmwareMetadata, Nitrokey3Bootloader, ProgressCallback, Variant

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -153,8 +153,8 @@ def close(self) -> None:
def reboot(self) -> bool:
return False

def uuid(self) -> Optional[int]:
return self._uuid
def uuid(self) -> Optional[Uuid]:
return Uuid(self._uuid)

def update(self, data: bytes, callback: Optional[ProgressCallback] = None) -> None:
# based on https://github.com/NordicSemiconductor/pc-nrfutil/blob/1caa347b1cca3896f4695823f48abba15fbef76b/nordicsemi/dfu/dfu.py
Expand Down
6 changes: 3 additions & 3 deletions pynitrokey/nk3/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

from .base import Nitrokey3Base
from .exceptions import TimeoutException
from .utils import Version
from .utils import Uuid, Version

RNG_LEN = 57
UUID_LEN = 16
Expand Down Expand Up @@ -96,14 +96,14 @@ def reboot(self, mode: BootMode = BootMode.FIRMWARE) -> bool:
self.logger.debug("ignoring OSError after reboot", exc_info=e)
return True

def uuid(self) -> Optional[int]:
def uuid(self) -> Optional[Uuid]:
uuid = self._call(Command.UUID)
if len(uuid) == 0:
# Firmware version 1.0.0 does not support querying the UUID
return None
if len(uuid) != UUID_LEN:
raise ValueError(f"UUID response has invalid length {len(uuid)}")
return int.from_bytes(uuid, "big")
return Uuid(int.from_bytes(uuid, byteorder="big"))

def version(self) -> Version:
version_bytes = self._call(Command.VERSION, response_len=VERSION_LEN)
Expand Down
11 changes: 11 additions & 0 deletions pynitrokey/nk3/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,20 @@
from functools import total_ordering
from typing import Tuple

from dataclasses import dataclass
from spsdk.sbfile.misc import BcdVersion3


@dataclass(order=True, frozen=True)
class Uuid:
"""UUID of a Nitrokey 3 device."""

value: int

def __str__(self) -> str:
return f"{self.value:032X}"


@total_ordering
class Version:
def __init__(self, major: int, minor: int, patch: int) -> None:
Expand Down

0 comments on commit 17f8564

Please sign in to comment.