Skip to content

Commit a5b5b07

Browse files
authored
Merge pull request #32 from c0d3d/master
Got this working with onlykey-agent
2 parents fb1cc0a + f15747a commit a5b5b07

6 files changed

Lines changed: 55 additions & 62 deletions

File tree

onlykey/client.py

Lines changed: 31 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
from sys import platform
1111

1212
log = logging.getLogger(__name__)
13-
logging.basicConfig(level=logging.DEBUG)
1413

1514
DEVICE_IDS = [
1615
(0x16C0, 0x0486), # OnlyKey
@@ -252,7 +251,6 @@ def send_message(self, payload=None, msg=None, slot_id=None, message_field=None)
252251
raw_bytes += bytes([payload])
253252
else:
254253
raise Exception('`payload` must be either `str` or `list`, got `{}`'.format(type(payload)))
255-
256254
# Pad the ouput with 0s
257255
while len(raw_bytes) < MAX_INPUT_REPORT_SIZE:
258256
raw_bytes += bytes([0])
@@ -271,22 +269,19 @@ def send_large_message(self, payload=None, msg=None, slot_id=chr(101)):
271269
for chunk in chunks:
272270
# print chunk
273271
# print [ord(c) for c in chunk]
274-
current_payload = [255] # 255 means that it's not the last payload
272+
current_payload = bytes([255]) # 255 means that it's not the last payload
275273
# If it's less than the max size, set explicitely the size
276274
if len(chunk) < 58:
277-
current_payload = [len(chunk)]
275+
current_payload = bytes([len(chunk)])
278276

279277
# Append the actual payload
280278
if isinstance(chunk, list):
281-
current_payload.extend(chunk)
279+
current_payload += bytes(chunk)
282280
else:
283-
for c in chunk:
284-
current_payload.append(ord(c))
281+
current_payload += chunk
285282

286283
self.send_message(payload=current_payload, msg=msg)
287284

288-
return
289-
290285

291286
def send_large_message2(self, payload=None, msg=None, slot_id=101):
292287
"""Wrapper for sending large message (larger than 58 bytes) in batch in a transparent way."""
@@ -303,18 +298,16 @@ def send_large_message2(self, payload=None, msg=None, slot_id=101):
303298
if len(chunk) < 57:
304299
current_payload = [slot_id, len(chunk)]
305300

301+
current_payload = bytes(current_payload)
302+
306303
# Append the actual payload
307304
if isinstance(chunk, list):
308-
current_payload.extend(chunk)
305+
current_payload += bytes(chunk)
309306
else:
310-
for c in chunk:
311-
current_payload.append(c)
307+
current_payload += chunk
312308

313309
self.send_message(payload=current_payload, msg=msg)
314310

315-
return
316-
317-
318311

319312
def send_large_message3(self, payload=None, msg=None, slot_id=101, key_type=1):
320313
"""Wrapper for sending large message (larger than 58 bytes) in batch in a transparent way."""
@@ -324,35 +317,32 @@ def send_large_message3(self, payload=None, msg=None, slot_id=101, key_type=1):
324317
# Split the payload in multiple chunks
325318
chunks = [payload[x:x+MAX_LARGE_PAYLOAD_SIZE-1] for x in range(0, len(payload), 57)]
326319
for chunk in chunks:
327-
# print chunk
328-
# print [ord(c) for c in chunk]
329-
current_payload = [slot_id, key_type]
320+
current_payload = bytes([slot_id, key_type])
330321

331322
# Append the actual payload
332323
if isinstance(chunk, list):
333-
current_payload.extend(chunk)
324+
current_payload += bytes(chunk)
334325
else:
335-
for c in chunk:
336-
current_payload.append(ord(c))
326+
current_payload += chunk
337327

338-
self.send_message(payload=current_payload, msg=msg)
339-
340-
return
328+
self.send_message(payload=current_payload, msg=msg)
341329

342-
def read_bytes(self, n=64, to_str=False, timeout_ms=100) -> bytes:
330+
def read_bytes(self, n=64, to_str=False, timeout_ms=100):
343331
"""Read n bytes and return an array of uint8 (int)."""
344332
out = self._hid.read(n, timeout=timeout_ms)
345-
log.debug('read="%s"', out.decode())
346333
if to_str:
347334
# Returns the bytes a string if requested
348-
return out.decode("utf-8")
335+
return out.hex()
349336

350337
# Returns the raw list
351338
return out
352339

353340
def read_string(self, timeout_ms=100):
354341
"""Read an ASCII string."""
355-
return self.read_bytes(MAX_INPUT_REPORT_SIZE, timeout_ms=timeout_ms).decode("ascii")
342+
return self.read_chunk(timeout_ms=timeout_ms).decode("ascii")
343+
344+
def read_chunk(self, timeout_ms=100):
345+
return self.read_bytes(MAX_INPUT_REPORT_SIZE, timeout_ms=timeout_ms)
356346

357347
def getlabels(self):
358348
"""Fetch the list of `Slot` from the OnlyKey.
@@ -377,13 +367,14 @@ def getkeylabels(self):
377367
No need to read messages.
378368
"""
379369
self.send_message(msg=Message.OKGETLABELS, slot_id=107)
380-
time.sleep(0)
381370
slots = []
382371
for _ in range(33):
383-
data = self.read_string().split('|')
384-
slot_number = ord(data[0])
372+
data = self.read_chunk()
373+
bef, _, aft = data.partition(b"|")
374+
slot_number = bef[0]
385375
if 25 <= slot_number <= 57:
386376
slots.append(Slot(slot_number, label=data[1]))
377+
387378
return slots
388379

389380
def displaykeylabels(self):
@@ -568,14 +559,14 @@ def getpub(self):
568559
ok_pubkey1 = ''
569560
while ok_pubkey1 == '':
570561
time.sleep(0.5)
571-
ok_pubkey1= self.read_bytes(64, to_str=True)
562+
ok_pubkey1= self.read_bytes(64)
572563

573564
print()
574565
print('received=', repr(ok_pubkey1))
575566

576567
print('Trying to read the public RSA N part 2...')
577568
for _ in range(10):
578-
ok_pubkey2 = self.read_bytes(64, to_str=True)
569+
ok_pubkey2 = self.read_bytes(64)
579570
if len(ok_pubkey2) == 64:
580571
break
581572

@@ -584,7 +575,7 @@ def getpub(self):
584575

585576
print('Trying to read the public RSA N part 3...')
586577
for _ in range(10):
587-
ok_pubkey3 = self.read_bytes(64, to_str=True)
578+
ok_pubkey3 = self.read_bytes(64)
588579
if len(ok_pubkey3) == 64:
589580
break
590581

@@ -594,7 +585,7 @@ def getpub(self):
594585

595586
print('Trying to read the public RSA N part 4...')
596587
for _ in range(10):
597-
ok_pubkey4 = self.read_bytes(64, to_str=True)
588+
ok_pubkey4 = self.read_bytes(64)
598589
if len(ok_pubkey4) == 64:
599590
break
600591

@@ -604,7 +595,7 @@ def getpub(self):
604595

605596
print('Trying to read the public RSA N part 5...')
606597
for _ in range(10):
607-
ok_pubkey5 = self.read_bytes(64, to_str=True)
598+
ok_pubkey5 = self.read_bytes(64)
608599
if len(ok_pubkey5) == 64:
609600
break
610601

@@ -614,7 +605,7 @@ def getpub(self):
614605

615606
print('Trying to read the public RSA N part 6...')
616607
for _ in range(10):
617-
ok_pubkey6 = self.read_bytes(64, to_str=True)
608+
ok_pubkey6 = self.read_bytes(64)
618609
if len(ok_pubkey6) == 64:
619610
break
620611

@@ -624,7 +615,7 @@ def getpub(self):
624615

625616
print('Trying to read the public RSA N part 7...')
626617
for _ in range(10):
627-
ok_pubkey7 = self.read_bytes(64, to_str=True)
618+
ok_pubkey7 = self.read_bytes(64)
628619
if len(ok_pubkey7) == 64:
629620
break
630621

@@ -634,7 +625,7 @@ def getpub(self):
634625
print('Trying to read the public RSA N part 8...')
635626

636627
for _ in range(10):
637-
ok_pubkey8 = self.read_bytes(64, to_str=True)
628+
ok_pubkey8 = self.read_bytes(64)
638629
if len(ok_pubkey8) == 64:
639630
break
640631

@@ -647,7 +638,7 @@ def getpub(self):
647638

648639
print('Received Public Key generated by OnlyKey')
649640
ok_pubkey = ok_pubkey1 + ok_pubkey2 + ok_pubkey3 + ok_pubkey4 + ok_pubkey5 + ok_pubkey6 + ok_pubkey7 + ok_pubkey8
650-
print('Public N='), repr(ok_pubkey)
641+
print('Public N=', repr(ok_pubkey))
651642
print()
652643

653644
print('Key Size =', len(ok_pubkey))

tests/PGP_message.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import pgpy
1010
from pgpy import PGPKey
11-
from pgpy.constants import PubKeyAlgorithm, KeyFlags, HashAlgorithm, SymmetricKeyAlgorithm, CompressionAlgorithm, ok
11+
from pgpy.constants import PubKeyAlgorithm, KeyFlags, HashAlgorithm, SymmetricKeyAlgorithm, CompressionAlgorithm
1212
from pgpy.packet.fields import RSAPub,MPI,RSAPriv
1313
from pgpy.packet.packets import PubKeyV4,PrivKeyV4
1414

@@ -18,6 +18,8 @@
1818

1919
from onlykey import OnlyKey, Message
2020

21+
ok = OnlyKey()
22+
2123
def custRSAPub(n,e):
2224
res = RSAPriv()
2325
res.n = MPI(n)
@@ -63,8 +65,8 @@ def makekey():
6365
# key_expires=timedelta(days=365))
6466
#p = n[:(len(n)/2)]
6567
#q = n[(len(n)/2):]
66-
n = n.encode("HEX")
67-
N = long(n, 16)
68+
n = n.hex()
69+
N = int(n, 16)
6870
#p = p.encode("HEX")
6971
#p = long(p, 16)
7072
#q = q.encode("HEX")
@@ -138,7 +140,7 @@ def makekey():
138140
print('Type or paste the text message, press return to go to new line, and then press Ctrl+D or Ctrl+Z (Windows only)')
139141
print()
140142
msg_blob = sys.stdin.read()
141-
message_from_blob = priv_key.sign2(msg_blob)
143+
message_from_blob = priv_key.sign(msg_blob)
142144
print('Encoded Signed Message =')
143145
print('-----BEGIN PGP SIGNED MESSAGE-----')
144146
print('Hash: SHA256')

tests/ecdh_curve25519.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,10 @@
6464

6565

6666
message = 'Secret Message'
67-
counter = "\x00\x00\x00\x01"
67+
counter = b"\x00\x00\x00\x01"
6868
shared_secret = curve.calculateAgreement(alice_private_key, bob_public_key)
6969
h = hashlib.sha256()
70-
h.update(counter.encode())
70+
h.update(counter)
7171
h.update(shared_secret)
7272
h.update(message.encode())
7373
d = h.digest()
@@ -159,7 +159,7 @@ def get_button(ibyte):
159159
ok_shared_secret = ''
160160
while ok_shared_secret == '':
161161
time.sleep(0.5)
162-
ok_shared_secret = ok.read_bytes(len(shared_secret), to_str=True)
162+
ok_shared_secret = ok.read_bytes(64, to_str=True)
163163

164164
print('OnlyKey Shared Secret =', repr(ok_shared_secret))
165165

tests/rsa_decrypt_1024.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def pack_long(n):
5252
it seems to be want you wanted? it's 64 bytes.
5353
"""
5454
h = '%x' % n
55-
s = ('0'*(len(h) % 2) + h).decode('hex')
55+
s = bytes.fromhex('0'*(len(h) % 2) + h)
5656
return s
5757

5858
def bin2hex(binStr):
@@ -61,15 +61,15 @@ def bin2hex(binStr):
6161
def hex2bin(hexStr):
6262
return binascii.unhexlify(hexStr)
6363

64-
hexPrivKey = bin2hex(binPrivKey)
65-
hexPubKey = bin2hex(binPubKey)
64+
hexPrivKey = binPrivKey.hex()
65+
hexPubKey = binPubKey.hex()
6666

6767
# p and q are long ints that are no more than 1/2 the size of pubkey
6868
# I need to convert these into a single byte array put p in the first
6969
# half byte[0] of the byte array and q in the second half byte[(type*128) / 2]
7070
# send the byte array to OnlyKey splitting into 56 bytes per packet
71-
q_and_p = pack_long(q) + pack_long(p)
72-
public_n = pack_long(n)
71+
q_and_p = q.to_bytes(64, "little") + p.to_bytes(64, "little")
72+
public_n = n.to_bytes(128, "little")
7373
#
7474
ok.send_large_message3(msg=Message.OKSETPRIV, slot_id=1, key_type=(1+32), payload=q_and_p)
7575

@@ -90,10 +90,10 @@ def hex2bin(hexStr):
9090
print()
9191

9292
print('Trying to read the public RSA N part 1...')
93-
ok.send_message(msg=Message.OKGETPUBKEY, payload=chr(1)) #, payload=[1, 1])
93+
ok.send_message(msg=Message.OKGETPUBKEY, payload=bytes([1,1])) #, payload=[1, 1])
9494
time.sleep(1.5)
95-
for _ in xrange(10):
96-
ok_pubkey1 = ok.read_bytes(64, to_str=True, timeout_ms=1000)
95+
for _ in range(10):
96+
ok_pubkey1 = ok.read_bytes(64, timeout_ms=1000)
9797
if len(ok_pubkey1) == 64:
9898
break
9999
time.sleep(1)
@@ -103,8 +103,8 @@ def hex2bin(hexStr):
103103
print('received=', repr(ok_pubkey1))
104104

105105
print('Trying to read the public RSA N part 2...')
106-
for _ in xrange(10):
107-
ok_pubkey2 = ok.read_bytes(64, to_str=True, timeout_ms=1000)
106+
for _ in range(10):
107+
ok_pubkey2 = ok.read_bytes(64, timeout_ms=1000)
108108
if len(ok_pubkey2) == 64:
109109
break
110110
time.sleep(1)

tests/rsa_decrypt_3072.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def pack_long(n):
5252
it seems to be want you wanted? it's 64 bytes.
5353
"""
5454
h = '%x' % n
55-
s = ('0'*(len(h) % 2) + h).decode('hex')
55+
s = bytes.fromhex('0'*(len(h) % 2) + h)
5656
return s
5757

5858
def bin2hex(binStr):

tests/ssh_auth_rsa_1024.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,16 +187,16 @@ def bytes2int(str):
187187
print('local messege to sign=', repr(h.hexdigest()))
188188
verifier = PKCS1_v1_5.new(key)
189189
if verifier.verify(h, signature):
190-
print "The local signature is authentic."
190+
print("The local signature is authentic.")
191191
else:
192-
print "The local signature is not authentic."
192+
print("The local signature is not authentic.")
193193

194194
print('OnlyKey messege to sign=', repr(test_payload2))
195195
verifier = PKCS1_v1_5.new(key)
196196
if verifier.verify(h, ok_signature):
197-
print "The OnlyKey signature is authentic."
197+
print("The OnlyKey signature is authentic.")
198198
else:
199-
print "The OnlyKey signature is not authentic."
199+
print("The OnlyKey signature is not authentic.")
200200

201201

202202

0 commit comments

Comments
 (0)