Esempio n. 1
0
    def test_sign_await_touch(self):
        client = U2fClient(None, APP_ID)
        client.ctap = mock.MagicMock()
        client.ctap.get_version.return_value = 'U2F_V2'
        client.ctap.authenticate.side_effect = [
            ApduError(APDU.USE_NOT_SATISFIED),
            ApduError(APDU.USE_NOT_SATISFIED),
            ApduError(APDU.USE_NOT_SATISFIED),
            ApduError(APDU.USE_NOT_SATISFIED), SIG_DATA
        ]

        event = Event()
        event.wait = mock.MagicMock()

        resp = client.sign(APP_ID,
                           'challenge', [{
                               'version': 'U2F_V2',
                               'keyHandle': 'a2V5'
                           }],
                           timeout=event)

        event.wait.assert_called()

        client.ctap.get_version.assert_called_with()
        client.ctap.authenticate.assert_called()
        client_param, app_param, key_handle = \
            client.ctap.authenticate.call_args[0]

        self.assertEqual(client_param,
                         sha256(websafe_decode(resp['clientData'])))
        self.assertEqual(app_param, sha256(APP_ID.encode()))
        self.assertEqual(key_handle, b'key')
        self.assertEqual(websafe_decode(resp['signatureData']), SIG_DATA)
Esempio n. 2
0
    def test_sign(self):
        client = U2fClient(None, APP_ID)
        client.ctap = mock.MagicMock()
        client.ctap.get_version.return_value = 'U2F_V2'
        client.ctap.authenticate.return_value = SIG_DATA

        resp = client.sign(
            APP_ID,
            'challenge',
            [{
                'version': 'U2F_V2',
                'keyHandle': 'a2V5'
            }],
        )

        client.ctap.get_version.assert_called_with()
        client.ctap.authenticate.assert_called_once()
        client_param, app_param, key_handle = \
            client.ctap.authenticate.call_args[0]

        self.assertEqual(client_param,
                         sha256(websafe_decode(resp['clientData'])))
        self.assertEqual(app_param, sha256(APP_ID.encode()))
        self.assertEqual(key_handle, b'key')
        self.assertEqual(websafe_decode(resp['signatureData']), SIG_DATA)
Esempio n. 3
0
    def test_sign_await_touch(self):
        client = U2fClient(None, APP_ID)
        client.ctap = mock.MagicMock()
        client.ctap.get_version.return_value = "U2F_V2"
        client.ctap.authenticate.side_effect = [
            ApduError(APDU.USE_NOT_SATISFIED),
            ApduError(APDU.USE_NOT_SATISFIED),
            ApduError(APDU.USE_NOT_SATISFIED),
            ApduError(APDU.USE_NOT_SATISFIED),
            SIG_DATA,
        ]

        event = Event()
        event.wait = mock.MagicMock()

        resp = client.sign(
            APP_ID,
            "challenge",
            [{"version": "U2F_V2", "keyHandle": "a2V5"}],
            event=event,
        )

        event.wait.assert_called()

        client.ctap.get_version.assert_called_with()
        client.ctap.authenticate.assert_called()
        client_param, app_param, key_handle = client.ctap.authenticate.call_args[0]

        self.assertEqual(client_param, sha256(websafe_decode(resp["clientData"])))
        self.assertEqual(app_param, sha256(APP_ID.encode()))
        self.assertEqual(key_handle, b"key")
        self.assertEqual(websafe_decode(resp["signatureData"]), SIG_DATA)
Esempio n. 4
0
    def test_register(self):
        client = U2fClient(None, APP_ID)
        client.ctap = mock.MagicMock()
        client.ctap.get_version.return_value = "U2F_V2"
        client.ctap.authenticate.side_effect = ApduError(APDU.WRONG_DATA)
        client.ctap.register.return_value = REG_DATA

        resp = client.register(
            APP_ID,
            [{
                "version": "U2F_V2",
                "challenge": "foobar"
            }],
            [{
                "version": "U2F_V2",
                "keyHandle": "a2V5"
            }],
        )

        client.ctap.get_version.assert_called_with()
        client.ctap.authenticate.assert_called_once()
        client.ctap.register.assert_called_once()

        client_param, app_param = client.ctap.register.call_args[0]
        self.assertEqual(sha256(websafe_decode(resp["clientData"])),
                         client_param)
        self.assertEqual(websafe_decode(resp["registrationData"]), REG_DATA)
        self.assertEqual(sha256(APP_ID.encode()), app_param)
