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)
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
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)
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)
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'))
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'))
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"), )
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"), )
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
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
def test_long_pin(self): prot = PinProtocolV1(mock.MagicMock()) with self.assertRaises(ValueError): prot.set_pin('1' * 256)
def test_short_pin(self): prot = PinProtocolV1(mock.MagicMock()) with self.assertRaises(ValueError): prot.set_pin("123")
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']
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)