} // anonymous namespace
-TEST(BtAdvertScanner, successful_await_advert_android_or_new_iphone_Positive)
+TEST(BtAdvertScanner, successful_await_advert_Positive)
{
+ // Android or new iPhone
SuccessfulAwaitAdvertTest("FFF9");
-}
-TEST(BtAdvertScanner, successful_await_advert_old_iphone_Positive)
-{
+ // Old iPhone
SuccessfulAwaitAdvertTest("FDE2");
}
EXPECT_EQ(bt->m_initialized, false);
}
-TEST(BtAdvertScanner, await_advert_because_of_errors_of_bluetooth_api_Negative)
+TEST(BtAdvertScanner, await_advert_because_of_initalize_error_Negative)
{
// Initialize error
- {
- auto eidKey = RandomEidKey();
- auto btUptr = std::make_unique<BluetoothMock>(true, BleAdverts{});
- auto bt = btUptr.get();
- bt->m_initializeRes = BT_ERROR_NOT_SUPPORTED;
- auto bas = BtAdvertScanner{std::move(btUptr)};
- CryptoBuffer decryptedAdvert;
- EXPECT_THAT([&] { bas.AwaitAdvert(eidKey, decryptedAdvert); },
- testing::ThrowsMessage<Exception::Unknown>(testing::HasSubstr(
- "Bluetooth initialization error: BT_ERROR_NOT_SUPPORTED")));
- EXPECT_EQ(decryptedAdvert, CryptoBuffer{});
- EXPECT_EQ(bt->m_initialized, false);
- }
- // StartLEAdvertScanAndAwaitStop error
- {
- auto eidKey = RandomEidKey();
- auto btUptr = std::make_unique<BluetoothMock>(true, BleAdverts{});
- auto bt = btUptr.get();
- bt->m_startLEAdvertScanRes = BT_ERROR_NOT_SUPPORTED;
- auto bas = BtAdvertScanner{std::move(btUptr)};
- CryptoBuffer decryptedAdvert;
- EXPECT_THAT([&] { bas.AwaitAdvert(eidKey, decryptedAdvert); },
- testing::ThrowsMessage<Exception::Unknown>(testing::HasSubstr(
- "Scanning for BLE advert error: BT_ERROR_NOT_SUPPORTED")));
- EXPECT_EQ(decryptedAdvert, CryptoBuffer{});
- EXPECT_EQ(bt->m_initialized, false);
- }
- // Deinitialize error
- {
- auto eidKey = RandomEidKey();
- auto advertPlaintext = RandomAdvertPlaintext();
- auto serviceData = GenerateServiceData(eidKey, advertPlaintext);
- auto btUptr =
- std::make_unique<BluetoothMock>(true,
- BleAdverts{
- {"FFF9", serviceData, IBluetooth::Scanning::STOP}
- });
- auto bt = btUptr.get();
- bt->m_deinitializeRes = BT_ERROR_NOT_SUPPORTED;
- auto bas = BtAdvertScanner{std::move(btUptr)};
- CryptoBuffer decryptedAdvert;
- EXPECT_THAT([&] { bas.AwaitAdvert(eidKey, decryptedAdvert); },
- testing::ThrowsMessage<Exception::Unknown>(testing::HasSubstr(
- "Bluetooth deinitialization error: BT_ERROR_NOT_SUPPORTED")));
- EXPECT_EQ(decryptedAdvert, advertPlaintext);
- EXPECT_EQ(bt->m_initialized, true);
- }
- // StartLEAdvertScanAndAwaitStop error and Deinitialize error
- {
- auto eidKey = RandomEidKey();
- auto btUptr = std::make_unique<BluetoothMock>(true, BleAdverts{});
- auto bt = btUptr.get();
- bt->m_startLEAdvertScanRes = BT_ERROR_NOT_SUPPORTED;
- bt->m_deinitializeRes = BT_ERROR_AUTHORIZATION_REJECTED;
- auto bas = BtAdvertScanner{std::move(btUptr)};
- CryptoBuffer decryptedAdvert;
- EXPECT_THAT([&] { bas.AwaitAdvert(eidKey, decryptedAdvert); },
- testing::ThrowsMessage<Exception::Unknown>(testing::HasSubstr(
- "Bluetooth deinitialization error: BT_ERROR_AUTHORIZATION_REJECTED")));
- EXPECT_EQ(decryptedAdvert, CryptoBuffer{});
- EXPECT_EQ(bt->m_initialized, true);
- }
+ auto eidKey = RandomEidKey();
+ auto btUptr = std::make_unique<BluetoothMock>(true, BleAdverts{});
+ auto bt = btUptr.get();
+ bt->m_initializeRes = BT_ERROR_NOT_SUPPORTED;
+ auto bas = BtAdvertScanner{std::move(btUptr)};
+ CryptoBuffer decryptedAdvert;
+ EXPECT_THAT([&] { bas.AwaitAdvert(eidKey, decryptedAdvert); },
+ testing::ThrowsMessage<Exception::Unknown>(
+ testing::HasSubstr("Bluetooth initialization error: BT_ERROR_NOT_SUPPORTED")));
+ EXPECT_EQ(decryptedAdvert, CryptoBuffer{});
+ EXPECT_EQ(bt->m_initialized, false);
+}
+
+TEST(BtAdvertScanner, await_advert_because_of_StartLEAdvertScanAndAwaitStop_error_Negative)
+{
+ auto eidKey = RandomEidKey();
+ auto btUptr = std::make_unique<BluetoothMock>(true, BleAdverts{});
+ auto bt = btUptr.get();
+ bt->m_startLEAdvertScanRes = BT_ERROR_NOT_SUPPORTED;
+ auto bas = BtAdvertScanner{std::move(btUptr)};
+ CryptoBuffer decryptedAdvert;
+ EXPECT_THAT([&] { bas.AwaitAdvert(eidKey, decryptedAdvert); },
+ testing::ThrowsMessage<Exception::Unknown>(
+ testing::HasSubstr("Scanning for BLE advert error: BT_ERROR_NOT_SUPPORTED")));
+ EXPECT_EQ(decryptedAdvert, CryptoBuffer{});
+ EXPECT_EQ(bt->m_initialized, false);
+}
+
+TEST(BtAdvertScanner, await_advert_because_of_deinitialize_error_Negative)
+{
+ auto eidKey = RandomEidKey();
+ auto advertPlaintext = RandomAdvertPlaintext();
+ auto serviceData = GenerateServiceData(eidKey, advertPlaintext);
+ auto btUptr =
+ std::make_unique<BluetoothMock>(true,
+ BleAdverts{
+ {"FFF9", serviceData, IBluetooth::Scanning::STOP}
+ });
+ auto bt = btUptr.get();
+ bt->m_deinitializeRes = BT_ERROR_NOT_SUPPORTED;
+ auto bas = BtAdvertScanner{std::move(btUptr)};
+ CryptoBuffer decryptedAdvert;
+ EXPECT_THAT([&] { bas.AwaitAdvert(eidKey, decryptedAdvert); },
+ testing::ThrowsMessage<Exception::Unknown>(testing::HasSubstr(
+ "Bluetooth deinitialization error: BT_ERROR_NOT_SUPPORTED")));
+ EXPECT_EQ(decryptedAdvert, advertPlaintext);
+ EXPECT_EQ(bt->m_initialized, true);
+}
+
+TEST(BtAdvertScanner,
+ await_advert_because_of_StartLEAdvertScanAndAwaitStop_and_deinitialize_error_Negative)
+{
+ auto eidKey = RandomEidKey();
+ auto btUptr = std::make_unique<BluetoothMock>(true, BleAdverts{});
+ auto bt = btUptr.get();
+ bt->m_startLEAdvertScanRes = BT_ERROR_NOT_SUPPORTED;
+ bt->m_deinitializeRes = BT_ERROR_AUTHORIZATION_REJECTED;
+ auto bas = BtAdvertScanner{std::move(btUptr)};
+ CryptoBuffer decryptedAdvert;
+ EXPECT_THAT([&] { bas.AwaitAdvert(eidKey, decryptedAdvert); },
+ testing::ThrowsMessage<Exception::Unknown>(testing::HasSubstr(
+ "Bluetooth deinitialization error: BT_ERROR_AUTHORIZATION_REJECTED")));
+ EXPECT_EQ(decryptedAdvert, CryptoBuffer{});
+ EXPECT_EQ(bt->m_initialized, true);
}
namespace {
}
#ifdef EMULATOR_BUILD
-TEST(BtAdvertScanner, BluetoothInitialize_Negative)
+TEST(BtAdvertScanner, BluetoothInitialize_Positive)
{
Bluetooth bt;
int err;
- ASSERT_EQ(err = bt.Initialize(), BT_ERROR_NOT_SUPPORTED) << BtErrorToString(err);
+ EXPECT_NO_THROW(err = bt.Initialize());
+ (void)err;
}
#endif
EXPECT_EQ(res.response.m_userDisplayName, "");
}
-TEST(CtapMessageProcessor, InvalidParamsForMakeCredential_Negative)
+static constexpr auto doTestMakeCredential = [](const auto &clientData, const auto &options) {
+ auto cmp = CtapMessageProcessor{};
+ cmp.SetEncryptedTunnel(std::make_unique<MEncryptedTunnel>(
+ std::vector<CryptoBuffer>{BUFFER(IPHONE_EXAMPLE_POST_HANDSHAKE_RAW_RESPONSE)}));
+ EXPECT_THROW(cmp.MakeCredential(clientData, options), Exception::InvalidParam);
+};
+
+TEST(CtapMessageProcessor, InvalidClientDataForMakeCredential1_Negative)
{
- static constexpr auto doTest = [](const auto &clientData, const auto &options) {
- auto cmp = CtapMessageProcessor{};
- cmp.SetEncryptedTunnel(std::make_unique<MEncryptedTunnel>(
- std::vector<CryptoBuffer>{BUFFER(IPHONE_EXAMPLE_POST_HANDSHAKE_RAW_RESPONSE)}));
- EXPECT_THROW(cmp.MakeCredential(clientData, options), Exception::InvalidParam);
- };
WithDefaultMCArgs([](auto &clientData, auto &options) {
clientData.client_data_json = nullptr;
SCOPED_TRACE("");
- doTest(clientData, options);
+ doTestMakeCredential(clientData, options);
});
+}
+
+TEST(CtapMessageProcessor, InvalidClientDataForMakeCredential2_Negative)
+{
WithDefaultMCArgs([](auto &clientData, auto &options) {
clientData.client_data_json->data = nullptr;
SCOPED_TRACE("");
- doTest(clientData, options);
+ doTestMakeCredential(clientData, options);
});
+}
+
+TEST(CtapMessageProcessor, InvalidClientDataForMakeCredential3_Negative)
+{
WithDefaultMCArgs([](auto &clientData, auto &options) {
clientData.hash_alg = static_cast<wauthn_hash_algorithm_e>(0);
SCOPED_TRACE("");
- doTest(clientData, options);
+ doTestMakeCredential(clientData, options);
});
+}
+
+TEST(CtapMessageProcessor, InvalidOptionsForMakeCredential1_Negative)
+{
WithDefaultMCArgs([](auto &clientData, auto &options) {
options.rp = nullptr;
SCOPED_TRACE("");
- doTest(clientData, options);
+ doTestMakeCredential(clientData, options);
});
+}
+
+TEST(CtapMessageProcessor, InvalidOptionsForMakeCredential2_Negative)
+{
WithDefaultMCArgs([](auto &clientData, auto &options) {
options.rp->id = nullptr;
SCOPED_TRACE("");
- doTest(clientData, options);
+ doTestMakeCredential(clientData, options);
});
+}
+
+TEST(CtapMessageProcessor, InvalidOptionsForMakeCredential3_Negative)
+{
// options.rp->name == nullptr is OK
WithDefaultMCArgs([](auto &clientData, auto &options) {
options.user = nullptr;
SCOPED_TRACE("");
- doTest(clientData, options);
+ doTestMakeCredential(clientData, options);
});
+}
+
+TEST(CtapMessageProcessor, InvalidOptionsForMakeCredential4_Negative)
+{
WithDefaultMCArgs([](auto &clientData, auto &options) {
options.user->id = nullptr;
SCOPED_TRACE("");
- doTest(clientData, options);
+ doTestMakeCredential(clientData, options);
});
+}
+
+TEST(CtapMessageProcessor, InvalidOptionsForMakeCredential5_Negative)
+{
WithDefaultMCArgs([](auto &clientData, auto &options) {
options.user->name = nullptr;
SCOPED_TRACE("");
- doTest(clientData, options);
+ doTestMakeCredential(clientData, options);
});
+}
+
+TEST(CtapMessageProcessor, InvalidOptionsForMakeCredential6_Negative)
+{
WithDefaultMCArgs([](auto &clientData, auto &options) {
options.user->display_name = nullptr;
SCOPED_TRACE("");
- doTest(clientData, options);
+ doTestMakeCredential(clientData, options);
});
+}
+
+TEST(CtapMessageProcessor, InvalidOptionsForMakeCredential7_Negative)
+{
// options.pubkey_cred_params == nullptr is OK
WithDefaultMCArgs([](auto &clientData, auto &options) {
options.pubkey_cred_params->params = nullptr;
SCOPED_TRACE("");
- doTest(clientData, options);
+ doTestMakeCredential(clientData, options);
});
}
-TEST(CtapMessageProcessor, InvalidParamsForGetAssertion_Negative)
+static constexpr auto doTestGetAssertion = [](const auto &clientData, const auto &options) {
+ auto cmp = CtapMessageProcessor{};
+ cmp.SetEncryptedTunnel(std::make_unique<MEncryptedTunnel>(
+ std::vector<CryptoBuffer>{BUFFER(IPHONE_EXAMPLE_POST_HANDSHAKE_RAW_RESPONSE)}));
+ EXPECT_THROW(cmp.GetAssertion(clientData, options), Exception::InvalidParam);
+};
+
+TEST(CtapMessageProcessor, InvalidClientDataForGetAssertion1_Negative)
{
- static constexpr auto doTest = [](const auto &clientData, const auto &options) {
- auto cmp = CtapMessageProcessor{};
- cmp.SetEncryptedTunnel(std::make_unique<MEncryptedTunnel>(
- std::vector<CryptoBuffer>{BUFFER(IPHONE_EXAMPLE_POST_HANDSHAKE_RAW_RESPONSE)}));
- EXPECT_THROW(cmp.GetAssertion(clientData, options), Exception::InvalidParam);
- };
WithDefaultGAArgs(
[](auto &clientData, auto &options) {
clientData.client_data_json = nullptr;
SCOPED_TRACE("");
- doTest(clientData, options);
+ doTestGetAssertion(clientData, options);
},
BufferView{});
+}
+
+TEST(CtapMessageProcessor, InvalidClientDataForGetAssertion2_Negative)
+{
WithDefaultGAArgs(
[](auto &clientData, auto &options) {
clientData.client_data_json->data = nullptr;
SCOPED_TRACE("");
- doTest(clientData, options);
+ doTestGetAssertion(clientData, options);
},
BufferView{});
+}
+
+TEST(CtapMessageProcessor, InvalidClientDataForGetAssertion3_Negative)
+{
WithDefaultGAArgs(
[](auto &clientData, auto &options) {
clientData.hash_alg = static_cast<wauthn_hash_algorithm_e>(0);
SCOPED_TRACE("");
- doTest(clientData, options);
+ doTestGetAssertion(clientData, options);
},
BufferView{});
+}
+
+TEST(CtapMessageProcessor, InvalidOptionsForGetAssertion1_Negative)
+{
WithDefaultGAArgs(
[](auto &clientData, auto &options) {
options.rpId = nullptr;
SCOPED_TRACE("");
- doTest(clientData, options);
+ doTestGetAssertion(clientData, options);
},
BufferView{});
+}
+
+TEST(CtapMessageProcessor, InvalidOptionsForGetAssertion2_Negative)
+{
// options.allow_credentials == nullptr is OK
WithDefaultGAArgs(
[](auto &clientData, auto &options) {
options.allow_credentials->descriptors = nullptr;
SCOPED_TRACE("");
- doTest(clientData, options);
+ doTestGetAssertion(clientData, options);
},
BufferView{});
+}
+
+TEST(CtapMessageProcessor, InvalidOptionsForGetAssertion3_Negative)
+{
WithDefaultGAArgs(
[](auto &clientData, auto &options) {
options.allow_credentials->descriptors[0].type =
static_cast<wauthn_pubkey_cred_type_e>(0);
SCOPED_TRACE("");
- doTest(clientData, options);
+ doTestGetAssertion(clientData, options);
},
BufferView{});
+}
+
+TEST(CtapMessageProcessor, InvalidOptionsForGetAssertion4_Negative)
+{
WithDefaultGAArgs(
[](auto &clientData, auto &options) {
options.allow_credentials->descriptors[0].id = nullptr;
SCOPED_TRACE("");
- doTest(clientData, options);
+ doTestGetAssertion(clientData, options);
},
BufferView{});
+}
+
+TEST(CtapMessageProcessor, InvalidOptionsForGetAssertion5_Negative)
+{
WithDefaultGAArgs(
[](auto &clientData, auto &options) {
options.allow_credentials->descriptors[0].id->data = nullptr;
SCOPED_TRACE("");
- doTest(clientData, options);
+ doTestGetAssertion(clientData, options);
},
BUFFER_VIEW("x"));
}
} // namespace
-TEST(CtapMessageProcessor,
- MakeCredential_without_update_message_cancel_from_the_other_thread_Positive)
+TEST(CtapMessageProcessor, MakeCredential_cancel_from_the_other_thread_Positive)
{
- auto makeCMP = [&] {
+ // MakeCredential without update message
+ auto makeCMP1 = [&] {
auto cmp = std::make_unique<CtapMessageProcessor>();
cmp->SetEncryptedTunnel(
std::make_unique<CancellationMEncryptedTunnel>(std::vector<CryptoBuffer>{
return cmp;
};
TestCancelFromTheOtherThread<ICtapMessageProcessor>(
- 100, 30, makeCMP, [](ICtapMessageProcessor &cmp) {
+ 100, 30, makeCMP1, [](ICtapMessageProcessor &cmp) {
WithDefaultMCArgs([&](const auto &clientData, const auto &options) {
cmp.MakeCredential(clientData, options);
});
});
-}
-TEST(CtapMessageProcessor, MakeCredential_with_update_message_cancel_from_the_other_thread_Positive)
-{
- auto makeCMP = [&] {
+ // MakeCredential with update message
+ auto makeCMP2 = [&] {
auto cmp = std::make_unique<CtapMessageProcessor>();
cmp->SetEncryptedTunnel(
std::make_unique<CancellationMEncryptedTunnel>(std::vector<CryptoBuffer>{
return cmp;
};
TestCancelFromTheOtherThread<ICtapMessageProcessor>(
- 100, 30, makeCMP, [](ICtapMessageProcessor &cmp) {
+ 100, 30, makeCMP2, [](ICtapMessageProcessor &cmp) {
WithDefaultMCArgs([&](const auto &clientData, const auto &options) {
cmp.MakeCredential(clientData, options);
});
});
}
-TEST(CtapMessageProcessor,
- GetAssertion_without_update_message_cancel_from_the_other_thread_Positive)
+TEST(CtapMessageProcessor, GetAssertion_cancel_from_the_other_thread_Positive)
{
- auto makeCMP = [&] {
+ // GetAssertion without update message
+ auto makeCMP1 = [&] {
auto cmp = std::make_unique<CtapMessageProcessor>();
cmp->SetEncryptedTunnel(
std::make_unique<CancellationMEncryptedTunnel>(std::vector<CryptoBuffer>{
return cmp;
};
TestCancelFromTheOtherThread<ICtapMessageProcessor>(
- 100, 30, makeCMP, [](ICtapMessageProcessor &cmp) {
+ 100, 30, makeCMP1, [](ICtapMessageProcessor &cmp) {
WithDefaultGAArgs([&](const auto &clientData,
const auto &options) { cmp.GetAssertion(clientData, options); },
BUFFER_VIEW(IPHONE_EXAMPLE_GET_ASSERTION_RAW_RESPONSE_CREDENTIAL_ID));
});
-}
-TEST(CtapMessageProcessor, GetAssertion_with_update_message_cancel_from_the_other_thread_Positive)
-{
- auto makeCMP = [&] {
+ // GetAssertion_with_update_message
+ auto makeCMP2 = [&] {
auto cmp = std::make_unique<CtapMessageProcessor>();
cmp->SetEncryptedTunnel(
std::make_unique<CancellationMEncryptedTunnel>(std::vector<CryptoBuffer>{
return cmp;
};
TestCancelFromTheOtherThread<ICtapMessageProcessor>(
- 100, 30, makeCMP, [](ICtapMessageProcessor &cmp) {
+ 100, 30, makeCMP2, [](ICtapMessageProcessor &cmp) {
WithDefaultGAArgs(
[&](const auto &clientData, const auto &options) {
cmp.GetAssertion(clientData, options);
0x1c, 0x50, 0x53, 0x23, 0x3a, 0xef, 0x03, 0xc2, 0xe4, 0xbb}));
}
-TEST(DeriveKey, empty_salt_Positive)
+TEST(DeriveKey, empty_key_salt_Positive)
{
- const CryptoBuffer secret = {'s', 'e', 'c', 'r', 'e', 't'};
+ CryptoBuffer secret;
const CryptoBuffer salt;
+ EXPECT_EQ(DeriveKey(secret, salt, KeyPurpose::EIDKey, 0), CryptoBuffer{});
+ EXPECT_EQ(DeriveKey(secret, salt, KeyPurpose::TunnelID, 0), CryptoBuffer{});
+ EXPECT_EQ(DeriveKey(secret, salt, KeyPurpose::PSK, 0), CryptoBuffer{});
+
+ secret = {'s', 'e', 'c', 'r', 'e', 't'};
+
EXPECT_EQ(DeriveKey(secret, salt, KeyPurpose::EIDKey, 8),
(CryptoBuffer{0x38, 0x6f, 0x97, 0x0e, 0xbc, 0x4f, 0xac, 0x0e}));
EXPECT_EQ(DeriveKey(secret, salt, KeyPurpose::PSK, 8),
(CryptoBuffer{0x98, 0xbd, 0x03, 0xeb, 0x65, 0xd4, 0x43, 0x40}));
}
-
-TEST(DeriveKey, empty_key_Positive)
-{
- const CryptoBuffer secret;
- const CryptoBuffer salt;
-
- EXPECT_EQ(DeriveKey(secret, salt, KeyPurpose::EIDKey, 0), CryptoBuffer{});
- EXPECT_EQ(DeriveKey(secret, salt, KeyPurpose::TunnelID, 0), CryptoBuffer{});
- EXPECT_EQ(DeriveKey(secret, salt, KeyPurpose::PSK, 0), CryptoBuffer{});
-}
} // namespace
-TEST(Handshake, QrInitiatedConnect_Positive)
+TEST(Handshake, Connect_Positive)
{
+ // QrInitiated connect
{
auto tunnel = std::make_unique<ConnectMTunnel>(
"wss://some.domain/cable/connect/" +
handshake.QrInitiatedConnect(
"a", reinterpret_cast<const uint8_t *>("b"), reinterpret_cast<const uint8_t *>("c"));
}
-}
-TEST(Handshake, StateAssistedConnect_Positive)
-{
+ // StateAssisted connect
{
auto tunnel = std::make_unique<ConnectMTunnel>(
"wss://some.domain/cable/contact/" +
} // namespace
-TEST(Handshake, DoQrInitiatedHandshake_Positive)
+TEST(Handshake, Handshake_Positive)
{
- auto test = QrInitiatedHandshakeTest<HandshakeMTunnel>();
- auto handshake = test.MakeHandshake();
- test.RunAndTestHandshake(handshake);
-}
-
-TEST(Handshake, DoStateAssistedHandshake_Positive)
-{
- auto test = StateAssistedHandshakeTest<HandshakeMTunnel>{};
- auto handshake = test.MakeHandshake();
- test.RunAndTestHandshake(handshake);
+ // QrInitiated handshake
+ {
+ auto test = QrInitiatedHandshakeTest<HandshakeMTunnel>();
+ auto handshake = test.MakeHandshake();
+ test.RunAndTestHandshake(handshake);
+ }
+ // StateAssisted handshake
+ {
+ auto test = StateAssistedHandshakeTest<HandshakeMTunnel>{};
+ auto handshake = test.MakeHandshake();
+ test.RunAndTestHandshake(handshake);
+ }
}
namespace {
} // namespace
-TEST(Handshake, qr_initiated_connect_Positive)
-{
- auto makeHandshake = [&] { return Handshake{std::make_unique<CancellationConnectMTunnel>()}; };
- TestCancelFromTheOtherThread<IHandshake>(100, 20, makeHandshake, [&](IHandshake &handshake) {
- handshake.QrInitiatedConnect({}, {}, {});
- });
-}
-
-TEST(Handshake, state_assisted_connect_Positive)
+TEST(Handshake, qr_initiated_connect_and_state_assisted_connect_Positive)
{
- auto makeHandshake = [&] { return Handshake{std::make_unique<CancellationConnectMTunnel>()}; };
- TestCancelFromTheOtherThread<IHandshake>(100, 20, makeHandshake, [&](IHandshake &handshake) {
- handshake.StateAssistedConnect({}, {}, {});
- });
+ // QrInitiated connect
+ {
+ auto makeHandshake = [&] {
+ return Handshake{std::make_unique<CancellationConnectMTunnel>()};
+ };
+ TestCancelFromTheOtherThread<IHandshake>(
+ 100, 20, makeHandshake, [&](IHandshake &handshake) {
+ handshake.QrInitiatedConnect({}, {}, {});
+ });
+ }
+ // StateAssisted connect
+ {
+ auto makeHandshake = [&] {
+ return Handshake{std::make_unique<CancellationConnectMTunnel>()};
+ };
+ TestCancelFromTheOtherThread<IHandshake>(
+ 100, 20, makeHandshake, [&](IHandshake &handshake) {
+ handshake.StateAssistedConnect({}, {}, {});
+ });
+ }
}
namespace {
} // namespace
-TEST(Handshake, qr_initiated_handshake_cancel_from_the_other_thread_Positive)
+TEST(Handshake, cancel_from_the_other_thread_Positive)
{
- auto test = QrInitiatedHandshakeTest<CancellationHandshakeMTunnel>{};
- auto makeHandshake = [&] { return test.MakeHandshake(); };
- TestCancelFromTheOtherThread<IHandshake>(100, 20, makeHandshake, [&](IHandshake &handshake) {
- test.RunAndTestHandshake(handshake);
- });
-}
-
-TEST(Handshake, state_assisted_handshake_cancel_from_the_other_thread_Positive)
-{
- auto test = StateAssistedHandshakeTest<CancellationHandshakeMTunnel>{};
- auto makeHandshake = [&] { return test.MakeHandshake(); };
- TestCancelFromTheOtherThread<IHandshake>(100, 20, makeHandshake, [&](IHandshake &handshake) {
- test.RunAndTestHandshake(handshake);
- });
+ // QrInitiated handshake
+ {
+ auto test = QrInitiatedHandshakeTest<CancellationHandshakeMTunnel>{};
+ auto makeHandshake = [&] { return test.MakeHandshake(); };
+ TestCancelFromTheOtherThread<IHandshake>(
+ 100, 20, makeHandshake, [&](IHandshake &handshake) {
+ test.RunAndTestHandshake(handshake);
+ });
+ }
+ // StateAssisted handshake
+ {
+ auto test = StateAssistedHandshakeTest<CancellationHandshakeMTunnel>{};
+ auto makeHandshake = [&] { return test.MakeHandshake(); };
+ TestCancelFromTheOtherThread<IHandshake>(
+ 100, 20, makeHandshake, [&](IHandshake &handshake) {
+ test.RunAndTestHandshake(handshake);
+ });
+ }
}
} // namespace
-TEST(Messages, ParsePostHandshakeMessage1_Positive)
+TEST(Messages, ParsePostHandshakeMessage_Positive)
{
// read post handshake message
- PostHandshakeResponse msg;
- auto view = BUFFER_VIEW(IPHONE_EXAMPLE_POST_HANDSHAKE_RAW_RESPONSE);
- ASSERT_NO_THROW(msg.Deserialize(view));
+ PostHandshakeResponse msg1;
+ auto viewIphone = BUFFER_VIEW(IPHONE_EXAMPLE_POST_HANDSHAKE_RAW_RESPONSE);
+ ASSERT_NO_THROW(msg1.Deserialize(viewIphone));
- EXPECT_EQ(msg.m_versions, (std::vector<std::string>{"FIDO_2_0", "FIDO_2_1"}));
- EXPECT_EQ(msg.m_extensions, std::vector<std::string>{"largeBlob"});
- EXPECT_EQ(ToBufferView(msg.m_aaguid),
+ EXPECT_EQ(msg1.m_versions, (std::vector<std::string>{"FIDO_2_0", "FIDO_2_1"}));
+ EXPECT_EQ(msg1.m_extensions, std::vector<std::string>{"largeBlob"});
+ EXPECT_EQ(ToBufferView(msg1.m_aaguid),
BUFFER_VIEW("\xf2\x4a\x8e\x70\xd0\xd3\xf8\x2c\x29\x37\x32\x52\x3c\xc4\xde\x5a"));
- EXPECT_TRUE(msg.m_options.uv);
- EXPECT_TRUE(msg.m_options.rk);
- EXPECT_EQ(msg.m_maxMsgSize, std::nullopt);
- EXPECT_EQ(msg.m_pinUvAuthProtocols, std::vector<uint64_t>{});
- EXPECT_EQ(msg.m_maxCredentialCountInList, std::nullopt);
- EXPECT_EQ(msg.m_maxCredentialIdLength, std::nullopt);
- EXPECT_EQ(msg.m_transports, (std::vector<std::string>{"internal", "hybrid"}));
- EXPECT_EQ(msg.m_algorithms.size(), 0);
- EXPECT_EQ(msg.m_maxSerializedLargeBlobArray, std::nullopt);
- EXPECT_EQ(msg.m_forcePINChange, std::nullopt);
- EXPECT_EQ(msg.m_minPINLength, std::nullopt);
- EXPECT_EQ(msg.m_firmwareVersion, std::nullopt);
- EXPECT_EQ(msg.m_maxCredBlobLength, std::nullopt);
- EXPECT_EQ(msg.m_maxRPIDsForSetMinPINLength, std::nullopt);
- EXPECT_EQ(msg.m_preferredPlatformUvAttempts, std::nullopt);
- EXPECT_EQ(msg.m_uvModality, std::nullopt);
- EXPECT_EQ(msg.m_certifications, (std::unordered_map<std::string, uint64_t>{}));
- EXPECT_EQ(msg.m_remainingDiscoverableCredentials, std::nullopt);
- EXPECT_EQ(msg.m_vendorPrototypeConfigCommands, std::vector<uint64_t>{});
- EXPECT_EQ(msg.m_attestationFormats, std::vector<std::string>{});
- EXPECT_EQ(msg.m_uvCountSinceLastPinEntry, std::nullopt);
- EXPECT_EQ(msg.m_longTouchForReset, std::nullopt);
-}
-
-TEST(Messages, ParsePostHandshakeMessage2_Positive)
-{
- // read post handshake message
- PostHandshakeResponse msg;
- auto view = BUFFER_VIEW(ANDROID_EXAMPLE_POST_HANDSHAKE_RAW_RESPONSE);
- ASSERT_NO_THROW(msg.Deserialize(view));
+ EXPECT_TRUE(msg1.m_options.uv);
+ EXPECT_TRUE(msg1.m_options.rk);
+ EXPECT_EQ(msg1.m_maxMsgSize, std::nullopt);
+ EXPECT_EQ(msg1.m_pinUvAuthProtocols, std::vector<uint64_t>{});
+ EXPECT_EQ(msg1.m_maxCredentialCountInList, std::nullopt);
+ EXPECT_EQ(msg1.m_maxCredentialIdLength, std::nullopt);
+ EXPECT_EQ(msg1.m_transports, (std::vector<std::string>{"internal", "hybrid"}));
+ EXPECT_EQ(msg1.m_algorithms.size(), 0);
+ EXPECT_EQ(msg1.m_maxSerializedLargeBlobArray, std::nullopt);
+ EXPECT_EQ(msg1.m_forcePINChange, std::nullopt);
+ EXPECT_EQ(msg1.m_minPINLength, std::nullopt);
+ EXPECT_EQ(msg1.m_firmwareVersion, std::nullopt);
+ EXPECT_EQ(msg1.m_maxCredBlobLength, std::nullopt);
+ EXPECT_EQ(msg1.m_maxRPIDsForSetMinPINLength, std::nullopt);
+ EXPECT_EQ(msg1.m_preferredPlatformUvAttempts, std::nullopt);
+ EXPECT_EQ(msg1.m_uvModality, std::nullopt);
+ EXPECT_EQ(msg1.m_certifications, (std::unordered_map<std::string, uint64_t>{}));
+ EXPECT_EQ(msg1.m_remainingDiscoverableCredentials, std::nullopt);
+ EXPECT_EQ(msg1.m_vendorPrototypeConfigCommands, std::vector<uint64_t>{});
+ EXPECT_EQ(msg1.m_attestationFormats, std::vector<std::string>{});
+ EXPECT_EQ(msg1.m_uvCountSinceLastPinEntry, std::nullopt);
+ EXPECT_EQ(msg1.m_longTouchForReset, std::nullopt);
- EXPECT_EQ(msg.m_versions, (std::vector<std::string>{"FIDO_2_0", "FIDO_2_1"}));
- EXPECT_EQ(msg.m_extensions, std::vector<std::string>{"prf"});
- EXPECT_EQ(msg.m_aaguid, Buffer(16, 0x00));
- EXPECT_TRUE(msg.m_options.uv);
- EXPECT_TRUE(msg.m_options.rk);
- EXPECT_EQ(msg.m_maxMsgSize, std::nullopt);
- EXPECT_EQ(msg.m_pinUvAuthProtocols, std::vector<uint64_t>{});
- EXPECT_EQ(msg.m_maxCredentialCountInList, std::nullopt);
- EXPECT_EQ(msg.m_maxCredentialIdLength, std::nullopt);
- EXPECT_EQ(msg.m_transports, (std::vector<std::string>{"internal", "hybrid"}));
- EXPECT_EQ(msg.m_algorithms.size(), 0);
- EXPECT_EQ(msg.m_maxSerializedLargeBlobArray, std::nullopt);
- EXPECT_EQ(msg.m_forcePINChange, std::nullopt);
- EXPECT_EQ(msg.m_minPINLength, std::nullopt);
- EXPECT_EQ(msg.m_firmwareVersion, std::nullopt);
- EXPECT_EQ(msg.m_maxCredBlobLength, std::nullopt);
- EXPECT_EQ(msg.m_maxRPIDsForSetMinPINLength, std::nullopt);
- EXPECT_EQ(msg.m_preferredPlatformUvAttempts, std::nullopt);
- EXPECT_EQ(msg.m_uvModality, std::nullopt);
- EXPECT_EQ(msg.m_certifications, (std::unordered_map<std::string, uint64_t>{}));
- EXPECT_EQ(msg.m_remainingDiscoverableCredentials, std::nullopt);
- EXPECT_EQ(msg.m_vendorPrototypeConfigCommands, std::vector<uint64_t>{});
- EXPECT_EQ(msg.m_attestationFormats, std::vector<std::string>{});
- EXPECT_EQ(msg.m_uvCountSinceLastPinEntry, std::nullopt);
- EXPECT_EQ(msg.m_longTouchForReset, std::nullopt);
+ // read post handshake message
+ PostHandshakeResponse msg2;
+ auto viewAndroid = BUFFER_VIEW(ANDROID_EXAMPLE_POST_HANDSHAKE_RAW_RESPONSE);
+ ASSERT_NO_THROW(msg2.Deserialize(viewAndroid));
+
+ EXPECT_EQ(msg2.m_versions, (std::vector<std::string>{"FIDO_2_0", "FIDO_2_1"}));
+ EXPECT_EQ(msg2.m_extensions, std::vector<std::string>{"prf"});
+ EXPECT_EQ(msg2.m_aaguid, Buffer(16, 0x00));
+ EXPECT_TRUE(msg2.m_options.uv);
+ EXPECT_TRUE(msg2.m_options.rk);
+ EXPECT_EQ(msg2.m_maxMsgSize, std::nullopt);
+ EXPECT_EQ(msg2.m_pinUvAuthProtocols, std::vector<uint64_t>{});
+ EXPECT_EQ(msg2.m_maxCredentialCountInList, std::nullopt);
+ EXPECT_EQ(msg2.m_maxCredentialIdLength, std::nullopt);
+ EXPECT_EQ(msg2.m_transports, (std::vector<std::string>{"internal", "hybrid"}));
+ EXPECT_EQ(msg2.m_algorithms.size(), 0);
+ EXPECT_EQ(msg2.m_maxSerializedLargeBlobArray, std::nullopt);
+ EXPECT_EQ(msg2.m_forcePINChange, std::nullopt);
+ EXPECT_EQ(msg2.m_minPINLength, std::nullopt);
+ EXPECT_EQ(msg2.m_firmwareVersion, std::nullopt);
+ EXPECT_EQ(msg2.m_maxCredBlobLength, std::nullopt);
+ EXPECT_EQ(msg2.m_maxRPIDsForSetMinPINLength, std::nullopt);
+ EXPECT_EQ(msg2.m_preferredPlatformUvAttempts, std::nullopt);
+ EXPECT_EQ(msg2.m_uvModality, std::nullopt);
+ EXPECT_EQ(msg2.m_certifications, (std::unordered_map<std::string, uint64_t>{}));
+ EXPECT_EQ(msg2.m_remainingDiscoverableCredentials, std::nullopt);
+ EXPECT_EQ(msg2.m_vendorPrototypeConfigCommands, std::vector<uint64_t>{});
+ EXPECT_EQ(msg2.m_attestationFormats, std::vector<std::string>{});
+ EXPECT_EQ(msg2.m_uvCountSinceLastPinEntry, std::nullopt);
+ EXPECT_EQ(msg2.m_longTouchForReset, std::nullopt);
}
TEST(Messages, DomainName_Positive)
EXPECT_NO_THROW(ValidateDomain(tooLongDomain.c_str() + 1));
}
-TEST(Messages, DomainName_Negative)
+TEST(Messages, TooLongLabel_Negative)
{
- const std::string notTooLongLabel(63, 'a');
const std::string tooLongLabel(64, 'a');
+ EXPECT_THROW(ValidateDomain(tooLongLabel.c_str()), Exception::InvalidParam);
+}
+
+TEST(Messages, TooLongDomain_Negative)
+{
+ const std::string notTooLongLabel(63, 'a');
std::string tooLongDomain = notTooLongLabel;
while (tooLongDomain.size() < 254)
tooLongDomain += "." + notTooLongLabel;
tooLongDomain.resize(254);
assert(tooLongDomain.back() != '.');
+ EXPECT_THROW(ValidateDomain(tooLongDomain.c_str()), Exception::InvalidParam);
+}
+
+TEST(Messages, InvalidDomainName1_Negative)
+{
EXPECT_THROW(ValidateDomain(nullptr), Exception::InvalidParam);
+}
+
+TEST(Messages, InvalidDomainName2_Negative)
+{
EXPECT_THROW(ValidateDomain("acme."), Exception::InvalidParam);
+}
+
+TEST(Messages, InvalidDomainName3_Negative)
+{
EXPECT_THROW(ValidateDomain(".acme"), Exception::InvalidParam);
+}
+
+TEST(Messages, InvalidDomainName4_Negative)
+{
EXPECT_THROW(ValidateDomain("-acme.com"), Exception::InvalidParam);
+}
+
+TEST(Messages, InvalidDomainName5_Negative)
+{
EXPECT_THROW(ValidateDomain("acme..com"), Exception::InvalidParam);
+}
+
+TEST(Messages, InvalidDomainName6_Negative)
+{
EXPECT_THROW(ValidateDomain("acme-.com"), Exception::InvalidParam);
+}
+
+TEST(Messages, InvalidDomainName7_Negative)
+{
EXPECT_THROW(ValidateDomain("acme.-com"), Exception::InvalidParam);
+}
+
+TEST(Messages, InvalidDomainName8_Negative)
+{
EXPECT_THROW(ValidateDomain("acme.com-"), Exception::InvalidParam);
+}
+
+TEST(Messages, InvalidDomainName9_Negative)
+{
EXPECT_THROW(ValidateDomain("a_cme.com"), Exception::InvalidParam);
+}
+
+TEST(Messages, InvalidDomainName10_Negative)
+{
EXPECT_THROW(ValidateDomain("a?cme.com"), Exception::InvalidParam);
- EXPECT_THROW(ValidateDomain(tooLongLabel.c_str()), Exception::InvalidParam);
- EXPECT_THROW(ValidateDomain(tooLongDomain.c_str()), Exception::InvalidParam);
}
TEST(Messages, SerializeMakeCredential1_Negative)
EXPECT_EQ(ToBufferView(linkData.m_handshakeSignature), (BufferView{blob + 459, 32}));
}
-TEST(Messages, MakeCredentialResponse_Negative)
+TEST(Messages, CborUnexpectedTypeMakeCredentialResponse_Negative)
{
MakeCredentialResponse msg;
- auto cborUnexpectedType = BUFFER_VIEW("\x11"); // NOLINT(modernize-raw-string-literal)
- auto errorProcessing = BUFFER_VIEW("\x21"); // NOLINT(modernize-raw-string-literal)
- auto unsupportedAlgorithm = BUFFER_VIEW("\x26"); // NOLINT(modernize-raw-string-literal)
- auto missingParameter = BUFFER_VIEW("\x14"); // NOLINT(modernize-raw-string-literal)
- auto operationDenied = BUFFER_VIEW("\x27"); // NOLINT(modernize-raw-string-literal)
- auto keyStoreFull = BUFFER_VIEW("\x28"); // NOLINT(modernize-raw-string-literal)
- auto userActionTimeout = BUFFER_VIEW("\x2F"); // NOLINT(modernize-raw-string-literal)
- auto pinBlocked = BUFFER_VIEW("\x32"); // NOLINT(modernize-raw-string-literal)
- auto credentialExcluded = BUFFER_VIEW("\x19"); // NOLINT(modernize-raw-string-literal)
+ auto cborUnexpectedType = BUFFER_VIEW("\x11"); // NOLINT(modernize-raw-string-literal)
EXPECT_THROW(msg.Deserialize(cborUnexpectedType), Exception::EncodingFailed);
+}
+
+TEST(Messages, ErrorProcessingMakeCredentialResponse_Negative)
+{
+ MakeCredentialResponse msg;
+ auto errorProcessing = BUFFER_VIEW("\x21"); // NOLINT(modernize-raw-string-literal)
EXPECT_THROW(msg.Deserialize(errorProcessing), Exception::InvalidState);
+}
+
+TEST(Messages, UnsupportedAlgorithmMakeCredentialResponse_Negative)
+{
+ MakeCredentialResponse msg;
+ auto unsupportedAlgorithm = BUFFER_VIEW("\x26"); // NOLINT(modernize-raw-string-literal)
EXPECT_THROW(msg.Deserialize(unsupportedAlgorithm), Exception::NotSupported);
+}
+
+TEST(Messages, MissingParameterMakeCredentialResponse_Negative)
+{
+ MakeCredentialResponse msg;
+ auto missingParameter = BUFFER_VIEW("\x14"); // NOLINT(modernize-raw-string-literal)
EXPECT_THROW(msg.Deserialize(missingParameter), Exception::InvalidParam);
+}
+
+TEST(Messages, OperationDeniedMakeCredentialResponse_Negative)
+{
+ MakeCredentialResponse msg;
+ auto operationDenied = BUFFER_VIEW("\x27"); // NOLINT(modernize-raw-string-literal)
EXPECT_THROW(msg.Deserialize(operationDenied), Exception::PermissionDenied);
+}
+
+TEST(Messages, KeyStoreFullMakeCredentialResponse_Negative)
+{
+ MakeCredentialResponse msg;
+ auto keyStoreFull = BUFFER_VIEW("\x28"); // NOLINT(modernize-raw-string-literal)
EXPECT_THROW(msg.Deserialize(keyStoreFull), Exception::InvalidState);
+}
+
+TEST(Messages, UserActionTimeoutMakeCredentialResponse_Negative)
+{
+ MakeCredentialResponse msg;
+ auto userActionTimeout = BUFFER_VIEW("\x2F"); // NOLINT(modernize-raw-string-literal)
EXPECT_THROW(msg.Deserialize(userActionTimeout), Exception::Timeout);
+}
+
+TEST(Messages, PinBlockedMakeCredentialResponse_Negative)
+{
+ MakeCredentialResponse msg;
+ auto pinBlocked = BUFFER_VIEW("\x32"); // NOLINT(modernize-raw-string-literal)
EXPECT_THROW(msg.Deserialize(pinBlocked), Exception::InvalidState);
+}
+
+TEST(Messages, CredentialExcludedMakeCredentialResponse_Negative)
+{
+ MakeCredentialResponse msg;
+ auto credentialExcluded = BUFFER_VIEW("\x19"); // NOLINT(modernize-raw-string-literal)
EXPECT_THROW(msg.Deserialize(credentialExcluded), Exception::NotAllowed);
}
InvalidState);
}
-TYPED_TEST(TunnelTypedTests, WrongHeaders_Negative)
+TYPED_TEST(TunnelTypedTests, ServerIgnoresHeaders1_Negative)
{
Tunnel tunnel(std::make_shared<TypeParam>());
// Test with a server which ignores headers
EXPECT_THROW(tunnel.Connect(TestUrl(), ExtraHttpHeader{"", "well_formatted_value"}), Unknown);
+}
+
+TYPED_TEST(TunnelTypedTests, ServerIgnoresHeaders2_Negative)
+{
+ Tunnel tunnel(std::make_shared<TypeParam>());
+
+ // Test with a server which ignores headers
EXPECT_THROW(
tunnel.Connect(TestUrl(), ExtraHttpHeader{"semicolonless_name", "well_formatted_value"}),
Unknown);
+}
+
+TYPED_TEST(TunnelTypedTests, ServerExpectsSpecificHeaders1_Negative)
+{
+ Tunnel tunnel(std::make_shared<TypeParam>());
// Test with a server which expects specific headers
EXPECT_THROW(
tunnel.Connect(HeadersTestUrl(), ExtraHttpHeader{TEST_HEADER_NAME, "unexpected_value"}),
InvalidState);
+}
+
+TYPED_TEST(TunnelTypedTests, ServerExpectsSpecificHeaders2_Negative)
+{
+ Tunnel tunnel(std::make_shared<TypeParam>());
+
+ // Test with a server which expects specific headers
EXPECT_THROW(
tunnel.Connect(HeadersTestUrl(), ExtraHttpHeader{"unexpected_name:", TEST_HEADER_VALUE}),
InvalidState);
+}
+
+TYPED_TEST(TunnelTypedTests, ServerExpectsSpecificHeaders3_Negative)
+{
+ Tunnel tunnel(std::make_shared<TypeParam>());
+
+ // Test with a server which expects specific headers
EXPECT_THROW(tunnel.Connect(HeadersTestUrl()), InvalidState);
}
#include <gmock/gmock.h>
#include <gtest/gtest.h>
-TEST(DecodeTunnelServerDomain, assigned_Positive)
-{
- EXPECT_EQ(DecodeTunnelServerDomain(0), "cable.ua5v.com");
- EXPECT_EQ(DecodeTunnelServerDomain(1), "cable.auth.com");
-}
-
TEST(DecodeTunnelServerDomain, assigned_Negative)
{
EXPECT_THROW(DecodeTunnelServerDomain(2), Exception::Unknown);
EXPECT_THROW(DecodeTunnelServerDomain(255), Exception::Unknown);
}
-TEST(DecodeTunnelServerDomain, hash_derived_Positive)
+TEST(DecodeTunnelServerDomain, assigned_and_hash_derived_Positive)
{
+ EXPECT_EQ(DecodeTunnelServerDomain(0), "cable.ua5v.com");
+ EXPECT_EQ(DecodeTunnelServerDomain(1), "cable.auth.com");
+
// Expected values obtained from the reference implementation in Go
EXPECT_EQ(DecodeTunnelServerDomain(256), "cable.qz2ekwmnd332c.info");
EXPECT_EQ(DecodeTunnelServerDomain(0x646a), "cable.xuzogsl3s3hrb.com");