Esempio n. 5
0
    def test_register_await_touch(self):
        client = U2fClient(None, APP_ID)
        client.ctap = mock.MagicMock()
        client.ctap.get_version.return_value = 'U2F_V2'
        client.ctap.authenticate.side_effect = ApduError(APDU.WRONG_DATA)
        client.ctap.register.side_effect = [
            ApduError(APDU.USE_NOT_SATISFIED),
            ApduError(APDU.USE_NOT_SATISFIED),
            ApduError(APDU.USE_NOT_SATISFIED),
            ApduError(APDU.USE_NOT_SATISFIED), REG_DATA
        ]

        event = Event()
        event.wait = mock.MagicMock()
        resp = client.register(APP_ID, [{
            'version': 'U2F_V2',
            'challenge': 'foobar'
        }], [{
            'version': 'U2F_V2',
            'keyHandle': 'a2V5'
        }],
                               timeout=event)

        event.wait.assert_called()

        client.ctap.get_version.assert_called_with()
        client.ctap.authenticate.assert_called_once()
        client.ctap.register.assert_called()

        client_param, app_param = client.ctap.register.call_args[0]
        self.assertEqual(sha256(websafe_decode(resp['clientData'])),
                         client_param)
        self.assertEqual(websafe_decode(resp['registrationData']), REG_DATA)
        self.assertEqual(sha256(APP_ID.encode()), app_param)
Esempio n. 6
0
 def test_u2f(self, ):
     chal = sha256(b"AAA")
     appid = sha256(b"BBB")
     for i in range(0, 5):
         reg = self.ctap1.register(chal, appid)
         reg.verify(appid, chal)
         auth = self.ctap1.authenticate(chal, appid, reg.key_handle)
         # check endianness
         assert auth.counter < 0x10000
         print("U2F reg + auth pass %d/5" % (i + 1))
Esempio n. 7
0
 def test_sha256_vectors(self):
     self.assertEqual(
         sha256(b'abc'),
         a2b_hex(
             b'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad'
         ))  # noqa
     self.assertEqual(
         sha256(
             b'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'),
         a2b_hex(
             b'248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1'
         ))  # noqa
Esempio n. 8
0
 def test_u2f(self, ):
     chal = sha256(b"AAA")
     appid = sha256(b"BBB")
     lastc = 0
     for i in range(0, 5):
         reg = self.ctap1.register(chal, appid)
         reg.verify(appid, chal)
         auth = self.ctap1.authenticate(chal, appid, reg.key_handle)
         # check endianness
         if lastc:
             assert (auth.counter - lastc) < 10
         lastc = auth.counter
         print(hex(lastc))
         print("U2F reg + auth pass %d/5" % (i + 1))
Esempio n. 9
0
 def test_sha256_vectors(self):
     self.assertEqual(
         sha256(b"abc"),
         bytes.fromhex(
             "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
         ),
     )
     self.assertEqual(
         sha256(
             b"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"),
         bytes.fromhex(
             "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"
         ),
     )
