Example #1
0
    def test_long_pin(self):
        ctap = mock.MagicMock()
        ctap.info.options = {"clientPin": True}
        prot = ClientPin(ctap, PinProtocolV1())

        with self.assertRaises(ValueError):
            prot.set_pin("1" * 256)
Example #2
0
def _ctap2_enroll(dev, alg, application, user, pin, resident):
    """Enroll a new security key using CTAP version 2"""

    ctap2 = CTAP2(dev)

    application = application.decode('utf-8')
    rp = {'id': application, 'name': application}
    user = {'id': user.encode('utf-8'), 'name': user}
    key_params = [{'type': 'public-key', 'alg': alg}]
    options = {'rk': resident}

    if pin:
        pin_protocol = PinProtocolV1(ctap2)
        pin_token = pin_protocol.get_pin_token(pin)

        pin_version = pin_protocol.VERSION
        pin_auth = hmac.new(pin_token, _dummy_hash, sha256).digest()[:16]
    else:
        pin_version = None
        pin_auth = None

    cred = ctap2.make_credential(_dummy_hash,
                                 rp,
                                 user,
                                 key_params,
                                 options=options,
                                 pin_auth=pin_auth,
                                 pin_protocol=pin_version)
    cdata = cred.auth_data.credential_data

    return _decode_public_key(alg, cdata.public_key), cdata.credential_id
Example #3
0
    def test_get_pin_token(self):
        prot = PinProtocolV1(mock.MagicMock())
        prot._init_shared_secret = mock.Mock(return_value=({}, SHARED))
        prot.ctap.client_pin.return_value = {2: TOKEN_ENC}

        self.assertEqual(prot.get_pin_token('1234'), TOKEN)
        prot.ctap.client_pin.assert_called_once()
        self.assertEqual(prot.ctap.client_pin.call_args[1]['pin_hash_enc'],
                         PIN_HASH_ENC)
Example #4
0
    def test_get_pin_token(self):
        ctap = mock.MagicMock()
        ctap.info.options = {"clientPin": True}
        prot = ClientPin(ctap, PinProtocolV1())

        prot._get_shared_secret = mock.Mock(return_value=({}, SHARED))
        prot.ctap.client_pin.return_value = {2: TOKEN_ENC}

        self.assertEqual(prot.get_pin_token("1234"), TOKEN)
        prot.ctap.client_pin.assert_called_once()
        self.assertEqual(prot.ctap.client_pin.call_args[1]["pin_hash_enc"],
                         PIN_HASH_ENC)
Example #5
0
    def test_set_pin(self):
        prot = PinProtocolV1(mock.MagicMock())
        prot._init_shared_secret = mock.Mock(return_value=({}, SHARED))

        prot.set_pin('1234')
        prot.ctap.client_pin.assert_called_with(
            1,
            3,
            key_agreement={},
            new_pin_enc=a2b_hex(
                '0222fc42c6dd76a274a7057858b9b29d98e8a722ec2dc6668476168c5320473cec9907b4cd76ce7943c96ba5683943211d84471e64d9c51e54763488cd66526a'
            ),  # noqa
            pin_auth=a2b_hex('7b40c084ccc5794194189ab57836475f'))
Example #6
0
    def test_change_pin(self):
        prot = PinProtocolV1(mock.MagicMock())
        prot._init_shared_secret = mock.Mock(return_value=({}, SHARED))

        prot.change_pin('1234', '4321')
        prot.ctap.client_pin.assert_called_with(
            1,
            4,
            key_agreement={},
            new_pin_enc=a2b_hex(
                '4280e14aac4fcbf02dd079985f0c0ffc9ea7d5f9c173fd1a4c843826f7590cb3c2d080c6923e2fe6d7a52c31ea1309d3fcca3dedae8a2ef14b6330cafc79339e'
            ),  # noqa
            pin_auth=a2b_hex('fb97e92f3724d7c85e001d7f93e6490a'),
            pin_hash_enc=a2b_hex('afe8327ce416da8ee3d057589c2ce1a9'))
Example #7
0
    def test_set_pin(self):
        prot = ClientPin(mock.MagicMock(), PinProtocolV1())
        prot._get_shared_secret = mock.Mock(return_value=({}, SHARED))

        prot.set_pin("1234")
        prot.ctap.client_pin.assert_called_with(
            1,
            3,
            key_agreement={},
            new_pin_enc=a2b_hex(
                "0222fc42c6dd76a274a7057858b9b29d98e8a722ec2dc6668476168c5320473cec9907b4cd76ce7943c96ba5683943211d84471e64d9c51e54763488cd66526a"  # noqa E501
            ),
            pin_uv_param=a2b_hex("7b40c084ccc5794194189ab57836475f"),
        )
