Reinforce parameter check logic and unittests 33/315633/13
authorYonggoo Kang <ygace.kang@samsung.com>
Mon, 5 Aug 2024 12:59:14 +0000 (21:59 +0900)
committerYonggoo Kang <ygace.kang@samsung.com>
Tue, 20 Aug 2024 07:44:20 +0000 (16:44 +0900)
- Update parameter check logic
- nullptr, invalid string, invalid setting
- Ingore some unknown enum values
- Modify some test-common data
- Update Webauthn API tests and add some positive cases

Change-Id: I4f568b99339fff278eb00797aae77d73ba3e6c80

srcs/common/utils.cpp
srcs/common/utils.h
tests/test-common.cpp
tests/test-common.h
tests/utils-tests.cpp
tests/webauthn-client-test.cpp

index 09b4370c7d83a23d5cee047036e5633b4e68f814..1066d3b11d8acbe218e776fcce57e4338194c37e 100644 (file)
 #include <utils.h>
 #include <webauthn-log.h>
 
-
 namespace WA {
 
+void CheckParameters(const char *str, const char *name, const bool checkBlank)
+{
+    if (!str)
+        ThrowMsg(ClientException::InvalidParameter, name << "->data is NULL");
+    int len = strlen(str);
+    if (checkBlank && (0 == len))
+        ThrowMsg(ClientException::InvalidParameter, "Invalid blank string: " << name);
+    if (' ' == str[0] || ' ' == str[len - 1])
+        LogWarning("Leading/tailing whitespaces on " << name << ": \"" << str << "\"");
+}
+
+void CheckParameters(const wauthn_const_buffer_s &buf, const char *name)
+{
+    if (!buf.data)
+        ThrowMsg(ClientException::InvalidParameter, name << "->data is NULL");
+    if (buf.size == 0)
+        ThrowMsg(ClientException::InvalidParameter, name << "->size is 0");
+}
+
+void CheckParameters(const wauthn_const_buffer_s *buf, const char *name)
+{
+    if (!buf)
+        ThrowMsg(ClientException::InvalidParameter, name << " is NULL");
+    CheckParameters(*buf, name);
+}
+
+void CheckParameters(const wauthn_hash_algorithm_e &value)
+{
+    switch (value) {
+    case WAUTHN_HASH_ALGORITHM_SHA_256:
+        return;
+    }
+    ThrowMsg(ClientException::InvalidParameter,
+             "Invalid hash algorithm: " << value);
+}
+
 void CheckParameters(const wauthn_client_data_s *client_data)
 {
-    if (client_data == nullptr)
-        ThrowMsg(ClientException::InvalidParameter, "Invalid client_data");
+    if (!client_data)
+        ThrowMsg(ClientException::InvalidParameter, "client_data is NULL");
+    CheckParameters(client_data->client_data_json, "client data json");
+    CheckParameters(client_data->hash_alg);
+}
+
+void CheckParameters(const wauthn_rp_entity_s *rp)
+{
+    if (!rp)
+        ThrowMsg(ClientException::InvalidParameter, "rp is NULL");
+    CheckParameters(rp->id, "rp->id", true);
+    CheckParameters(rp->name, "rp->name", true);
+}
+
+void CheckParameters(const wauthn_user_entity_s *user)
+{
+    if (!user)
+        ThrowMsg(ClientException::InvalidParameter, "user is NULL");
+    CheckParameters(user->name, "user->name", true);
+    CheckParameters(user->id, "user->id");
+    CheckParameters(user->display_name, "user->display_name", false);
 }
+
+void CheckParameters(const wauthn_pubkey_cred_type_e &value)
+{
+    switch (value) {
+    case WAUTHN_PUBKEY_CRED_TYPE_PUBLIC_KEY:
+        return;
+    }
+    LogWarning("Ignore unknown public key credential type: " << value);
+}
+
+void CheckParameters(const wauthn_cose_algorithm_e &value)
+{
+    switch (value) {
+    case WAUTHN_COSE_ALGORITHM_ECDSA_P256_WITH_SHA256:
+    case WAUTHN_COSE_ALGORITHM_ECDSA_P384_WITH_SHA384:
+    case WAUTHN_COSE_ALGORITHM_ECDSA_P521_WITH_SHA512:
+    case WAUTHN_COSE_ALGORITHM_EDDSA:
+    case WAUTHN_COSE_ALGORITHM_RSA_PSS_WITH_SHA256:
+    case WAUTHN_COSE_ALGORITHM_RSA_PSS_WITH_SHA384:
+    case WAUTHN_COSE_ALGORITHM_RSA_PSS_WITH_SHA512:
+    case WAUTHN_COSE_ALGORITHM_RSASSA_PKCS1_V1_5_WITH_SHA256:
+    case WAUTHN_COSE_ALGORITHM_RSASSA_PKCS1_V1_5_WITH_SHA384:
+    case WAUTHN_COSE_ALGORITHM_RSASSA_PKCS1_V1_5_WITH_SHA512:
+        return;
+    }
+    ThrowMsg(ClientException::InvalidParameter,
+             "Invalid credential algorithm: " << value);
+}
+
+void CheckParameters(const wauthn_pubkey_cred_params_s *pubkey_cred_params)
+{
+    if (!pubkey_cred_params)
+        ThrowMsg(ClientException::InvalidParameter, "pubkey_cred_params is NULL");
+    if (!pubkey_cred_params->params)
+        ThrowMsg(ClientException::InvalidParameter, "pubkey_cred_params->params is NULL");
+    if (pubkey_cred_params->size == 0)
+        ThrowMsg(ClientException::InvalidParameter, "pubkey_cred_params->size is 0");
+    for (size_t i = 0; i < pubkey_cred_params->size; ++i)
+    {
+        auto param = pubkey_cred_params->params[i];
+        CheckParameters(param.type);
+        CheckParameters(param.alg);
+    }
+}
+
+void CheckParameters(const unsigned int value)
+{
+    if (value >> 6)
+        LogWarning("Ignore unknown transports value: " << value);
+}
+
+void CheckParameters(const wauthn_pubkey_cred_descriptors_s *cred_descriptors)
+{
+    if (!cred_descriptors)
+        return;
+    if (!cred_descriptors->descriptors)
+        ThrowMsg(ClientException::InvalidParameter, "cred_descriptors->descriptors is NULL");
+    if (cred_descriptors->size == 0)
+        ThrowMsg(ClientException::InvalidParameter, "cred_descriptors->size is 0");
+    for (size_t i = 0; i < cred_descriptors->size; ++i)
+    {
+        auto desc = cred_descriptors->descriptors[i];
+        CheckParameters(desc.type);
+        CheckParameters(desc.id, "descriptor->id");
+        CheckParameters(desc.transports);
+    }
+}
+
+void CheckParameters(const wauthn_authenticator_attachment_e &value)
+{
+    switch (value) {
+    case WAUTHN_AUTHENTICATOR_ATTACHMENT_NONE:
+    case WAUTHN_AUTHENTICATOR_ATTACHMENT_PLATFORM:
+    case WAUTHN_AUTHENTICATOR_ATTACHMENT_CROSS_PLATFORM:
+        return;
+    }
+    LogWarning("Ignore unknown authenticator attachment value: " << value);
+}
+
+void CheckParameters(const wauthn_resident_key_requirement_e &value)
+{
+    switch (value) {
+    case WAUTHN_RESIDENT_KEY_REQUIREMENT_NONE:
+    case WAUTHN_RESIDENT_KEY_REQUIREMENT_DISCOURAGED:
+    case WAUTHN_RESIDENT_KEY_REQUIREMENT_PREFERRED:
+    case WAUTHN_RESIDENT_KEY_REQUIREMENT_REQUIRED:
+        return;
+    }
+    LogWarning("Ignore unknown resident key requirement value: " << value);
+}
+
+void CheckParameters(const wauthn_user_verification_requirement_e &value)
+{
+    switch (value) {
+    case WAUTHN_USER_VERIFICATION_REQUIREMENT_NONE:
+    case WAUTHN_USER_VERIFICATION_REQUIREMENT_REQUIRED:
+    case WAUTHN_USER_VERIFICATION_REQUIREMENT_PREFERRED:
+    case WAUTHN_USER_VERIFICATION_REQUIREMENT_DISCOURAGED:
+        return;
+    }
+    LogWarning("Ignore unknown user verification requirement value: " << value);
+}
+
+void CheckParameters(const wauthn_authenticator_sel_cri_s *authenticator_selection)
+{
+    if (!authenticator_selection)
+        return;
+    CheckParameters(authenticator_selection->attachment);
+    CheckParameters(authenticator_selection->resident_key);
+    CheckParameters(authenticator_selection->user_verification);
+    if(authenticator_selection->require_resident_key
+       && authenticator_selection->resident_key != WAUTHN_RESIDENT_KEY_REQUIREMENT_REQUIRED)
+       ThrowMsg(ClientException::InvalidParameter,
+                "require_resident_key SHOULD setted to true"
+                << "when resident_key is setted to required");
+}
+
+void CheckParameters(const wauthn_pubkey_cred_hint_e &value)
+{
+    switch (value) {
+    case WAUTHN_PUBKEY_CRED_HINT_NONE:
+    case WAUTHN_PUBKEY_CRED_HINT_SECURITY_KEY:
+    case WAUTHN_PUBKEY_CRED_HINT_CLIENT_DEVICE:
+    case WAUTHN_PUBKEY_CRED_HINT_HYBRID:
+        return;
+    }
+    LogWarning("Ignore unknown hint value: " << value);
+}
+
+void CheckParameters(const wauthn_pubkey_cred_hints_s *hints)
+{
+    if (!hints)
+        return;
+    if (!hints->hints)
+        ThrowMsg(ClientException::InvalidParameter, "hints->hints is NULL");
+    if (hints->size == 0)
+        ThrowMsg(ClientException::InvalidParameter, "hints->size is 0");
+    for (size_t i = 0; i < hints->size; ++i)
+    {
+        auto hint = hints->hints[i];
+        CheckParameters(hint);
+    }
+}
+
+void CheckParameters(const wauthn_attestation_pref_e &value)
+{
+    switch (value) {
+    case WAUTHN_ATTESTATION_PREF_NONE:
+    case WAUTHN_ATTESTATION_PREF_INDIRECT:
+    case WAUTHN_ATTESTATION_PREF_DIRECT:
+    case WAUTHN_ATTESTATION_PREF_ENTERPRISE:
+        return;
+    }
+    LogWarning("Ignore unknown attestation preference value: " << value);
+}
+
+void CheckParameters(const wauthn_attestation_formats_s *attestation_formats)
+{
+    if (!attestation_formats)
+        return;
+    if (!attestation_formats->attestation_formats)
+        ThrowMsg(ClientException::InvalidParameter,
+                "attestation_formats->attestation_formats is NULL");
+    if (attestation_formats->size == 0)
+        ThrowMsg(ClientException::InvalidParameter, "attestation_formats->size is 0");
+    for (size_t i = 0; i < attestation_formats->size; ++i)
+    {
+        auto format = attestation_formats->attestation_formats[i];
+        CheckParameters(format, "attestation_format");
+    }
+}
+
+void CheckParameters(const wauthn_authentication_exts_s *extensions)
+{
+    if (!extensions)
+        return;
+    if (!extensions->extensions)
+        ThrowMsg(ClientException::InvalidParameter, "extensions->extensions is NULL");
+    if (extensions->size == 0)
+        ThrowMsg(ClientException::InvalidParameter, "extensions->size is 0");
+    for (size_t i = 0; i < extensions->size; ++i)
+    {
+        auto extension = extensions->extensions[i];
+        CheckParameters(extension.extension_id, "extension id");
+        CheckParameters(extension.extension_value, "extension value");
+    }
+}
+
+void CheckParameters(const wauthn_hybrid_linked_data_s *linked_device,
+                     const unsigned int flags)
+{
+    if (!linked_device)
+        return;
+    if (flags & CHECK_CONTACT_ID)
+        CheckParameters(linked_device->contact_id, "contact id");
+    if (flags & CHECK_LINK_ID)
+        CheckParameters(linked_device->link_id, "link id");
+    if (flags & CHECK_LINK_SECRET)
+        CheckParameters(linked_device->link_secret, "link secret");
+    if (flags & CHECK_AUTHENTICATOR_PUBKEY)
+        CheckParameters(linked_device->authenticator_pubkey, "authenticator pubkey");
+    if (flags & CHECK_AUTHENTICATOR_NAME)
+        CheckParameters(linked_device->authenticator_name, "authenticator name");
+    if (flags & CHECK_SIGNATURE)
+        CheckParameters(linked_device->signature, "signature");
+    if (flags & CHECK_TUNNEL_SERVER_DOMAIN)
+        CheckParameters(linked_device->tunnel_server_domain, "tunnel server domain");
+    if (flags & CHECK_IDENTITY_KEY)
+        CheckParameters(linked_device->identity_key, "identity key");
+}
+
 void CheckParameters(const wauthn_pubkey_cred_creation_options_s *options)
 {
-    if (options == nullptr)
-        ThrowMsg(ClientException::InvalidParameter, "Invalid options");
+    if (!options)
+        ThrowMsg(ClientException::InvalidParameter, "options is NULL");
+    CheckParameters(options->rp);
+    CheckParameters(options->user);
+    CheckParameters(options->pubkey_cred_params);
+    CheckParameters(options->exclude_credentials);
+    CheckParameters(options->authenticator_selection);
+    CheckParameters(options->hints);
+    CheckParameters(options->attestation);
+    CheckParameters(options->attestation_formats);
+    CheckParameters(options->extensions);
+    CheckParameters(options->linked_device, CHECK_PARAMETER_ALL);
 }
+
 void CheckParameters(const wauthn_pubkey_cred_request_options_s *options)
 {
-    if (options == nullptr)
-        ThrowMsg(ClientException::InvalidParameter, "Invalid options");
+    if (!options)
+        ThrowMsg(ClientException::InvalidParameter, "options is NULL");
+    CheckParameters(options->rpId, "options->rpId", true);
+    CheckParameters(options->allow_credentials);
+    CheckParameters(options->user_verification);
+    CheckParameters(options->hints);
+    CheckParameters(options->attestation);
+    CheckParameters(options->attestation_formats);
+    CheckParameters(options->extensions);
+    CheckParameters(options->linked_device, CHECK_PARAMETER_ALL);
 }
+
+void CheckParameters(wauthn_update_linked_data_cb callback)
+{
+    if (!callback)
+        ThrowMsg(ClientException::InvalidParameter,
+                 "linked_data_callback is NULL");
+}
+
 void CheckParameters(wauthn_mc_callbacks_s *callbacks)
 {
-    if (callbacks == nullptr || callbacks->response_callback == nullptr
-        || callbacks->linked_data_callback == nullptr)
-        ThrowMsg(ClientException::InvalidParameter, "Invalid callback");
+    if (!callbacks)
+        ThrowMsg(ClientException::InvalidParameter, "callbacks is NULL");
+    if (!callbacks->response_callback)
+        ThrowMsg(ClientException::InvalidParameter, "response_callback is NULL");
+    CheckParameters(callbacks->linked_data_callback);
 }
+
 void CheckParameters(wauthn_ga_callbacks_s *callbacks)
 {
-    if (callbacks == nullptr || callbacks->response_callback == nullptr
-        || callbacks->linked_data_callback == nullptr)
-        ThrowMsg(ClientException::InvalidParameter, "Invalid callback");
+    if (!callbacks)
+        ThrowMsg(ClientException::InvalidParameter, "callbacks is NULL");
+    if (!callbacks->response_callback)
+        ThrowMsg(ClientException::InvalidParameter, "response_callback is NULL");
+    CheckParameters(callbacks->linked_data_callback);
 }
+
 void CheckParameters(wauthn_hybrid_linked_data_s *linked_device,
                     wauthn_display_qrcode_cb qrcode_callback)
 {
-    if (linked_device == nullptr && qrcode_callback == nullptr)
-        ThrowMsg(ClientException::InvalidParameter, "The qrcode_callback is missed");
+    if (!linked_device && !qrcode_callback)
+        ThrowMsg(ClientException::InvalidParameter,
+                 "If linked_device is NULL, a qrcode_callback is required");
 }
+
 void CheckParameters(const wauthn_client_data_s *client_data,
                     const wauthn_pubkey_cred_creation_options_s *options,
                     wauthn_mc_callbacks_s *callbacks)
@@ -67,6 +367,7 @@ void CheckParameters(const wauthn_client_data_s *client_data,
     CheckParameters(callbacks);
     CheckParameters(options->linked_device, callbacks->qrcode_callback);
 }
+
 void CheckParameters(const wauthn_client_data_s *client_data,
                     const wauthn_pubkey_cred_request_options_s *options,
                     wauthn_ga_callbacks_s *callbacks)
@@ -76,4 +377,5 @@ void CheckParameters(const wauthn_client_data_s *client_data,
     CheckParameters(callbacks);
     CheckParameters(options->linked_device, callbacks->qrcode_callback);
 }
+
 } /* namespace WebAuthn */