Esempio n. 10
0
 def list(self):
     token = self.client.pin_protocol.get_pin_token(self.pin)
     pin_protocol = 1
     cm = CredentialManagement(self.ctap2, pin_protocol, token)
     meta = cm.get_metadata()
     existing = meta[CredentialManagement.RESULT.EXISTING_CRED_COUNT]
     if existing == 0:
         print("No PGP keys found")
         return
     creds = cm.enumerate_creds(sha256(RP_ID.encode('ascii')))
     for cred in creds:
         user_id = cred[CredentialManagement.RESULT.USER]['id']
         created = int.from_bytes(user_id, 'big', signed=False)
         username = cred[CredentialManagement.RESULT.USER]['name']
         pubkey_x = cred[CredentialManagement.RESULT.PUBLIC_KEY][-2]
         pubkey_y = cred[CredentialManagement.RESULT.PUBLIC_KEY][-3]
         pubkey = (pubkey_x, pubkey_y)
         pubkey_pkt = self._pubkey_packet(pubkey, created)
         fp = self._fingerprint(pubkey_pkt)
         key_id = fp[-8:]
         created_date = datetime.utcfromtimestamp(created).strftime(
             '%Y-%m-%d %H:%M:%S')
         print("Created: {}".format(created_date))
         print("User: {}".format(username))
         print("ID: {}".format(key_id.hex().upper()))
         print("Fingerprint: {}".format(fp.hex().upper()))
         print()
    def _ctap1_get_assertion(self, client_data, rp_id, allow_list, extensions,
                             uv, pin, event, on_keepalive):
        if uv or not allow_list:
            raise CtapError(CtapError.ERR.UNSUPPORTED_OPTION)

        app_param = sha256(rp_id.encode())
        client_param = client_data.hash
        for cred in allow_list:
            try:
                auth_resp = _call_polling(
                    self.ctap1_poll_delay,
                    event,
                    on_keepalive,
                    self.ctap1.authenticate,
                    client_param,
                    app_param,
                    cred["id"],
                )
                return [
                    AssertionResponse.from_ctap1(app_param, cred, auth_resp)
                ]
            except ClientError as e:
                if e.code == ClientError.ERR.TIMEOUT:
                    raise  # Other errors are ignored so we move to the next.
        raise ClientError.ERR.DEVICE_INELIGIBLE()
Esempio n. 12
0
def get_firmware_object():
    sk = SigningKey.from_pem(open("signing_key.pem").read())
    h = open(HEX_FILE, 'r').read()
    h = base64.b64encode(h.encode())
    h = to_websafe(h.decode())

    num_pages = 64
    START = 0x4000
    END = 2048 * (num_pages - 3) - 4

    ih = IntelHex(HEX_FILE)
    segs = ih.segments()
    arr = ih.tobinarray(start=START, size=END - START)

    im_size = END - START

    print('im_size: ', im_size)
    print('firmware_size: ', len(arr))

    byts = (arr).tobytes() if hasattr(arr, 'tobytes') else (arr).tostring()
    sig = sha256(byts)
    print('hash', binascii.hexlify(sig))
    sig = sk.sign_digest(sig)

    print('sig', binascii.hexlify(sig))

    sig = base64.b64encode(sig)
    sig = to_websafe(sig.decode())

    #msg = {'data': read()}
    msg = {'firmware': h, 'signature': sig}
    return msg
Esempio n. 13
0
    def test_make_credential_ctap1(self):
        dev = mock.Mock()
        dev.capabilities = 0  # No CTAP2
        client = Fido2Client(dev, APP_ID)

        client.ctap = mock.MagicMock()
        client.ctap.get_version.return_value = 'U2F_V2'
        client.ctap.register.return_value = REG_DATA

        attestation, client_data = client.make_credential(rp,
                                                          user,
                                                          challenge,
                                                          timeout=1)

        self.assertIsInstance(attestation, AttestationObject)
        self.assertIsInstance(client_data, ClientData)

        client.ctap.register.assert_called_with(
            client_data.hash,
            sha256(rp['id'].encode()),
        )

        self.assertEqual(client_data.get('origin'), APP_ID)
        self.assertEqual(client_data.get('type'), 'webauthn.create')
        self.assertEqual(client_data.get('challenge'), challenge)

        self.assertEqual(attestation.fmt, 'fido-u2f')
Esempio n. 14
0
    def test_make_credential_ctap1(self):
        dev = mock.Mock()
        dev.capabilities = 0  # No CTAP2
        client = Fido2Client(dev, APP_ID)

        client.ctap1 = mock.MagicMock()
        client.ctap1.get_version.return_value = "U2F_V2"
        client.ctap1.register.return_value = REG_DATA

        attestation, client_data = client.make_credential(rp,
                                                          user,
                                                          challenge,
                                                          timeout=1)

        self.assertIsInstance(attestation, AttestationObject)
        self.assertIsInstance(client_data, ClientData)

        client.ctap1.register.assert_called_with(client_data.hash,
                                                 sha256(rp["id"].encode()))

        self.assertEqual(client_data.get("origin"), APP_ID)
        self.assertEqual(client_data.get("type"), "webauthn.create")
        self.assertEqual(client_data.get("challenge"), challenge)

        self.assertEqual(attestation.fmt, "fido-u2f")