Example #8
0
    def test_change_pin(self):
        prot = ClientPin(mock.MagicMock(), PinProtocolV1())
        prot._get_shared_secret = mock.Mock(return_value=({}, SHARED))

        prot.change_pin("1234", "4321")
        prot.ctap.client_pin.assert_called_with(
            1,
            4,
            key_agreement={},
            new_pin_enc=a2b_hex(
                "4280e14aac4fcbf02dd079985f0c0ffc9ea7d5f9c173fd1a4c843826f7590cb3c2d080c6923e2fe6d7a52c31ea1309d3fcca3dedae8a2ef14b6330cafc79339e"  # noqa E501
            ),
            pin_uv_param=a2b_hex("fb97e92f3724d7c85e001d7f93e6490a"),
            pin_hash_enc=a2b_hex("afe8327ce416da8ee3d057589c2ce1a9"),
        )
Example #9
0
    def test_establish_shared_secret(self, patched_generate):
        prot = ClientPin(mock.MagicMock(), PinProtocolV1())

        patched_generate.return_value = ec.derive_private_key(
            EC_PRIV, ec.SECP256R1(), default_backend()
        )

        prot.ctap.client_pin.return_value = {
            1: {1: 2, 3: -25, -1: 1, -2: DEV_PUB_X, -3: DEV_PUB_Y}
        }

        key_agreement, shared = prot._get_shared_secret()

        self.assertEqual(shared, SHARED)
        self.assertEqual(key_agreement[-2], EC_PUB_X)
        self.assertEqual(key_agreement[-3], EC_PUB_Y)
    def __init__(self, device, origin, verify=verify_rp_id):
        super(Fido2Client, self).__init__(origin, verify)

        self.ctap1_poll_delay = 0.25
        try:
            self.ctap2 = CTAP2(device)
            self.info = self.ctap2.get_info()
            if PinProtocolV1.VERSION in self.info.pin_protocols:
                self.pin_protocol = PinProtocolV1(self.ctap2)
            else:
                self.pin_protocol = None
            self._do_make_credential = self._ctap2_make_credential
            self._do_get_assertion = self._ctap2_get_assertion
        except (ValueError, CtapError):
            self.ctap1 = CTAP1(device)
            self.info = _CTAP1_INFO
            self._do_make_credential = self._ctap1_make_credential
            self._do_get_assertion = self._ctap1_get_assertion
Example #11
0
def sk_get_resident(application, user, pin):
    """Get keys resident on a security key"""

    app_hash = sha256(application).digest()
    result = []

    for dev in CtapHidDevice.list_devices():
        try:
            ctap2 = CTAP2(dev)

            pin_protocol = PinProtocolV1(ctap2)
            pin_token = pin_protocol.get_pin_token(pin)

            cred_mgmt = CredentialManagement(ctap2, pin_protocol.VERSION,
                                             pin_token)

            for cred in cred_mgmt.enumerate_creds(app_hash):
                name = cred[CredentialManagement.RESULT.USER]['name']

                if user and name != user:
                    continue

                cred_id = cred[CredentialManagement.RESULT.CREDENTIAL_ID]
                key_handle = cred_id['id']

                public_key = cred[CredentialManagement.RESULT.PUBLIC_KEY]
                alg = public_key[3]
                public_value = _decode_public_key(alg, public_key)

                result.append((alg, name, public_value, key_handle))
        except CtapError as exc:
            if exc.code == CtapError.ERR.NO_CREDENTIALS:
                continue
            elif exc.code == CtapError.ERR.PIN_INVALID:
                raise ValueError('Invalid PIN') from None
            elif exc.code == CtapError.ERR.PIN_NOT_SET:
                raise ValueError('PIN not set') from None
            else:
                raise ValueError(str(exc)) from None
        finally:
            dev.close()

    return result
Example #12
0
 def test_long_pin(self):
     prot = PinProtocolV1(mock.MagicMock())
     with self.assertRaises(ValueError):
         prot.set_pin('1' * 256)
Example #13
0
 def test_short_pin(self):
     prot = PinProtocolV1(mock.MagicMock())
     with self.assertRaises(ValueError):
         prot.set_pin("123")
Example #14
0
 def __init__(self, driver):
     self.ctap = CTAP2(driver._dev)
     self.pin = PinProtocolV1(self.ctap)
     self._info = self.ctap.get_info()
     self._pin = self._info.options['clientPin']
Example #15
0
 def test_long_pin(self):
     prot = ClientPin(mock.MagicMock(), PinProtocolV1())
     with self.assertRaises(ValueError):
         prot.set_pin("1" * 256)
 def __init__(self, ctap):
     self._pin_protocol = PinProtocolV1(ctap)