index 8a79125522190110c05633c86f77e69f50cdca1c..e4184b244f6967a898dbdde31abe3b9c5a028c63 100644 (file)
@@ -47,7 +47,8 @@ int try_catch(F &&f) {
         return WAUTHN_ERROR_INVALID_PARAMETER;
     } catch (const SerializationException::InvalidStreamData &e) {
         LogError("WA::SerializationException::InvalidStreamData: " << e.DumpToString());
-        std::cerr << "WA::SerializationException::InvalidStreamData: " << e.DumpToString() << std::endl;
+        std::cerr << "WA::SerializationException::InvalidStreamData: " << e.DumpToString()
+                  << std::endl;
         return WAUTHN_ERROR_INVALID_PARAMETER;
     } catch (const MessageBufferException::OutOfData &e) {
         LogError("WA::MessageBufferException::OutOfData: " << e.DumpToString());
@@ -93,28 +94,25 @@ int try_catch(F &&f) {
     return WAUTHN_ERROR_NONE;
 }
 
-void CheckParameters(const wauthn_client_data_s *client_data);
-void CheckParameters(const wauthn_pubkey_cred_creation_options_s *options);
-void CheckParameters(const wauthn_pubkey_cred_request_options_s *options);
-void CheckParameters(wauthn_mc_callbacks_s *callbacks);
-void CheckParameters(wauthn_ga_callbacks_s *callbacks);
-void CheckParameters(wauthn_hybrid_linked_data_s *linked_device,
-                    wauthn_display_qrcode_cb qrcode_callback);
+typedef enum __check_linked_device_flag {
+    CHECK_CONTACT_ID                = 0x00000001,
+    CHECK_LINK_ID                   = 0x00000002,
+    CHECK_LINK_SECRET               = 0x00000004,
+    CHECK_AUTHENTICATOR_PUBKEY      = 0x00000008,
+    CHECK_AUTHENTICATOR_NAME        = 0x00000010,
+    CHECK_SIGNATURE                 = 0x00000020,
+    CHECK_TUNNEL_SERVER_DOMAIN      = 0x00000040,
+    CHECK_IDENTITY_KEY              = 0x00000080,
+    CHECK_PARAMETER_ALL             = 0x000000CF,
+    CHECK_ALL                       = 0x000000FF,
+} check_linked_device_flag_e;
+
 void CheckParameters(const wauthn_client_data_s *client_data,
                     const wauthn_pubkey_cred_creation_options_s *options,
                     wauthn_mc_callbacks_s *callbacks);
+
 void CheckParameters(const wauthn_client_data_s *client_data,
                     const wauthn_pubkey_cred_request_options_s *options,
                     wauthn_ga_callbacks_s *callbacks);
 
 } // namespace WebAuthn