Esempio n. 15
0
    def test_make_credential_ctap1(self):
        dev = mock.Mock()
        dev.capabilities = 0  # No CTAP2
        client = Fido2Client(dev, APP_ID)

        client.ctap1 = mock.MagicMock()
        client.ctap1.get_version.return_value = "U2F_V2"
        client.ctap1.register.return_value = REG_DATA

        response = client.make_credential(
            PublicKeyCredentialCreationOptions(rp, user, challenge, [{
                "type": "public-key",
                "alg": -7
            }]))

        self.assertIsInstance(response.attestation_object, AttestationObject)
        self.assertIsInstance(response.client_data, ClientData)
        client_data = response.client_data

        client.ctap1.register.assert_called_with(client_data.hash,
                                                 sha256(rp["id"].encode()))

        self.assertEqual(client_data.get("origin"), APP_ID)
        self.assertEqual(client_data.get("type"), "webauthn.create")
        self.assertEqual(client_data.challenge, challenge)

        self.assertEqual(response.attestation_object.fmt, "fido-u2f")
Esempio n. 16
0
    def __init__(self, request=None, **kwargs):

        if not isinstance(request, FidoRequest) and request is not None:
            request = request.request

        self.request = request

        for i in (
            "cdh",
            "key_params",
            "allow_list",
            "challenge",
            "rp",
            "user",
            "pin_protocol",
            "options",
            "appid",
            "exclude_list",
            "extensions",
            "pin_auth",
            "timeout",
            "on_keepalive",
        ):
            self.save_attr(i, kwargs.get(i, Empty), request)

        if isinstance(self.rp, dict) and "id" in self.rp:
            if hasattr(self.rp["id"], "encode"):
                self.appid = sha256(self.rp["id"].encode("utf8"))
Esempio n. 17
0
 def sign(self, key_id, data):
     key_id = bytes.fromhex(key_id)
     token = self.client.pin_protocol.get_pin_token(self.pin)
     pin_protocol = 1
     cm = CredentialManagement(self.ctap2, pin_protocol, token)
     creds = cm.enumerate_creds(sha256(RP_ID.encode('ascii')))
     for cred in creds:
         user_id = cred[CredentialManagement.RESULT.USER]['id']
         created = int.from_bytes(user_id, 'big', signed=False)
         username = cred[CredentialManagement.RESULT.USER]['name']
         cred_id = cred[CredentialManagement.RESULT.CREDENTIAL_ID]['id']
         pubkey_x = cred[CredentialManagement.RESULT.PUBLIC_KEY][-2]
         pubkey_y = cred[CredentialManagement.RESULT.PUBLIC_KEY][-3]
         pubkey = (pubkey_x, pubkey_y)
         pubkey_pkt = self._pubkey_packet(pubkey, created)
         fp = self._fingerprint(pubkey_pkt)
         curr_key_id = fp[-8:]
         if curr_key_id == key_id:
             break
     else:
         print("Key {} not found".format(key_id))
         return None
     created = int(time.time())
     hashed_subpkts = [
         SubPacket(0x21, b'\x04' + fp),
         SubPacket(0x02, struct.pack('>I', created))
     ]
     unhashed_subpkts = [SubPacket(0x10, key_id)]  # issuer
     sig_pkt = self._signature_packet_data(cred_id, data, hashed_subpkts,
                                           unhashed_subpkts)
     armored = self._ascii_armor(sig_pkt)
     print('\n[GNUPG:] SIG_CREATED ', file=sys.stderr)
     print('-----BEGIN PGP SIGNATURE-----\n\n{}-----END PGP SIGNATURE-----'.
           format(armored))
