Example #1
0
print("Bob's public key: ", hexlify(bob_public_key))

print()
print("Alices's private key: ", hexlify(alice_private_key))
print("Alices's public key: ", hexlify(alice_public_key))
print()

print()
print('Initialize OnlyKey client...')
ok = OnlyKey()
print('Done')
print()

time.sleep(2)

ok.read_string(timeout_ms=100)
empty = 'a'
while not empty:
    empty = ok.read_string(timeout_ms=100)

print('You should see your OnlyKey blink 3 times')
print()

print('Setting ECC private...')
ok.set_ecc_key(101, (2 + 32), bob_private_key)
# Slot 101 - 132 for ECC
# Type 1 = Ed25519, Type 2 = p256r1, Type 3 = p256k1
# Key Features -
# if backup key = type + 128
# if signature key = type + 64
# if decryption key = type + 32
Example #2
0
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')