-
-template <class E>
-constexpr auto underlying(const E &e) {
-    return std::underlying_type_t<E>(e);
-}
-
-template <class T, size_t S>
-constexpr size_t arraySize(T (&)[S]) {
-    return S;
-}
index 1dad5a0e33250ca35668d54471f1020bb81007cc..59d3cdf268dbf2ac7546202b6aeffc69f6f1209d 100644 (file)
 namespace WA {
 
 namespace TestCommonData {
-    unsigned char clientDataJsonRaw[06] = {0x01, 0x02, 0x03, 0x04, };
+    unsigned char clientDataJsonRaw[] = "{}";
     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 clientDataJson = {clientDataJsonRaw, sizeof(clientDataJsonRaw) - 1};
     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};
+            = {&clientDataJson, &attestationObject, transports, &authenticatorData,
+               &subjectPubkeyInfo, pubkey_alg};
     wauthn_authenticator_attestation_response_s emptyAuthenticatorAttestationResponse
             = {nullptr, nullptr, 0x00, nullptr, nullptr, pubkey_alg};
 
@@ -48,24 +49,28 @@ namespace TestCommonData {
     wauthn_authenticator_assertion_response_s emptyAuthenticatorAssertionResponse
             = {nullptr, nullptr, nullptr, nullptr, nullptr};
 
-    const char *name = "test name";
-    const char *id = "test id";
+    const char *name = "webauthn test";
+    const char *id = "webauthn-test.com";
     wauthn_rp_entity_s rpEntity = {name, id};
     wauthn_rp_entity_s emptyRpEntity = {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)};
+    const char *displayName = "webauthn display name";
+    wauthn_user_entity_s userEntity = {name, &bufferId, displayName};
     wauthn_user_entity_s emptyUserEntity = {nullptr, nullptr, nullptr};
 
     wauthn_pubkey_cred_type_e pubkeyCredType = WAUTHN_PUBKEY_CRED_TYPE_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 credParam0 = {pubkeyCredType,
+                                             WAUTHN_COSE_ALGORITHM_RSASSA_PKCS1_V1_5_WITH_SHA256};
+    wauthn_pubkey_cred_param_s credParam1 = {pubkeyCredType,
+                                             WAUTHN_COSE_ALGORITHM_ECDSA_P256_WITH_SHA256};
     wauthn_pubkey_cred_param_s pubkeyCredParam2[2] = {credParam0, credParam1};
-    wauthn_pubkey_cred_params_s pubkeyCredParams2 = {sizeof(pubkeyCredParam2)/sizeof(pubkeyCredParam2[0]), pubkeyCredParam2};
+    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 pubkeyCredParams1 =
+        {sizeof(pubkeyCredParam1)/sizeof(pubkeyCredParam1[0]), pubkeyCredParam1};
     wauthn_pubkey_cred_params_s emptyPubkeyCredParams = {0, nullptr};
 
     wauthn_pubkey_cred_descriptor_s pubkeyCredDescriptor = {pubkeyCredType, &bufferId, 3};
@@ -78,11 +83,11 @@ namespace TestCommonData {
     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_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 pubkeyCredDescriptors1 =
+        {sizeof(pubkeyCredDescriptor1)/sizeof(pubkeyCredDescriptor1[0]), pubkeyCredDescriptor1};
     wauthn_pubkey_cred_descriptors_s emptyPubkeyCredDescriptors = {0, nullptr};
 
     unsigned char extensionIdRaw[06] = {0x01, 0x02, 0x03, 0x04, };
@@ -99,25 +104,28 @@ namespace TestCommonData {
     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 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 = WAUTHN_AUTHENTICATOR_ATTACHMENT_PLATFORM;
     wauthn_resident_key_requirement_e resident_key = WAUTHN_RESIDENT_KEY_REQUIREMENT_PREFERRED;
     bool require_resident_key = false;
-    wauthn_user_verification_requirement_e user_verification = WAUTHN_USER_VERIFICATION_REQUIREMENT_DISCOURAGED;
-    wauthn_authenticator_sel_cri_s authenticatorSelCri = {attachment, resident_key,
-                                require_resident_key, user_verification};
+    wauthn_user_verification_requirement_e user_verification =
+        WAUTHN_USER_VERIFICATION_REQUIREMENT_DISCOURAGED;
+    wauthn_authenticator_sel_cri_s authenticatorSelCri =
+        {attachment, resident_key, require_resident_key, user_verification};
 
     wauthn_pubkey_cred_hint_e hint0 = WAUTHN_PUBKEY_CRED_HINT_SECURITY_KEY;
     wauthn_pubkey_cred_hint_e hint1 = WAUTHN_PUBKEY_CRED_HINT_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 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, };
@@ -130,14 +138,17 @@ namespace TestCommonData {
     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 authenticatorPubkey =
+        {authenticatorPubkeyRaw, sizeof(authenticatorPubkeyRaw)};
     wauthn_const_buffer_s authenticatorName = {authenticatorNameRaw, sizeof(authenticatorNameRaw)};
     wauthn_const_buffer_s identityKey = {identityKeyRaw, sizeof(identityKeyRaw)};
-    wauthn_const_buffer_s tunnelServerDomain = {tunnelServerDomainRaw, sizeof(tunnelServerDomainRaw)};
-    wauthn_hybrid_linked_data_s hybridLinkedData = {&contactId, &linkId, &linkSecret, &authenticatorPubkey,
-                                &authenticatorName, &signature, &tunnelServerDomain, &identityKey};
-    wauthn_hybrid_linked_data_s emptyHybridLinkedData = {nullptr, nullptr, nullptr, nullptr,
-                                            nullptr, nullptr, nullptr, nullptr};
+    wauthn_const_buffer_s tunnelServerDomain =
+        {tunnelServerDomainRaw, sizeof(tunnelServerDomainRaw)};
+    wauthn_hybrid_linked_data_s hybridLinkedData =
+        {&contactId, &linkId, &linkSecret, &authenticatorPubkey,
+         &authenticatorName, &signature, &tunnelServerDomain, &identityKey};
+    wauthn_hybrid_linked_data_s emptyHybridLinkedData =
+        {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
 
     unsigned char bufferRaw0[06] = {0x01, 0x02, 0x03, 0x04, };
     unsigned char bufferRaw1[16] = {0x11, 0x12, 0x13, 0x14, };
@@ -145,45 +156,64 @@ namespace TestCommonData {
     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 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 = WAUTHN_ATTESTATION_PREF_DIRECT;
-    wauthn_pubkey_cred_creation_options_s pubkeyCredCreationOptions = {&rpEntity, &userEntity,
-            &pubkeyCredParams2, timeout, &pubkeyCredDescriptors2, &authenticatorSelCri, &pubkeyCredHints2,
-            attestation, &attestationFormats1, &authenticationExts2, &hybridLinkedData};
-    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,
-            nullptr, 0, nullptr, nullptr, nullptr, WAUTHN_ATTESTATION_PREF_NONE, nullptr, nullptr, nullptr};
+    wauthn_pubkey_cred_creation_options_s pubkeyCredCreationOptions =
+        {&rpEntity, &userEntity, &pubkeyCredParams2, timeout, &pubkeyCredDescriptors2,
+         &authenticatorSelCri, &pubkeyCredHints2, attestation, &attestationFormats1,
+         &authenticationExts2, &hybridLinkedData};
+    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, nullptr, 0, nullptr, nullptr, nullptr, WAUTHN_ATTESTATION_PREF_NONE,
+         nullptr, nullptr, nullptr};
+    wauthn_pubkey_cred_creation_options_s pubkeyCredCreationOptionsOK =
+        {&rpEntity, &userEntity, &pubkeyCredParams2, 0, nullptr, nullptr, nullptr,
+            WAUTHN_ATTESTATION_PREF_NONE, nullptr, nullptr, &hybridLinkedData};
+    wauthn_pubkey_cred_creation_options_s pubkeyCredCreationOptionsOKNoLD =
+        {&rpEntity, &userEntity, &pubkeyCredParams2, 0, nullptr, nullptr, nullptr,
+            WAUTHN_ATTESTATION_PREF_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, &hybridLinkedData};
-    wauthn_pubkey_cred_request_options_s pubkeyCredRequestOptionsNoLD = {timeout, const_cast<char *>(rpId),
-            &pubkeyCredDescriptors2, user_verification, &pubkeyCredHints2, attestation, &attestationFormats1,
-            &authenticationExts2, nullptr};
-    wauthn_pubkey_cred_request_options_s emptyPubkeyCredRequestOptions = {0, nullptr,
-            nullptr, WAUTHN_USER_VERIFICATION_REQUIREMENT_NONE, nullptr, WAUTHN_ATTESTATION_PREF_NONE, nullptr, nullptr, nullptr};
-
-    wauthn_pubkey_credential_attestation_s pubkeyCredentialAttestation = {&bufferId, pubkeyCredType, &bufferId0,
-            &authenticatorAttestationResponse, attachment, &authenticationExts2, &hybridLinkedData};
-    wauthn_pubkey_credential_attestation_s emptyPubkeyCredentialAttestation = {nullptr, pubkeyCredType, nullptr,
-            nullptr, attachment, nullptr, nullptr};
-
-    wauthn_pubkey_credential_assertion_s pubkeyCredentialAssertion = {&bufferId, pubkeyCredType, &bufferId0,
-            &authenticatorAssertionResponse, attachment, &authenticationExts2, &hybridLinkedData};
-    wauthn_pubkey_credential_assertion_s emptyPubkeyCredentialAssertion = {nullptr, pubkeyCredType, nullptr,
-            nullptr, attachment, nullptr, nullptr};
+    wauthn_pubkey_cred_request_options_s pubkeyCredRequestOptions =
+        {timeout, rpId, &pubkeyCredDescriptors2, user_verification, &pubkeyCredHints2, attestation,
+         &attestationFormats1, &authenticationExts2, &hybridLinkedData};
+    wauthn_pubkey_cred_request_options_s pubkeyCredRequestOptionsNoLD =
+        {timeout, rpId, &pubkeyCredDescriptors2, user_verification, nullptr, attestation,
+         &attestationFormats1, &authenticationExts2, nullptr};
+    wauthn_pubkey_cred_request_options_s emptyPubkeyCredRequestOptions =
+        {0, nullptr, nullptr, WAUTHN_USER_VERIFICATION_REQUIREMENT_NONE, nullptr,
+         WAUTHN_ATTESTATION_PREF_NONE, nullptr, nullptr, nullptr};
+    wauthn_pubkey_cred_request_options_s pubkeyCredRequestOptionsOK =
+        {0, rpId, nullptr, WAUTHN_USER_VERIFICATION_REQUIREMENT_NONE, nullptr,
+         WAUTHN_ATTESTATION_PREF_NONE, nullptr, nullptr, &hybridLinkedData};
+    wauthn_pubkey_cred_request_options_s pubkeyCredRequestOptionsOKNoLD =
+        {0, rpId, nullptr, WAUTHN_USER_VERIFICATION_REQUIREMENT_NONE, nullptr,
+            WAUTHN_ATTESTATION_PREF_NONE, nullptr, nullptr, nullptr};
+
+    wauthn_pubkey_credential_attestation_s pubkeyCredentialAttestation =
+        {&bufferId, pubkeyCredType, &bufferId0, &authenticatorAttestationResponse, attachment,
+         &authenticationExts2, &hybridLinkedData};
+    wauthn_pubkey_credential_attestation_s emptyPubkeyCredentialAttestation =
+        {nullptr, pubkeyCredType, nullptr, nullptr, attachment, nullptr, nullptr};
+
+    wauthn_pubkey_credential_assertion_s pubkeyCredentialAssertion =
+        {&bufferId, pubkeyCredType, &bufferId0, &authenticatorAssertionResponse, attachment,
+         &authenticationExts2, &hybridLinkedData};
+    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 clientData = {&clientDataJson, hashAlg};
     wauthn_client_data_s emptyClientData = {nullptr, hashAlg};
 } // namespace TestCommonData
 
index 54ec7522c996854efff16b266024dada26c1591a..f9dac1705e3bf49e270671c41d21274744317ed5 100644 (file)
@@ -101,7 +101,8 @@ inline void test_cb_update_linked_data(
     wauthn_error_e result,
     void *user_data)
 {
-    std::cout << "update_linked_data, result: " << get_error_message(result) << std::endl;
+    std::cout << "update_linked_data, result: " << get_error_message(result)
+              << std::endl;
     if (linked_data == nullptr)
         std::cout << "linked_data is null" << std::endl;
     else
@@ -111,7 +112,7 @@ inline void test_cb_update_linked_data(
 }
 
 namespace TestCommonData {
-    extern unsigned char clientDataJsonRaw[06];
+    extern unsigned char clientDataJsonRaw[];
     extern unsigned char attestationObjectRaw[16];
     extern unsigned char authenticatorDataRaw[26];
     extern unsigned char subjectPubkeyInfoRaw[36];
@@ -230,11 +231,15 @@ namespace TestCommonData {
     extern wauthn_pubkey_cred_creation_options_s pubkeyCredCreationOptions;
     extern wauthn_pubkey_cred_creation_options_s pubkeyCredCreationOptionsNoLD;
     extern wauthn_pubkey_cred_creation_options_s emptyPubkeyCredCreationOptions;
+    extern wauthn_pubkey_cred_creation_options_s pubkeyCredCreationOptionsOK;
+    extern wauthn_pubkey_cred_creation_options_s pubkeyCredCreationOptionsOKNoLD;
 
     extern const char *rpId;
     extern wauthn_pubkey_cred_request_options_s pubkeyCredRequestOptions;
     extern wauthn_pubkey_cred_request_options_s pubkeyCredRequestOptionsNoLD;
     extern wauthn_pubkey_cred_request_options_s emptyPubkeyCredRequestOptions;
+    extern wauthn_pubkey_cred_request_options_s pubkeyCredRequestOptionsOK;
+    extern wauthn_pubkey_cred_request_options_s pubkeyCredRequestOptionsOKNoLD;
 
     extern wauthn_pubkey_credential_attestation_s pubkeyCredentialAttestation;
     extern wauthn_pubkey_credential_attestation_s emptyPubkeyCredentialAttestation;
index 2cb3ee332c3b7f2f565889bd4a59f7b776227a69..36050e96d714a7aafa6e609c6047ff7a5e23772c 100644 (file)
 
 #include <gtest/gtest.h>
 #include <iostream>
+#include <limits>
 #include <utils.h>
-
+#include "test-common.h"
 
 namespace WA {
+void CheckParameters(const char *str, const char *name, const bool checkBlank);
+void CheckParameters(const wauthn_client_data_s *client_data);
+void CheckParameters(const wauthn_rp_entity_s *rp);
+void CheckParameters(const wauthn_user_entity_s *user);
+void CheckParameters(const wauthn_pubkey_cred_params_s *pubkey_cred_params);
+void CheckParameters(const wauthn_pubkey_cred_descriptors_s *cred_descriptors);
+void CheckParameters(const wauthn_authenticator_sel_cri_s *authenticator_selection);
+void CheckParameters(const wauthn_pubkey_cred_hints_s *hints);
+void CheckParameters(const wauthn_attestation_formats_s *attestation_formats);
+void CheckParameters(const wauthn_authentication_exts_s *extensions);
+void CheckParameters(const wauthn_hybrid_linked_data_s *linked_device,
+                     const unsigned int flags);
+void CheckParameters(const wauthn_pubkey_cred_creation_options_s *options);
+void CheckParameters(const wauthn_pubkey_cred_request_options_s *options);
 
 class UtilsTest : public ::testing::Test {
 protected:
@@ -37,80 +52,1323 @@ protected:
     }
 };
 
-TEST_F(UtilsTest, handle_exceptions_by_try_catch_function_P)
+TEST_F(UtilsTest, handle_exceptions_by_try_catch_functions_P)
 {
     int ret = try_catch([&]() -> int {
         Throw(SerializationException::InvalidStreamData);
     });
     EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
-    std::cout << "ret: " << get_error_message(ret) << std::endl;
 
     ret = try_catch([&]() -> int {
         Throw(MessageBufferException::OutOfData);
     });
     EXPECT_EQ(ret, WAUTHN_ERROR_OUT_OF_MEMORY);
-    std::cout << "ret: " << get_error_message(ret) << std::endl;
 
     ret = try_catch([&]() -> int {
         Throw(ServiceException::InvalidAction);
     });
     EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_STATE);
-    std::cout << "ret: " << get_error_message(ret) << std::endl;
 
     ret = try_catch([&]() -> int {
         Throw(ServiceException::InActive);
     });
     EXPECT_EQ(ret, WAUTHN_ERROR_SOCKET);
-    std::cout << "ret: " << get_error_message(ret) << std::endl;
 
     ret = try_catch([&]() -> int {
         Throw(FileLockerException::LockFailed);
     });
     EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_STATE);
-    std::cout << "ret: " << get_error_message(ret) << std::endl;
 
     ret = try_catch([&]() -> int {
         Throw(SocketManagerException::InitFailed);
     });
     EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_STATE);
-    std::cout << "ret: " << get_error_message(ret) << std::endl;
 
     ret = try_catch([&]() -> int {
         throw std::logic_error("logic error");
     });
     EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_STATE);
-    std::cout << "ret: " << get_error_message(ret) << std::endl;
 
     ret = try_catch([&]() -> int {
         throw std::bad_alloc();
     });
     EXPECT_EQ(ret, WAUTHN_ERROR_OUT_OF_MEMORY);
-    std::cout << "ret: " << get_error_message(ret) << std::endl;
 
     ret = try_catch([&]() -> int {
         throw std::system_error();
     });
     EXPECT_EQ(ret, WAUTHN_ERROR_UNKNOWN);
-    std::cout << "ret: " << get_error_message(ret) << std::endl;
 
     ret = try_catch([&]() -> int {
         throw std::exception();
     });
     EXPECT_EQ(ret, WAUTHN_ERROR_UNKNOWN);
-    std::cout << "ret: " << get_error_message(ret) << std::endl;
 
     ret = try_catch([&]() -> int {
         throw std::overflow_error("overflow_error");
     });
     EXPECT_EQ(ret, WAUTHN_ERROR_UNKNOWN);
-    std::cout << "ret: " << get_error_message(ret) << std::endl;
 
     ret = try_catch([&]() -> int {
         return WAUTHN_ERROR_NONE;
     });
     EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
-    std::cout << "ret: " << get_error_message(ret) << std::endl;
+}
+
+TEST_F(UtilsTest, check_parameter_invalid_blank_str_N)
+{
+    const char str[] = "";
+    int ret = try_catch([&]() -> int {
+        CheckParameters(str, "test string", true);
+        return WAUTHN_ERROR_NONE;
+    });
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_invalid_str_skip_P)
+{
+    const char str[] = "";
+    int ret = try_catch([&]() -> int {
+        CheckParameters(str, "test string", false);
+        return WAUTHN_ERROR_NONE;
+    });
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+
+    const char str2[] = "   lead spaces";
+
+    ret = try_catch([&]() -> int {
+        CheckParameters(str2, "lead spaces", false);
+        return WAUTHN_ERROR_NONE;
+    });
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+
+    const char str3[] = "tail spaces   ";
+
+    ret = try_catch([&]() -> int {
+        CheckParameters(str3, "tail spaces", false);
+        return WAUTHN_ERROR_NONE;
+    });
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+}
+
+TEST_F(UtilsTest, check_parameter_clientdatajson_null_N)
+{
+    auto clientData = TestCommonData::clientData;
+    auto backupData = clientData.client_data_json;
+    clientData.client_data_json = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&clientData);
+        return WAUTHN_ERROR_NONE;
+    });
+    clientData.client_data_json = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_clientdatajson_buffer_null_N)
+{
+    auto clientData = TestCommonData::clientData;
+    auto backupData = clientData.client_data_json->data;
+    clientData.client_data_json->data = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&clientData);
+        return WAUTHN_ERROR_NONE;
+    });
+    clientData.client_data_json->data = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_clientdatajson_buffer_size_zero_N)
+{
+    auto clientData = TestCommonData::clientData;
+    auto backupData = clientData.client_data_json->size;
+    clientData.client_data_json->size = 0;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&clientData);
+        return WAUTHN_ERROR_NONE;
+    });
+    clientData.client_data_json->size = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_clientdata_invalid_hash_N)
+{
+    auto clientData = TestCommonData::clientData;
+    auto backupData = clientData.hash_alg;
+    clientData.hash_alg = (wauthn_hash_algorithm_e)-1;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&clientData);
+        return WAUTHN_ERROR_NONE;
+    });
+    clientData.hash_alg = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_options_rp_id_null_N)
+{
+    auto rpData = TestCommonData::rpEntity;
+    auto backupData = rpData.id;
+    rpData.id = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&rpData);
+        return WAUTHN_ERROR_NONE;
+    });
+    rpData.id = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_options_rp_name_null_N)
+{
+    auto rpData = TestCommonData::rpEntity;
+    auto backupData = rpData.name;
+    rpData.name = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&rpData);
+        return WAUTHN_ERROR_NONE;
+    });
+    rpData.name = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+
+TEST_F(UtilsTest, check_parameter_options_user_id_null_N)
+{
+    auto userData = TestCommonData::userEntity;
+    auto backupData = userData.id;
+    userData.id = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&userData);
+        return WAUTHN_ERROR_NONE;
+    });
+    userData.id = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_options_user_name_null_N)
+{
+    auto userData = TestCommonData::userEntity;
+    auto backupData = userData.name;
+    userData.name = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&userData);
+        return WAUTHN_ERROR_NONE;
+    });
+    userData.name = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+
+TEST_F(UtilsTest, check_parameter_options_user_displayname_null_N)
+{
+    auto userData = TestCommonData::userEntity;
+    auto backupData = userData.display_name;
+    userData.display_name = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&userData);
+        return WAUTHN_ERROR_NONE;
+    });
+    userData.display_name = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_options_user_id_data_null_N)
+{
+    auto userData = TestCommonData::userEntity;
+    auto backupData = userData.id->data;
+    userData.id->data = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&userData);
+        return WAUTHN_ERROR_NONE;
+    });
+    userData.id->data = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_options_user_id_size_zero_N)
+{
+    auto userData = TestCommonData::userEntity;
+    auto backupData = userData.id->size;
+    userData.id->size = 0;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&userData);
+        return WAUTHN_ERROR_NONE;
+    });
+    userData.id->size = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_options_pubkey_cred_params_params_null_N)
+{
+    auto credParams = TestCommonData::pubkeyCredParams2;
+    auto backupData = credParams.params;
+    credParams.params = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&credParams);
+        return WAUTHN_ERROR_NONE;
+    });
+    credParams.params = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_options_pubkey_cred_params_size_zero_N)
+{
+    auto credParams = TestCommonData::pubkeyCredParams2;
+    auto backupData = credParams.size;
+    credParams.size = 0;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&credParams);
+        return WAUTHN_ERROR_NONE;
+    });
+    credParams.size = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_options_pubkey_cred_params_ignore_invalid_type_P)
+{
+    auto credParams = TestCommonData::pubkeyCredParams2;
+    for (size_t i = 0; i < credParams.size; ++i)
+    {
+        int ret = WAUTHN_ERROR_NONE;
+        auto backupData = credParams.params[i].type;
+        credParams.params[i].type = (wauthn_pubkey_cred_type_e)-1;
+        ret = try_catch([&]() -> int {
+            CheckParameters(&credParams);
+            return WAUTHN_ERROR_NONE;
+        });
+        credParams.params[i].type = backupData;
+        EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+    }
+}
+
+TEST_F(UtilsTest, check_parameter_options_pubkey_cred_params_invalid_alg_N)
+{
+    auto credParams = TestCommonData::pubkeyCredParams2;
+    for (size_t i = 0; i < credParams.size; ++i)
+    {
+        int ret = WAUTHN_ERROR_NONE;
+        auto backupData = credParams.params[i].alg;
+        credParams.params[i].alg = (wauthn_cose_algorithm_e)-1;
+        ret = try_catch([&]() -> int {
+            CheckParameters(&credParams);
+            return WAUTHN_ERROR_NONE;
+        });
+        credParams.params[i].alg = backupData;
+        EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+    }
+}
+
+TEST_F(UtilsTest, check_parameter_options_cred_descriptors_descs_null_N)
+{
+    auto credDescs = TestCommonData::pubkeyCredDescriptors2;
+    auto backupData = credDescs.descriptors;
+    credDescs.descriptors = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&credDescs);
+        return WAUTHN_ERROR_NONE;
+    });
+    credDescs.descriptors = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_options_cred_descriptors_desc_size_zero_N)
+{
+    auto credDescs = TestCommonData::pubkeyCredDescriptors2;
+    auto backupData = credDescs.size;
+    credDescs.size = 0;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&credDescs);
+        return WAUTHN_ERROR_NONE;
+    });
+    credDescs.size = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_options_cred_descriptors_ignore_invalid_type_P)
+{
+    auto credDescs = TestCommonData::pubkeyCredDescriptors2;
+    for (size_t i = 0; i < credDescs.size; ++i)
+    {
+        int ret = WAUTHN_ERROR_NONE;
+        auto backupData = credDescs.descriptors[i].type;
+        credDescs.descriptors[i].type = (wauthn_pubkey_cred_type_e)-1;
+        ret = try_catch([&]() -> int {
+            CheckParameters(&credDescs);
+            return WAUTHN_ERROR_NONE;
+        });
+        credDescs.descriptors[i].type = backupData;
+        EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+    }
+}
+
+TEST_F(UtilsTest, check_parameter_options_cred_descriptors_invalid_id_N)
+{
+    auto credDescs = TestCommonData::pubkeyCredDescriptors2;
+    for (size_t i = 0; i < credDescs.size; ++i)
+    {
+        int ret = WAUTHN_ERROR_NONE;
+        auto backupData = credDescs.descriptors[i].id;
+        credDescs.descriptors[i].id = nullptr;
+        ret = try_catch([&]() -> int {
+            CheckParameters(&credDescs);
+            return WAUTHN_ERROR_NONE;
+        });
+        credDescs.descriptors[i].id = backupData;
+        EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+        auto backupDataId = credDescs.descriptors[i].id->data;
+        credDescs.descriptors[i].id->data = nullptr;
+        ret = try_catch([&]() -> int {
+            CheckParameters(&credDescs);
+            return WAUTHN_ERROR_NONE;
+        });
+        credDescs.descriptors[i].id->data = backupDataId;
+        EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+        auto backupDataSize = credDescs.descriptors[i].id->size;
+        credDescs.descriptors[i].id->size = 0;
+        ret = try_catch([&]() -> int {
+            CheckParameters(&credDescs);
+            return WAUTHN_ERROR_NONE;
+        });
+        credDescs.descriptors[i].id->size = backupDataSize;
+        EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+    }
+}
+
+TEST_F(UtilsTest, check_parameter_options_cred_descriptors_ignore_invalid_transports_P)
+{
+    auto credDescs = TestCommonData::pubkeyCredDescriptors2;
+    for (size_t i = 0; i < credDescs.size; ++i)
+    {
+        int ret = WAUTHN_ERROR_NONE;
+        auto backupData = credDescs.descriptors[i].transports;
+        credDescs.descriptors[i].transports = std::numeric_limits<unsigned int>::max();
+        ret = try_catch([&]() -> int {
+            CheckParameters(&credDescs);
+            return WAUTHN_ERROR_NONE;
+        });
+        credDescs.descriptors[i].transports = backupData;
+        EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+    }
+}
+
+TEST_F(UtilsTest, check_parameter_options_authenticator_selection_ignore_invalid_attachment_P)
+{
+    auto authSel = TestCommonData::authenticatorSelCri;
+    auto backupData = authSel.attachment;
+    authSel.attachment = (wauthn_authenticator_attachment_e)-1;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&authSel);
+        return WAUTHN_ERROR_NONE;
+    });
+    authSel.attachment = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+}
+
+TEST_F(UtilsTest, check_parameter_options_authenticator_selection_ignore_invalid_resident_key_P)
+{
+    auto authSel = TestCommonData::authenticatorSelCri;
+    auto backupData = authSel.resident_key;
+    authSel.resident_key = (wauthn_resident_key_requirement_e)-1;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&authSel);
+        return WAUTHN_ERROR_NONE;
+    });
+    authSel.resident_key = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+}
+
+TEST_F(UtilsTest, check_parameter_options_authenticator_selection_ignore_invalid_user_verification_P)
+{
+    auto authSel = TestCommonData::authenticatorSelCri;
+    auto backupData = authSel.user_verification;
+    authSel.user_verification = (wauthn_user_verification_requirement_e)-1;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&authSel);
+        return WAUTHN_ERROR_NONE;
+    });
+    authSel.user_verification = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+}
+
+TEST_F(UtilsTest, check_parameter_options_authenticator_selection_invalid_resident_key_pair_N)
+{
+    auto authSel = TestCommonData::authenticatorSelCri;
+    auto backupRequiredResidentKey = authSel.require_resident_key;
+    auto backupResidentKey = authSel.resident_key;
+    authSel.require_resident_key = true;
+    authSel.resident_key = WAUTHN_RESIDENT_KEY_REQUIREMENT_NONE;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&authSel);
+        return WAUTHN_ERROR_NONE;
+    });
+    authSel.require_resident_key = backupRequiredResidentKey;
+    authSel.resident_key = backupResidentKey;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_options_hints_hints_null_N)
+{
+    auto hints = TestCommonData::pubkeyCredHints2;
+    auto backupData = hints.hints;
+    hints.hints = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&hints);
+        return WAUTHN_ERROR_NONE;
+    });
+    hints.hints = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_options_hints_size_zero_N)
+{
+    auto hints = TestCommonData::pubkeyCredHints2;
+    auto backupData = hints.size;
+    hints.size = 0;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&hints);
+        return WAUTHN_ERROR_NONE;
+    });
+    hints.size = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_options_hints_invalid_value_P)
+{
+    auto hints = TestCommonData::pubkeyCredHints2;
+    for (size_t i = 0; i < hints.size; ++i)
+    {
+        int ret = WAUTHN_ERROR_NONE;
+        auto backupData = hints.hints[i];
+        hints.hints[i] = (wauthn_pubkey_cred_hint_e)-1;
+        ret = try_catch([&]() -> int {
+            CheckParameters(&hints);
+            return WAUTHN_ERROR_NONE;
+        });
+        hints.hints[i] = backupData;
+        EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+    }
+}
+
+TEST_F(UtilsTest, check_parameter_options_attestation_formats_formats_null_N)
+{
+    auto formats = TestCommonData::attestationFormats2;
+    auto backupData = formats.attestation_formats;
+    formats.attestation_formats = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&formats);
+        return WAUTHN_ERROR_NONE;
+    });
+    formats.attestation_formats = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_options_attestation_formats_size_zero_N)
+{
+    auto formats = TestCommonData::attestationFormats2;
+    auto backupData = formats.size;
+    formats.size = 0;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&formats);
+        return WAUTHN_ERROR_NONE;
+    });
+    formats.size = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_options_attestation_formats_invalid_value_N)
+{
+    auto formats = TestCommonData::attestationFormats2;
+    for (size_t i = 0; i < formats.size; ++i)
+    {
+        int ret = WAUTHN_ERROR_NONE;
+        auto backupData = formats.attestation_formats[i].data;
+        formats.attestation_formats[i].data = nullptr;
+        ret = try_catch([&]() -> int {
+            CheckParameters(&formats);
+            return WAUTHN_ERROR_NONE;
+        });
+        formats.attestation_formats[i].data = backupData;
+        EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+        auto backupSize = formats.attestation_formats[i].size;
+        formats.attestation_formats[i].size = 0;
+        ret = try_catch([&]() -> int {
+            CheckParameters(&formats);
+            return WAUTHN_ERROR_NONE;
+        });
+        formats.attestation_formats[i].size = backupSize;
+        EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+    }
+}
+
+TEST_F(UtilsTest, check_parameter_options_extensions_extensions_null_N)
+{
+    auto authExts = TestCommonData::authenticationExts2;
+    auto backupData = authExts.extensions;
+    authExts.extensions = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&authExts);
+        return WAUTHN_ERROR_NONE;
+    });
+    authExts.extensions = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_options_extensions_size_zero_N)
+{
+    auto authExts = TestCommonData::authenticationExts2;
+    auto backupData = authExts.size;
+    authExts.size = 0;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&authExts);
+        return WAUTHN_ERROR_NONE;
+    });
+    authExts.size = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_options_extensions_invalid_id_N)
+{
+    auto authExts = TestCommonData::authenticationExts2;
+    for (size_t i = 0; i < authExts.size; ++i)
+    {
+        int ret = WAUTHN_ERROR_NONE;
+        auto backupId = authExts.extensions[i].extension_id;
+        authExts.extensions[i].extension_id = nullptr;
+        ret = try_catch([&]() -> int {
+            CheckParameters(&authExts);
+            return WAUTHN_ERROR_NONE;
+        });
+        authExts.extensions[i].extension_id = backupId;
+        EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+        auto backupIdData = authExts.extensions[i].extension_id->data;
+        authExts.extensions[i].extension_id->data = nullptr;
+        ret = try_catch([&]() -> int {
+            CheckParameters(&authExts);
+            return WAUTHN_ERROR_NONE;
+        });
+        authExts.extensions[i].extension_id->data = backupIdData;
+        EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+        auto backupIdSize = authExts.extensions[i].extension_id->size;
+        authExts.extensions[i].extension_id->size = 0;
+        ret = try_catch([&]() -> int {
+            CheckParameters(&authExts);
+            return WAUTHN_ERROR_NONE;
+        });
+        authExts.extensions[i].extension_id->size = backupIdSize;
+        EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+    }
+}
+
+TEST_F(UtilsTest, check_parameter_options_extensions_invalid_value_N)
+{
+    auto authExts = TestCommonData::authenticationExts2;
+    for (size_t i = 0; i < authExts.size; ++i)
+    {
+        int ret = WAUTHN_ERROR_NONE;
+        auto backupValue = authExts.extensions[i].extension_value;
+        authExts.extensions[i].extension_value = nullptr;
+        ret = try_catch([&]() -> int {
+            CheckParameters(&authExts);
+            return WAUTHN_ERROR_NONE;
+        });
+        authExts.extensions[i].extension_value = backupValue;
+        EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+        auto backupValueData = authExts.extensions[i].extension_value->data;
+        authExts.extensions[i].extension_value->data = nullptr;
+        ret = try_catch([&]() -> int {
+            CheckParameters(&authExts);
+            return WAUTHN_ERROR_NONE;
+        });
+        authExts.extensions[i].extension_value->data = backupValueData;
+        EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+        auto backupValueSize = authExts.extensions[i].extension_value->size;
+        authExts.extensions[i].extension_value->size = 0;
+        ret = try_catch([&]() -> int {
+            CheckParameters(&authExts);
+            return WAUTHN_ERROR_NONE;
+        });
+        authExts.extensions[i].extension_value->size = backupValueSize;
+        EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+    }
+}
+
+TEST_F(UtilsTest, check_parameter_options_linked_device_P)
+{
+    auto linkedData = TestCommonData::hybridLinkedData;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_ALL);
+        return WAUTHN_ERROR_NONE;
+    });
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+}
 
