* @brief This file is implementation of client-common functions.
*/
-#include <webauthn-log.h>
#include <singleton.h>
+#include <webauthn-log.h>
#define WEBAUTHN_CLIENT_LOG_TAG "WEBAUTHN-CLIENT"
namespace {
-void webauthnClientEnableLogSystem(void) {
+void webauthnClientEnableLogSystem(void)
+{
auto& logSystem = WA::Singleton<WA::WebAuthnLog>::Instance();
if (!logSystem.IsTagSet())
logSystem.SetTag(WEBAUTHN_CLIENT_LOG_TAG);
{
}
-
#include "client-request.h"
namespace WA {
-class ClientRequestGA : public ClientRequest
-{
+class ClientRequestGA : public ClientRequest {
public:
typedef wauthn_pubkey_cred_request_options_s Options;
typedef wauthn_ga_callbacks_s Callbacks;
typedef wauthn_pubkey_credential_assertion_s PubKeyCred;
- explicit ClientRequestGA() : ClientRequest(WebAuthnCall::GET_ASSERTION) {}
+ explicit ClientRequestGA() : ClientRequest(WebAuthnCall::GET_ASSERTION)
+ {
+ }
};
+
} //namespace WebAuthn
#include "client-request.h"
namespace WA {
-class ClientRequestMC : public ClientRequest
-{
+class ClientRequestMC : public ClientRequest {
public:
typedef wauthn_pubkey_cred_creation_options_s Options;
typedef wauthn_mc_callbacks_s Callbacks;
typedef wauthn_pubkey_credential_attestaion_s PubKeyCred;
- explicit ClientRequestMC() : ClientRequest(WebAuthnCall::MAKE_CREDENTIAL) {}
+ explicit ClientRequestMC() : ClientRequest(WebAuthnCall::MAKE_CREDENTIAL)
+ {
+ }
};
+
} //namespace WebAuthn
#pragma once
-#include <stdexcept>
#include <iostream>
+#include <stdexcept>
+#include <thread>
+#include <unistd.h>
+#include <utils.h>
#include <connection.h>
#include <message-buffer.h>
#include <protocols.h>
-#include <webauthn-types.h>
#include <webauthn-log.h>
-#include <utils.h>
-
+#include <webauthn-types.h>
namespace WA {
-class ClientRequest {
+class GenericClientRequest {
public:
- explicit ClientRequest(WebAuthnCall action) :
- m_action(action),
- m_conn(std::make_unique<Connection>())
+ explicit GenericClientRequest(WebAuthnCall action, const char *interface) :
+ m_action(action), m_conn(std::make_unique<Connection>())
{
- int ret = m_conn->createConnect(SERVICE_SOCKET);
+ int ret = m_conn->createConnect(interface);
if (ret != WAUTHN_ERROR_NONE)
ThrowMsg(ServiceException::InActive, "Error in createConnect");
m_buffer.InitForStreaming();
Serialization::Serialize(m_buffer, static_cast<int>(m_action));
- LogDebug("ClientRequest " << WebAuthnCallToString(m_action));
+ LogDebug("GenericClientRequest " << WebAuthnCallToString(m_action));
}
- ~ClientRequest()
- {}
+ virtual ~GenericClientRequest()
+ {
+ }
int getStatus() const
{
return m_status != WAUTHN_ERROR_NONE;
}
- ClientRequest &send()
+ GenericClientRequest &send()
{
if (m_sent)
throw std::logic_error(
- "Only one call to ClientRequest::send() is allowed");
+ "Only one call to send() is allowed");
m_sent = true;
m_status = m_conn->send(m_buffer);
return *this;
}
- template <typename... T> ClientRequest &send(const T&... args)
+ template <typename... T> GenericClientRequest &send(const T&... args)
{
Serialization::Serialize(m_buffer, args...);
return send();
}
- ClientRequest &recv()
+ GenericClientRequest &recv()
{
if (!m_sent)
throw std::logic_error(
- "Call to ClientRequest::send() must happen before call to ClientRequest::recv()");
+ "Call to send() must happen before call to recv()");
if (failed())
throw std::logic_error(
- "ClientRequest::recv() not allowed if the request failed");
+ "recv() not allowed if the request failed");
m_status = m_conn->recv(m_buffer);
if (failed())
{
return *this;
}
- template <typename... T> ClientRequest &recv(T&... args)
+ template <typename... T> GenericClientRequest &recv(T&... args)
{
recv();
if (failed())
throw std::logic_error(
- "ClientRequest::recv() is failed. Pass to receiving response.");
+ "recv() is failed. Pass to receiving response.");
Deserialization::Deserialize(m_buffer, args...);
return *this;
}
- template <typename... T> ClientRequest &recv(T&&... args)
+ template <typename... T> GenericClientRequest &recv(T&&... args)
{
recv();
if (failed())
throw std::logic_error(
- "ClientRequest::recv() is failed. Pass to receiving response.");
+ "recv() is failed. Pass to receiving response.");
Deserialization::Deserialize(m_buffer, args...);
return *this;
}
- template <typename... T> ClientRequest &sendRequest(const T&... args)
+ template <typename... T> GenericClientRequest &sendRequest(const T&... args)
{
Serialization::Serialize(m_buffer, args...);
if (send().failed())
return recv();
}
- ClientRequest &sendRequest()
+ GenericClientRequest &sendRequest()
{
if (send().failed())
return *this;
std::unique_ptr<Connection> m_conn;
};
+class ClientRequest : public GenericClientRequest {
+public:
+ explicit ClientRequest(WebAuthnCall action) :
+ GenericClientRequest(action, SERVICE_SOCKET)
+ {
+ }
+
+ virtual ~ClientRequest()
+ {
+ }
+};
+
+template <typename A, typename B>
+void cb_worker(std::shared_ptr<GenericClientRequest> 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())
+ 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");
+ return WAUTHN_ERROR_NONE;
+ });
+ callbacks->response_callback(cred, wauthn_error_e(ret), callbacks->user_data);
+}
+
+template <typename T>
+int wauthn_process(const wauthn_client_data_s *client_data,
+ const typename T::Options *options,
+ typename T::Callbacks *callbacks)
+{
+ return try_catch([&]() -> int {
+ checkParameters(client_data, options, callbacks);
+ if (options->linked_device != nullptr) // The qrcode_callback should not be called.
+ {
+ LogDebug("Adjust qrcode_callback to null");
+ callbacks->qrcode_callback = nullptr;
+ }
+ std::shared_ptr<T> request = std::make_shared<T>();
+
+ if (request->sendRequest(client_data, options).failed())
+ return request->getStatus();
+ LogDebug("Response: " << wauthn_error_to_string(request->getStatus()));
+
+ typename T::PubKeyCred *cred = NULL;
+ std::thread worker([request, callbacks, cred]{cb_worker(std::move(request), callbacks, cred);});
+ worker.detach();
+ return WAUTHN_ERROR_NONE;
+ });
+}
+
} // namespace WebAuthn
* @brief Wrap C++ functions to provide C APIs
*/
+#include <utils.h>
#include <webauthn.h>
#include <webauthn-log.h>
-#include <utils.h>
-#include <unistd.h>
-#include <thread>
-
-#include "client-request-mc.h"
#include "client-request-ga.h"
-
-template <typename A, typename B>
-void cb_worker(std::shared_ptr<ClientRequest> 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())
- 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");
- return WAUTHN_ERROR_NONE;
- });
- callbacks->response_callback(cred, wauthn_error_e(ret), callbacks->user_data);
-}
-
-template <typename T>
-int wauthn_process(const wauthn_client_data_s *client_data,
- const typename T::Options *options,
- typename T::Callbacks *callbacks)
-{
- return try_catch([&]() -> int {
- checkParameters(client_data, options, callbacks);
- if (options->linked_device != nullptr) // The qrcode_callback should not be called.
- {
- LogDebug("Adjust qrcode_callback to null");
- callbacks->qrcode_callback = nullptr;
- }
- std::shared_ptr<T> request = std::make_shared<T>();
-
- if (request->sendRequest(client_data, options).failed())
- return request->getStatus();
- LogDebug("Response: " << wauthn_error_to_string(request->getStatus()));
-
- typename T::PubKeyCred *cred = NULL;
- std::thread worker([request, callbacks, cred]{cb_worker(std::move(request), callbacks, cred);});
- worker.detach();
- return WAUTHN_ERROR_NONE;
- });
-}
+#include "client-request-mc.h"
int wauthn_make_credential( const wauthn_client_data_s *client_data,
const wauthn_pubkey_cred_creation_options_s *options,
LogError("Error on cancel request, Response: " << wauthn_error_to_string(request.getStatus()));
return request.getStatus();
});
-}
\ No newline at end of file
+}
*/
#include <dl-loader.h>
-#include <webauthn-log.h>
-#include <dlfcn.h>
namespace WA {
- DLLoader::DLLoader(std::string path) : m_libraryPath(std::move(path))
+
+DLLoader::DLLoader(std::string path) : m_libraryPath(std::move(path))
+{
+ LogDebug("Loading library: " << m_libraryPath);
+ m_libraryHandle = dlopen(m_libraryPath.c_str(), RTLD_LAZY | RTLD_LOCAL);
+ if (!m_libraryHandle)
{
- LogDebug("Loading library: " << m_libraryPath);
- m_libraryHandle = dlopen(m_libraryPath.c_str(), RTLD_LAZY | RTLD_LOCAL);
- if (!m_libraryHandle)
- {
- LogError("Unable to load library(" << m_libraryPath << "): " << dlerror());
- throw std::runtime_error("Unable to load library");
- }
+ LogError("Unable to load library(" << m_libraryPath << "): " << dlerror());
+ throw std::runtime_error("Unable to load library");
}
- DLLoader::~DLLoader()
- {
- LogDebug("Unloading library: " << m_libraryPath);
+}
+DLLoader::~DLLoader()
+{
+ LogDebug("Unloading library: " << m_libraryPath);
+ if (m_libraryHandle)
dlclose(m_libraryHandle);
- }
- void* DLLoader::ResolveFunction(const std::string &name) noexcept
- {
- LogDebug("Resolving symbol: " << name << " from " << m_libraryPath);
- void* sym = dlsym(m_libraryHandle, name.c_str());
- if (!sym)
- LogError("Unable to resolve symbol: " << name << " from " << m_libraryPath << ": " << dlerror());
- return sym;
- }
+}
} // namespace WebAuthn
\ No newline at end of file
#include <string>
#include <stdexcept>
+#include <webauthn-log.h>
+#include <dlfcn.h>
namespace WA {
class DLLoader {
public:
+ DLLoader() = default;
explicit DLLoader(std::string path);
- ~DLLoader();
+ virtual ~DLLoader();
- void* ResolveFunction(const std::string &name) noexcept;
+ virtual void *ResolveFunction(const std::string &name) noexcept
+ {
+ LogDebug("Resolving symbol: " << name << " from " << m_libraryPath);
+ void *sym = dlsym(m_libraryHandle, name.c_str());
+ if (!sym)
+ LogError("Unable to resolve symbol: " << name << " from " << m_libraryPath << ": " << dlerror());
+ return sym;
+ }
template<typename ReturnValue, typename... Args>
ReturnValue Invoke(const std::string &name, Args... args)
LogDebug("Start!");
WA::SocketManager manager;
try{
- auto service = std::make_unique<WA::Service>();
+ auto service = std::make_unique<WA::Service>(
+ std::make_shared<DLLoader>(WAH_PLUGIN_SO_PATH_HYBRID));
manager.RegisterSocketService(std::move(service));
manager.MainLoop();
return EXIT_SUCCESS;
#include <service.h>
#include <unistd.h>
#include <utils.h>
-#include <webauthn-hal.h>
#include "request-mc.h"
#include "request-ga.h"
namespace WA {
-Service::Service() : m_pluginHybrid(std::make_shared<DLLoader>(WAH_PLUGIN_SO_PATH_HYBRID)){}
-
-SocketManager *Service::GetSocketmanager()
+SocketManager *GenericService::GetSocketmanager()
{
return this->m_serviceManager;
}
-void Service::ProcessEvent(Event &&msg)
+void GenericService::ProcessEvent(Event &&msg)
{
LogDebug("Processing message for socket " << msg.connectionID.sock <<
" counter " << msg.connectionID.counter);
}
template <typename T>
-void Service::Worker(SocketManager::ConnectionID connectionID,
+void GenericService::Worker(SocketManager::ConnectionID connectionID,
wauthn_client_data_s *clientData,
typename T::Options *options)
{
}
template <typename T>
-void Service::Process(Event &&msg)
+void GenericService::Process(Event &&msg)
{
wauthn_client_data_s *clientData;
typename T::Options *options;
m_serviceManager->Write(msg.connectionID, std::move(responseBuffer));
if (0 == isBusy)
{
- std::thread worker(&Service::Worker<T>, this, msg.connectionID, clientData, options);
+ std::thread worker(&GenericService::Worker<T>, this, msg.connectionID, clientData, options);
worker.detach();
}
}
-void Service::Cancel(Event &&msg)
+void GenericService::Cancel(Event &&msg)
{
int ret = WAUTHN_ERROR_NONE;
int isBusy = CheckBusyAndCred(msg.connectionID);
m_serviceManager->Write(msg.connectionID, std::move(responseBuffer));
}
-void Service::UnsetBusy()
+void GenericService::UnsetBusy()
{
std::lock_guard<std::mutex> ulock(m_isBusyMutex);
m_isBusy = false;
}
-int Service::CheckBusyAndCred(SocketManager::ConnectionID connectionID)
+int GenericService::CheckBusyAndCred(SocketManager::ConnectionID connectionID)
{
std::lock_guard<std::mutex> ulock(m_isBusyMutex);
if (m_isBusy)
}
}
-int Service::CheckBusyAndSet(SocketManager::ConnectionID connectionID)
+int GenericService::CheckBusyAndSet(SocketManager::ConnectionID connectionID)
{
std::lock_guard<std::mutex> ulock(m_isBusyMutex);
if (m_isBusy)
}
}
-int Service::SetCredentials(SocketManager::ConnectionID connectionID)
+int GenericService::SetCredentials(SocketManager::ConnectionID connectionID)
{
return GetCredentials(connectionID, &m_credentials);
}
-int Service::GetCredentials(SocketManager::ConnectionID connectionID, Cred *creds)
+int GenericService::GetCredentials(SocketManager::ConnectionID connectionID, Cred *creds)
{
socklen_t length = sizeof(ucred);
if (0 > getsockopt(connectionID.sock, SOL_SOCKET, SO_PEERCRED, &creds->cred, &length)) {
#include <protocols.h>
#include <mutex>
#include <webauthn-types.h>
+#include <webauthn-hal.h>
#include "socket-manager.h"
#include "dl-loader.h"
typedef struct __struct_user_data
{
- Service *service;
+ GenericService *service;
SocketManager::ConnectionID connectionID;
}user_data_s;
ucred cred;
};
-class Service final
+class GenericService
{
- SocketManager *m_serviceManager = nullptr;
public:
- static inline const SocketManager::ServiceDescription DESCRIPTION{
- SERVICE_SOCKET, /* path */
- "*" /* smackLabel label (not used, we rely on systemd) */
- };
- explicit Service();
+ explicit GenericService(std::shared_ptr<DLLoader> pluginHybrid) :
+ m_pluginHybrid(pluginHybrid) {}
+
+ virtual ~GenericService() {}
void SetSocketManager(SocketManager *manager) {
m_serviceManager = manager;
}
*/
SocketManager *GetSocketmanager();
- /**
- * Unset to server is not busy
- */
- void UnsetBusy();
+ virtual SocketManager::ServiceDescription GetServiceDescription() = 0;
private:
template <typename T>
*/
int GetCredentials(SocketManager::ConnectionID connectionID, Cred *creds);
+ /**
+ * Unset to server is not busy
+ */
+ void UnsetBusy();
+
+ SocketManager *m_serviceManager = nullptr;
bool m_isBusy = false;
std::mutex m_isBusyMutex;
Cred m_credentials;
std::shared_ptr<DLLoader> m_pluginHybrid;
};
+
+class Service : public GenericService {
+public:
+ explicit Service(std::shared_ptr<DLLoader> pluginHybrid) :
+ GenericService(pluginHybrid) {}
+ virtual ~Service() {}
+ SocketManager::ServiceDescription GetServiceDescription() override {
+ return SocketManager::ServiceDescription {
+ SERVICE_SOCKET, /* path */
+ "*" /* smackLabel label (not used, we rely on systemd) */
+ };
+ }
+};
+
} // namespace WebAuthn
{
FD_ZERO(&m_readSet);
+ if ((m_notifyMe = eventfd(0, 0)) < 0)
+ ThrowErrno(Exception::InitFailed, "eventfd");
+ LogInfo("Eventfd desc: " << m_notifyMe);
+ RegisterFdForReading(m_notifyMe);
+
// std::thread bases on pthread so this should work fine
sigset_t set;
sigemptyset(&set);
// All service sockets have been closed. Close internal descriptors.
close(m_signalFd);
close(m_listenSock);
+ close(m_notifyMe);
}
void SocketManager::ReadyForAccept() {
// Daemon is ready to work.
sd_notify(0, "READY=1");
-
- for (;;) {
+ m_working = true;
+ while (m_working) {
fd_set readSet = m_readSet;
int ret = 0;
FD_CLR(m_listenSock, &readSet);
ret--;
}
+ if (FD_ISSET(m_notifyMe, &readSet)) {
+ eventfd_t dummyValue;
+ TEMP_FAILURE_RETRY(eventfd_read(m_notifyMe, &dummyValue));
+ FD_CLR(m_notifyMe, &readSet);
+ ret--;
+ }
for (int i = 0; ret; ++i) {
if (FD_ISSET(i, &readSet)) {
ReadyForRead(i);
}
}
+void SocketManager::MainLoopStop()
+{
+ m_working = false;
+ NotifyMe();
+}
+
int SocketManager::GetSocketFromSystemD(const ServiceDescription &desc)
{
int fd;
" Handler: " << desc.serviceHandlerPath.c_str());
}
-void SocketManager::RegisterSocketService(std::unique_ptr<Service> service) {
+void SocketManager::RegisterSocketService(std::unique_ptr<GenericService> service) {
service->SetSocketManager(this);
- CreateDomainSocket(Service::DESCRIPTION);
+ CreateDomainSocket(service->GetServiceDescription());
m_service = std::move(service);
}
+void SocketManager::NotifyMe()
+{
+ TEMP_FAILURE_RETRY(eventfd_write(m_notifyMe, 1));
+}
+
void SocketManager::Close(ConnectionID connectionID) {
std::lock_guard<std::mutex> ulock(m_serverProcessMutex);
if (connectionID.counter == m_socketDescriptionVector[connectionID.sock].counter)
namespace WA {
-class Service;
+class GenericService;
class SocketManager final {
public:
SocketManager();
virtual ~SocketManager();
void MainLoop();
+ void MainLoopStop();
- void RegisterSocketService(std::unique_ptr<Service> service);
+ void RegisterSocketService(std::unique_ptr<GenericService> service);
void Close(ConnectionID connectionID);
void Write(ConnectionID connectionID, MessageBuffer &&messageBuffer);
MessageBuffer newMessage();
void ReadyForAccept();
bool GotSigTerm() const;
void CloseSocket(int sock);
+ void NotifyMe();
void RegisterFdForReading(int fd);
};
SocketDescriptionVector m_socketDescriptionVector;
- std::unique_ptr<Service> m_service;
+ std::unique_ptr<GenericService> m_service;
fd_set m_readSet;
int m_maxDesc = -1;
- int m_signalFd, m_listenSock = -1;
+ int m_signalFd, m_listenSock = -1, m_notifyMe;
time_t m_nextGenerationStart = 0;
std::mutex m_eventQueueMutex;
std::mutex m_serverProcessMutex;
std::queue<WriteBuffer> m_writeBufferQueue;
std::queue<ConnectionID> m_closeQueue;
bool m_enableActivation = false;
+ bool m_working = false;
};
} // namespace WebAuthn
REQUIRED
dlog
gtest
+ libsystemd
)
SET(UNIT_TESTS_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/unittests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/webauthn-client-test.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/client-request-test.cpp
${CMAKE_CURRENT_SOURCE_DIR}/file-lock-test.cpp
${CMAKE_CURRENT_SOURCE_DIR}/serialization-test.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/dl-loader-test.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/socket-manager-test.cpp
+
+ ${PRJ_SRC_SERVER_PATH}/dl-loader.cpp
+ ${PRJ_SRC_SERVER_PATH}/service.cpp
+ ${PRJ_SRC_SERVER_PATH}/socket-manager.cpp
)
SET_SOURCE_FILES_PROPERTIES(
${PRJ_SRC_CLIENT_PATH}
${PRJ_SRC_COMMON_PATH}
${PRJ_SRC_SERVER_PATH}
+ ${PRJ_TEST_PATH}
)
LINK_DIRECTORIES(${UNIT_TESTS_DEPS_LIBRARY_DIRS})
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd. All rights reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ *
+ *
+ * @file socket-manager-test.cpp
+ * @version 1.0
+ * @brief unit tests for socket-manager
+ */
+
+#include "test-common.h"
+
+#include <client-request.h>
+#include <dl-loader.h>
+#include <socket-manager.h>
+#include <gtest/gtest.h>
+#include <iostream>
+#include <service.h>
+
+namespace WA {
+
+typedef enum __client_request_test_case {
+ TC_MC_without_QR_callback_P = 0,
+ TC_MC_with_QR_callback_P = 1,
+ TC_GA_without_QR_callback_P = 2,
+ TC_GA_with_QR_callback_P = 3,
+ TC_not_allowed_N = 4,
+ TC_cancel_P = 5
+} client_request_test_case_e;
+
+namespace ClientRequestTestData {
+ unsigned char clientDataJsonRaw[06] = {0x01, 0x02, 0x03, 0x04, };
+ unsigned char attestationObjectRaw[16] = {0x11, 0x12, 0x13, 0x14, };
+ unsigned char authenticatorDataRaw[26] = {0x21, 0x22, 0x23, 0x24, };
+ unsigned char subjectPubkeyInfoRaw[36] = {0x31, 0x32, 0x33, 0x34, };
+ wauthn_const_buffer_s clientDataJson = {clientDataJsonRaw, sizeof(clientDataJsonRaw)};
+ wauthn_const_buffer_s attestationObject = {attestationObjectRaw, sizeof(attestationObjectRaw)};
+ unsigned int transports = 3;
+ wauthn_const_buffer_s authenticatorData = {authenticatorDataRaw, sizeof(authenticatorDataRaw)};
+ wauthn_const_buffer_s subjectPubkeyInfo = {subjectPubkeyInfoRaw, sizeof(subjectPubkeyInfoRaw)};
+ wauthn_cose_algorithm_e pubkey_alg = WAUTHN_COSE_ALGORITHM_ECDSA_P256_WITH_SHA256;
+ wauthn_authenticator_attestation_response_s authenticatorAttestationResponse
+ = {&clientDataJson, &attestationObject, transports, &authenticatorData, &subjectPubkeyInfo, pubkey_alg};
+ wauthn_authenticator_attestation_response_s emptyAuthenticatorAttestationResponse
+ = {nullptr, nullptr, 0x00, nullptr, nullptr, pubkey_alg};
+
+ unsigned char signatureRaw[26] = {0x21, 0x22, 0x23, 0x24, };
+ unsigned char userHandleRaw[36] = {0x31, 0x32, 0x33, 0x34, };
+ wauthn_const_buffer_s signature = {signatureRaw, sizeof(signatureRaw)};
+ wauthn_const_buffer_s userHandle = {userHandleRaw, sizeof(userHandleRaw)};
+ wauthn_authenticator_assertion_response_s authenticatorAssertionResponse
+ = {&clientDataJson, &authenticatorData, &signature, &userHandle, &attestationObject};
+ wauthn_authenticator_assertion_response_s emptyAuthenticatorAssertionResponse
+ = {nullptr, nullptr, nullptr, nullptr, nullptr};
+
+ const char *name = "test name";
+ const char *id = "test id";
+ wauthn_rp_entity_s rpEntity = {name, id};
+ wauthn_rp_entity_s emptyRpEntiy = {nullptr, nullptr};
+
+ unsigned char idRaw[06] = {0x01, 0x02, 0x03, 0x04, };
+ wauthn_const_buffer_s bufferId = {idRaw, sizeof(idRaw)};
+ const char *displayName = "test displayName";
+ wauthn_user_entity_s userEntity = {const_cast<char*>(name), &bufferId, const_cast<char*>(displayName)};
+ wauthn_user_entity_s emptyUserEntity = {nullptr, nullptr, nullptr};
+
+ wauthn_pubkey_cred_type_e pubkeyCredType = PCT_PUBLIC_KEY;
+ wauthn_pubkey_cred_param_s credParam0 = {pubkeyCredType, WAUTHN_COSE_ALGORITHM_ECDSA_P256_WITH_SHA256};
+ wauthn_pubkey_cred_param_s credParam1 = {pubkeyCredType, WAUTHN_COSE_ALGORITHM_ECDSA_P521_WITH_SHA512};
+ wauthn_pubkey_cred_param_s pubkeyCredParam2[2] = {credParam0, credParam1};
+ wauthn_pubkey_cred_params_s pubkeyCredParams2 = {sizeof(pubkeyCredParam2)/sizeof(pubkeyCredParam2[0]), pubkeyCredParam2};
+ wauthn_pubkey_cred_param_s pubkeyCredParam1[1] = {credParam0};
+ wauthn_pubkey_cred_params_s pubkeyCredParams1 = {sizeof(pubkeyCredParam1)/sizeof(pubkeyCredParam1[0]), pubkeyCredParam1};
+ wauthn_pubkey_cred_params_s emptyPubkeyCredParams = {0, nullptr};
+
+ wauthn_pubkey_cred_descriptor_s pubkeyCredDescriptor = {pubkeyCredType, &bufferId, 3};
+ wauthn_pubkey_cred_descriptor_s emptyPubkeyCredDescriptor = {pubkeyCredType, nullptr, 0};
+
+ unsigned char idRaw0[06] = {0x01, 0x02, 0x03, 0x04, };
+ unsigned char idRaw1[16] = {0x11, 0x12, 0x13, 0x14, };
+ wauthn_const_buffer_s bufferId0 = {idRaw0, sizeof(idRaw0)};
+ wauthn_const_buffer_s bufferId1 = {idRaw1, sizeof(idRaw1)};
+ wauthn_pubkey_cred_descriptor_s credDescriptor0 = {pubkeyCredType, &bufferId0, 3};
+ wauthn_pubkey_cred_descriptor_s credDescriptor1 = {pubkeyCredType, &bufferId1, 13};
+ wauthn_pubkey_cred_descriptor_s pubkeyCredDescriptor2[2] = {credDescriptor0, credDescriptor1};
+ wauthn_pubkey_cred_descriptors_s pubkeyCredDescriptors2 = {sizeof(pubkeyCredDescriptor2)/sizeof(pubkeyCredDescriptor2[0]),
+ pubkeyCredDescriptor2};
+ wauthn_pubkey_cred_descriptor_s pubkeyCredDescriptor1[1] = {credDescriptor0};
+ wauthn_pubkey_cred_descriptors_s pubkeyCredDescriptors1 = {sizeof(pubkeyCredDescriptor1)/sizeof(pubkeyCredDescriptor1[0]),
+ pubkeyCredDescriptor1};
+ wauthn_pubkey_cred_descriptors_s emptyPubkeyCredDescriptors = {0, nullptr};
+
+ unsigned char extensionIdRaw[06] = {0x01, 0x02, 0x03, 0x04, };
+ unsigned char extensionValueRaw[16] = {0x11, 0x12, 0x13, 0x14, };
+ wauthn_const_buffer_s extensionId = {extensionIdRaw, sizeof(extensionIdRaw)};
+ wauthn_const_buffer_s extensionValue = {extensionValueRaw, sizeof(extensionValueRaw)};
+ wauthn_authentication_ext_s authenticationExt = {&extensionId, &extensionValue};
+ wauthn_authentication_ext_s emptyAuthenticationExt = {nullptr, nullptr};
+
+ unsigned char extensionIdRaw1[06] = {0x01, 0x02, 0x03, 0x04, };
+ unsigned char extensionValueRaw1[16] = {0x11, 0x12, 0x13, 0x14, };
+ wauthn_const_buffer_s extensionId1 = {extensionIdRaw1, sizeof(extensionIdRaw1)};
+ wauthn_const_buffer_s extensionValue1 = {extensionValueRaw1, sizeof(extensionValueRaw1)};
+ wauthn_authentication_ext_s authenticationExt1 = {&extensionId1, &extensionValue1};
+ wauthn_authentication_ext_s authenticationExtArr1[1] = {authenticationExt};
+ wauthn_authentication_ext_s authenticationExtArr2[2] = {authenticationExt, authenticationExt1};
+ wauthn_authentication_exts_s authenticationExts1 = {sizeof(authenticationExtArr1)/sizeof(authenticationExtArr1[0]),
+ authenticationExtArr1};
+ wauthn_authentication_exts_s authenticationExts2 = {sizeof(authenticationExtArr2)/sizeof(authenticationExtArr2[0]),
+ authenticationExtArr2};
+ wauthn_authentication_exts_s emptyAuthenticationExts = {0, nullptr};
+
+ wauthn_authenticator_attachment_e attachment = AA_PLATFORM;
+ wauthn_resident_key_requirement_e resident_key = RKR_PREFERRED;
+ bool require_resident_key = false;
+ wauthn_user_verification_requirement_e user_verification = UVR_DISCOURAGED;
+ wauthn_authenticator_sel_cri_s authenticatorSelCri = {attachment, resident_key,
+ require_resident_key, user_verification};
+
+ wauthn_pubkey_cred_hint_e hint0 = PCH_SECURITY_KEY;
+ wauthn_pubkey_cred_hint_e hint1 = PCH_CLIENT_DEVICE;
+ wauthn_pubkey_cred_hint_e pubkeyCredHint1[1] = {hint0};
+ wauthn_pubkey_cred_hint_e pubkeyCredHint2[2] = {hint0, hint1};
+ wauthn_pubkey_cred_hints_s pubkeyCredHints1 = {sizeof(pubkeyCredHint1)/sizeof(pubkeyCredHint1[0]), pubkeyCredHint1};
+ wauthn_pubkey_cred_hints_s pubkeyCredHints2 = {sizeof(pubkeyCredHint2)/sizeof(pubkeyCredHint2[0]), pubkeyCredHint2};
+ wauthn_pubkey_cred_hints_s emptyPubkeyCredHints = {0, nullptr};
+
+ unsigned char contactIdRaw[06] = {0x01, 0x02, 0x03, 0x04, };
+ unsigned char linkIdRaw[16] = {0x11, 0x12, 0x13, 0x14, };
+ unsigned char linkSecretRaw[26] = {0x11, 0x12, 0x13, 0x14, };
+ unsigned char authenticatorPubkeyRaw[16] = {0x11, 0x12, 0x13, 0x14, };
+ unsigned char authenticatorNameRaw[26] = {0x11, 0x12, 0x13, 0x14, };
+ unsigned char authPubkeyRaw[36] = {0x11, 0x12, 0x13, 0x14, };
+ unsigned char tunnelServerDomainRaw[36] = {0x11, 0x12, 0x13, 0x14, };
+ wauthn_const_buffer_s contactId = {contactIdRaw, sizeof(contactIdRaw)};
+ wauthn_const_buffer_s linkId = {linkIdRaw, sizeof(linkIdRaw)};
+ wauthn_const_buffer_s linkSecret = {linkSecretRaw, sizeof(linkSecretRaw)};
+ wauthn_const_buffer_s authenticatorPubkey = {authenticatorPubkeyRaw, sizeof(authenticatorPubkeyRaw)};
+ wauthn_const_buffer_s authenticatorName = {authenticatorNameRaw, sizeof(authenticatorNameRaw)};
+ wauthn_const_buffer_s authPubkey = {authPubkeyRaw, sizeof(authPubkeyRaw)};
+ wauthn_const_buffer_s tunnelServerDomain = {tunnelServerDomainRaw, sizeof(tunnelServerDomainRaw)};
+ wauthn_hybrid_linked_data_s hybirdLinkedData = {&contactId, &linkId, &linkSecret, &authenticatorPubkey,
+ &authenticatorName, &signature, &authPubkey, &tunnelServerDomain};
+ wauthn_hybrid_linked_data_s emptyHybirdLinkedData = {nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr};
+
+ unsigned char bufferRaw0[06] = {0x01, 0x02, 0x03, 0x04, };
+ unsigned char bufferRaw1[16] = {0x11, 0x12, 0x13, 0x14, };
+ wauthn_const_buffer_s buffer0 = {bufferRaw0, sizeof(bufferRaw0)};
+ wauthn_const_buffer_s buffer1 = {bufferRaw1, sizeof(bufferRaw1)};
+ wauthn_const_buffer_s attestationFormat1[1] = {buffer0};
+ wauthn_const_buffer_s attestationFormat2[2] = {buffer0, buffer1};
+ wauthn_attestation_formats_s attestationFormats1 = {sizeof(attestationFormat1)/sizeof(attestationFormat1[0]),
+ attestationFormat1};
+ wauthn_attestation_formats_s attestationFormats2 = {sizeof(attestationFormat2)/sizeof(attestationFormat2[0]),
+ attestationFormat2};
+ wauthn_attestation_formats_s emptyAttestationFormats = {0, nullptr};
+
+ unsigned long timeout = 1000;
+ wauthn_attestation_pref_e attestation = AP_DIRECT;
+ wauthn_pubkey_cred_creation_options_s pubkeyCredCreationOptions = {&rpEntity, &userEntity,
+ &pubkeyCredParams2, timeout, &pubkeyCredDescriptors2, &authenticatorSelCri, &pubkeyCredHints2,
+ attestation, &attestationFormats1, &authenticationExts2, &hybirdLinkedData};
+ wauthn_pubkey_cred_creation_options_s pubkeyCredCreationOptionsWithQR = {&rpEntity, &userEntity,
+ &pubkeyCredParams2, timeout, &pubkeyCredDescriptors2, &authenticatorSelCri, &pubkeyCredHints2,
+ attestation, &attestationFormats1, &authenticationExts2, nullptr};
+ wauthn_pubkey_cred_creation_options_s emptyPubkeyCredCreationOptions = {nullptr, nullptr,
+ nullptr, 0, nullptr, nullptr, nullptr, AP_NONE, nullptr, nullptr, nullptr};
+
+ const char *rpId = "test RP ID";
+ wauthn_pubkey_cred_request_options_s pubkeyCredRequestOptions = {timeout, const_cast<char *>(rpId),
+ &pubkeyCredDescriptors2, user_verification, &pubkeyCredHints2, attestation, &attestationFormats1,
+ &authenticationExts2, &hybirdLinkedData};
+ wauthn_pubkey_cred_request_options_s pubkeyCredRequestOptionsWithQR = {timeout, const_cast<char *>(rpId),
+ &pubkeyCredDescriptors2, user_verification, &pubkeyCredHints2, attestation, &attestationFormats1,
+ &authenticationExts2, nullptr};
+ wauthn_pubkey_cred_request_options_s emptyPubkeyCredRequestOptions = {0, nullptr,
+ nullptr, UVR_NONE, nullptr, AP_NONE, nullptr, nullptr, nullptr};
+
+ wauthn_pubkey_credential_attestaion_s pubkeyCredentialAttestation = {&bufferId, pubkeyCredType, &bufferId0,
+ &authenticatorAttestationResponse, attachment, &authenticationExts2, &hybirdLinkedData};
+ wauthn_pubkey_credential_attestaion_s emptyPubkeyCredentialAttestation = {nullptr, pubkeyCredType, nullptr,
+ nullptr, attachment, nullptr, nullptr};
+
+ wauthn_pubkey_credential_assertion_s pubkeyCredentialAssertion = {&bufferId, pubkeyCredType, &bufferId0,
+ &authenticatorAssertionResponse, attachment, &authenticationExts2, &hybirdLinkedData};
+ wauthn_pubkey_credential_assertion_s emptyPubkeyCredentialAssertion = {nullptr, pubkeyCredType, nullptr,
+ nullptr, attachment, nullptr, nullptr};
+
+ wauthn_hash_algorithm_e hashAlg = WAUTHN_HASH_ALGORITHM_SHA_256;
+ wauthn_client_data_s clientData = {&bufferId, hashAlg};
+ wauthn_client_data_s emptyClientData = {nullptr, hashAlg};
+}
+
+class TestClientRequest : public GenericClientRequest {
+public:
+ explicit TestClientRequest(WebAuthnCall action) :
+ GenericClientRequest(action, TEST_SERVICE_SOCKET) {}
+ virtual ~TestClientRequest() {}
+};
+
+class TestClientRequestMC : public TestClientRequest
+{
+public:
+ typedef wauthn_pubkey_cred_creation_options_s Options;
+ typedef wauthn_mc_callbacks_s Callbacks;
+ typedef wauthn_pubkey_credential_attestaion_s PubKeyCred;
+
+ explicit TestClientRequestMC() : TestClientRequest(WebAuthnCall::MAKE_CREDENTIAL) {}
+};
+
+class TestClientRequestGA : public TestClientRequest
+{
+public:
+ typedef wauthn_pubkey_cred_request_options_s Options;
+ typedef wauthn_ga_callbacks_s Callbacks;
+ typedef wauthn_pubkey_credential_assertion_s PubKeyCred;
+
+ explicit TestClientRequestGA() : TestClientRequest(WebAuthnCall::GET_ASSERTION) {}
+};
+
+void wah_make_credential(const wauthn_client_data_s *client_data,
+ const wauthn_pubkey_cred_creation_options_s *options,
+ wauthn_mc_callbacks_s *callbacks)
+{
+ std::cout << "IN wah_make_credential by TestDLLoader" << std::endl;
+ if (client_data == NULL)
+ std::cout << "client_data is null" << std::endl;
+ else
+ std::cout << "client_data->hash_alg: " << client_data->hash_alg << std::endl;
+
+ if (options == NULL)
+ std::cout << "options is null" << std::endl;
+ else
+ std::cout << "options->timeout,attestation: " << options->timeout <<
+ ", " << options->attestation << std::endl;
+ sleep(1);
+ if (callbacks->qrcode_callback != nullptr)
+ callbacks->qrcode_callback(std::string("FIDO:/TestDLLoader-wah_make_credential").c_str(),
+ callbacks->user_data);
+ else
+ std::cout << "callbacks->qrcode_callback is null" << std::endl;
+ sleep(1);
+ callbacks->response_callback(nullptr, WAUTHN_ERROR_NONE, callbacks->user_data);
+}
+
+void wah_get_assertion(const wauthn_client_data_s *client_data,
+ const wauthn_pubkey_cred_request_options_s *options,
+ wauthn_ga_callbacks_s *callbacks)
+{
+ std::cout << "IN wah_get_assertion by TestDLLoader" << std::endl;
+ if (client_data == NULL)
+ std::cout << "client_data is null" << std::endl;
+ else
+ std::cout << "client_data->hash_alg: " << client_data->hash_alg << std::endl;
+
+ if (options == NULL)
+ std::cout << "options is null" << std::endl;
+ else
+ std::cout << "options->timeout,attestation: " << options->timeout <<
+ ", " << options->attestation << std::endl;
+ sleep(1);
+ if (callbacks->qrcode_callback != nullptr)
+ callbacks->qrcode_callback(std::string("FIDO:/TestDLLoader-wah_get_assertion").c_str(),
+ callbacks->user_data);
+ sleep(1);
+ callbacks->response_callback(nullptr, WAUTHN_ERROR_NONE, callbacks->user_data);
+}
+
+int wah_cancel()
+{
+ std::cout << "IN wah_cancel by TestDLLoader" << std::endl;
+ return WAUTHN_ERROR_NONE;
+}
+
+class TestDLLoader : public DLLoader {
+public:
+ explicit TestDLLoader ()
+ {
+ try{
+ DLLoader("");
+ }catch (...) {}
+ }
+ void* ResolveFunction(const std::string &name) noexcept override
+ {
+ if (name == WAH_API_MC)
+ return (void *) (&wah_make_credential);
+ else if (name == WAH_API_GA)
+ return (void *) (&wah_get_assertion);
+ else if (name == WAH_API_CANCEL)
+ return (void *) (&wah_cancel);
+ else
+ return nullptr;
+ }
+};
+
+class TestService : public GenericService {
+public:
+ SocketManager::ServiceDescription GetServiceDescription() override {
+ return SocketManager::ServiceDescription {
+ TEST_SERVICE_SOCKET, /* path */
+ "*" /* smackLabel label (not used, we rely on systemd) */
+ };
+ }
+ TestService(std::shared_ptr<DLLoader> pluginHybrid) :
+ GenericService(pluginHybrid) {}
+ virtual ~TestService() {}
+};
+
+class SocketManagerLoop final {
+public:
+ explicit SocketManagerLoop(SocketManager& manager) :
+ m_manager(manager),
+ m_thread([&]{
+ try {
+ manager.MainLoop();
+ } catch (const std::exception& e) {
+ m_exception = true;
+ m_what = e.what();
+ } catch (...) {
+ m_exception = true;
+ }
+ })
+ {
+ }
+
+ ~SocketManagerLoop() {
+ m_manager.MainLoopStop();
+ m_thread.join();
+ }
+
+private:
+ bool m_exception = false;
+ std::string m_what = "Unknown exception";
+ SocketManager& m_manager;
+ std::thread m_thread;
+};
+
+typedef struct _test_user_data_s {
+ char *test_data;
+ int test_int;
+ client_request_test_case_e tc_num;
+} test_user_data_s;
+
+void _client_test_print_user_data(void *user_data)
+{
+ std::cout << "user_data is not null, data=" <<
+ (static_cast<test_user_data_s*>(user_data))->test_data <<
+ ", int=" << (static_cast<test_user_data_s*>(user_data))->test_int <<
+ ", tc_num=" << (static_cast<test_user_data_s*>(user_data))->tc_num << std::endl;
+}
+
+void client_request_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
+ _client_test_print_user_data(user_data);
+
+}
+void client_request_test_cb_mc_on_response(
+ const wauthn_pubkey_credential_attestaion_s *pubkey_cred,
+ wauthn_error_e result,
+ void *user_data)
+{
+ std::cout << "mc response, result: " << wauthn_error_to_string(result) << std::endl;
+ if (pubkey_cred == nullptr)
+ std::cout << "pubkey_cred is null" << std::endl;
+ else
+ 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
+ _client_test_print_user_data(user_data);
+
+}
+
+void client_request_test_cb_ga_on_response(
+ const wauthn_pubkey_credential_assertion_s *pubkey_cred,
+ wauthn_error_e result,
+ void *user_data)
+{
+ std::cout << "ga response, result: " << wauthn_error_to_string(result) << std::endl;
+ if (pubkey_cred == nullptr)
+ 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
+ _client_test_print_user_data(user_data);
+}
+
+class ClientRequestTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ // Do initialization if needed.
+ }
+
+ void TearDown() override {
+ // Do deinitialization if needed.
+ }
+};
+
+
+TEST_F(ClientRequestTest, MC_without_QR_callback_P)
+{
+ int ret = 1;
+ WA::SocketManager manager;
+ try{
+ auto service = std::make_unique<WA::TestService>(std::make_shared<TestDLLoader>());
+ manager.RegisterSocketService(std::move(service));
+ SocketManagerLoop loop(manager);
+
+ {
+ int retVal = WAUTHN_ERROR_NONE;
+ wauthn_mc_callbacks_s *callbacks = nullptr;
+ callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s));
+ callbacks->qrcode_callback = client_request_test_cb_display_qrcode;
+ callbacks->response_callback = client_request_test_cb_mc_on_response;
+ 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->tc_num = TC_MC_without_QR_callback_P;
+ callbacks->user_data = userdata;
+ retVal = wauthn_process<TestClientRequestMC>(&ClientRequestTestData::clientData,
+ &ClientRequestTestData::pubkeyCredCreationOptions, callbacks);
+
+ EXPECT_EQ(retVal, WAUTHN_ERROR_NONE)
+ << "[wauthn_process<TestClientRequestMC>] failed. "
+ << "retVal=" << wauthn_error_to_string(ret) << std::endl;
+ sleep(5);
+ free(userdata);
+ free(callbacks);
+ }
+ sleep(1);
+ ret = 0;
+ } catch (...) {
+ std::cout << "Error in starting service, unknown exception occured" << std::endl;
+ ret = -1;
+ }
+ EXPECT_EQ(ret, 0);
+}
+
+TEST_F(ClientRequestTest, MC_with_QR_callback_P)
+{
+ int ret = 1;
+ WA::SocketManager manager;
+ try{
+ auto service = std::make_unique<WA::TestService>(std::make_shared<TestDLLoader>());
+ manager.RegisterSocketService(std::move(service));
+ SocketManagerLoop loop(manager);
+
+ {
+ int retVal = WAUTHN_ERROR_NONE;
+ wauthn_mc_callbacks_s *callbacks = nullptr;
+ callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s));
+ callbacks->qrcode_callback = client_request_test_cb_display_qrcode;
+ callbacks->response_callback = client_request_test_cb_mc_on_response;
+ 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->tc_num = TC_MC_with_QR_callback_P;
+ callbacks->user_data = userdata;
+ retVal = wauthn_process<TestClientRequestMC>(&ClientRequestTestData::clientData,
+ &ClientRequestTestData::pubkeyCredCreationOptionsWithQR, callbacks);
+
+ EXPECT_EQ(retVal, WAUTHN_ERROR_NONE)
+ << "[wauthn_process<TestClientRequestMC>] failed. "
+ << "retVal=" << wauthn_error_to_string(ret) << std::endl;
+ sleep(5);
+ free(userdata);
+ free(callbacks);
+ }
+ sleep(1);
+ ret = 0;
+ } catch (...) {
+ std::cout << "Error in starting service, unknown exception occured" << std::endl;
+ ret = -1;
+ }
+ EXPECT_EQ(ret, 0);
+}
+
+
+TEST_F(ClientRequestTest, GA_without_QR_callback_P)
+{
+ int ret = 1;
+ WA::SocketManager manager;
+ try{
+ auto service = std::make_unique<WA::TestService>(std::make_shared<TestDLLoader>());
+ manager.RegisterSocketService(std::move(service));
+ SocketManagerLoop loop(manager);
+
+ {
+ int retVal = WAUTHN_ERROR_NONE;
+ wauthn_ga_callbacks_s *callbacks = nullptr;
+ callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s));
+ callbacks->qrcode_callback = client_request_test_cb_display_qrcode;
+ callbacks->response_callback = client_request_test_cb_ga_on_response;
+ 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->tc_num = TC_GA_without_QR_callback_P;
+ callbacks->user_data = userdata;
+ retVal = wauthn_process<TestClientRequestGA>(&ClientRequestTestData::clientData,
+ &ClientRequestTestData::pubkeyCredRequestOptions, callbacks);
+
+ EXPECT_EQ(retVal, WAUTHN_ERROR_NONE)
+ << "[wauthn_process<TestClientRequestGA>] failed. "
+ << "retVal=" << wauthn_error_to_string(ret) << std::endl;
+ sleep(5);
+ free(userdata);
+ free(callbacks);
+ }
+ sleep(1);
+ ret = 0;
+ } catch (...) {
+ std::cout << "Error in starting service, unknown exception occured" << std::endl;
+ ret = -1;
+ }
+ EXPECT_EQ(ret, 0);
+}
+
+TEST_F(ClientRequestTest, GA_with_QR_callback_P)
+{
+ int ret = 1;
+ WA::SocketManager manager;
+ try{
+ auto service = std::make_unique<WA::TestService>(std::make_shared<TestDLLoader>());
+ manager.RegisterSocketService(std::move(service));
+ SocketManagerLoop loop(manager);
+
+ {
+ int retVal = WAUTHN_ERROR_NONE;
+ wauthn_ga_callbacks_s *callbacks = nullptr;
+ callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s));
+ callbacks->qrcode_callback = client_request_test_cb_display_qrcode;
+ callbacks->response_callback = client_request_test_cb_ga_on_response;
+ 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->tc_num = TC_GA_with_QR_callback_P;
+ callbacks->user_data = userdata;
+ retVal = wauthn_process<TestClientRequestGA>(&ClientRequestTestData::clientData,
+ &ClientRequestTestData::pubkeyCredRequestOptionsWithQR, callbacks);
+
+ EXPECT_EQ(retVal, WAUTHN_ERROR_NONE)
+ << "[wauthn_process<TestClientRequestGA>] failed. "
+ << "retVal=" << wauthn_error_to_string(ret) << std::endl;
+ sleep(5);
+ free(userdata);
+ free(callbacks);
+ }
+ sleep(1);
+ ret = 0;
+ } catch (...) {
+ std::cout << "Error in starting service, unknown exception occured" << std::endl;
+ ret = -1;
+ }
+ EXPECT_EQ(ret, 0);
+}
+
+TEST_F(ClientRequestTest, not_allowed_N)
+{
+ int ret = 1;
+ WA::SocketManager manager;
+ try{
+ auto service = std::make_unique<WA::TestService>(std::make_shared<TestDLLoader>());
+ 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 = client_request_test_cb_display_qrcode;
+ mc_callbacks->response_callback = client_request_test_cb_mc_on_response;
+ 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->tc_num = TC_not_allowed_N;
+ mc_callbacks->user_data = mc_userdata;
+ retVal = wauthn_process<TestClientRequestMC>(&ClientRequestTestData::clientData,
+ &ClientRequestTestData::pubkeyCredCreationOptions, mc_callbacks);
+
+ EXPECT_EQ(retVal, WAUTHN_ERROR_NONE)
+ << "[wauthn_process<TestClientRequestMC>] failed. "
+ << "retVal=" << wauthn_error_to_string(ret) << std::endl;
+
+ sleep(1);
+
+ wauthn_ga_callbacks_s *ga_callbacks = nullptr;
+ ga_callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s));
+ ga_callbacks->qrcode_callback = client_request_test_cb_display_qrcode;
+ ga_callbacks->response_callback = client_request_test_cb_ga_on_response;
+ 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->tc_num = TC_not_allowed_N;
+ ga_callbacks->user_data = ga_userdata;
+ retVal = wauthn_process<TestClientRequestGA>(&ClientRequestTestData::clientData,
+ &ClientRequestTestData::pubkeyCredRequestOptions, ga_callbacks);
+
+ EXPECT_EQ(retVal, WAUTHN_ERROR_NOT_ALLOWED)
+ << "[wauthn_process<TestClientRequestGA>] failed. "
+ << "ret=" << wauthn_error_to_string(retVal) << std::endl;
+
+ sleep(5);
+ free(mc_userdata);
+ free(ga_userdata);
+ free(mc_callbacks);
+ free(ga_callbacks);
+ }
+ sleep(1);
+ ret = 0;
+ } catch (...) {
+ std::cout << "Error in starting service, unknown exception occured" << std::endl;
+ ret = -1;
+ }
+ EXPECT_EQ(ret, 0);
+}
+
+
+TEST_F(ClientRequestTest, cancel_P)
+{
+ int ret = 1;
+ WA::SocketManager manager;
+ try{
+ auto service = std::make_unique<WA::TestService>(std::make_shared<TestDLLoader>());
+ 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 = client_request_test_cb_display_qrcode;
+ mc_callbacks->response_callback = client_request_test_cb_mc_on_response;
+ 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->tc_num = TC_cancel_P;
+ mc_callbacks->user_data = mc_userdata;
+ retVal = wauthn_process<TestClientRequestMC>(&ClientRequestTestData::clientData,
+ &ClientRequestTestData::pubkeyCredCreationOptions, mc_callbacks);
+
+ EXPECT_EQ(retVal, WAUTHN_ERROR_NONE)
+ << "[wauthn_process<TestClientRequestMC>] failed. "
+ << "retVal=" << wauthn_error_to_string(ret) << std::endl;
+
+ sleep(1);
+ TestClientRequest request(WebAuthnCall::CANCEL);
+ if (request.sendRequest().failed())
+ LogError("Error on cancel request, Response: "
+ << 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);
+ free(mc_userdata);
+ free(mc_callbacks);
+ }
+ sleep(1);
+ ret = 0;
+ } catch (...) {
+ std::cout << "Error in starting service, unknown exception occured" << std::endl;
+ ret = -1;
+ }
+ EXPECT_EQ(ret, 0);
+}
+
+} // namespace WebAuthn
--- /dev/null
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd. All rights reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ *
+ *
+ * @file dl-loader-test.cpp
+ * @version 1.0
+ * @brief unit tests for dl-loader
+ */
+
+#include "test-common.h"
+
+#include <dl-loader.h>
+#include <gtest/gtest.h>
+#include <webauthn-hal.h>
+#include <iostream>
+
+namespace WA {
+
+class DLLoaderTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ // Do initialization if needed.
+ }
+
+ void TearDown() override {
+ // Do deinitialization if needed.
+ }
+};
+
+TEST_F(DLLoaderTest, DLLoader_P)
+{
+ int ret = 0;
+ try{
+ auto dlLoader = std::make_unique<DLLoader>(WAH_PLUGIN_SO_PATH_HYBRID);
+ } catch (...)
+ {
+ std::cout << "Error in make_unique DLLoader" << std::endl;
+ ret = -1;
+ }
+
+ EXPECT_EQ(ret, 0);
+}
+
+TEST_F(DLLoaderTest, DLLoader_N)
+{
+ int ret = 0;
+ try{
+ auto dlLoader = std::make_unique<DLLoader>("invalid_so_path");
+ } catch (...)
+ {
+ std::cout << "Error in make_unique DLLoader" << std::endl;
+ ret = -1;
+ }
+
+ EXPECT_EQ(ret, -1);
+}
+
+TEST_F(DLLoaderTest, Invoke_P)
+{
+ int ret = 0;
+ try{
+ auto dlLoader = std::make_unique<DLLoader>(WAH_PLUGIN_SO_PATH_HYBRID);
+ dlLoader->Invoke<int>(WAH_API_CANCEL);
+ } catch (...)
+ {
+ std::cout << "Error in make_unique DLLoader" << std::endl;
+ ret = -1;
+ }
+
+ EXPECT_EQ(ret, 0);
+}
+
+TEST_F(DLLoaderTest, Invoke_N)
+{
+ int ret = 0;
+ try{
+ auto dlLoader = std::make_unique<DLLoader>(WAH_PLUGIN_SO_PATH_HYBRID);
+ dlLoader->Invoke<int>("invalid_api_name");
+ } catch (...)
+ {
+ std::cout << "Error in make_unique DLLoader" << std::endl;
+ ret = -1;
+ }
+
+ EXPECT_EQ(ret, -1);
+}
+
+} // namespace WebAuthn
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd. All rights reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ *
+ *
+ * @file socket-manager-test.cpp
+ * @version 1.0
+ * @brief unit tests for socket-manager
+ */
+
+#include "test-common.h"
+
+#include <dl-loader.h>
+#include <socket-manager.h>
+#include <gtest/gtest.h>
+#include <iostream>
+#include <service.h>
+
+namespace WA {
+
+class TestService : public GenericService {
+public:
+ SocketManager::ServiceDescription GetServiceDescription() override {
+ return SocketManager::ServiceDescription {
+ TEST_SERVICE_SOCKET, /* path */
+ "*" /* smackLabel label (not used, we rely on systemd) */
+ };
+ }
+ TestService(std::shared_ptr<DLLoader> pluginHybrid) :
+ GenericService(pluginHybrid) {}
+ virtual ~TestService() {}
+};
+
+class SocketManagerTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ // Do initialization if needed.
+ }
+
+ void TearDown() override {
+ // Do deinitialization if needed.
+ }
+};
+
+class SocketManagerLoop final {
+public:
+ explicit SocketManagerLoop(SocketManager& manager) :
+ m_manager(manager),
+ m_thread([&]{
+ try {
+ manager.MainLoop();
+ } catch (const std::exception& e) {
+ m_exception = true;
+ m_what = e.what();
+ } catch (...) {
+ m_exception = true;
+ }
+ })
+ {
+ }
+
+ ~SocketManagerLoop() {
+ m_manager.MainLoopStop();
+ m_thread.join();
+ }
+
+private:
+ bool m_exception = false;
+ std::string m_what = "Unknown exception";
+ SocketManager& m_manager;
+ std::thread m_thread;
+};
+
+
+TEST_F(SocketManagerTest, mainloop_P)
+{
+ int ret = 1;
+ WA::SocketManager manager;
+ try{
+ auto service = std::make_unique<WA::TestService>(std::make_shared<DLLoader>(WAH_PLUGIN_SO_PATH_HYBRID));
+ manager.RegisterSocketService(std::move(service));
+ SocketManagerLoop loop(manager);
+ sleep(1);
+ ret = 0;
+ } catch (...) {
+ std::cout << "Error in starting service, unknown exception occured" << std::endl;
+ ret = -1;
+ }
+ EXPECT_EQ(ret, 0);
+}
+
+} // namespace WebAuthn
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd. All rights reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ *
+ *
+ * @file test-common.h
+ * @version 1.0
+ * @brief common header for test
+ */
+
+#pragma once
+
+#include <webauthn-types.h>
+
+namespace WA {
+
+inline constexpr auto TEST_SERVICE_SOCKET = "/tmp/.webauthn-test.socket";
+
+inline constexpr auto WAH_API_MC = "wah_make_credential";
+inline constexpr auto WAH_API_GA = "wah_get_assertion";
+inline constexpr auto WAH_API_CANCEL = "wah_cancel";
+
+} // namespace WebAuthn
\ No newline at end of file
int main(int argc, char *argv[])
{
-
WA::Singleton<WA::WebAuthnLog>::Instance().SetTag(WEBAUTHN_TEST_LOG_TAG);
-
bool ret = false;
- LogDebug("START");
#ifdef GCOV_BUILD
- LogDebug("SET GCOV_PREFIX");
+ std::cout << "SET GCOV_PREFIX" << std::endl;
setenv("GCOV_PREFIX", "/tmp", 1);
#endif
try {
ret = true;
}
#ifdef GCOV_BUILD
- LogDebug("The webauthn-server process need to be stopped to flush gcov");
std::cout << "The webauthn-server process need to be stopped to flush gcov"
<< std::endl;
#endif
#include <gtest/gtest.h>
#include <unistd.h>
#include <webauthn.h>
-#include <thread>
-namespace WA {
-
-using std::thread;
-#define WEBAUTHN_CODE_DESCRIBE(name) case name: return #name
+namespace WA {
namespace CommonTestData {
unsigned char clientDataJsonRaw[06] = {0x01, 0x02, 0x03, 0x04, };
wauthn_client_data_s emptyClientData = {nullptr, hashAlg};
}
-typedef struct _user_data_s {
- char *test_data;
- int test_int;
-} user_data_s;
-
class WebAuthnTest : public ::testing::Test {
protected:
void SetUp() override {
// Do deinitialization if needed.
}
};
+
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;
+
}
void test_cb_mc_on_response(const wauthn_pubkey_credential_attestaion_s *pubkey_cred,
wauthn_error_e result,
std::cout << "pubkey_cred is null" << std::endl;
else
std::cout << "pubkey_cred is not null: " <<
- pubkey_cred->type << ", " <<
- pubkey_cred->authenticator_attachment << std::endl;
+ pubkey_cred->type << ", " <<
+ pubkey_cred->authenticator_attachment << std::endl;
if (user_data == nullptr)
std::cout << "user_data is null" << std::endl;
- else
- std::cout << "user_data is not null:" <<
- (static_cast<user_data_s*>(user_data))->test_data <<
- ", " << (static_cast<user_data_s*>(user_data))->test_int << std::endl;
-
}
void test_cb_ga_on_response(const wauthn_pubkey_credential_assertion_s *pubkey_cred,
std::cout << "pubkey_cred is not null" << std::endl;
if (user_data == nullptr)
std::cout << "user_data is null" << std::endl;
- else
- std::cout << "user_data is not null:" <<
- (static_cast<user_data_s*>(user_data))->test_data <<
- ", " << (static_cast<user_data_s*>(user_data))->test_int << std::endl;
-
}
-TEST_F(WebAuthnTest, testMCRequest)
+TEST_F(WebAuthnTest, invalid_client_data_N)
{
int ret = WAUTHN_ERROR_NONE;
- wauthn_mc_callbacks_s *callbacks = nullptr;
- 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_on_response;
- user_data_s *userdata = (user_data_s*) calloc(1, sizeof(user_data_s));
- userdata->test_data = (char*)("user data");
- userdata->test_int = 10;
- callbacks->user_data = userdata;
- ret = wauthn_make_credential(&CommonTestData::clientData,
- &CommonTestData::pubkeyCredCreationOptions,
- callbacks);
+ 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_on_response;
+ ret = wauthn_make_credential(nullptr,
+ &CommonTestData::pubkeyCredCreationOptions,
+ mc_callbacks);
- EXPECT_EQ(ret, WAUTHN_ERROR_NONE)
- << "[wauthn_make_credential] failed. " << "ret=" << wauthn_error_to_string(ret) << std::endl;
- std::cout << "wauthn_make_credential ret=" << wauthn_error_to_string(ret) << std::endl;
- sleep(10);
-}
-TEST_F(WebAuthnTest, testMCRequestQR)
-{
- int ret = WAUTHN_ERROR_NONE;
+ EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER)
+ << "[wauthn_make_credential] failed. "
+ << "ret=" << wauthn_error_to_string(ret) << std::endl;
- wauthn_mc_callbacks_s *callbacks = nullptr;
- 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_on_response;
- user_data_s *userdata = (user_data_s*) calloc(1, sizeof(user_data_s));
- userdata->test_data = (char*)("user data");
- userdata->test_int = 10;
- callbacks->user_data = userdata;
- ret = wauthn_make_credential(&CommonTestData::clientData,
- &CommonTestData::pubkeyCredCreationOptionsWithQR,
- callbacks);
+ ret = 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_on_response;
+ ret = wauthn_get_assertion(nullptr,
+ &CommonTestData::pubkeyCredRequestOptions,
+ ga_callbacks);
+
+ EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER)
+ << "[wauthn_get_assertion] failed. "
+ << "ret=" << wauthn_error_to_string(ret) << std::endl;
- EXPECT_EQ(ret, WAUTHN_ERROR_NONE)
- << "[wauthn_make_credential] failed. " << "ret=" << wauthn_error_to_string(ret) << std::endl;
- std::cout << "wauthn_make_credential ret=" << wauthn_error_to_string(ret) << std::endl;
- sleep(10);
+ free(mc_callbacks);
+ free(ga_callbacks);
}
-TEST_F(WebAuthnTest, testGARequest)
+TEST_F(WebAuthnTest, invalid_options_N)
{
int ret = WAUTHN_ERROR_NONE;
- wauthn_ga_callbacks_s *callbacks = nullptr;
- 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_on_response;
- user_data_s *userdata = (user_data_s*) calloc(1, sizeof(user_data_s));
- userdata->test_data = (char*)("user data");
- userdata->test_int = 10;
- callbacks->user_data = userdata;
- ret = wauthn_get_assertion(&CommonTestData::clientData,
- &CommonTestData::pubkeyCredRequestOptions,
- callbacks);
- EXPECT_EQ(ret, WAUTHN_ERROR_NONE)
- << "[wauthn_get_assertion] failed. " << "ret=" << wauthn_error_to_string(ret) << std::endl;
- std::cout << "wauthn_get_assertion ret=" << wauthn_error_to_string(ret) << std::endl;
- sleep(10);
-}
+ 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_on_response;
+ ret = wauthn_make_credential(&CommonTestData::clientData,
+ nullptr,
+ mc_callbacks);
-TEST_F(WebAuthnTest, testGARequestQR)
-{
- int ret = WAUTHN_ERROR_NONE;
+ EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER)
+ << "[wauthn_make_credential] failed. "
+ << "ret=" << wauthn_error_to_string(ret) << std::endl;
- wauthn_ga_callbacks_s *callbacks = nullptr;
- 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_on_response;
- user_data_s *userdata = (user_data_s*) calloc(1, sizeof(user_data_s));
- userdata->test_data = (char*)("user data");
- userdata->test_int = 10;
- callbacks->user_data = userdata;
+ ret = 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_on_response;
ret = wauthn_get_assertion(&CommonTestData::clientData,
- &CommonTestData::pubkeyCredRequestOptionsWithQR,
- callbacks);
- EXPECT_EQ(ret, WAUTHN_ERROR_NONE)
- << "[wauthn_get_assertion] failed. " << "ret=" << wauthn_error_to_string(ret) << std::endl;
- std::cout << "wauthn_get_assertion ret=" << wauthn_error_to_string(ret) << std::endl;
- sleep(10);
+ nullptr,
+ ga_callbacks);
+
+ EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER)
+ << "[wauthn_get_assertion] failed. "
+ << "ret=" << wauthn_error_to_string(ret) << std::endl;
+
+ free(mc_callbacks);
+ free(ga_callbacks);
}
-TEST_F(WebAuthnTest, testNotAllowedByBusy)
+TEST_F(WebAuthnTest, invalid_callbacks_N)
{
int ret = WAUTHN_ERROR_NONE;
+ ret = wauthn_make_credential(&CommonTestData::clientData,
+ &CommonTestData::pubkeyCredCreationOptions,
+ nullptr);
+ EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER)
+ << "[wauthn_make_credential] failed. "
+ << "ret=" << wauthn_error_to_string(ret) << std::endl;
+ ret = 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_on_response;
+ mc_callbacks->response_callback = nullptr;
ret = wauthn_make_credential(&CommonTestData::clientData,
- &CommonTestData::pubkeyCredCreationOptions,
- mc_callbacks);
-
- EXPECT_EQ(ret, WAUTHN_ERROR_NONE)
- << "[wauthn_make_credential] failed. " << "ret=" << wauthn_error_to_string(ret) << std::endl;
- std::cout << "wauthn_make_credential ret=" << wauthn_error_to_string(ret) << std::endl;
+ &CommonTestData::pubkeyCredCreationOptions,
+ mc_callbacks);
+ EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER)
+ << "[wauthn_make_credential] failed. "
+ << "ret=" << wauthn_error_to_string(ret) << std::endl;
- sleep(1);
+ ret = WAUTHN_ERROR_NONE;
+ ret = wauthn_get_assertion(&CommonTestData::clientData,
+ &CommonTestData::pubkeyCredRequestOptions,
+ nullptr);
+ EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER)
+ << "[wauthn_get_assertion] failed. "
+ << "ret=" << wauthn_error_to_string(ret) << std::endl;
+ ret = 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_on_response;
+ ga_callbacks->response_callback = nullptr;
ret = wauthn_get_assertion(&CommonTestData::clientData,
- &CommonTestData::pubkeyCredRequestOptions,
- ga_callbacks);
-
- EXPECT_EQ(ret, WAUTHN_ERROR_NOT_ALLOWED)
- << "[wauthn_get_assertion] failed. " << "ret=" << wauthn_error_to_string(ret) << std::endl;
- std::cout << "wauthn_get_assertion ret=" << wauthn_error_to_string(ret) << std::endl;
- sleep(10);
+ &CommonTestData::pubkeyCredRequestOptions,
+ ga_callbacks);
+ EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER)
+ << "[wauthn_get_assertion] failed. "
+ << "ret=" << wauthn_error_to_string(ret) << std::endl;
+ free(mc_callbacks);
+ free(ga_callbacks);
}
-TEST_F(WebAuthnTest, testCancelOK)
+TEST_F(WebAuthnTest, miss_qr_callback_without_linked_data_N)
{
int ret = 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->qrcode_callback = nullptr;
mc_callbacks->response_callback = test_cb_mc_on_response;
ret = wauthn_make_credential(&CommonTestData::clientData,
- &CommonTestData::pubkeyCredCreationOptionsWithQR,
- mc_callbacks);
+ &CommonTestData::pubkeyCredCreationOptionsWithQR,
+ mc_callbacks);
+ EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER)
+ << "[wauthn_make_credential] failed. "
+ << "ret=" << wauthn_error_to_string(ret) << std::endl;
- EXPECT_EQ(ret, WAUTHN_ERROR_NONE)
- << "[wauthn_make_credential] failed. " << "ret=" << wauthn_error_to_string(ret) << std::endl;
- std::cout << "wauthn_make_credential ret=" << wauthn_error_to_string(ret) << std::endl;
-
- sleep(1);
-
- ret = wauthn_cancel();
- EXPECT_EQ(ret, WAUTHN_ERROR_NONE)
- << "[wauthn_cancel] failed. " << "ret=" << wauthn_error_to_string(ret) << std::endl;
- std::cout << "wauthn_cancel ret=" << wauthn_error_to_string(ret) << std::endl;
- sleep(10);
+ ret = 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 = nullptr;
+ ga_callbacks->response_callback = test_cb_ga_on_response;
+ ret = wauthn_get_assertion(&CommonTestData::clientData,
+ &CommonTestData::pubkeyCredRequestOptionsWithQR,
+ nullptr);
+ EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER)
+ << "[wauthn_get_assertion] failed. "
+ << "ret=" << wauthn_error_to_string(ret) << std::endl;
+ free(mc_callbacks);
+ free(ga_callbacks);
}
} // namespace WA