Esempio n. 18
0
    def test_sign(self):
        client = U2fClient(None, APP_ID)
        client.ctap = mock.MagicMock()
        client.ctap.get_version.return_value = "U2F_V2"
        client.ctap.authenticate.return_value = SIG_DATA

        resp = client.sign(
            APP_ID, "challenge", [{"version": "U2F_V2", "keyHandle": "a2V5"}]
        )

        client.ctap.get_version.assert_called_with()
        client.ctap.authenticate.assert_called_once()
        client_param, app_param, key_handle = client.ctap.authenticate.call_args[0]

        self.assertEqual(client_param, sha256(websafe_decode(resp["clientData"])))
        self.assertEqual(app_param, sha256(APP_ID.encode()))
        self.assertEqual(key_handle, b"key")
        self.assertEqual(websafe_decode(resp["signatureData"]), SIG_DATA)
Esempio n. 19
0
    def sign(self, client_data):
        authenticator_data = AuthenticatorData.create(
            sha256(self.app_id),
            flags=AuthenticatorData.FLAG.USER_PRESENT,
            counter=0)

        signature = self.priv_key.sign(authenticator_data + client_data.hash,
                                       ec.ECDSA(hashes.SHA256()))

        return authenticator_data, signature
Esempio n. 20
0
 def __init__(self, ui, appId, nonce, credentialId):
     """
     :param appId: Base URL string for Okta IDP e.g. https://xxxx.okta.com'
     :param nonce: nonce
     :param credentialid: credentialid
     """
     self.ui = ui
     self._clients = None
     self._has_prompted = False
     self._cancel = Event()
     self._credentialId = base64.urlsafe_b64decode(credentialId)
     self._appId = sha256(appId.encode())
     self._version = 'U2F_V2'
     self._signature = None
     self._clientData = json.dumps({
         "challenge": nonce,
         "origin": appId,
         "typ": "navigator.id.getAssertion"
     }).encode()
     self._nonce = sha256(self._clientData)
Esempio n. 21
0
    def get(self, options, origin):
        """get authentication credential aka assertion"""

        if self.rp_id != options['publicKey']['rpId']:
            raise ValueError(
                'Requested rpID does not match current credential')

        self.sign_count += 1

        # prepare signature
        client_data = json.dumps({
            'type':
            'webauthn.get',
            'challenge':
            urlsafe_b64encode(
                options['publicKey']['challenge']).decode('ascii'),
            'origin':
            origin
        }).encode('utf-8')
        client_data_hash = sha256(client_data)

        rp_id_hash = sha256(self.rp_id.encode('ascii'))
        flags = b'\x01'
        sign_count = pack('>I', self.sign_count)
        authenticator_data = rp_id_hash + flags + sign_count

        signature = self.private_key.sign(
            authenticator_data + client_data_hash, ec.ECDSA(hashes.SHA256()))

        # generate assertion
        return {
            'id': urlsafe_b64encode(self.credential_id),
            'rawId': self.credential_id,
            'response': {
                'authenticatorData': authenticator_data,
                'clientDataJSON': client_data,
                'signature': signature,
                'userHandle': self.user_handle
            },
            'type': 'public-key'
        }
Esempio n. 22
0
    def test_backup_credential_is_generated_correctly(
        self,
        solo,
        device,
    ):
        import seedweed
        from binascii import hexlify

        key_A = b"A" * 32
        ext_state = b"I'm a dicekey key!"
        version = b"\x01"

        ext_key_cmd = 0x62
        print("Enter user presence THREE times.")
        solo.send_data_hid(ext_key_cmd, version + key_A + ext_state)

        # New credential works.
        mc_A_req = FidoRequest()
        mc_A_res = device.sendMC(*mc_A_req.toMC())

        rpIdHash = sha256(mc_A_req.rp["id"].encode("utf8"))

        credId = mc_A_res.auth_data.credential_data.credential_id

        (
            uniqueId,
            extStateInCredId,
            credMacInCredId,
        ) = seedweed.nonce_extstate_mac_from_credential_id(credId)

        seedweed.validate_credential_id(key_A, credId, rpIdHash)
        credMac = hmac_sha256(key_A, rpIdHash + version + uniqueId + ext_state)

        allow_list = [{
            "id": mc_A_res.auth_data.credential_data.credential_id,
            "type": "public-key",
        }]
        ga_req = FidoRequest(allow_list=allow_list)

        ga_res = device.sendGA(*ga_req.toGA())

        verify(mc_A_res, ga_res, ga_req.cdh)

        # Independently create the key and verify
        _, _, keypair, iterations = seedweed.keypair_from_seed_mac(
            key_A, credMac)
        assert iterations == 1
        keypair.verifying_key.verify(
            ga_res.signature,
            ga_res.auth_data + ga_req.cdh,
            sigdecode=ecdsa.util.sigdecode_der,
            hashfunc=hashlib.sha256,
        )