+TEST_F(UtilsTest, check_parameter_options_linked_device_contact_id_null_N)
+{
+    auto linkedData = TestCommonData::hybridLinkedData;
+    auto backupData = linkedData.contact_id;
+    linkedData.contact_id = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_CONTACT_ID);
+        return WAUTHN_ERROR_NONE;
+    });
+    linkedData.contact_id = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+    auto backupDataData = linkedData.contact_id->data;
+    linkedData.contact_id->data = nullptr;
+    ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_CONTACT_ID);
+        return WAUTHN_ERROR_NONE;
+    });
+    linkedData.contact_id->data = backupDataData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+    auto backupDataSize = linkedData.contact_id->size;
+    linkedData.contact_id->size = 0;
+    ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_CONTACT_ID);
+        return WAUTHN_ERROR_NONE;
+    });
+    linkedData.contact_id->size = backupDataSize;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_options_linked_device_link_id_null_N)
+{
+    auto linkedData = TestCommonData::hybridLinkedData;
+    auto backupData = linkedData.link_id;
+    linkedData.link_id = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_LINK_ID);
+        return WAUTHN_ERROR_NONE;
+    });
+    linkedData.link_id = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+    auto backupDataData = linkedData.link_id->data;
+    linkedData.link_id->data = nullptr;
+    ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_LINK_ID);
+        return WAUTHN_ERROR_NONE;
+    });
+    linkedData.link_id->data = backupDataData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+    auto backupDataSize = linkedData.link_id->size;
+    linkedData.link_id->size = 0;
+    ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_LINK_ID);
+        return WAUTHN_ERROR_NONE;
+    });
+    linkedData.link_id->size = backupDataSize;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_options_linked_device_link_secret_null_N)
+{
+    auto linkedData = TestCommonData::hybridLinkedData;
+    auto backupData = linkedData.link_secret;
+    linkedData.link_secret = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_LINK_SECRET);
+        return WAUTHN_ERROR_NONE;
+    });
+    linkedData.link_secret = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+    auto backupDataData = linkedData.link_secret->data;
+    linkedData.link_secret->data = nullptr;
+    ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_LINK_SECRET);
+        return WAUTHN_ERROR_NONE;
+    });
+    linkedData.link_secret->data = backupDataData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+    auto backupDataSize = linkedData.link_secret->size;
+    linkedData.link_secret->size = 0;
+    ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_LINK_SECRET);
+        return WAUTHN_ERROR_NONE;
+    });
+    linkedData.link_secret->size = backupDataSize;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_options_linked_device_authenticator_pubkey_null_N)
+{
+    auto linkedData = TestCommonData::hybridLinkedData;
+    auto backupData = linkedData.authenticator_pubkey;
+    linkedData.authenticator_pubkey = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_AUTHENTICATOR_PUBKEY);
+        return WAUTHN_ERROR_NONE;
+    });
+    linkedData.authenticator_pubkey = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+    auto backupDataData = linkedData.authenticator_pubkey->data;
+    linkedData.authenticator_pubkey->data = nullptr;
+    ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_AUTHENTICATOR_PUBKEY);
+        return WAUTHN_ERROR_NONE;
+    });
+    linkedData.authenticator_pubkey->data = backupDataData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+    auto backupDataSize = linkedData.authenticator_pubkey->size;
+    linkedData.authenticator_pubkey->size = 0;
+    ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_AUTHENTICATOR_PUBKEY);
+        return WAUTHN_ERROR_NONE;
+    });
+    linkedData.authenticator_pubkey->size = backupDataSize;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_options_linked_device_authenticator_name_null_N)
+{
+    auto linkedData = TestCommonData::hybridLinkedData;
+    auto backupData = linkedData.authenticator_name;
+    linkedData.authenticator_name = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_AUTHENTICATOR_NAME);
+        return WAUTHN_ERROR_NONE;
+    });
+    linkedData.authenticator_name = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+    auto backupDataData = linkedData.authenticator_name->data;
+    linkedData.authenticator_name->data = nullptr;
+    ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_AUTHENTICATOR_NAME);
+        return WAUTHN_ERROR_NONE;
+    });
+    linkedData.authenticator_name->data = backupDataData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+    auto backupDataSize = linkedData.authenticator_name->size;
+    linkedData.authenticator_name->size = 0;
+    ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_AUTHENTICATOR_NAME);
+        return WAUTHN_ERROR_NONE;
+    });
+    linkedData.authenticator_name->size = backupDataSize;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_options_linked_device_signature_null_N)
+{
+    auto linkedData = TestCommonData::hybridLinkedData;
+    auto backupData = linkedData.signature;
+    linkedData.signature = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_SIGNATURE);
+        return WAUTHN_ERROR_NONE;
+    });
+    linkedData.signature = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+    auto backupDataData = linkedData.signature->data;
+    linkedData.signature->data = nullptr;
+    ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_SIGNATURE);
+        return WAUTHN_ERROR_NONE;
+    });
+    linkedData.signature->data = backupDataData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+    auto backupDataSize = linkedData.signature->size;
+    linkedData.signature->size = 0;
+    ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_SIGNATURE);
+        return WAUTHN_ERROR_NONE;
+    });
+    linkedData.signature->size = backupDataSize;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_options_linked_device_tunnel_server_domain_null_N)
+{
+    auto linkedData = TestCommonData::hybridLinkedData;
+    auto backupData = linkedData.tunnel_server_domain;
+    linkedData.tunnel_server_domain = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_TUNNEL_SERVER_DOMAIN);
+        return WAUTHN_ERROR_NONE;
+    });
+    linkedData.tunnel_server_domain = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+    auto backupDataData = linkedData.tunnel_server_domain->data;
+    linkedData.tunnel_server_domain->data = nullptr;
+    ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_TUNNEL_SERVER_DOMAIN);
+        return WAUTHN_ERROR_NONE;
+    });
+    linkedData.tunnel_server_domain->data = backupDataData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+    auto backupDataSize = linkedData.tunnel_server_domain->size;
+    linkedData.tunnel_server_domain->size = 0;
+    ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_TUNNEL_SERVER_DOMAIN);
+        return WAUTHN_ERROR_NONE;
+    });
+    linkedData.tunnel_server_domain->size = backupDataSize;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_options_linked_device_identity_key_null_N)
+{
+    auto linkedData = TestCommonData::hybridLinkedData;
+    auto backupData = linkedData.identity_key;
+    linkedData.identity_key = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_IDENTITY_KEY);
+        return WAUTHN_ERROR_NONE;
+    });
+    linkedData.identity_key = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+    auto backupDataData = linkedData.identity_key->data;
+    linkedData.identity_key->data = nullptr;
+    ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_IDENTITY_KEY);
+        return WAUTHN_ERROR_NONE;
+    });
+    linkedData.identity_key->data = backupDataData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+    auto backupDataSize = linkedData.identity_key->size;
+    linkedData.identity_key->size = 0;
+    ret = try_catch([&]() -> int {
+        CheckParameters(&linkedData, CHECK_IDENTITY_KEY);
+        return WAUTHN_ERROR_NONE;
+    });
+    linkedData.identity_key->size = backupDataSize;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_MC_options_rp_null_N)
+{
+    auto options = TestCommonData::pubkeyCredCreationOptions;
+    auto backupData = options.rp;
+    options.rp = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&options);
+        return WAUTHN_ERROR_NONE;
+    });
+    options.rp = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_MC_options_user_null_N)
+{
+    auto options = TestCommonData::pubkeyCredCreationOptions;
+    auto backupData = options.user;
+    options.user = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&options);
+        return WAUTHN_ERROR_NONE;
+    });
+    options.user = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_MC_options_pubkey_cred_params_null_N)
+{
+    auto options = TestCommonData::pubkeyCredCreationOptions;
+    auto backupData = options.pubkey_cred_params;
+    options.pubkey_cred_params = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&options);
+        return WAUTHN_ERROR_NONE;
+    });
+    options.pubkey_cred_params = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_MC_options_exclude_credentials_null_P)
+{
+    auto options = TestCommonData::pubkeyCredCreationOptions;
+    auto backupData = options.exclude_credentials;
+    options.exclude_credentials = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&options);
+        return WAUTHN_ERROR_NONE;
+    });
+    options.exclude_credentials = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+}
+
+TEST_F(UtilsTest, check_parameter_MC_options_authenticator_selection_null_P)
+{
+    auto options = TestCommonData::pubkeyCredCreationOptions;
+    auto backupData = options.authenticator_selection;
+    options.authenticator_selection = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&options);
+        return WAUTHN_ERROR_NONE;
+    });
+    options.authenticator_selection = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+}
+
+TEST_F(UtilsTest, check_parameter_MC_options_hints_null_P)
+{
+    auto options = TestCommonData::pubkeyCredCreationOptions;
+    auto backupData = options.hints;
+    options.hints = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&options);
+        return WAUTHN_ERROR_NONE;
+    });
+    options.hints = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+}
+
+TEST_F(UtilsTest, check_parameter_MC_options_ignore_invalid_attestation_P)
+{
+    auto options = TestCommonData::pubkeyCredCreationOptions;
+    auto backupData = options.attestation;
+    options.attestation = (wauthn_attestation_pref_e)-1;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&options);
+        return WAUTHN_ERROR_NONE;
+    });
+    options.attestation = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+}
+
+TEST_F(UtilsTest, check_parameter_MC_options_attestation_formats_null_P)
+{
+    auto options = TestCommonData::pubkeyCredCreationOptions;
+    auto backupData = options.attestation_formats;
+    options.attestation_formats = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&options);
+        return WAUTHN_ERROR_NONE;
+    });
+    options.attestation_formats = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+}
+
+TEST_F(UtilsTest, check_parameter_MC_options_extensions_null_P)
+{
+    auto options = TestCommonData::pubkeyCredCreationOptions;
+    auto backupData = options.extensions;
+    options.extensions = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&options);
+        return WAUTHN_ERROR_NONE;
+    });
+    options.extensions = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+}
+
+TEST_F(UtilsTest, check_parameter_MC_options_linked_device_null_P)
+{
+    auto options = TestCommonData::pubkeyCredCreationOptions;
+    auto backupData = options.linked_device;
+    options.linked_device = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&options);
+        return WAUTHN_ERROR_NONE;
+    });
+    options.linked_device = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+}
+
+TEST_F(UtilsTest, check_parameter_GA_options_rp_id_null_N)
+{
+    auto options = TestCommonData::pubkeyCredRequestOptions;
+    auto backupData = options.rpId;
+    options.rpId = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&options);
+        return WAUTHN_ERROR_NONE;
+    });
+    options.rpId = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_GA_options_allow_credentials_null_P)
+{
+    auto options = TestCommonData::pubkeyCredRequestOptions;
+    auto backupData = options.allow_credentials;
+    options.allow_credentials = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&options);
+        return WAUTHN_ERROR_NONE;
+    });
+    options.allow_credentials = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+}
+
+TEST_F(UtilsTest, check_parameter_GA_options_invalid_user_verification_P)
+{
+    auto options = TestCommonData::pubkeyCredRequestOptions;
+    auto backupData = options.user_verification;
+    options.user_verification = (wauthn_user_verification_requirement_e)-1;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&options);
+        return WAUTHN_ERROR_NONE;
+    });
+    options.user_verification = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+}
+
+TEST_F(UtilsTest, check_parameter_GA_options_hints_null_P)
+{
+    auto options = TestCommonData::pubkeyCredRequestOptions;
+    auto backupData = options.hints;
+    options.hints = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&options);
+        return WAUTHN_ERROR_NONE;
+    });
+    options.hints = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+}
+
+
+TEST_F(UtilsTest, check_parameter_GA_options_ignore_invalid_attestation_P)
+{
+    auto options = TestCommonData::pubkeyCredRequestOptions;
+    auto backupData = options.attestation;
+    options.attestation = (wauthn_attestation_pref_e)-1;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&options);
+        return WAUTHN_ERROR_NONE;
+    });
+    options.attestation = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+}
+
+
+TEST_F(UtilsTest, check_parameter_GA_options_attestation_formats_null_P)
+{
+    auto options = TestCommonData::pubkeyCredRequestOptions;
+    auto backupData = options.attestation_formats;
+    options.attestation_formats = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&options);
+        return WAUTHN_ERROR_NONE;
+    });
+    options.attestation_formats = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+}
+
+TEST_F(UtilsTest, check_parameter_GA_options_extensions_null_P)
+{
+    auto options = TestCommonData::pubkeyCredRequestOptions;
+    auto backupData = options.extensions;
+    options.extensions = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&options);
+        return WAUTHN_ERROR_NONE;
+    });
+    options.extensions = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+}
+
+TEST_F(UtilsTest, check_parameter_GA_options_linked_device_null_P)
+{
+    auto options = TestCommonData::pubkeyCredRequestOptions;
+    auto backupData = options.linked_device;
+    options.linked_device = nullptr;
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&options);
+        return WAUTHN_ERROR_NONE;
+    });
+    options.linked_device = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+}
+
+TEST_F(UtilsTest, check_parameter_MC_clientdata_null_N)
+{
+    wauthn_mc_callbacks_s callbacks = {test_cb_display_qrcode,
+                                       test_cb_mc_response,
+                                       test_cb_update_linked_data,
+                                       nullptr};
+    int ret = try_catch([&]() -> int {
+        CheckParameters(nullptr, &TestCommonData::pubkeyCredCreationOptions, &callbacks);
+        return WAUTHN_ERROR_NONE;
+    });
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_MC_options_null_N)
+{
+    wauthn_mc_callbacks_s callbacks = {test_cb_display_qrcode,
+                                       test_cb_mc_response,
+                                       test_cb_update_linked_data,
+                                       nullptr};
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&TestCommonData::clientData, nullptr, &callbacks);
+        return WAUTHN_ERROR_NONE;
+    });
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_MC_callbacks_null_N)
+{
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&TestCommonData::clientData, &TestCommonData::pubkeyCredCreationOptions,
+                        nullptr);
+        return WAUTHN_ERROR_NONE;
+    });
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+    wauthn_mc_callbacks_s callbacks = {test_cb_display_qrcode,
+                                       nullptr,
+                                       test_cb_update_linked_data,
+                                       nullptr};
+
+    ret = try_catch([&]() -> int {
+        CheckParameters(&TestCommonData::clientData, &TestCommonData::pubkeyCredCreationOptions,
+                        &callbacks);
+        return WAUTHN_ERROR_NONE;
+    });
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+    callbacks.response_callback = test_cb_mc_response;
+    callbacks.linked_data_callback = nullptr;
+
+    ret = try_catch([&]() -> int {
+        CheckParameters(&TestCommonData::clientData, &TestCommonData::pubkeyCredCreationOptions,
+                        &callbacks);
+        return WAUTHN_ERROR_NONE;
+    });
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_MC_qr_callback_null_without_linkeddata_N)
+{
+    wauthn_mc_callbacks_s callbacks = {nullptr,
+                                       test_cb_mc_response,
+                                       test_cb_update_linked_data,
+                                       nullptr};
+    auto options = TestCommonData::pubkeyCredCreationOptions;
+    auto backupData = options.linked_device;
+    options.linked_device = nullptr;
+
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&TestCommonData::clientData, &options, &callbacks);
+        return WAUTHN_ERROR_NONE;
+    });
+    options.linked_device = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_GA_clientdata_null_N)
+{
+    wauthn_ga_callbacks_s callbacks = {test_cb_display_qrcode,
+                                       test_cb_ga_response,
+                                       test_cb_update_linked_data,
+                                       nullptr};
+    int ret = try_catch([&]() -> int {
+        CheckParameters(nullptr, &TestCommonData::pubkeyCredRequestOptions, &callbacks);
+        return WAUTHN_ERROR_NONE;
+    });
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_GA_options_null_N)
+{
+    wauthn_ga_callbacks_s callbacks = {test_cb_display_qrcode,
+                                       test_cb_ga_response,
+                                       test_cb_update_linked_data,
+                                       nullptr};
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&TestCommonData::clientData, nullptr, &callbacks);
+        return WAUTHN_ERROR_NONE;
+    });
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_GA_callbacks_null_N)
+{
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&TestCommonData::clientData, &TestCommonData::pubkeyCredRequestOptions,
+                        nullptr);
+        return WAUTHN_ERROR_NONE;
+    });
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+    wauthn_ga_callbacks_s callbacks = {test_cb_display_qrcode,
+                                       nullptr,
+                                       test_cb_update_linked_data,
+                                       nullptr};
+
+    ret = try_catch([&]() -> int {
+        CheckParameters(&TestCommonData::clientData, &TestCommonData::pubkeyCredRequestOptions,
+                        &callbacks);
+        return WAUTHN_ERROR_NONE;
+    });
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+
+    callbacks.response_callback = test_cb_ga_response;
+    callbacks.linked_data_callback = nullptr;
+
+    ret = try_catch([&]() -> int {
+        CheckParameters(&TestCommonData::clientData, &TestCommonData::pubkeyCredRequestOptions,
+                        &callbacks);
+        return WAUTHN_ERROR_NONE;
+    });
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_GA_qr_callback_null_without_linkeddata_N)
+{
+    wauthn_ga_callbacks_s callbacks = {nullptr,
+                                       test_cb_ga_response,
+                                       test_cb_update_linked_data,
+                                       nullptr};
+    auto options = TestCommonData::pubkeyCredRequestOptions;
+    auto backupData = options.linked_device;
+    options.linked_device = nullptr;
+
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&TestCommonData::clientData, &options, &callbacks);
+        return WAUTHN_ERROR_NONE;
+    });
+    options.linked_device = backupData;
+    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(UtilsTest, check_parameter_MC_P)
+{
+    wauthn_mc_callbacks_s callbacks = {test_cb_display_qrcode,
+                                       test_cb_mc_response,
+                                       test_cb_update_linked_data,
+                                       nullptr};
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&TestCommonData::clientData, &TestCommonData::pubkeyCredCreationOptions,
+                        &callbacks);
+        return WAUTHN_ERROR_NONE;
+    });
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+}
+
+TEST_F(UtilsTest, check_parameter_GA_P)
+{
+    wauthn_ga_callbacks_s callbacks = {test_cb_display_qrcode,
+                                       test_cb_ga_response,
+                                       test_cb_update_linked_data,
+                                       nullptr};
+    int ret = try_catch([&]() -> int {
+        CheckParameters(&TestCommonData::clientData, &TestCommonData::pubkeyCredRequestOptions,
+                        &callbacks);
+        return WAUTHN_ERROR_NONE;
+    });
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
 }
 
 } // namespace WebAuthn
