Skip to content

Commit 1e312ef

Browse files
committed
Move certificate listing to separate command
1 parent e82019e commit 1e312ef

File tree

1 file changed

+45
-17
lines changed

1 file changed

+45
-17
lines changed

pynitrokey/cli/nk3/piv.py

+45-17
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import datetime
22
import sys
3-
from typing import Optional, Sequence, Tuple, Union
3+
from typing import Any, Iterable, Optional, Sequence, Tuple, Union
44

55
import click
66
import cryptography
@@ -118,6 +118,26 @@ def sign(
118118

119119
return self._device.sign_p256(data, self._key_reference)
120120

121+
def print_row(values: Iterable[str], widths: Iterable[int]) -> None:
122+
row = [value.ljust(width) for (value, width) in zip(values, widths)]
123+
print(*row, sep="\t")
124+
125+
def print_table(headers: Sequence[str], data: Iterable[Sequence[Any]]) -> None:
126+
widths = [len(header) for header in headers]
127+
str_data = []
128+
for row in data:
129+
str_row = []
130+
for i in range(len(widths)):
131+
str_value = str(row[i])
132+
str_row.append(str_value)
133+
widths[i] = max(widths[i], len(str_value))
134+
str_data.append(str_row)
135+
136+
print_row(headers, widths)
137+
print_row(["-" * width for width in widths], widths)
138+
for row in str_data:
139+
print_row(row, widths)
140+
121141
@nk3.group()
122142
@click.option(
123143
"--experimental",
@@ -180,22 +200,6 @@ def info() -> None:
180200
guid = device.guid()
181201
local_print(f"GUID: {guid.hex().upper()}")
182202

183-
printed_head = False
184-
for key, slot in KEY_TO_CERT_OBJ_ID_MAP.items():
185-
cert = device.cert(bytes(bytearray.fromhex(slot)))
186-
if cert is not None:
187-
if not printed_head:
188-
local_print("Keys:")
189-
printed_head = True
190-
parsed_cert = x509.load_der_x509_certificate(cert)
191-
local_print(f" {key}")
192-
local_print(
193-
f" algorithm: {parsed_cert.signature_algorithm_oid._name}"
194-
)
195-
if not printed_head:
196-
local_print("No certificate found")
197-
pass
198-
199203
@piv.command(help="Change the admin key.")
200204
@click.option(
201205
"--current-admin-key",
@@ -768,6 +772,30 @@ def read_certificate(format: str, key: str, path: str) -> None:
768772
with click.open_file(path, mode="wb") as f:
769773
f.write(cert_serialized)
770774

775+
@piv.command(help="List certificates.")
776+
def list_certificates() -> None:
777+
device = PivApp()
778+
779+
headers = ["Slot", "Algorithm", "Subject"]
780+
data = []
781+
782+
for key, slot in KEY_TO_CERT_OBJ_ID_MAP.items():
783+
cert = device.cert(bytes(bytearray.fromhex(slot)))
784+
if cert is not None:
785+
parsed_cert = x509.load_der_x509_certificate(cert)
786+
data.append(
787+
[
788+
key,
789+
parsed_cert.signature_algorithm_oid._name,
790+
parsed_cert.subject.rfc4514_string(),
791+
]
792+
)
793+
794+
if data:
795+
print_table(headers, data)
796+
else:
797+
local_print("No certificate found.")
798+
771799
except ImportError:
772800
from pynitrokey.cli.nk3.pcsc_absent import PCSC_ABSENT
773801

0 commit comments

Comments
 (0)