From eaf946b89db949da3853cd3795562e4e39fa6c39 Mon Sep 17 00:00:00 2001 From: Yonggoo Kang Date: Tue, 16 Apr 2024 01:21:04 +0900 Subject: [PATCH] Update the callback logic for handle the wauthn_cb_update_linked_data - Add wauthn_cb_update_linked_data related logic and unittests - Fix bug on the __checkValidity() about valid range - Move UnsetBusy() into the Response Callback - Minor fix about naming - Ready for manual test with the added callback Change-Id: I31794d5e6c9036f142ae8aaf0b58552e59c98546 --- srcs/client/client-request.h | 100 +++++++------ srcs/client/client.cpp | 7 +- srcs/common/serialization.cpp | 2 +- srcs/common/utils.cpp | 6 +- srcs/server/request-ga.h | 1 + srcs/server/request-mc.h | 1 + srcs/server/request.h | 15 ++ srcs/server/service.cpp | 4 +- srcs/server/service.h | 10 +- tests/client-request-test.cpp | 318 ++++++++++++++++++++++++++++++++++++----- tests/manual/man_tests.cpp | 36 ++++- tests/serialization-test.cpp | 13 +- tests/test-common.cpp | 4 +- tests/test-common.h | 58 +++++--- tests/webauthn-client-test.cpp | 32 ++++- 15 files changed, 484 insertions(+), 123 deletions(-) diff --git a/srcs/client/client-request.h b/srcs/client/client-request.h index c7f1057..e02fe4a 100644 --- a/srcs/client/client-request.h +++ b/srcs/client/client-request.h @@ -46,19 +46,24 @@ public: { } - int getStatus() const + int GetStatus() const { return m_status; } - bool failed() const + bool Failed() const { - return m_status != WAUTHN_ERROR_NONE; + return m_status < WAUTHN_ERROR_NONE; } - GenericClientRequest &send() + bool Incompleted() const { - if (failed()) + return m_status == WAUTHN_ERROR_NONE_AND_WAIT; + } + + GenericClientRequest &Send() + { + if (Failed()) { m_status = WAUTHN_ERROR_INVALID_STATE; return *this; @@ -71,25 +76,25 @@ public: } m_sent = true; m_status = m_conn->send(m_buffer); - if (failed()) + if (Failed()) LogError("Error in send. Error code: " << m_status); return *this; } - template GenericClientRequest &send(const T&... args) + template GenericClientRequest &Send(const T&... args) { - if (failed()) + if (Failed()) { m_status = WAUTHN_ERROR_INVALID_STATE; return *this; } Serialization::Serialize(m_buffer, args...); - return send(); + return Send(); } - GenericClientRequest &recv() + GenericClientRequest &Recv() { - if (failed()) + if (Failed()) { m_status = WAUTHN_ERROR_INVALID_STATE; return *this; @@ -101,37 +106,37 @@ public: return *this; } m_status = m_conn->recv(m_buffer); - if (failed()) + if (Failed()) LogError("Error in recv: " << wauthn_error_to_string(m_status)); else Deserialization::Deserialize(m_buffer, m_status); return *this; } - template GenericClientRequest &recv(T&... args) + template GenericClientRequest &Recv(T&... args) { - if (failed()) + if (Failed()) { m_status = WAUTHN_ERROR_INVALID_STATE; return *this; } - recv(); - if (failed()) + Recv(); + if (Failed()) LogError("Error in recv: " << wauthn_error_to_string(m_status)); else Deserialization::Deserialize(m_buffer, args...); return *this; } - template GenericClientRequest &recv(T&&... args) + template GenericClientRequest &Recv(T&&... args) { - if (failed()) + if (Failed()) { m_status = WAUTHN_ERROR_INVALID_STATE; return *this; } - recv(); - if (failed()) + Recv(); + if (Failed()) { LogError("Error in recv: " << wauthn_error_to_string(m_status)); } @@ -139,29 +144,29 @@ public: return *this; } - template GenericClientRequest &sendRequest(const T&... args) + template GenericClientRequest &SendRequest(const T&... args) { - if (failed()) + if (Failed()) { m_status = WAUTHN_ERROR_INVALID_STATE; return *this; } Serialization::Serialize(m_buffer, args...); - if (send().failed()) + if (Send().Failed()) return *this; - return recv(); + return Recv(); } - GenericClientRequest &sendRequest() + GenericClientRequest &SendRequest() { - if (failed()) + if (Failed()) { m_status = WAUTHN_ERROR_INVALID_STATE; return *this; } - if (send().failed()) + if (Send().Failed()) return *this; - return recv(); + return Recv(); } virtual int Init() = 0; @@ -218,24 +223,39 @@ template void cb_worker(std::shared_ptr request, A &callbacks, B cred) { int ret = try_catch([&]() -> int { - if (callbacks == nullptr || callbacks->response_callback == nullptr){ - LogError("Invalid callback parameter"); - return WAUTHN_ERROR_INVALID_PARAMETER; - } if (callbacks->qrcode_callback == nullptr) LogDebug("There is no qrcode_callback"); else{ //callbacks->qrcode_callback != nullptr std::string qr_code; - if (request->recv(qr_code).failed()) + if (request->Recv(qr_code).Failed()) LogError("Error on receive qrcode"); LogDebug("Received qr_contents: " << qr_code); callbacks->qrcode_callback(qr_code.c_str(), callbacks->user_data); } - if(request->recv(&cred).failed()) - LogError("Error on receive response"); + request->Recv(&cred); + callbacks->response_callback(cred, wauthn_error_e(request->GetStatus()), + callbacks->user_data); + if(request->Failed()) + { + LogError("Error on receive response: " << request->GetStatus()); + return WAUTHN_ERROR_INVALID_STATE; + } + + wauthn_hybrid_linked_data_s *linked_data = nullptr; + + while (request->Recv(&linked_data).Incompleted()) + { + callbacks->linked_data_callback(linked_data, wauthn_error_e(request->GetStatus()), + callbacks->user_data); + LogDebug("More update linked_data can be received. Waiting to recv()"); + } + LogDebug("There is no more updated linked_data"); + callbacks->linked_data_callback(linked_data, wauthn_error_e(request->GetStatus()), + callbacks->user_data); return WAUTHN_ERROR_NONE; }); - callbacks->response_callback(cred, wauthn_error_e(ret), callbacks->user_data); + if (ret != WAUTHN_ERROR_NONE) + LogError("Error on handling callbacks"); } template @@ -255,11 +275,11 @@ int wauthn_process(const wauthn_client_data_s *client_data, if (ret != WAUTHN_ERROR_NONE) return ret; - if (request->sendRequest(client_data, options).failed()) - return request->getStatus(); - LogDebug("Response: " << wauthn_error_to_string(request->getStatus())); + if (request->SendRequest(client_data, options).Failed()) + return request->GetStatus(); + LogDebug("Response: " << wauthn_error_to_string(request->GetStatus())); - typename T::PubKeyCred *cred = NULL; + typename T::PubKeyCred *cred = nullptr; std::thread worker([request, callbacks, cred]{cb_worker(std::move(request), callbacks, cred);}); worker.detach(); return WAUTHN_ERROR_NONE; diff --git a/srcs/client/client.cpp b/srcs/client/client.cpp index 671ff37..4061824 100644 --- a/srcs/client/client.cpp +++ b/srcs/client/client.cpp @@ -44,8 +44,9 @@ int wauthn_cancel() return try_catch([&]() -> int { ClientRequest request(WebAuthnCall::CANCEL); request.Init(); - if (request.sendRequest().failed()) - LogError("Error on cancel request, Response: " << wauthn_error_to_string(request.getStatus())); - return request.getStatus(); + if (request.SendRequest().Failed()) + LogError("Error on cancel request, Response: " + << wauthn_error_to_string(request.GetStatus())); + return request.GetStatus(); }); } diff --git a/srcs/common/serialization.cpp b/srcs/common/serialization.cpp index 32ec092..2f44dcf 100644 --- a/srcs/common/serialization.cpp +++ b/srcs/common/serialization.cpp @@ -106,7 +106,7 @@ void WAuthnCtypeSerializer::deserialize(IStream& stream, const char** data) { // For wauthn_error_e void __checkValidity(const wauthn_error_e data) { - if (data > WAUTHN_ERROR_NONE || data < WAUTHN_ERROR_CANCELLED) + if (data > WAUTHN_ERROR_NONE_AND_WAIT || data < WAUTHN_ERROR_TIMEOUT) ThrowMsg(SerializationException::InvalidStreamData, "Invalid value for wauthn_error_e: value=" << data); } diff --git a/srcs/common/utils.cpp b/srcs/common/utils.cpp index 80b783b..712bec7 100644 --- a/srcs/common/utils.cpp +++ b/srcs/common/utils.cpp @@ -43,12 +43,14 @@ void checkParameters(const wauthn_pubkey_cred_request_options_s *options) } void checkParameters(wauthn_mc_callbacks_s *callbacks) { - if (callbacks == nullptr || callbacks->response_callback == nullptr) + if (callbacks == nullptr || callbacks->response_callback == nullptr + || callbacks->linked_data_callback == nullptr) ThrowMsg(ClientException::InvalidParameter, "Invalid callback"); } void checkParameters(wauthn_ga_callbacks_s *callbacks) { - if (callbacks == nullptr || callbacks->response_callback == nullptr) + if (callbacks == nullptr || callbacks->response_callback == nullptr + || callbacks->linked_data_callback == nullptr) ThrowMsg(ClientException::InvalidParameter, "Invalid callback"); } void checkParameters(wauthn_hybrid_linked_data_s *linked_device, diff --git a/srcs/server/request-ga.h b/srcs/server/request-ga.h index 78a700b..fdecb2c 100644 --- a/srcs/server/request-ga.h +++ b/srcs/server/request-ga.h @@ -40,6 +40,7 @@ public: MessageBuffer buffer(userData->service->GetSocketManager()->newMessage()); Serialization::Serialize(buffer, result, pubkey_cred); userData->service->GetSocketManager()->Write(userData->connectionID, std::move(buffer)); + userData->service->UnsetBusy(); } else { diff --git a/srcs/server/request-mc.h b/srcs/server/request-mc.h index 7af5fb7..d925c04 100644 --- a/srcs/server/request-mc.h +++ b/srcs/server/request-mc.h @@ -40,6 +40,7 @@ public: MessageBuffer buffer(userData->service->GetSocketManager()->newMessage()); Serialization::Serialize(buffer, result, pubkey_cred); userData->service->GetSocketManager()->Write(userData->connectionID, std::move(buffer)); + userData->service->UnsetBusy(); } else { diff --git a/srcs/server/request.h b/srcs/server/request.h index b67eff5..ce06924 100644 --- a/srcs/server/request.h +++ b/srcs/server/request.h @@ -33,6 +33,21 @@ public: LogError("Cannot write qr_contents to client"); } + static void UpdateLinkedDataCallback(const wauthn_hybrid_linked_data_s *linked_data, + wauthn_error_e result, + void *user_data) + { + user_data_s *userData = GetUserData(user_data); + if (userData != nullptr) + { + MessageBuffer buffer(userData->service->GetSocketManager()->newMessage()); + Serialization::Serialize(buffer, result, linked_data); + userData->service->GetSocketManager()->Write(userData->connectionID, std::move(buffer)); + } + else + LogError("Cannot write updated linked_data to client"); + } + protected: static user_data_s *GetUserData(void *user_data) { diff --git a/srcs/server/service.cpp b/srcs/server/service.cpp index e4ec284..9fc3999 100644 --- a/srcs/server/service.cpp +++ b/srcs/server/service.cpp @@ -83,7 +83,8 @@ void GenericService::Worker(SocketManager::ConnectionID connectionID, typename T::Callbacks callbacks; callbacks.qrcode_callback = &(Request::QRCallback); callbacks.response_callback = &(T::ResponseCallback); - //checkParameters(clientData, options, &callbacks); + callbacks.linked_data_callback = &(Request::UpdateLinkedDataCallback); + if (options->linked_device != nullptr) // The qrcode_callback should not be called. { LogDebug("Adjust qrcode_callback to nullptr"); @@ -108,7 +109,6 @@ void GenericService::Worker(SocketManager::ConnectionID connectionID, }); if (ret != WAUTHN_ERROR_NONE) LogError("Unhandled Error: " << wauthn_error_to_string(ret)); - UnsetBusy(); } template diff --git a/srcs/server/service.h b/srcs/server/service.h index 3f49e37..e5aba54 100644 --- a/srcs/server/service.h +++ b/srcs/server/service.h @@ -69,6 +69,11 @@ public: */ SocketManager *GetSocketManager(); + /** + * Unset to server is not busy + */ + void UnsetBusy(); + virtual SocketManager::ServiceDescription GetServiceDescription() = 0; private: @@ -117,11 +122,6 @@ private: */ int GetCredentials(SocketManager::ConnectionID connectionID, Cred *creds); - /** - * Unset to server is not busy - */ - void UnsetBusy(); - bool PluginEnabled(); int HandleNotSupported(Event &&msg); diff --git a/tests/client-request-test.cpp b/tests/client-request-test.cpp index 1a2a526..d2b6333 100644 --- a/tests/client-request-test.cpp +++ b/tests/client-request-test.cpp @@ -90,6 +90,22 @@ void wah_make_credential(const wauthn_client_data_s *client_data, sleep(1); if (callbacks != nullptr && callbacks->response_callback != nullptr) callbacks->response_callback(nullptr, WAUTHN_ERROR_NONE, callbacks->user_data); + + if (callbacks != nullptr && callbacks->linked_data_callback != nullptr) + { + int callTimes = g_target_times_update_linked_data; + std::cout << "Calling linked_data_callback for " << callTimes << " times.." << + std::endl; + while (callTimes > 1) + { + sleep(1); + callbacks->linked_data_callback(nullptr, WAUTHN_ERROR_NONE_AND_WAIT, + callbacks->user_data); + callTimes -= 1; + } + sleep(1); + callbacks->linked_data_callback(nullptr, WAUTHN_ERROR_NONE, callbacks->user_data); + } } void wah_get_assertion(const wauthn_client_data_s *client_data, @@ -105,6 +121,22 @@ void wah_get_assertion(const wauthn_client_data_s *client_data, sleep(1); if (callbacks != nullptr && callbacks->response_callback != nullptr) callbacks->response_callback(nullptr, WAUTHN_ERROR_NONE, callbacks->user_data); + + if (callbacks != nullptr && callbacks->linked_data_callback != nullptr) + { + int callTimes = g_target_times_update_linked_data; + std::cout << "Calling linked_data_callback for " << callTimes << " times.." << + std::endl; + while (callTimes > 1) + { + sleep(1); + callbacks->linked_data_callback(nullptr, WAUTHN_ERROR_NONE_AND_WAIT, + callbacks->user_data); + callTimes -= 1; + } + sleep(1); + callbacks->linked_data_callback(nullptr, WAUTHN_ERROR_NONE, callbacks->user_data); + } } int wah_cancel() @@ -220,9 +252,9 @@ TEST_F(ClientRequestTest, send_failed_N) try{ TestInvalidClientRequest invalidRequest(WebAuthnCall::MAKE_CREDENTIAL); EXPECT_EQ(invalidRequest.Init(), WAUTHN_ERROR_SOCKET); - EXPECT_EQ(invalidRequest.getStatus(), WAUTHN_ERROR_SOCKET); - invalidRequest.send(); - EXPECT_EQ(invalidRequest.getStatus(), WAUTHN_ERROR_INVALID_STATE); + EXPECT_EQ(invalidRequest.GetStatus(), WAUTHN_ERROR_SOCKET); + invalidRequest.Send(); + EXPECT_EQ(invalidRequest.GetStatus(), WAUTHN_ERROR_INVALID_STATE); } catch (...) { ret = -1; } @@ -243,17 +275,30 @@ TEST_F(ClientRequestTest, request_to_not_supported_server_N) callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s)); callbacks->qrcode_callback = test_cb_display_qrcode; callbacks->response_callback = test_cb_mc_response; + callbacks->linked_data_callback = test_cb_update_linked_data; test_user_data_s *userdata = (test_user_data_s*) calloc(1, sizeof(test_user_data_s)); userdata->test_data = (char*)("user data"); userdata->test_int = 999; + userdata->called_qr = false; + userdata->called_response = false; + g_target_times_update_linked_data = 1; + userdata->times_update_linked_data = 0; callbacks->user_data = userdata; retVal = wauthn_process(&TestCommonData::clientData, &TestCommonData::pubkeyCredCreationOptions, callbacks); EXPECT_EQ(retVal, WAUTHN_ERROR_NOT_SUPPORTED) - << "[wauthn_process] failed. " - << "retVal=" << wauthn_error_to_string(ret) << std::endl; + << "[wauthn_process] failed. " + << "retVal=" << wauthn_error_to_string(ret) << std::endl; sleep(1); + EXPECT_EQ(userdata->called_qr, false) + << "The QR callback should not be called by cancel" << std::endl; + EXPECT_EQ(userdata->called_response, false) + << "The response callback should not be called by cancel" << std::endl; + EXPECT_EQ(0, userdata->times_update_linked_data) + << "The update_linked_data callback should not be called by cancel" + << std::endl; + free(userdata); free(callbacks); } @@ -266,7 +311,7 @@ TEST_F(ClientRequestTest, request_to_not_supported_server_N) EXPECT_EQ(ret, 0); } -TEST_F(ClientRequestTest, MC_without_QR_callback_P) +TEST_F(ClientRequestTest, MC_with_LD_and_not_call_QR_callback_P) { int ret = 1; WA::SocketManager manager; @@ -280,21 +325,35 @@ TEST_F(ClientRequestTest, MC_without_QR_callback_P) callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s)); callbacks->qrcode_callback = test_cb_display_qrcode; callbacks->response_callback = test_cb_mc_response; + callbacks->linked_data_callback = test_cb_update_linked_data; test_user_data_s *userdata = (test_user_data_s*) calloc(1, sizeof(test_user_data_s)); userdata->test_data = (char*)("user data"); userdata->test_int = 999; + userdata->called_qr = false; + userdata->called_response = false; + g_target_times_update_linked_data = 1; + userdata->times_update_linked_data = 0; callbacks->user_data = userdata; retVal = wauthn_process(&TestCommonData::clientData, &TestCommonData::pubkeyCredCreationOptions, callbacks); EXPECT_EQ(retVal, WAUTHN_ERROR_NONE) - << "[wauthn_process] failed. " - << "retVal=" << wauthn_error_to_string(ret) << std::endl; - sleep(5); + << "[wauthn_process] failed. " + << "retVal=" << wauthn_error_to_string(ret) << std::endl; + + // Waiting for called the callbacks + sleep(g_target_times_update_linked_data + 5); + EXPECT_EQ(userdata->called_qr, false) + << "The QR callback should not be called" << std::endl; + EXPECT_EQ(userdata->called_response, true) + << "The response callback should be called" << std::endl; + EXPECT_EQ(g_target_times_update_linked_data, + userdata->times_update_linked_data) + << "The update_linked_data callback should be called for setted times" + << std::endl; free(userdata); free(callbacks); } - sleep(1); ret = 0; } catch (...) { std::cout << "Error in starting service, unknown exception occurred" << std::endl; @@ -303,7 +362,7 @@ TEST_F(ClientRequestTest, MC_without_QR_callback_P) EXPECT_EQ(ret, 0); } -TEST_F(ClientRequestTest, MC_with_QR_callback_P) +TEST_F(ClientRequestTest, MC_without_LD_and_call_QR_callback_P) { int ret = 1; WA::SocketManager manager; @@ -317,17 +376,33 @@ TEST_F(ClientRequestTest, MC_with_QR_callback_P) callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s)); callbacks->qrcode_callback = test_cb_display_qrcode; callbacks->response_callback = test_cb_mc_response; + callbacks->linked_data_callback = test_cb_update_linked_data; test_user_data_s *userdata = (test_user_data_s*) calloc(1, sizeof(test_user_data_s)); userdata->test_data = (char*)("user data"); userdata->test_int = 999; + userdata->called_qr = false; + userdata->called_response = false; + g_target_times_update_linked_data = 1; + userdata->times_update_linked_data = 0; callbacks->user_data = userdata; retVal = wauthn_process(&TestCommonData::clientData, - &TestCommonData::pubkeyCredCreationOptionsWithQR, callbacks); + &TestCommonData::pubkeyCredCreationOptionsNoLD, callbacks); EXPECT_EQ(retVal, WAUTHN_ERROR_NONE) - << "[wauthn_process] failed. " - << "retVal=" << wauthn_error_to_string(ret) << std::endl; - sleep(5); + << "[wauthn_process] failed. " + << "retVal=" << wauthn_error_to_string(ret) << std::endl; + + // Waiting for called the callbacks + sleep(g_target_times_update_linked_data + 5); + EXPECT_EQ(userdata->called_qr, true) + << "The QR callback should be called" << std::endl; + EXPECT_EQ(userdata->called_response, true) + << "The response callback should be called" << std::endl; + EXPECT_EQ(g_target_times_update_linked_data, + userdata->times_update_linked_data) + << "The update_linked_data callback should be called for setted times" + << std::endl; + free(userdata); free(callbacks); } @@ -341,7 +416,7 @@ TEST_F(ClientRequestTest, MC_with_QR_callback_P) } -TEST_F(ClientRequestTest, GA_without_QR_callback_P) +TEST_F(ClientRequestTest, GA_with_LD_and_not_call_QR_callback_P) { int ret = 1; WA::SocketManager manager; @@ -355,17 +430,33 @@ TEST_F(ClientRequestTest, GA_without_QR_callback_P) callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s)); callbacks->qrcode_callback = test_cb_display_qrcode; callbacks->response_callback = test_cb_ga_response; + callbacks->linked_data_callback = test_cb_update_linked_data; test_user_data_s *userdata = (test_user_data_s*) calloc(1, sizeof(test_user_data_s)); userdata->test_data = (char*)("user data"); userdata->test_int = 999; + userdata->called_qr = false; + userdata->called_response = false; + g_target_times_update_linked_data = 1; + userdata->times_update_linked_data = 0; callbacks->user_data = userdata; retVal = wauthn_process(&TestCommonData::clientData, &TestCommonData::pubkeyCredRequestOptions, callbacks); EXPECT_EQ(retVal, WAUTHN_ERROR_NONE) - << "[wauthn_process] failed. " - << "retVal=" << wauthn_error_to_string(ret) << std::endl; - sleep(5); + << "[wauthn_process] failed. " + << "retVal=" << wauthn_error_to_string(ret) << std::endl; + + // Waiting for called the callbacks + sleep(g_target_times_update_linked_data + 5); + EXPECT_EQ(userdata->called_qr, false) + << "The QR callback should not be called" << std::endl; + EXPECT_EQ(userdata->called_response, true) + << "The response callback should be called" << std::endl; + EXPECT_EQ(g_target_times_update_linked_data, + userdata->times_update_linked_data) + << "The update_linked_data callback should be called for setted times" + << std::endl; + free(userdata); free(callbacks); } @@ -378,7 +469,7 @@ TEST_F(ClientRequestTest, GA_without_QR_callback_P) EXPECT_EQ(ret, 0); } -TEST_F(ClientRequestTest, GA_with_QR_callback_P) +TEST_F(ClientRequestTest, GA_without_LD_and_call_QR_callback_P) { int ret = 1; WA::SocketManager manager; @@ -392,17 +483,33 @@ TEST_F(ClientRequestTest, GA_with_QR_callback_P) callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s)); callbacks->qrcode_callback = test_cb_display_qrcode; callbacks->response_callback = test_cb_ga_response; + callbacks->linked_data_callback = test_cb_update_linked_data; test_user_data_s *userdata = (test_user_data_s*) calloc(1, sizeof(test_user_data_s)); userdata->test_data = (char*)("user data"); userdata->test_int = 999; + userdata->called_qr = false; + userdata->called_response = false; + g_target_times_update_linked_data = 1; + userdata->times_update_linked_data = 0; callbacks->user_data = userdata; retVal = wauthn_process(&TestCommonData::clientData, - &TestCommonData::pubkeyCredRequestOptionsWithQR, callbacks); + &TestCommonData::pubkeyCredRequestOptionsNoLD, callbacks); EXPECT_EQ(retVal, WAUTHN_ERROR_NONE) - << "[wauthn_process] failed. " - << "retVal=" << wauthn_error_to_string(ret) << std::endl; - sleep(5); + << "[wauthn_process] failed. " + << "retVal=" << wauthn_error_to_string(ret) << std::endl; + + // Waiting for called the callbacks + sleep(g_target_times_update_linked_data + 5); + EXPECT_EQ(userdata->called_qr, true) + << "The QR callback should be called" << std::endl; + EXPECT_EQ(userdata->called_response, true) + << "The response callback should be called" << std::endl; + EXPECT_EQ(g_target_times_update_linked_data, + userdata->times_update_linked_data) + << "The update_linked_data callback should be called for setted times" + << std::endl; + free(userdata); free(callbacks); } @@ -429,12 +536,17 @@ TEST_F(ClientRequestTest, not_allowed_N) mc_callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s)); mc_callbacks->qrcode_callback = test_cb_display_qrcode; mc_callbacks->response_callback = test_cb_mc_response; + mc_callbacks->linked_data_callback = test_cb_update_linked_data; test_user_data_s *mc_userdata = (test_user_data_s*) calloc(1, sizeof(test_user_data_s)); mc_userdata->test_data = (char*)("user data"); mc_userdata->test_int = 999; + mc_userdata->called_qr = false; + mc_userdata->called_response = false; + g_target_times_update_linked_data = 1; + mc_userdata->times_update_linked_data = 0; mc_callbacks->user_data = mc_userdata; retVal = wauthn_process(&TestCommonData::clientData, - &TestCommonData::pubkeyCredCreationOptions, mc_callbacks); + &TestCommonData::pubkeyCredCreationOptionsNoLD, mc_callbacks); EXPECT_EQ(retVal, WAUTHN_ERROR_NONE) << "[wauthn_process] failed. " @@ -446,9 +558,13 @@ TEST_F(ClientRequestTest, not_allowed_N) ga_callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s)); ga_callbacks->qrcode_callback = test_cb_display_qrcode; ga_callbacks->response_callback = test_cb_ga_response; + ga_callbacks->linked_data_callback = test_cb_update_linked_data; test_user_data_s *ga_userdata = (test_user_data_s*) calloc(1, sizeof(test_user_data_s)); ga_userdata->test_data = (char*)("user data"); ga_userdata->test_int = 999; + ga_userdata->called_qr = false; + ga_userdata->called_response = false; + ga_userdata->times_update_linked_data = 0; ga_callbacks->user_data = ga_userdata; retVal = wauthn_process(&TestCommonData::clientData, &TestCommonData::pubkeyCredRequestOptions, ga_callbacks); @@ -457,7 +573,25 @@ TEST_F(ClientRequestTest, not_allowed_N) << "[wauthn_process] failed. " << "ret=" << wauthn_error_to_string(retVal) << std::endl; - sleep(5); + // Waiting for called the callbacks + sleep(g_target_times_update_linked_data + 5); + EXPECT_EQ(mc_userdata->called_qr, true) + << "The QR callback for MC should be called" << std::endl; + EXPECT_EQ(mc_userdata->called_response, true) + << "The response callback for MC should be called" << std::endl; + EXPECT_EQ(g_target_times_update_linked_data, + mc_userdata->times_update_linked_data) + << "The update_linked_data callback for MC should be called for setted times" + << std::endl; + + EXPECT_EQ(ga_userdata->called_qr, false) + << "The QR callback for GA should not be called by not allowed" << std::endl; + EXPECT_EQ(ga_userdata->called_response, false) + << "The response callback for GA should not be called by not allowed" << std::endl; + EXPECT_EQ(0, ga_userdata->times_update_linked_data) + << "The update_linked_data callback for GA should not be called by not allowed" + << std::endl; + free(mc_userdata); free(ga_userdata); free(mc_callbacks); @@ -472,7 +606,6 @@ TEST_F(ClientRequestTest, not_allowed_N) EXPECT_EQ(ret, 0); } - TEST_F(ClientRequestTest, cancel_P) { int ret = 1; @@ -487,9 +620,14 @@ TEST_F(ClientRequestTest, cancel_P) mc_callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s)); mc_callbacks->qrcode_callback = test_cb_display_qrcode; mc_callbacks->response_callback = test_cb_mc_response; + mc_callbacks->linked_data_callback = test_cb_update_linked_data; test_user_data_s *mc_userdata = (test_user_data_s*) calloc(1, sizeof(test_user_data_s)); mc_userdata->test_data = (char*)("user data"); mc_userdata->test_int = 999; + mc_userdata->called_qr = false; + mc_userdata->called_response = false; + g_target_times_update_linked_data = 1; + mc_userdata->times_update_linked_data = 0; mc_callbacks->user_data = mc_userdata; retVal = wauthn_process(&TestCommonData::clientData, &TestCommonData::pubkeyCredCreationOptions, mc_callbacks); @@ -498,18 +636,80 @@ TEST_F(ClientRequestTest, cancel_P) << "[wauthn_process] failed. " << "retVal=" << wauthn_error_to_string(ret) << std::endl; - sleep(1); TestClientRequest request(WebAuthnCall::CANCEL); request.Init(); - if (request.sendRequest().failed()) + if (request.SendRequest().Failed()) LogError("Error on cancel request, Response: " - << wauthn_error_to_string(request.getStatus())); - retVal = request.getStatus(); + << wauthn_error_to_string(request.GetStatus())); + retVal = request.GetStatus(); EXPECT_EQ(retVal, WAUTHN_ERROR_NONE) << "[wauthn_cancel] failed. " << "ret=" << wauthn_error_to_string(retVal) << std::endl; - sleep(5); + + EXPECT_EQ(mc_userdata->called_qr, false) + << "The QR callback should not be called by cancel" << std::endl; + EXPECT_EQ(mc_userdata->called_response, false) + << "The response callback should not be called by cancel" << std::endl; + EXPECT_EQ(0, mc_userdata->times_update_linked_data) + << "The update_linked_data callback should not be called by cancel" + << std::endl; + + // Waiting for called the callbacks + sleep(g_target_times_update_linked_data + 5); + free(mc_userdata); + free(mc_callbacks); + } + ret = 0; + } catch (...) { + std::cout << "Error in starting service, unknown exception occurred" << std::endl; + ret = -1; + } + EXPECT_EQ(ret, 0); +} + +TEST_F(ClientRequestTest, MC_multiple_update_linked_data_P) +{ + int ret = 1; + WA::SocketManager manager; + try{ + auto service = std::make_unique(std::make_shared()); + manager.RegisterSocketService(std::move(service)); + SocketManagerLoop loop(manager); + { + int retVal = WAUTHN_ERROR_NONE; + wauthn_mc_callbacks_s *mc_callbacks = nullptr; + mc_callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s)); + mc_callbacks->qrcode_callback = test_cb_display_qrcode; + mc_callbacks->response_callback = test_cb_mc_response; + mc_callbacks->linked_data_callback = test_cb_update_linked_data; + test_user_data_s *mc_userdata = (test_user_data_s*) calloc(1, sizeof(test_user_data_s)); + mc_userdata->test_data = (char*)("user data"); + mc_userdata->test_int = 999; + mc_userdata->called_qr = false; + mc_userdata->called_response = false; + g_target_times_update_linked_data = 5; + mc_userdata->times_update_linked_data = 0; + mc_callbacks->user_data = mc_userdata; + retVal = wauthn_process(&TestCommonData::clientData, + &TestCommonData::pubkeyCredCreationOptionsNoLD, mc_callbacks); + + EXPECT_EQ(retVal, WAUTHN_ERROR_NONE) + << "[wauthn_process] failed. " + << "retVal=" << wauthn_error_to_string(ret) << std::endl; + + // Waiting for called the callbacks + sleep(g_target_times_update_linked_data + 5); + + EXPECT_EQ(mc_userdata->called_qr, true) + << "The QR callback should be called" << std::endl; + EXPECT_EQ(mc_userdata->called_response, true) + << "The response callback should be called" << std::endl; + EXPECT_EQ(g_target_times_update_linked_data, + mc_userdata->times_update_linked_data) + << "The update_linked_data callback should be called for setted times" + << std::endl; + free(mc_userdata); free(mc_callbacks); } @@ -522,4 +722,58 @@ TEST_F(ClientRequestTest, cancel_P) EXPECT_EQ(ret, 0); } +TEST_F(ClientRequestTest, GA_multiple_update_linked_data_P) +{ + int ret = 1; + WA::SocketManager manager; + try{ + auto service = std::make_unique(std::make_shared()); + manager.RegisterSocketService(std::move(service)); + SocketManagerLoop loop(manager); + { + int retVal = WAUTHN_ERROR_NONE; + wauthn_ga_callbacks_s *ga_callbacks = nullptr; + ga_callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s)); + ga_callbacks->qrcode_callback = test_cb_display_qrcode; + ga_callbacks->response_callback = test_cb_ga_response; + ga_callbacks->linked_data_callback = test_cb_update_linked_data; + test_user_data_s *ga_userdata = (test_user_data_s*) calloc(1, sizeof(test_user_data_s)); + ga_userdata->test_data = (char*)("user data"); + ga_userdata->test_int = 999; + ga_userdata->called_qr = false; + ga_userdata->called_response = false; + g_target_times_update_linked_data = 5; + ga_userdata->times_update_linked_data = 0; + ga_callbacks->user_data = ga_userdata; + retVal = wauthn_process(&TestCommonData::clientData, + &TestCommonData::pubkeyCredRequestOptionsNoLD, ga_callbacks); + + EXPECT_EQ(retVal, WAUTHN_ERROR_NONE) + << "[wauthn_process] failed. " + << "retVal=" << wauthn_error_to_string(ret) << std::endl; + + // Waiting for called the callbacks + sleep(g_target_times_update_linked_data + 5); + + EXPECT_EQ(ga_userdata->called_qr, true) + << "The QR callback should be called" << std::endl; + EXPECT_EQ(ga_userdata->called_response, true) + << "The response callback should be called" << std::endl; + EXPECT_EQ(g_target_times_update_linked_data, + ga_userdata->times_update_linked_data) + << "The update_linked_data callback should be called for setted times" + << std::endl; + + free(ga_userdata); + free(ga_callbacks); + } + sleep(1); + ret = 0; + } catch (...) { + std::cout << "Error in starting service, unknown exception occurred" << std::endl; + ret = -1; + } + EXPECT_EQ(ret, 0); +} + } // namespace WebAuthn diff --git a/tests/manual/man_tests.cpp b/tests/manual/man_tests.cpp index d1d4cb6..94cb51f 100644 --- a/tests/manual/man_tests.cpp +++ b/tests/manual/man_tests.cpp @@ -114,11 +114,14 @@ void DisplayQRCallback(const char *qr_contents, void *data) auto testContents = static_cast(data); if (testContents->path.empty() || !qr_contents) { std::cout << "qrcode_callback failed" << std::endl; - std::cout << "QRcode path: " << testContents->path << std::endl; - std::cout << "qr_contents: " << qr_contents << std::endl; testContents->status = false; return; } + else + { + std::cout << "QRcode path: " << testContents->path << std::endl; + std::cout << "qr_contents: " << qr_contents << std::endl; + } if (testContents->negative) GenerateAndDisplayQR("https://tinyurl.com/5x2bcwjy", *testContents); else @@ -177,7 +180,13 @@ void GACallback(const wauthn_pubkey_credential_assertion_s *pubkey_cred, } testContents->status = 2; } - +/* TBD +void UpdateLinkedDataCallback(const wauthn_hybrid_linked_data_s *linked_data, + wauthn_error_e result, + void *user_data) +{ +} +*/ bool Test(struct TestContents &testContents) { /* MakeCredential */ @@ -227,6 +236,7 @@ bool Test(struct TestContents &testContents) wauthn_mc_callbacks_s mcCallbacks; mcCallbacks.qrcode_callback = DisplayQRCallback; mcCallbacks.response_callback = MCCallback; + // TODO: Add UpdateLinkedDataCallback with the webauthn-ble's update mcCallbacks.user_data = &testContents; int ret = wauthn_make_credential(&clientData, &mcOptions, &mcCallbacks); @@ -275,6 +285,7 @@ bool Test(struct TestContents &testContents) wauthn_ga_callbacks_s gaCallbacks; gaCallbacks.qrcode_callback = DisplayQRCallback; gaCallbacks.response_callback = GACallback; + // TODO: Add UpdateLinkedDataCallback with the webauthn-ble's update gaCallbacks.user_data = &testContents; ret = wauthn_get_assertion(&clientData, &gaOptions, &gaCallbacks); @@ -301,8 +312,21 @@ int main(int argc, char *argv[]) TestContents testContents = {0, "/tmp/webauthn-qrcode.png", {}, {}, WAUTHN_TRANSPORT_NONE}; - if (argc > 1 && std::string_view("-n") == argv[1]) - testContents.negative = true; + if (argc == 2) + { + if (std::string_view("-n") == argv[1]) + testContents.negative = true; + else + { + std::cout << "only -\"n\" option is supported" << std::endl; + return true; + } + } + else if (argc > 2) + { + std::cout << "Invalid parameters" << std::endl; + return true; + } int err = TurnBluetoothOn(); if (err != BT_ERROR_NONE) { @@ -318,7 +342,7 @@ int main(int argc, char *argv[]) ret = true; } - if (system("killall /usr/apps/org.tizen.image-viewer_common/bin/image-viewer")) { + if (system("/usr/bin/killall /usr/apps/org.tizen.image-viewer_common/bin/image-viewer")) { std::cout << "Cannot close org.tizen.image-viewer\n"; ret = true; } diff --git a/tests/serialization-test.cpp b/tests/serialization-test.cpp index 5a8d2d1..14a7fac 100644 --- a/tests/serialization-test.cpp +++ b/tests/serialization-test.cpp @@ -163,7 +163,8 @@ void __testUnsignedCharPtr(unsigned char *data, size_t data_size) WAuthnCtypeSerializer::deserialize(buffer, &deserialized, &deserialized_len); EXPECT_EQ(data_size, deserialized_len); - if (deserialized_len != 0) { // If deserialized_len is zero, memcmp is guaranteed to return zero + if (data_size != 0 && deserialized_len != 0) { + // If deserialized_len is zero, memcmp is guaranteed to return zero EXPECT_EQ(memcmp(data, deserialized, deserialized_len), 0); } else { @@ -264,22 +265,24 @@ bool __compareWAuthErrorE(wauthn_error_e expected, wauthn_error_e actual) TEST_F(WAuthnSerializationTest, wauthn_error_e_P) { __testSerialization(WAUTHN_ERROR_NONE, __compareWAuthErrorE); + __testSerialization(WAUTHN_ERROR_NONE_AND_WAIT, __compareWAuthErrorE); __testSerialization(WAUTHN_ERROR_NOT_ALLOWED, __compareWAuthErrorE); __testSerialization(WAUTHN_ERROR_ENCODING_FAILED, __compareWAuthErrorE); __testSerialization(WAUTHN_ERROR_CANCELLED, __compareWAuthErrorE); + __testSerialization(WAUTHN_ERROR_TIMEOUT, __compareWAuthErrorE); } TEST_F(WAuthnSerializationTest, wauthn_error_e_N1) {// serialize: invalid wauthn_error_e - wauthn_error_e data1 = static_cast(WAUTHN_ERROR_NONE + 1); + wauthn_error_e data1 = static_cast(WAUTHN_ERROR_NONE_AND_WAIT + 1); __testSerializeForInvalidMember(data1); - wauthn_error_e data2 = static_cast(WAUTHN_ERROR_CANCELLED - 1); + wauthn_error_e data2 = static_cast(WAUTHN_ERROR_TIMEOUT - 1); __testSerializeForInvalidMember(data2); } TEST_F(WAuthnSerializationTest, wauthn_error_e_N2) {// deserialize: invalid wauthn_error_e MessageBuffer buffer; wauthn_error_e deserialized; - __fillBufferWithTestCommonData(buffer, WAUTHN_ERROR_NONE + 1, nullptr, 0); + __fillBufferWithTestCommonData(buffer, WAUTHN_ERROR_NONE_AND_WAIT + 1, nullptr, 0); try { WAuthnCtypeSerializer::deserialize(buffer, &deserialized); EXPECT_TRUE(false); @@ -287,7 +290,7 @@ TEST_F(WAuthnSerializationTest, wauthn_error_e_N2) } MessageBuffer buffer1; - __fillBufferWithTestCommonData(buffer1, WAUTHN_ERROR_CANCELLED - 1, nullptr, 0); + __fillBufferWithTestCommonData(buffer1, WAUTHN_ERROR_TIMEOUT - 1, nullptr, 0); try { WAuthnCtypeSerializer::deserialize(buffer1, &deserialized); EXPECT_TRUE(false); diff --git a/tests/test-common.cpp b/tests/test-common.cpp index 533d8e6..fbafa91 100644 --- a/tests/test-common.cpp +++ b/tests/test-common.cpp @@ -156,7 +156,7 @@ namespace TestCommonData { wauthn_pubkey_cred_creation_options_s pubkeyCredCreationOptions = {&rpEntity, &userEntity, &pubkeyCredParams2, timeout, &pubkeyCredDescriptors2, &authenticatorSelCri, &pubkeyCredHints2, attestation, &attestationFormats1, &authenticationExts2, &hybridLinkedData}; - wauthn_pubkey_cred_creation_options_s pubkeyCredCreationOptionsWithQR = {&rpEntity, &userEntity, + wauthn_pubkey_cred_creation_options_s pubkeyCredCreationOptionsNoLD = {&rpEntity, &userEntity, &pubkeyCredParams2, timeout, &pubkeyCredDescriptors2, &authenticatorSelCri, &pubkeyCredHints2, attestation, &attestationFormats1, &authenticationExts2, nullptr}; wauthn_pubkey_cred_creation_options_s emptyPubkeyCredCreationOptions = {nullptr, nullptr, @@ -166,7 +166,7 @@ namespace TestCommonData { wauthn_pubkey_cred_request_options_s pubkeyCredRequestOptions = {timeout, const_cast(rpId), &pubkeyCredDescriptors2, user_verification, &pubkeyCredHints2, attestation, &attestationFormats1, &authenticationExts2, &hybridLinkedData}; - wauthn_pubkey_cred_request_options_s pubkeyCredRequestOptionsWithQR = {timeout, const_cast(rpId), + wauthn_pubkey_cred_request_options_s pubkeyCredRequestOptionsNoLD = {timeout, const_cast(rpId), &pubkeyCredDescriptors2, user_verification, &pubkeyCredHints2, attestation, &attestationFormats1, &authenticationExts2, nullptr}; wauthn_pubkey_cred_request_options_s emptyPubkeyCredRequestOptions = {0, nullptr, diff --git a/tests/test-common.h b/tests/test-common.h index b6511fd..fe9d3d7 100644 --- a/tests/test-common.h +++ b/tests/test-common.h @@ -37,25 +37,31 @@ typedef struct _test_user_data_s { int test_int; bool called_qr; bool called_response; + int times_update_linked_data; } test_user_data_s; +inline int g_target_times_update_linked_data; inline void _print_user_data(void *user_data) { - std::cout << "user_data is not null, data=" << - (static_cast(user_data))->test_data << - ", int=" << (static_cast(user_data))->test_int << std::endl; + if (user_data == nullptr) + std::cout << "user_data is null" << std::endl; + else{ + test_user_data_s *userData = static_cast(user_data); + + std::cout << "user_data is not null, data=" << + userData->test_data << ", int=" << userData->test_int << + ", qr=" << userData->called_qr << ", response=" << + ", target update times=" << g_target_times_update_linked_data << + ", update times=" << userData->times_update_linked_data << std::endl; + } } inline void test_cb_display_qrcode(const char *qr_contents, void *user_data) { std::cout << "QR Code: " << std::string(qr_contents) << std::endl; - if (user_data == nullptr) - std::cout << "user_data is null" << std::endl; - else - { - _print_user_data(user_data); + _print_user_data(user_data); + if (user_data != nullptr) (static_cast(user_data))->called_qr = true; - } } inline void test_cb_mc_response( @@ -70,13 +76,9 @@ inline void test_cb_mc_response( std::cout << "pubkey_cred is not null: " << pubkey_cred->type << ", " << pubkey_cred->authenticator_attachment << std::endl; - if (user_data == nullptr) - std::cout << "user_data is null" << std::endl; - else - { - _print_user_data(user_data); + _print_user_data(user_data); + if (user_data != nullptr) (static_cast(user_data))->called_response = true; - } } inline void test_cb_ga_response( @@ -89,13 +91,23 @@ inline void test_cb_ga_response( std::cout << "pubkey_cred is null" << std::endl; else std::cout << "pubkey_cred is not null" << std::endl; - if (user_data == nullptr) - std::cout << "user_data is null" << std::endl; - else - { - _print_user_data(user_data); + _print_user_data(user_data); + if (user_data != nullptr) (static_cast(user_data))->called_response = true; - } +} + +inline void test_cb_update_linked_data( + const wauthn_hybrid_linked_data_s *linked_data, + wauthn_error_e result, + void *user_data) +{ + std::cout << "update_linked_data, result: " << wauthn_error_to_string(result) << std::endl; + if (linked_data == nullptr) + std::cout << "linked_data is null" << std::endl; + else + std::cout << "linked_data is not null" << std::endl; + (static_cast(user_data))->times_update_linked_data += 1; + _print_user_data(user_data); } namespace TestCommonData { @@ -216,12 +228,12 @@ namespace TestCommonData { extern unsigned long timeout; extern wauthn_attestation_pref_e attestation; extern wauthn_pubkey_cred_creation_options_s pubkeyCredCreationOptions; - extern wauthn_pubkey_cred_creation_options_s pubkeyCredCreationOptionsWithQR; + extern wauthn_pubkey_cred_creation_options_s pubkeyCredCreationOptionsNoLD; extern wauthn_pubkey_cred_creation_options_s emptyPubkeyCredCreationOptions; extern const char *rpId; extern wauthn_pubkey_cred_request_options_s pubkeyCredRequestOptions; - extern wauthn_pubkey_cred_request_options_s pubkeyCredRequestOptionsWithQR; + extern wauthn_pubkey_cred_request_options_s pubkeyCredRequestOptionsNoLD; extern wauthn_pubkey_cred_request_options_s emptyPubkeyCredRequestOptions; extern wauthn_pubkey_credential_attestation_s pubkeyCredentialAttestation; diff --git a/tests/webauthn-client-test.cpp b/tests/webauthn-client-test.cpp index 723df4a..6da25d7 100644 --- a/tests/webauthn-client-test.cpp +++ b/tests/webauthn-client-test.cpp @@ -47,6 +47,7 @@ TEST_F(WebAuthnTest, invalid_client_data_N) mc_callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s)); mc_callbacks->qrcode_callback = test_cb_display_qrcode; mc_callbacks->response_callback = test_cb_mc_response; + mc_callbacks->linked_data_callback = test_cb_update_linked_data; ret = wauthn_make_credential(nullptr, &TestCommonData::pubkeyCredCreationOptions, mc_callbacks); @@ -60,6 +61,7 @@ TEST_F(WebAuthnTest, invalid_client_data_N) ga_callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s)); ga_callbacks->qrcode_callback = test_cb_display_qrcode; ga_callbacks->response_callback = test_cb_ga_response; + ga_callbacks->linked_data_callback = test_cb_update_linked_data; ret = wauthn_get_assertion(nullptr, &TestCommonData::pubkeyCredRequestOptions, ga_callbacks); @@ -80,6 +82,7 @@ TEST_F(WebAuthnTest, invalid_options_N) mc_callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s)); mc_callbacks->qrcode_callback = test_cb_display_qrcode; mc_callbacks->response_callback = test_cb_mc_response; + mc_callbacks->linked_data_callback = test_cb_update_linked_data; ret = wauthn_make_credential(&TestCommonData::clientData, nullptr, mc_callbacks); @@ -93,6 +96,7 @@ TEST_F(WebAuthnTest, invalid_options_N) ga_callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s)); ga_callbacks->qrcode_callback = test_cb_display_qrcode; ga_callbacks->response_callback = test_cb_ga_response; + ga_callbacks->linked_data_callback = test_cb_update_linked_data; ret = wauthn_get_assertion(&TestCommonData::clientData, nullptr, ga_callbacks); @@ -120,6 +124,17 @@ TEST_F(WebAuthnTest, invalid_callbacks_N) mc_callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s)); mc_callbacks->qrcode_callback = test_cb_display_qrcode; mc_callbacks->response_callback = nullptr; + mc_callbacks->linked_data_callback = test_cb_update_linked_data; + ret = wauthn_make_credential(&TestCommonData::clientData, + &TestCommonData::pubkeyCredCreationOptions, + mc_callbacks); + EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER) + << "[invalid_callbacks_N] failed. " + << "ret=" << wauthn_error_to_string(ret) << std::endl; + + ret = WAUTHN_ERROR_NONE; + mc_callbacks->response_callback = test_cb_mc_response; + mc_callbacks->linked_data_callback = nullptr; ret = wauthn_make_credential(&TestCommonData::clientData, &TestCommonData::pubkeyCredCreationOptions, mc_callbacks); @@ -140,6 +155,17 @@ TEST_F(WebAuthnTest, invalid_callbacks_N) ga_callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s)); ga_callbacks->qrcode_callback = test_cb_display_qrcode; ga_callbacks->response_callback = nullptr; + ga_callbacks->linked_data_callback = test_cb_update_linked_data; + ret = wauthn_get_assertion(&TestCommonData::clientData, + &TestCommonData::pubkeyCredRequestOptions, + ga_callbacks); + EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER) + << "[invalid_callbacks_N] failed. " + << "ret=" << wauthn_error_to_string(ret) << std::endl; + + ret = WAUTHN_ERROR_NONE; + ga_callbacks->response_callback = test_cb_ga_response; + ga_callbacks->linked_data_callback = nullptr; ret = wauthn_get_assertion(&TestCommonData::clientData, &TestCommonData::pubkeyCredRequestOptions, ga_callbacks); @@ -157,8 +183,9 @@ TEST_F(WebAuthnTest, miss_qr_callback_without_linked_data_N) mc_callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s)); mc_callbacks->qrcode_callback = nullptr; mc_callbacks->response_callback = test_cb_mc_response; + mc_callbacks->linked_data_callback = test_cb_update_linked_data; ret = wauthn_make_credential(&TestCommonData::clientData, - &TestCommonData::pubkeyCredCreationOptionsWithQR, + &TestCommonData::pubkeyCredCreationOptionsNoLD, mc_callbacks); EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER) << "[miss_qr_callback_without_linked_data_N] failed. " @@ -169,8 +196,9 @@ TEST_F(WebAuthnTest, miss_qr_callback_without_linked_data_N) ga_callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s)); ga_callbacks->qrcode_callback = nullptr; ga_callbacks->response_callback = test_cb_ga_response; + ga_callbacks->linked_data_callback = test_cb_update_linked_data; ret = wauthn_get_assertion(&TestCommonData::clientData, - &TestCommonData::pubkeyCredRequestOptionsWithQR, + &TestCommonData::pubkeyCredRequestOptionsNoLD, nullptr); EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER) << "[miss_qr_callback_without_linked_data_N] failed. " -- 2.7.4