index 2afc8250f9bb32b90aff05935b6b5e4f9a8ebd72..774aa63ebe59780bae431aa5d54dfb19760151ce 100644 (file)
@@ -28,7 +28,7 @@
 
 namespace WA {
 
-class WebAuthnTest : public ::testing::Test {
+class WebAuthnAPITest : public ::testing::Test {
 protected:
     void SetUp() override {
         // Do initialization if needed.
@@ -39,191 +39,134 @@ protected:
     }
 };
 
-TEST_F(WebAuthnTest, invalid_client_data_N)
+TEST_F(WebAuthnAPITest, invalid_client_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));
-    EXPECT_TRUE(mc_callbacks);
-    if (!mc_callbacks)
-        return ;
-    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;
+    wauthn_mc_callbacks_s mc_callbacks = {test_cb_display_qrcode,
+                                          test_cb_mc_response,
+                                          test_cb_update_linked_data,
+                                          nullptr};
     ret = wauthn_make_credential(nullptr,
-                                 &TestCommonData::pubkeyCredCreationOptions,
-                                 mc_callbacks);
-
+                                 &TestCommonData::pubkeyCredCreationOptionsOK,
+                                 &mc_callbacks);
     EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
 
     ret = WAUTHN_ERROR_NONE;
-    wauthn_ga_callbacks_s *ga_callbacks = nullptr;
-    ga_callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s));
-    EXPECT_TRUE(ga_callbacks);
-    if (!ga_callbacks)
-    {
-        free(mc_callbacks);
-        return ;
-    }
-    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;
+    wauthn_ga_callbacks_s ga_callbacks = {test_cb_display_qrcode,
+                                          test_cb_ga_response,
+                                          test_cb_update_linked_data,
+                                          nullptr};
     ret = wauthn_get_assertion(nullptr,
-                               &TestCommonData::pubkeyCredRequestOptions,
-                               ga_callbacks);
-
+                               &TestCommonData::pubkeyCredRequestOptionsOK,
+                               &ga_callbacks);
     EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