Esempio n. 23
0
    def create(self, options, origin):
        """create credential and return PublicKeyCredential object aka attestation"""

        if {
                'alg': -7,
                'type': 'public-key'
        } not in options['publicKey']['pubKeyCredParams']:
            raise ValueError(
                'Requested pubKeyCredParams does not contain supported type')

        if ('attestation' in options['publicKey']) and (
                options['publicKey']['attestation'] != 'none'):
            raise ValueError('Only none attestation supported')

        # prepare new key
        self.cred_init(options['publicKey']['rp']['id'],
                       options['publicKey']['user']['id'])

        # generate credential response
        client_data = {
            'type':
            'webauthn.create',
            'challenge':
            urlsafe_b64encode(
                options['publicKey']['challenge']).decode('ascii'),
            'origin':
            origin
        }

        rp_id_hash = sha256(self.rp_id.encode('ascii'))
        flags = b'\x41'  # attested_data + user_present
        sign_count = pack('>I', self.sign_count)
        credential_id_length = pack('>H', len(self.credential_id))
        cose_key = cbor.encode(
            ES256.from_cryptography_key(self.private_key.public_key()))
        attestation_object = {
            'authData':
            rp_id_hash + flags + sign_count + self.aaguid +
            credential_id_length + self.credential_id + cose_key,
            'fmt':
            'none',
            'attStmt': {}
        }

        return {
            'id': urlsafe_b64encode(self.credential_id),
            'rawId': self.credential_id,
            'response': {
                'clientDataJSON': json.dumps(client_data).encode('utf-8'),
                'attestationObject': cbor.encode(attestation_object)
            },
            'type': 'public-key'
        }
Esempio n. 24
0
def u2f_complete():
    data = cbor.decode(request.get_data())
    reg_data = RegistrationData.from_b64(data["registrationData"])
    print("clientData", websafe_decode(data["clientData"]))
    print("U2F RegistrationData:", reg_data)
    att_obj = AttestationObject.from_ctap1(sha256(b"https://localhost:5000"),
                                           reg_data)
    print("AttestationObject:", att_obj)

    auth_data = att_obj.auth_data

    credentials.append(auth_data.credential_data)
    print("REGISTERED U2F CREDENTIAL:", auth_data.credential_data)
    return cbor.encode({"status": "OK"})
Esempio n. 25
0
def test_get():
    """test get"""

    device = SoftWebauthnDevice()
    device.cred_init(PKCRO['publicKey']['rpId'], b'randomhandle')

    assertion = device.get(PKCRO, 'https://example.org')

    assert assertion
    device.private_key.public_key().verify(
        assertion['response']['signature'],
        assertion['response']['authenticatorData'] +
        sha256(assertion['response']['clientDataJSON']),
        ec.ECDSA(hashes.SHA256()))
