Skip to content

Commit 2c364aa

Browse files
committed
cli: add setpqc command to load composite PQC PGP key into RSA slot
Wire onlykey/pqc.py into the CLI: "onlykey-cli setpqc RSA1 <160-byte hex|file>" loads a composite IETF OpenPGP-PQC seed blob (OKSETPRIV 0x67) into slot 1-4. Also fix load_composite_key framing: send_message rejects bytes, use bytearray.
1 parent a32220a commit 2c364aa

2 files changed

Lines changed: 29 additions & 1 deletion

File tree

onlykey/cli.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,32 @@ def prompt_pin():
418418
print(sys.exc_info()[0])
419419
print('Input error. See available commands with examples here https://docs.crp.to/command-line.html')
420420
return
421+
elif sys.argv[1] == 'setpqc':
422+
# Load a composite PQC PGP key (IETF OpenPGP-PQC) into an RSA slot.
423+
# setpqc [RSA1-RSA4] [160-byte hex blob | path to .hex/.bin file]
424+
# blob layout (see onlykey/pqc.py): Ed25519(32)|ML-DSA seed(32)|X25519(32)|ML-KEM seed(64)
425+
try:
426+
from . import pqc
427+
slotmap = {'RSA1': 1, 'RSA2': 2, 'RSA3': 3, 'RSA4': 4}
428+
slot_id = slotmap.get(sys.argv[2])
429+
if not slot_id:
430+
print('setpqc [RSA1-RSA4] [160-byte hex blob | file]')
431+
return
432+
arg = sys.argv[3]
433+
if os.path.isfile(arg):
434+
raw = open(arg, 'rb').read()
435+
try:
436+
blob = bytes.fromhex(raw.decode().strip())
437+
except Exception:
438+
blob = raw
439+
else:
440+
blob = bytes.fromhex(arg.strip())
441+
pqc.load_composite_key(only_key, slot_id, blob)
442+
print('Loaded composite PQC PGP key (%d bytes) into %s' % (len(blob), sys.argv[2]))
443+
except Exception:
444+
print(sys.exc_info()[0])
445+
print('setpqc [RSA1-RSA4] [160-byte hex blob | file]')
446+
return
421447
elif sys.argv[1] == 'wipekey':
422448
try:
423449
if sys.argv[2] == 'RSA1':

onlykey/pqc.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,10 @@ def load_composite_key(ok, slot, blob):
8787
blob = bytes(blob)
8888
for i in range(0, PQC_PGP_BLOB_LEN, 57):
8989
chunk = blob[i:i + 57]
90+
# send_message accepts str(hex)/list/bytearray/int — NOT bytes — so frame
91+
# the payload as a bytearray: [key_type] + 57-byte chunk (key_type -> buffer[6]).
9092
ok.send_message(msg=Message.OKSETPRIV, slot_id=slot,
91-
payload=bytes([PQC_KEY_TYPE_BYTE]) + chunk)
93+
payload=bytearray([PQC_KEY_TYPE_BYTE]) + bytearray(chunk))
9294

9395

9496
def decrypt(ok, slot, data):

0 commit comments

Comments
 (0)