-
-    free(mc_callbacks);
-    free(ga_callbacks);
 }
 
-TEST_F(WebAuthnTest, invalid_options_N)
+TEST_F(WebAuthnAPITest, invalid_options_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));
-    EXPECT_TRUE(mc_callbacks);
-    if (!mc_callbacks)
-        return ;
-    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;
+    wauthn_mc_callbacks_s mc_callbacks = {test_cb_display_qrcode,
+                                          test_cb_mc_response,
+                                          test_cb_update_linked_data,
+                                          nullptr};
     ret = wauthn_make_credential(&TestCommonData::clientData,
                                  nullptr,
-                                 mc_callbacks);
-
+                                 &mc_callbacks);
     EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
 
     ret = WAUTHN_ERROR_NONE;
-    wauthn_ga_callbacks_s *ga_callbacks = nullptr;
-    ga_callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s));
-    EXPECT_TRUE(ga_callbacks);
-    if (!ga_callbacks)
-    {
-        free(mc_callbacks);
-        return ;
-    }
-    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;
+    wauthn_ga_callbacks_s ga_callbacks = {test_cb_display_qrcode,
+                                          test_cb_ga_response,
+                                          test_cb_update_linked_data,
+                                          nullptr};
     ret = wauthn_get_assertion(&TestCommonData::clientData,
                                nullptr,
-                               ga_callbacks);
-
+                               &ga_callbacks);
     EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
