# Type 1 = 1024, Type 2 = 2048, Type 3 = 3072, Type 4 = 4096 # Key Features - # if backup key = type + 128 # if signature key = type + 64 # if decryption key = type + 32 # if authentication key = type + 16 # For this example it will be a decryption key time.sleep(1.5) print ok.read_string() time.sleep(2) print 'You should see your OnlyKey blink 3 times' print print 'Trying to read the public RSA N part 1...' ok.send_message(msg=Message.OKGETPUBKEY, payload=chr(1)) #, payload=[1, 1]) time.sleep(1.5) for _ in xrange(10): ok_pubkey1 = ok.read_bytes(64, to_str=True, timeout_ms=1000) if len(ok_pubkey1) == 64: break time.sleep(1) print print 'received=', repr(ok_pubkey1) print 'Trying to read the public RSA N part 2...' for _ in xrange(10): ok_pubkey2 = ok.read_bytes(64, to_str=True, timeout_ms=1000) if len(ok_pubkey2) == 64:
class Client(object): """Client wrapper for SSH authentication device.""" def __init__(self, curve=formats.CURVE_NIST256): """Connect to hardware device.""" self.device_name = 'OnlyKey' self.ok = OnlyKey() self.curve = curve def __enter__(self): """Start a session, and test connection.""" self.ok.read_string(timeout_ms=50) empty = 'a' while not empty: empty = self.ok.read_string(timeout_ms=50) return self def __exit__(self, *args): """Forget PIN, shutdown screen and disconnect.""" log.info('disconnected from %s', self.device_name) self.ok.close() def get_identity(self, label, index=0): """Parse label string into Identity protobuf.""" identity = string_to_identity(label) identity['proto'] = 'ssh' identity['index'] = index print 'identity', identity return identity def get_public_key(self, label): log.info('getting public key from %s...', self.device_name) log.info('Trying to read the public key...') # Compute the challenge pin h = hashlib.sha256() h.update(label) data = h.hexdigest() if self.curve == formats.CURVE_NIST256: data = '02' + data else: data = '01' + data data = data.decode("hex") log.info('Identity hash =%s', repr(data)) self.ok.send_message(msg=Message.OKGETPUBKEY, slot_id=132, payload=data) time.sleep(.5) for _ in xrange(2): ok_pubkey = self.ok.read_bytes(64, to_str=True, timeout_ms=10) if len(ok_pubkey) == 64: break log.info('received= %s', repr(ok_pubkey)) if len(set(ok_pubkey[34:63])) == 1: ok_pubkey = ok_pubkey[0:32] log.info('Received Public Key generated by OnlyKey= %s', repr(ok_pubkey)) vk = ed25519.VerifyingKey(ok_pubkey) return formats.export_public_key(vk=vk, label=label) else: ok_pubkey = ok_pubkey[0:64] log.info('Received Public Key generated by OnlyKey= %s', repr(ok_pubkey)) vk = ecdsa.VerifyingKey.from_string(ok_pubkey, curve=ecdsa.NIST256p) return formats.export_public_key(vk=vk, label=label) def sign_ssh_challenge(self, label, blob): """Sign given blob using a private key, specified by the label.""" msg = _parse_ssh_blob(blob) log.debug('%s: user %r via %r (%r)', msg['conn'], msg['user'], msg['auth'], msg['key_type']) log.debug('nonce: %s', binascii.hexlify(msg['nonce'])) log.debug('fingerprint: %s', msg['public_key']['fingerprint']) log.debug('hidden challenge size: %d bytes', len(blob)) # self.ok.send_large_message(payload=blob, msg=Message.OKSIGNSSHCHALLENGE) log.info('please confirm user "%s" login to "%s" using %s', msg['user'], label, self.device_name) h1 = hashlib.sha256() h1.update(label) data = h1.hexdigest() data = data.decode("hex") test_payload = blob + data # Compute the challenge pin h2 = hashlib.sha256() h2.update(test_payload) d = h2.digest() assert len(d) == 32 def get_button(byte): ibyte = ord(byte) return ibyte % 6 + 1 b1, b2, b3 = get_button(d[0]), get_button(d[15]), get_button(d[31]) log.info('blob to send', repr(test_payload)) # Determine type of key to derive on OnlyKey for signature # 201 = ed25519 # 202 = P256 # 203 = secp256k1 keytype = msg['key_type'] if msg['key_type'].startswith('ssh-ed25519'): this_slot_id = 201 log.info('Key type ed25519') elif msg['key_type'].startswith('ecdsa-sha2-nistp256'): this_slot_id = 202 log.info('Key type P256') else: this_slot_id = 203 log.info('Key type secp256k1') self.ok.send_large_message2(msg=Message.OKSIGNCHALLENGE, payload=test_payload, slot_id=this_slot_id) #TODO ping messages so that we don't need enter key to tell when done. print 'Please confirm user', msg[ 'user'], 'login to', label, 'using', self.device_name print( 'Enter the 3 digit challenge code shown below on OnlyKey to authenticate' ) print '{} {} {}'.format(b1, b2, b3) raw_input() for _ in xrange(10): result = self.ok.read_bytes(64, to_str=True, timeout_ms=200) if len(result) >= 60: log.info('received= %s', repr(result)) while len(result) < 64: result.append(0) log.info('disconnected from %s', self.device_name) self.ok.close() return result raise Exception('failed to sign challenge')
# Type 1 = 1024, Type 2 = 2048, Type 3 = 3072, Type 4 = 4096 # Key Features - # if backup key = type + 128 # if signature key = type + 64 # if decryption key = type + 32 # if authentication key = type + 16 # For this example it will be a decryption key time.sleep(1.5) print(ok.read_string()) time.sleep(2) print('You should see your OnlyKey blink 3 times') print() print('Trying to read the public RSA N part 1...') ok.send_message(msg=Message.OKGETPUBKEY, payload=bytes([1, 1])) #, payload=[1, 1]) time.sleep(1.5) for _ in range(10): ok_pubkey1 = ok.read_bytes(64, timeout_ms=1000) if len(ok_pubkey1) == 64: break time.sleep(1) print() print('received=', repr(ok_pubkey1)) print('Trying to read the public RSA N part 2...') for _ in range(10): ok_pubkey2 = ok.read_bytes(64, timeout_ms=1000) if len(ok_pubkey2) == 64:
print('You should see your OnlyKey blink 3 times') print() print('Setting SSH private...') ok.set_ecc_key(101, (1+64), privkey.to_seed()) # ok.set_ecc_privsend_message(msg=Message.OKSETPRIV, payload=privkey.to_seed()) time.sleep(1.5) print(ok.read_string()) time.sleep(2) print('You should see your OnlyKey blink 3 times') print() print('Trying to read the pubkey...') ok.send_message(msg=Message.OKGETPUBKEY, payload=101, slot_id=65) #, payload=[1, 1]) time.sleep(1.5) for i in range(10): print(i) ok_pubkey = ok.read_bytes(32, to_str=True) print(ok_pubkey) if len(ok_pubkey) == 32: break time.sleep(1) print() print(ok_pubkey) print('received=', repr(ok_pubkey)) if not ok_pubkey: raise Exception('failed to set the SSH key')