From 1e138683362c9bda42a382963ddbd6d5f201b3db Mon Sep 17 00:00:00 2001 From: Jakub Wlostowski Date: Mon, 25 Nov 2024 18:41:16 +0100 Subject: [PATCH] Increase negative to positive tests ratio (part 2) Change-Id: I0c78790d0b3674973a8be662a39cab18ff04b00b --- tests/bluetooth_tests.cpp | 140 +++++++-------- tests/ctap_message_processor_tests.cpp | 162 +++++++++++------ tests/derive_key_tests.cpp | 20 +-- tests/handshake_tests.cpp | 99 ++++++----- tests/message_tests.cpp | 233 +++++++++++++++++-------- tests/tunnel/common_tests.cpp | 28 ++- tests/tunnel_server_domain_tests.cpp | 11 +- 7 files changed, 435 insertions(+), 258 deletions(-) diff --git a/tests/bluetooth_tests.cpp b/tests/bluetooth_tests.cpp index eea1c62..18debaf 100644 --- a/tests/bluetooth_tests.cpp +++ b/tests/bluetooth_tests.cpp @@ -266,13 +266,12 @@ void SuccessfulAwaitAdvertTest(const char *correctBleAdvertUUID) } // 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"); } @@ -290,71 +289,73 @@ TEST(BtAdvertScanner, await_advert_fails_because_bluetooth_is_turned_off_Negativ 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(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(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(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(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(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(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(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(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(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( + 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(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( + 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(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(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(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(testing::HasSubstr( + "Bluetooth deinitialization error: BT_ERROR_AUTHORIZATION_REJECTED"))); + EXPECT_EQ(decryptedAdvert, CryptoBuffer{}); + EXPECT_EQ(bt->m_initialized, true); } namespace { @@ -531,10 +532,11 @@ TEST(UnpackDecryptedAdvert, validate_bluetooth_errors_Positive) } #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 diff --git a/tests/ctap_message_processor_tests.cpp b/tests/ctap_message_processor_tests.cpp index dcf0600..d680da2 100644 --- a/tests/ctap_message_processor_tests.cpp +++ b/tests/ctap_message_processor_tests.cpp @@ -466,132 +466,198 @@ TEST(CtapMessageProcessor, AndroidExampleGetAssertionWithUpdate_Positive) 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( + std::vector{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( - std::vector{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(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( + std::vector{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( - std::vector{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(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(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")); } @@ -724,10 +790,10 @@ private: } // 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(); cmp->SetEncryptedTunnel( std::make_unique(std::vector{ @@ -737,16 +803,14 @@ TEST(CtapMessageProcessor, return cmp; }; TestCancelFromTheOtherThread( - 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(); cmp->SetEncryptedTunnel( std::make_unique(std::vector{ @@ -757,17 +821,17 @@ TEST(CtapMessageProcessor, MakeCredential_with_update_message_cancel_from_the_ot return cmp; }; TestCancelFromTheOtherThread( - 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(); cmp->SetEncryptedTunnel( std::make_unique(std::vector{ @@ -777,16 +841,14 @@ TEST(CtapMessageProcessor, return cmp; }; TestCancelFromTheOtherThread( - 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(); cmp->SetEncryptedTunnel( std::make_unique(std::vector{ @@ -797,7 +859,7 @@ TEST(CtapMessageProcessor, GetAssertion_with_update_message_cancel_from_the_othe return cmp; }; TestCancelFromTheOtherThread( - 100, 30, makeCMP, [](ICtapMessageProcessor &cmp) { + 100, 30, makeCMP2, [](ICtapMessageProcessor &cmp) { WithDefaultGAArgs( [&](const auto &clientData, const auto &options) { cmp.GetAssertion(clientData, options); diff --git a/tests/derive_key_tests.cpp b/tests/derive_key_tests.cpp index 7acbfbe..ef1a315 100644 --- a/tests/derive_key_tests.cpp +++ b/tests/derive_key_tests.cpp @@ -55,11 +55,17 @@ TEST(DeriveKey, Simple_Positive) 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})); @@ -69,13 +75,3 @@ TEST(DeriveKey, empty_salt_Positive) 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{}); -} diff --git a/tests/handshake_tests.cpp b/tests/handshake_tests.cpp index 69e7040..12093ee 100644 --- a/tests/handshake_tests.cpp +++ b/tests/handshake_tests.cpp @@ -95,8 +95,9 @@ private: } // namespace -TEST(Handshake, QrInitiatedConnect_Positive) +TEST(Handshake, Connect_Positive) { + // QrInitiated connect { auto tunnel = std::make_unique( "wss://some.domain/cable/connect/" + @@ -114,10 +115,8 @@ TEST(Handshake, QrInitiatedConnect_Positive) handshake.QrInitiatedConnect( "a", reinterpret_cast("b"), reinterpret_cast("c")); } -} -TEST(Handshake, StateAssistedConnect_Positive) -{ + // StateAssisted connect { auto tunnel = std::make_unique( "wss://some.domain/cable/contact/" + @@ -291,18 +290,20 @@ private: } // namespace -TEST(Handshake, DoQrInitiatedHandshake_Positive) +TEST(Handshake, Handshake_Positive) { - auto test = QrInitiatedHandshakeTest(); - auto handshake = test.MakeHandshake(); - test.RunAndTestHandshake(handshake); -} - -TEST(Handshake, DoStateAssistedHandshake_Positive) -{ - auto test = StateAssistedHandshakeTest{}; - auto handshake = test.MakeHandshake(); - test.RunAndTestHandshake(handshake); + // QrInitiated handshake + { + auto test = QrInitiatedHandshakeTest(); + auto handshake = test.MakeHandshake(); + test.RunAndTestHandshake(handshake); + } + // StateAssisted handshake + { + auto test = StateAssistedHandshakeTest{}; + auto handshake = test.MakeHandshake(); + test.RunAndTestHandshake(handshake); + } } namespace { @@ -322,20 +323,28 @@ private: } // namespace -TEST(Handshake, qr_initiated_connect_Positive) -{ - auto makeHandshake = [&] { return Handshake{std::make_unique()}; }; - TestCancelFromTheOtherThread(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()}; }; - TestCancelFromTheOtherThread(100, 20, makeHandshake, [&](IHandshake &handshake) { - handshake.StateAssistedConnect({}, {}, {}); - }); + // QrInitiated connect + { + auto makeHandshake = [&] { + return Handshake{std::make_unique()}; + }; + TestCancelFromTheOtherThread( + 100, 20, makeHandshake, [&](IHandshake &handshake) { + handshake.QrInitiatedConnect({}, {}, {}); + }); + } + // StateAssisted connect + { + auto makeHandshake = [&] { + return Handshake{std::make_unique()}; + }; + TestCancelFromTheOtherThread( + 100, 20, makeHandshake, [&](IHandshake &handshake) { + handshake.StateAssistedConnect({}, {}, {}); + }); + } } namespace { @@ -370,20 +379,24 @@ private: } // namespace -TEST(Handshake, qr_initiated_handshake_cancel_from_the_other_thread_Positive) +TEST(Handshake, cancel_from_the_other_thread_Positive) { - auto test = QrInitiatedHandshakeTest{}; - auto makeHandshake = [&] { return test.MakeHandshake(); }; - TestCancelFromTheOtherThread(100, 20, makeHandshake, [&](IHandshake &handshake) { - test.RunAndTestHandshake(handshake); - }); -} - -TEST(Handshake, state_assisted_handshake_cancel_from_the_other_thread_Positive) -{ - auto test = StateAssistedHandshakeTest{}; - auto makeHandshake = [&] { return test.MakeHandshake(); }; - TestCancelFromTheOtherThread(100, 20, makeHandshake, [&](IHandshake &handshake) { - test.RunAndTestHandshake(handshake); - }); + // QrInitiated handshake + { + auto test = QrInitiatedHandshakeTest{}; + auto makeHandshake = [&] { return test.MakeHandshake(); }; + TestCancelFromTheOtherThread( + 100, 20, makeHandshake, [&](IHandshake &handshake) { + test.RunAndTestHandshake(handshake); + }); + } + // StateAssisted handshake + { + auto test = StateAssistedHandshakeTest{}; + auto makeHandshake = [&] { return test.MakeHandshake(); }; + TestCancelFromTheOtherThread( + 100, 20, makeHandshake, [&](IHandshake &handshake) { + test.RunAndTestHandshake(handshake); + }); + } } diff --git a/tests/message_tests.cpp b/tests/message_tests.cpp index d09b244..64e0120 100644 --- a/tests/message_tests.cpp +++ b/tests/message_tests.cpp @@ -250,73 +250,70 @@ wauthn_pubkey_cred_params_s PUBKEY_PARAMS{1, PUBKEY_PARAM}; } // 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{"FIDO_2_0", "FIDO_2_1"})); - EXPECT_EQ(msg.m_extensions, std::vector{"largeBlob"}); - EXPECT_EQ(ToBufferView(msg.m_aaguid), + EXPECT_EQ(msg1.m_versions, (std::vector{"FIDO_2_0", "FIDO_2_1"})); + EXPECT_EQ(msg1.m_extensions, std::vector{"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{}); - EXPECT_EQ(msg.m_maxCredentialCountInList, std::nullopt); - EXPECT_EQ(msg.m_maxCredentialIdLength, std::nullopt); - EXPECT_EQ(msg.m_transports, (std::vector{"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{})); - EXPECT_EQ(msg.m_remainingDiscoverableCredentials, std::nullopt); - EXPECT_EQ(msg.m_vendorPrototypeConfigCommands, std::vector{}); - EXPECT_EQ(msg.m_attestationFormats, std::vector{}); - 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{}); + EXPECT_EQ(msg1.m_maxCredentialCountInList, std::nullopt); + EXPECT_EQ(msg1.m_maxCredentialIdLength, std::nullopt); + EXPECT_EQ(msg1.m_transports, (std::vector{"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{})); + EXPECT_EQ(msg1.m_remainingDiscoverableCredentials, std::nullopt); + EXPECT_EQ(msg1.m_vendorPrototypeConfigCommands, std::vector{}); + EXPECT_EQ(msg1.m_attestationFormats, std::vector{}); + EXPECT_EQ(msg1.m_uvCountSinceLastPinEntry, std::nullopt); + EXPECT_EQ(msg1.m_longTouchForReset, std::nullopt); - EXPECT_EQ(msg.m_versions, (std::vector{"FIDO_2_0", "FIDO_2_1"})); - EXPECT_EQ(msg.m_extensions, std::vector{"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{}); - EXPECT_EQ(msg.m_maxCredentialCountInList, std::nullopt); - EXPECT_EQ(msg.m_maxCredentialIdLength, std::nullopt); - EXPECT_EQ(msg.m_transports, (std::vector{"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{})); - EXPECT_EQ(msg.m_remainingDiscoverableCredentials, std::nullopt); - EXPECT_EQ(msg.m_vendorPrototypeConfigCommands, std::vector{}); - EXPECT_EQ(msg.m_attestationFormats, std::vector{}); - 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{"FIDO_2_0", "FIDO_2_1"})); + EXPECT_EQ(msg2.m_extensions, std::vector{"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{}); + EXPECT_EQ(msg2.m_maxCredentialCountInList, std::nullopt); + EXPECT_EQ(msg2.m_maxCredentialIdLength, std::nullopt); + EXPECT_EQ(msg2.m_transports, (std::vector{"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{})); + EXPECT_EQ(msg2.m_remainingDiscoverableCredentials, std::nullopt); + EXPECT_EQ(msg2.m_vendorPrototypeConfigCommands, std::vector{}); + EXPECT_EQ(msg2.m_attestationFormats, std::vector{}); + EXPECT_EQ(msg2.m_uvCountSinceLastPinEntry, std::nullopt); + EXPECT_EQ(msg2.m_longTouchForReset, std::nullopt); } TEST(Messages, DomainName_Positive) @@ -343,28 +340,72 @@ 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) @@ -764,25 +805,65 @@ TEST(Messages, ParseUpdateMessage_Positive) 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); } diff --git a/tests/tunnel/common_tests.cpp b/tests/tunnel/common_tests.cpp index 7beb289..b0d367d 100644 --- a/tests/tunnel/common_tests.cpp +++ b/tests/tunnel/common_tests.cpp @@ -366,23 +366,49 @@ TYPED_TEST(TunnelTypedTests, NullHeaderBuffer_Negative) InvalidState); } -TYPED_TEST(TunnelTypedTests, WrongHeaders_Negative) +TYPED_TEST(TunnelTypedTests, ServerIgnoresHeaders1_Negative) { Tunnel tunnel(std::make_shared()); // 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()); + + // 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()); // 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()); + + // 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()); + + // Test with a server which expects specific headers EXPECT_THROW(tunnel.Connect(HeadersTestUrl()), InvalidState); } diff --git a/tests/tunnel_server_domain_tests.cpp b/tests/tunnel_server_domain_tests.cpp index f6c3924..efd62ea 100644 --- a/tests/tunnel_server_domain_tests.cpp +++ b/tests/tunnel_server_domain_tests.cpp @@ -20,20 +20,17 @@ #include #include -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"); -- 2.34.1