-
-    free(mc_callbacks);
-    free(ga_callbacks);
 }
 
-TEST_F(WebAuthnTest, invalid_callbacks_N)
+TEST_F(WebAuthnAPITest, invalid_callbacks_N)
 {
     int ret = WAUTHN_ERROR_NONE;
     ret = wauthn_make_credential(&TestCommonData::clientData,
-                                 &TestCommonData::pubkeyCredCreationOptions,
+                                 &TestCommonData::pubkeyCredCreationOptionsOK,
                                  nullptr);
     EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
 
-    ret = WAUTHN_ERROR_NONE;
-    wauthn_mc_callbacks_s *mc_callbacks = nullptr;
-    mc_callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s));
-    EXPECT_TRUE(mc_callbacks);
-    if (!mc_callbacks)
-        return ;
-    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);
-
-    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);
-    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
-
     ret = WAUTHN_ERROR_NONE;
     ret = wauthn_get_assertion(&TestCommonData::clientData,
-                               &TestCommonData::pubkeyCredRequestOptions,
+                               &TestCommonData::pubkeyCredRequestOptionsOK,
                                nullptr);
     EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+}
 
-    ret = WAUTHN_ERROR_NONE;
-    wauthn_ga_callbacks_s *ga_callbacks = nullptr;
-    ga_callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s));
-    EXPECT_TRUE(ga_callbacks);
-    if (!ga_callbacks)
-    {
-        free(mc_callbacks);
-        return ;
-    }
-    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);
+TEST_F(WebAuthnAPITest, miss_qr_callback_without_linked_data_N)
+{
+    int ret = WAUTHN_ERROR_NONE;
+    wauthn_mc_callbacks_s mc_callbacks = {nullptr,
+                                          test_cb_mc_response,
+                                          test_cb_update_linked_data,
+                                          nullptr};
+    ret = wauthn_make_credential(&TestCommonData::clientData,
+                                 &TestCommonData::pubkeyCredCreationOptionsOKNoLD,
+                                 &mc_callbacks);
     EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
 
     ret = WAUTHN_ERROR_NONE;
-    ga_callbacks->response_callback = test_cb_ga_response;
-    ga_callbacks->linked_data_callback = nullptr;
+    wauthn_ga_callbacks_s ga_callbacks = {nullptr,
+                                          test_cb_ga_response,
+                                          test_cb_update_linked_data,
+                                          nullptr};
     ret = wauthn_get_assertion(&TestCommonData::clientData,
-                               &TestCommonData::pubkeyCredRequestOptions,
-                               ga_callbacks);
+                               &TestCommonData::pubkeyCredRequestOptionsOKNoLD,
+                               &ga_callbacks);
     EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
