Esempio n. 1
0
def msg_authenticate_genkey(app_id: bytes, keyhandle: bytes, pathformat: str):
    from apps.common import seed

    # unpack the keypath from the first half of keyhandle
    keybuf = keyhandle[:32]
    keypath = ustruct.unpack(pathformat, keybuf)

    # check high bit for hardened keys
    for i in keypath:
        if not i & HARDENED:
            if __debug__:
                log.warning(__name__, "invalid key path")
            return None

    # derive the signing key
    nodepath = [_U2F_KEY_PATH] + list(keypath)
    node = seed.derive_node_without_passphrase(nodepath, "nist256p1")

    # second half of keyhandle is a hmac of app_id and keypath
    keybase = hmac.Hmac(node.private_key(), app_id, hashlib.sha256)
    keybase.update(keybuf)
    keybase = keybase.digest()

    # verify the hmac
    if keybase != keyhandle[32:]:
        if __debug__:
            log.warning(__name__, "invalid key handle")
        return None

    return node
Esempio n. 2
0
def msg_authenticate_genkey(app_id: bytes, keyhandle: bytes):

    from apps.common import seed

    # unpack the keypath from the first half of keyhandle
    keybuf = keyhandle[:32]
    keypath = ustruct.unpack('>8L', keybuf)

    # check high bit for hardened keys
    for i in keypath:
        if not i & 0x80000000:
            log.warning(__name__, 'invalid key path')
            return None

    # derive the signing key
    nodepath = [_U2F_KEY_PATH] + list(keypath)
    node = seed.get_root_without_passphrase('nist256p1')
    node.derive_path(nodepath)

    # second half of keyhandle is a hmac of app_id and keypath
    keybase = hmac.Hmac(node.private_key(), app_id, hashlib.sha256)
    keybase.update(keybuf)
    keybase = keybase.digest()

    # verify the hmac
    if keybase != keyhandle[32:]:
        log.warning(__name__, 'invalid key handle')
        return None

    return node
Esempio n. 3
0
    def _node_from_key_handle(rp_id_hash: bytes, keyhandle: bytes,
                              pathformat: str) -> Optional[bip32.HDNode]:
        # unpack the keypath from the first half of keyhandle
        keypath = keyhandle[:32]
        path = ustruct.unpack(pathformat, keypath)

        # check high bit for hardened keys
        for i in path:
            if not i & HARDENED:
                if __debug__:
                    log.warning(__name__, "invalid key path")
                return None

        # derive the signing key
        nodepath = [_U2F_KEY_PATH] + list(path)
        node = seed.derive_node_without_passphrase(nodepath, "nist256p1")

        # second half of keyhandle is a hmac of rp_id_hash and keypath
        mac = hmac.Hmac(node.private_key(), rp_id_hash, hashlib.sha256)
        mac.update(keypath)

        # verify the hmac
        if not utils.consteq(mac.digest(), keyhandle[32:]):
            if __debug__:
                log.warning(__name__, "invalid key handle")
            return None

        return node
Esempio n. 4
0
def msg_register_sign(challenge: bytes, app_id: bytes) -> bytes:

    from apps.common import seed

    # derivation path is m/U2F'/r'/r'/r'/r'/r'/r'/r'/r'
    keypath = [0x80000000 | random.uniform(0xf0000000) for _ in range(0, 8)]
    nodepath = [_U2F_KEY_PATH] + keypath

    # prepare signing key from random path, compute decompressed public key
    node = seed.get_root_without_passphrase('nist256p1')
    node.derive_path(nodepath)
    pubkey = nist256p1.publickey(node.private_key(), False)

    # first half of keyhandle is keypath
    keybuf = ustruct.pack('>8L', *keypath)

    # second half of keyhandle is a hmac of app_id and keypath
    keybase = hmac.Hmac(node.private_key(), app_id, hashlib.sha256)
    keybase.update(keybuf)
    keybase = keybase.digest()

    # hash the request data together with keyhandle and pubkey
    dig = hashlib.sha256()
    dig.update(b'\x00')  # uint8_t reserved;
    dig.update(app_id)  # uint8_t appId[32];
    dig.update(challenge)  # uint8_t chal[32];
    dig.update(keybuf)  # uint8_t keyHandle[64];
    dig.update(keybase)
    dig.update(pubkey)  # uint8_t pubKey[65];
    dig = dig.digest()

    # sign the digest and convert to der
    sig = nist256p1.sign(_U2F_ATT_PRIV_KEY, dig, False)
    sig = der.encode_seq((sig[1:33], sig[33:]))

    # pack to a response
    buf, resp = make_struct(
        resp_cmd_register(
            len(keybuf) + len(keybase), len(_U2F_ATT_CERT), len(sig)))
    resp.registerId = _U2F_REGISTER_ID
    utils.memcpy(resp.pubKey, 0, pubkey, 0, len(pubkey))
    resp.keyHandleLen = len(keybuf) + len(keybase)
    utils.memcpy(resp.keyHandle, 0, keybuf, 0, len(keybuf))
    utils.memcpy(resp.keyHandle, len(keybuf), keybase, 0, len(keybase))
    utils.memcpy(resp.cert, 0, _U2F_ATT_CERT, 0, len(_U2F_ATT_CERT))
    utils.memcpy(resp.sig, 0, sig, 0, len(sig))
    resp.status = _SW_NO_ERROR

    return buf
    def generate_key_handle(self) -> None:
        # derivation path is m/U2F'/r'/r'/r'/r'/r'/r'/r'/r'
        path = [HARDENED | random.uniform(0x80000000) for _ in range(0, 8)]
        nodepath = [_U2F_KEY_PATH] + path

        # prepare signing key from random path, compute decompressed public key
        self.node = seed.derive_node_without_passphrase(nodepath, "nist256p1")

        # first half of keyhandle is keypath
        keypath = ustruct.pack("<8L", *path)

        # second half of keyhandle is a hmac of rp_id_hash and keypath
        mac = hmac.Hmac(self.node.private_key(), self.rp_id_hash, hashlib.sha256)
        mac.update(keypath)

        self.id = keypath + mac.digest()
def get_identifier(script_pubkey: bytes, keychain: Keychain) -> bytes:
    # k = Key(m/"SLIP-0019"/"Ownership identification key")
    node = keychain.derive_slip21(_OWNERSHIP_ID_KEY_PATH)

    # id = HMAC-SHA256(key = k, msg = scriptPubKey)
    return hmac.Hmac(node.key(), script_pubkey, hashlib.sha256).digest()