def get_auth_webauthn(user: "******") -> Authenticator:
    return Authenticator.objects.create(
        type=3,  # u2f
        user=user,
        config={
            "devices": [
                {
                    "binding": {
                        "publicKey":
                        "aowekroawker",
                        "keyHandle":
                        "devicekeyhandle",
                        "appId":
                        "https://dev.getsentry.net:8000/auth/2fa/u2fappid.json",
                    },
                    "name": "Amused Beetle",
                    "ts": 1512505334,
                },
                {
                    "binding": {
                        "publicKey":
                        "publickey",
                        "keyHandle":
                        "aowerkoweraowerkkro",
                        "appId":
                        "https://dev.getsentry.net:8000/auth/2fa/u2fappid.json",
                    },
                    "name": "Sentry",
                    "ts": 1512505334,
                },
                {
                    "name":
                    "Alert Escargot",
                    "ts":
                    1512505334,
                    "binding":
                    AuthenticatorData.create(
                        sha256(b"test"),
                        0x41,
                        1,
                        create_credential_object({
                            "publicKey": "webauthn",
                            "keyHandle": "webauthn",
                        }),
                    ),
                },
            ]
        },
    )
    def _ctap1_make_credential(
        self,
        client_data,
        rp,
        user,
        key_params,
        exclude_list,
        extensions,
        rk,
        uv,
        pin,
        event,
        on_keepalive,
    ):
        if rk or uv or ES256.ALGORITHM not in [p.alg for p in key_params]:
            raise CtapError(CtapError.ERR.UNSUPPORTED_OPTION)

        app_param = sha256(rp["id"].encode())

        dummy_param = b"\0" * 32
        for cred in exclude_list or []:
            key_handle = cred["id"]
            try:
                self.ctap1.authenticate(dummy_param, app_param, key_handle,
                                        True)
                raise ClientError.ERR.OTHER_ERROR()  # Shouldn't happen
            except ApduError as e:
                if e.code == APDU.USE_NOT_SATISFIED:
                    _call_polling(
                        self.ctap1_poll_delay,
                        event,
                        on_keepalive,
                        self.ctap1.register,
                        dummy_param,
                        dummy_param,
                    )
                    raise ClientError.ERR.DEVICE_INELIGIBLE()

        return AttestationObject.from_ctap1(
            app_param,
            _call_polling(
                self.ctap1_poll_delay,
                event,
                on_keepalive,
                self.ctap1.register,
                client_data.hash,
                app_param,
            ),
        )
Esempio n. 28
0
def u2f_complete():
    data = cbor.loads(request.get_data())[0]
    client_data = ClientData.from_b64(data['clientData'])
    reg_data = RegistrationData.from_b64(data['registrationData'])
    print('clientData', client_data)
    print('U2F RegistrationData:', reg_data)
    att_obj = AttestationObject.from_ctap1(sha256(b'https://localhost:5000'),
                                           reg_data)
    print('AttestationObject:', att_obj)

    auth_data = att_obj.auth_data

    credentials.append(auth_data.credential_data)
    print('REGISTERED U2F CREDENTIAL:', auth_data.credential_data)
    return cbor.dumps({'status': 'OK'})
Esempio n. 29
0
    def test_solo(self, ):
        """
        Solo specific tests
        """
        # RNG command
        sc = SoloClient()
        sc.find_device(self.dev)
        sc.use_u2f()
        memmap = (0x08005000, 0x08005000 + 198 * 1024 - 8)

        total = 1024 * 16
        with Test("Gathering %d random bytes..." % total):
            entropy = b""
            while len(entropy) < total:
                entropy += sc.get_rng()

        with Test("Test entropy is close to perfect"):
            s = shannon_entropy(entropy)
            assert s > 7.98
        print("Entropy is %.5f bits per byte." % s)

        with Test("Test Solo version command"):
            assert len(sc.solo_version()) == 3

        with Test("Test bootloader is not active"):
            try:
                sc.write_flash(memmap[0], b"1234")
            except ApduError:
                pass

        sc.exchange = sc.exchange_fido2

        req = SoloClient.format_request(SoloExtension.version, 0, b"A" * 16)
        a = sc.ctap2.get_assertion(sc.host, b"B" * 32, [{
            "id": req,
            "type": "public-key"
        }])

        with Test("Test custom command returned valid assertion"):
            assert a.auth_data.rp_id_hash == sha256(sc.host.encode("utf8"))
            assert a.credential["id"] == req
            assert (a.auth_data.flags & 0x5) == 0x5

        with Test("Test Solo version and random commands with fido2 layer"):
            assert len(sc.solo_version()) == 3
            sc.get_rng()
Esempio n. 30
0
    def test_fido2_bridge(self, solo):
        exchange = solo.exchange
        solo.exchange = solo.exchange_fido2

        req = SoloClient.format_request(SoloExtension.version, 0, b"A" * 16)
        a = solo.ctap2.get_assertion(solo.host, b"B" * 32,
                                     [{
                                         "id": req,
                                         "type": "public-key"
                                     }])

        assert a.auth_data.rp_id_hash == sha256(solo.host.encode("utf8"))
        assert a.credential["id"] == req
        assert (a.auth_data.flags & 0x5) == 0x5

        solo.get_rng()

        solo.exchange = exchange