-    free(mc_callbacks);
-    free(ga_callbacks);
 }
 
-TEST_F(WebAuthnTest, miss_qr_callback_without_linked_data_N)
+TEST_F(WebAuthnAPITest, cancel_not_allowed_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));
-    EXPECT_TRUE(mc_callbacks);
-    if (!mc_callbacks)
-        return ;
-    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_cancel();
+    EXPECT_EQ(ret, WAUTHN_ERROR_NOT_ALLOWED);
+}
+
+TEST_F(WebAuthnAPITest, MC_valid_request_and_cancel_P)
+{
+    sleep(3); // wait 3 secs for make interval
+    int ret = WAUTHN_ERROR_NONE;
+    wauthn_mc_callbacks_s mc_callbacks = {test_cb_display_qrcode,
+                                          test_cb_mc_response,
+                                          test_cb_update_linked_data,
+                                          nullptr};
     ret = wauthn_make_credential(&TestCommonData::clientData,
-                                 &TestCommonData::pubkeyCredCreationOptionsNoLD,
-                                 mc_callbacks);
-    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
+                                 &TestCommonData::pubkeyCredCreationOptionsOKNoLD,
+                                 &mc_callbacks);
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
 
-    ret = WAUTHN_ERROR_NONE;
-    wauthn_ga_callbacks_s *ga_callbacks = nullptr;
-    ga_callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s));
-    EXPECT_TRUE(ga_callbacks);
-    if (!ga_callbacks)
-    {
-        free(mc_callbacks);
-        return ;
-    }
-    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::pubkeyCredRequestOptionsNoLD,
-                               nullptr);
-    EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER);
-    free(mc_callbacks);
-    free(ga_callbacks);
+    sleep(3); // wait 3 secs for make interval
+    ret = wauthn_cancel();
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+    sleep(3); // wait 3 secs for make interval
 }
 
-TEST_F(WebAuthnTest, cancel_not_allowed_N)
+TEST_F(WebAuthnAPITest, GA_valid_request_and_cancel_P)
 {
+    sleep(3); // wait 3 secs for make interval
     int ret = WAUTHN_ERROR_NONE;
+    wauthn_ga_callbacks_s ga_callbacks = {test_cb_display_qrcode,
+                                          test_cb_ga_response,
+                                          test_cb_update_linked_data,
+                                          nullptr};
+    ret = wauthn_get_assertion(&TestCommonData::clientData,
+                               &TestCommonData::pubkeyCredRequestOptionsOKNoLD,
+                               &ga_callbacks);
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+
+    sleep(3); // wait 3 secs for make interval
     ret = wauthn_cancel();
-    EXPECT_EQ(ret, WAUTHN_ERROR_NOT_ALLOWED);
+    EXPECT_EQ(ret, WAUTHN_ERROR_NONE);
+    sleep(3); // wait 3 secs for make interval
 }
 
+
 } // namespace WA