Enable unfixed userId and allowCredential for test 32/315832/14
authorYonggoo Kang <ygace.kang@samsung.com>
Thu, 8 Aug 2024 05:55:36 +0000 (14:55 +0900)
committerYonggoo Kang <ygace.kang@samsung.com>
Tue, 20 Aug 2024 10:03:12 +0000 (10:03 +0000)
- Replace userId from fixed value to input value
- Replace error value to string for log
- Minor fix with log
- Save created credential descriptors in memory
- Enable unfixed allowCredential option for authentication
- Deny requests with username as blank for registration
- Add testMsg to UI for display error information
- Add created usernames to UI
- Modify position and size of some UI components

Change-Id: If5d672adf9dc0fa5a420b2cb37e258dc182d999c

tests/webauthn-manual-test-app/src/app_gui.cpp
tests/webauthn-manual-test-app/src/app_gui.h
tests/webauthn-manual-test-app/src/common.h
tests/webauthn-manual-test-app/src/scenarios.cpp
tests/webauthn-manual-test-app/src/ui_component.cpp

index 2dbc21422e3d15304726aa592134464014279654..563935ce2f2475ed19b21e715335e688fa453fff 100644 (file)
@@ -86,7 +86,7 @@ void AppGUI::RegistrationHintsCheckboxCb(Evas_Object *obj)
             LogDebug("Hybrid hint removed");
         } else {
             m_testContents.prefLevel.push_back(WAUTHN_PUBKEY_CRED_HINT_HYBRID);
-            LogDebug("Hybrid hint removed");
+            LogDebug("Hybrid hint added");
         }
     }
     std::string hintsText = " { ";
@@ -225,9 +225,16 @@ void *AppGUI::UpdateRegStatus(void *data)
     auto appGUI = static_cast<AppGUI *>(data);
 
     if (appGUI->m_testContents.status != TestState::REG_SUCCCEEDED)
-        elm_object_text_set(appGUI->m_testInfo, _("<color=#FF0000FF>REGISTRATION FAILED!</color>"));
+    {
+        elm_object_text_set(appGUI->m_testResult,
+                            _("<color=#FF0000FF>REGISTRATION FAILED!</color>"));
+        std::string coloredMsg = "<color=#FF0000FF>"
+                         + appGUI->m_testContents.testMsg
+                         + "</color>";
+        elm_object_text_set(appGUI->m_resultInfo, _(coloredMsg.c_str()));
+    }
     else
-        elm_object_text_set(appGUI->m_testInfo,
+        elm_object_text_set(appGUI->m_testResult,
                             _("<color=#00FF00FF>REGISTRATION COMPLETED!</color>"));
 
     return NULL;
@@ -238,15 +245,37 @@ void *AppGUI::UpdateAuthStatus(void *data)
     auto appGUI = static_cast<AppGUI *>(data);
 
     if (appGUI->m_testContents.status != TestState::AUTH_SUCCCEEDED)
-        elm_object_text_set(appGUI->m_testInfo,
+    {
+        elm_object_text_set(appGUI->m_testResult,
                             _("<color=#FF0000FF>AUTHENTICATION FAILED!</color>"));
+        std::string coloredMsg = "<color=#FF0000FF>"
+                         + appGUI->m_testContents.testMsg
+                         + "</color>";
+        elm_object_text_set(appGUI->m_resultInfo, _(coloredMsg.c_str()));
+    }
     else
-        elm_object_text_set(appGUI->m_testInfo,
+        elm_object_text_set(appGUI->m_testResult,
                             _("<color=#00FF00FF>AUTHENTICATION COMPLETED!</color>"));
 
     return NULL;
 }
 
+void *AppGUI::UpdateCreatedUserIds(void *data)
+{
+    auto appGUI = static_cast<AppGUI *>(data);
+
+    std::string userIdsText = "Created usernames: { ";
+    for (auto const& cred : appGUI->m_testContents.createdCredDescs)
+    {
+        userIdsText += std::string(cred.first.begin(), cred.first.end());
+    }
+    userIdsText += "} ";
+    std::cout << userIdsText.c_str() << std::endl;
+    elm_object_text_set(appGUI->m_createdUserIds, userIdsText.c_str());
+
+    return NULL;
+}
+
 void AppGUI::RegisterStaticCb(void *data, Ecore_Thread *thread EINA_UNUSED)
 {
     auto appGUI = static_cast<AppGUI *>(data);
@@ -258,6 +287,7 @@ void AppGUI::RegisterCb()
     TestMC(m_testContents);
     ecore_main_loop_thread_safe_call_sync(CleanQRFieldAndEnableUI, this);
     ecore_main_loop_thread_safe_call_sync(UpdateRegStatus, this);
+    ecore_main_loop_thread_safe_call_sync(UpdateCreatedUserIds, this);
 }
 
 void AppGUI::RegisterButtonClickedStaticCb(void *data,
@@ -272,15 +302,24 @@ void AppGUI::RegisterButtonClickedCb()
 {
 
     std::ostringstream log;
-    elm_object_text_set(m_testInfo, "");
+    elm_object_text_set(m_testResult, "");
+    elm_object_text_set(m_resultInfo, "");
+    m_testContents.username = elm_object_text_get(m_entry);
+    log << "Registering username: " << m_testContents.username << std::endl;
+    LogDebug(log.str().c_str());
+    size_t userIdLength = strlen(m_testContents.username);
+    if(userIdLength == 0)
+    {
+        m_testContents.testMsg = "Username is required for register";
+        ecore_main_loop_thread_safe_call_sync(UpdateAuthStatus, this);
+        return;
+    }
+
     DisableUIComponents(EINA_TRUE);
     evas_object_show(m_cancelBt);
 
-    m_testContents.status = TestState::REG_IN_PROCESS;
-    m_testContents.username = elm_object_text_get(m_entry);
 
-    log << "Registering username: " << m_testContents.username << std::endl;
-    LogDebug(log.str().c_str());
+    m_testContents.status = TestState::REG_IN_PROCESS;
 
     ecore_thread_run(RegisterStaticCb, NULL, NULL, this);
 }
@@ -296,19 +335,20 @@ void AppGUI::AuthenticateCb()
     TestGA(m_testContents);
     ecore_main_loop_thread_safe_call_sync(CleanQRFieldAndEnableUI, this);
     ecore_main_loop_thread_safe_call_sync(UpdateAuthStatus, this);
+    ecore_main_loop_thread_safe_call_sync(UpdateCreatedUserIds, this);
 }
 
 void AppGUI::AuthenticateButtonClickedCb()
 {
     std::ostringstream log;
-    if ((m_testContents.status != TestState::AUTH_SUCCCEEDED) &&
-        (m_testContents.status != TestState::REG_SUCCCEEDED)) {
+    elm_object_text_set(m_testResult, "");
+    elm_object_text_set(m_resultInfo, "");
+    if (m_testContents.createdCredDescs.size() == 0) {
         std::cout << "Cannot authenticate, you need to register first!\n";
+        m_testContents.testMsg = "There is no created credential";
         ecore_main_loop_thread_safe_call_sync(UpdateAuthStatus, this);
         return;
     }
-
-    elm_object_text_set(m_testInfo, "");
     DisableUIComponents(EINA_TRUE);
     evas_object_show(m_cancelBt);
 
@@ -342,7 +382,8 @@ void AppGUI::CancelButtonCb()
     int ret = CancelTest();
     if (ret != 0) {
         elm_object_text_set(
-            m_testInfo, _("<color=#FF0000FF>CANNOT CANCEL! WAIT FOR END OF THE SCENARIO</color>"));
+            m_testResult,
+            _("<color=#FF0000FF>CANNOT CANCEL! WAIT FOR END OF THE SCENARIO</color>"));
         return;
     }
 
@@ -362,6 +403,17 @@ void AppGUI::CreateGUI()
     Evas_Object *labelUN = nullptr;
     m_uiComp->AddLabel("Username", &labelUN);
     m_uiComp->AddEntry("testUser", &m_entry);
+    m_uiComp->AddLabel("Created usernames: { }", &m_createdUserIds);
+
+    /* Run scenarios buttons */
+    m_uiComp->AddButton("Register", &m_regBt, RegisterButtonClickedStaticCb, DARK_BLUE, this);
+    m_uiComp->AddButton(
+        "Authenticate", &m_authBt, AuthenticateButtonClickedStaticCb, DARK_BLUE, this);
+    m_uiComp->AddButton("Terminate", &m_terBt, WindowDeleteCb, DARK_BLUE, this, true);
+    m_uiComp->AddLabel(" ", &m_testResult);
+    m_uiComp->AddLabel(" ", &m_resultInfo);
+
+    m_uiComp->AddCancelButton("Cancel", &m_cancelBt, CancelButtonStaticCb, DARK_BLUE, this);
 
     /* Public Key Algorithms */
     Evas_Object *labelPKA = nullptr;
@@ -412,14 +464,6 @@ void AppGUI::CreateGUI()
     m_uiComp->AddButton("None", &m_atteBtNone, AttestationButtonStaticCb, PURPLE, this);
     m_uiComp->AddButton("Direct", &m_atteBtDir, AttestationButtonStaticCb, LIGHT_BLUE, this, true);
 
-    /* Run scenarios buttons */
-    m_uiComp->AddButton("Register", &m_regBt, RegisterButtonClickedStaticCb, DARK_BLUE, this);
-    m_uiComp->AddButton(
-        "Authenticate", &m_authBt, AuthenticateButtonClickedStaticCb, DARK_BLUE, this);
-    m_uiComp->AddButton("Terminate", &m_terBt, WindowDeleteCb, DARK_BLUE, this, true);
-    m_uiComp->AddLabel(" ", &m_testInfo);
-
-    m_uiComp->AddCancelButton("Cancel...", &m_cancelBt, CancelButtonStaticCb, DARK_BLUE, this);
 
     m_uiComp->ShowWindow();
 }
index 2909f1777b417b0fc2e7e5271b64399129c789ee..f0079f3c30cf7c919dbb8aac701833646a2b84b3 100644 (file)
@@ -75,6 +75,7 @@ private:
     static void *CleanQRFieldAndEnableUI(void *data);
     static void *UpdateAuthStatus(void *data);
     static void *UpdateRegStatus(void *data);
+    static void *UpdateCreatedUserIds(void *data);
 
     void DisableUIComponents(Eina_Bool disable);
 
@@ -82,7 +83,9 @@ private:
     std::unique_ptr<UIComponent> m_uiComp;
 
     // Webauthn manual test UI objects
-    Evas_Object *m_testInfo = nullptr;
+    Evas_Object *m_createdUserIds = nullptr;
+    Evas_Object *m_testResult = nullptr;
+    Evas_Object *m_resultInfo = nullptr;
     Evas_Object *m_hintsTable = nullptr;
 
     Evas_Object *m_entry = nullptr;
index 17ca99bda49fe7a11341319ace5d49dcc845054f..d197f3396d9f9eae388e6ed97f31ef740d71b631 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <condition_variable>
 #include <deque>
+#include <map>
 #include <mutex>
 #include <optional>
 #include <string>
@@ -104,13 +105,22 @@ struct LinkedData {
     Buffer identityKey;
 };
 
+struct CredDescriptor {
+    wauthn_pubkey_cred_type_e type;
+    Buffer id;
+    unsigned int transports;
+};
+
 struct TestContents {
     TestState status = TestState::REG_IN_PROCESS;
-    Buffer credentialRawId;
+    //Buffer credentialRawId;
     Buffer userId;
-    unsigned transports = WAUTHN_TRANSPORT_NONE;
+    //unsigned transports = WAUTHN_TRANSPORT_NONE;
     std::optional<LinkedData> linkedData = std::nullopt;
     const char *username = nullptr;
+    std::string testMsg;
+
+    std::map<Buffer, CredDescriptor> createdCredDescs;
 
     // an array containing information about which algorithms will be used in
     // wauthn_pubkey_cred_params_s
index bea35f58ac09790e60a985175c78412717b4ed26..f0194351f37d25e99ad41db1a8f1fc28ed2ec624 100644 (file)
@@ -30,11 +30,6 @@ constexpr inline char RP_NAME[] = "webauthn-manual-test-rpID";
 constexpr inline char RP_ID[] = "webauthn-manual-test-rpID";
 wauthn_rp_entity_s RP_ENTITY = {RP_NAME, RP_ID};
 
-// names and an identifier for the user account
-constexpr inline char USER_ID_RAW[] = "\x64\x47\x56\x7a\x64\x44\x4d\x79\x4d\x77";
-wauthn_const_buffer_s USER_ID = {reinterpret_cast<const uint8_t *>(USER_ID_RAW),
-                                 sizeof(USER_ID_RAW) - 1};
-
 constexpr unsigned long TIMEOUT = 120'000;
 
 // client data
@@ -138,7 +133,7 @@ void DisplayQRCallback(const char *qrContents, void *data)
 
     if (!ret) {
         std::cout << "mv_barcode_generate_image failed\n"
-                  << "Error code: " << ret << std::endl;
+                  << "Error code: " << get_error_message(ret) << std::endl;
         goto callback_failed;
     } else {
         std::cout << "mv_barcode_generate_image PASSED\n";
@@ -213,38 +208,41 @@ void ResponseCbMC(const wauthn_pubkey_credential_attestation_s *pubkey_cred,
                   wauthn_error_e result,
                   void *data)
 {
+    Buffer credRawId;
+    CredDescriptor credDesc;
     std::cout << "MC: response_callback() was called." << std::endl;
     TestContents *contents = static_cast<TestContents *>(data);
 
     if (result == WAUTHN_ERROR_TIMED_OUT) {
-        std::cout << "MC: request timed out" << std::endl;
+        contents->testMsg = "Timed out";
         goto callback_failed;
     }
     if (result != WAUTHN_ERROR_NONE) {
-        std::cout << "MC: Response_callback failed, Error code: " << result << std::endl;
+        contents->testMsg = "Response_callback Error: " + std::string(get_error_message(result));
         goto callback_failed;
     }
     if (!pubkey_cred) {
-        std::cout << "MC: pubkey_cred is null\n";
+        contents->testMsg = "pubkey_cred is NULL";
         goto callback_failed;
     }
     if (!pubkey_cred->rawId) {
-        std::cout << "MC: pubkey_cred->rawId is NULL\n";
+        contents->testMsg = "pubkey_cred->rawId is NULL";
         goto callback_failed;
     }
     if (!pubkey_cred->response) {
-        std::cout << "MC: pubkey_cred->response is NULL\n";
+        contents->testMsg = "pubkey_cred->response is NULL";
         goto callback_failed;
     }
-
-    contents->credentialRawId = ToBuffer(*pubkey_cred->rawId);
-    std::cout << "MC: credentialRawId: " << LowercaseHexStringOf(contents->credentialRawId)
-              << std::endl;
-    contents->transports = pubkey_cred->response->transports;
+    credRawId = ToBuffer(*pubkey_cred->rawId);
+    credDesc = {pubkey_cred->type, credRawId, pubkey_cred->response->transports};
+    std::cout << "MC: credentialRawId: " << LowercaseHexStringOf(credRawId) << std::endl;
+    contents->createdCredDescs[contents->userId] = credDesc;
+    std::cout << "MakeCredential: awaiting potential CTAP UPDATE messages..." << std::endl;
     contents->UpdateLinkedData(pubkey_cred->linked_device);
     return;
 
 callback_failed:
+    std::cout << "MC: " << contents->testMsg.c_str() << std::endl;
     contents->status = TestState::RESP_MC_CB_FAILED;
     contents->finished = true;
     contents->cv.notify_one();
@@ -260,46 +258,86 @@ void ResponseCbGA(const wauthn_pubkey_credential_assertion_s *pubkey_cred,
     Buffer credentialRawId;
 
     if (result == WAUTHN_ERROR_TIMED_OUT) {
-        std::cout << "GA: request timed out" << std::endl;
+        contents->testMsg = "Timed out";
     }
     if (result != WAUTHN_ERROR_NONE) {
-        std::cout << "GA: response_callback failed with code " << result << std::endl;
+        contents->testMsg = "Response_callback Error: " + std::string(get_error_message(result));
         goto callback_failed;
     }
     if (!pubkey_cred) {
-        std::cout << "GA: pubkey_cred is NULL" << std::endl;
+        contents->testMsg = "pubkey_cred is NULL";
         goto callback_failed;
     }
     if (!pubkey_cred->rawId) {
-        std::cout << "GA: pubkey_cred->rawId is NULL" << std::endl;
+        contents->testMsg = "pubkey_cred->rawId is NULL";
         goto callback_failed;
     }
     if (!pubkey_cred->response) {
-        std::cout << "GA: pubkey_cred->response is NULL" << std::endl;
+        contents->testMsg = "pubkey_cred->response is NULL";
         goto callback_failed;
     }
 
+    // Check credential is valid
     credentialRawId = ToBuffer(*pubkey_cred->rawId);
-    if (credentialRawId != contents->credentialRawId) {
-        std::cout << "Error: invalid credentialRawId in GA: "
-                  << LowercaseHexStringOf(credentialRawId) << std::endl;
-        goto callback_failed;
+    if (strlen(contents->username) != 0) // with username
+    {
+        if (pubkey_cred->response->user_handle)
+        {
+            auto userHandle = ToBuffer(*pubkey_cred->response->user_handle);
+            if (userHandle != contents->userId)
+            {
+                std::cout << "Error: invalid userHandle in GA: "
+                          << LowercaseHexStringOf(userHandle)
+                          << std::endl;
+                contents->testMsg = "Invalid username";
+                goto callback_failed;
+            }
+        }
+        auto it = contents->createdCredDescs.find(contents->userId);
+        if (it == contents->createdCredDescs.end()
+            || it->second.id != credentialRawId)
+        {
+            std::cout << "Error: invalid credentialRawId in GA: "
+                      << LowercaseHexStringOf(credentialRawId)
+                      << " and found(" << LowercaseHexStringOf(it->second.id)
+                      << ")" << std::endl;
+            contents->testMsg = "Invalid credentialRawId";
+            goto callback_failed;
+        }
+        else
+        {
+            std::cout << "Found credential of username(" << LowercaseHexStringOf(it->first)
+                      << "): "<< LowercaseHexStringOf(credentialRawId) << std::endl;
+        }
     }
-
-    if (pubkey_cred->response->user_handle) {
-        auto userHandle = ToBuffer(*pubkey_cred->response->user_handle);
-        if (userHandle != contents->userId) {
-            std::cout << "Error: invalid userHandle in GA: " << LowercaseHexStringOf(userHandle)
-                      << std::endl;
+    else // without username
+    {
+        bool isFound = false;
+        for (auto const& cred : contents->createdCredDescs)
+        {
+            if (cred.second.id == credentialRawId) // Found
+            {
+                contents->userId == cred.first;
+                isFound = true;
+                std::cout << "Found credential of userId(" << LowercaseHexStringOf(cred.first)
+                          << "): "<< LowercaseHexStringOf(credentialRawId) << std::endl;
+                break;
+            }
+        }
+        if (!isFound)
+        {
+            std::cout << "Error: unrecognized credentialRawId in GA: "
+                      << LowercaseHexStringOf(credentialRawId) << std::endl;
+            contents->testMsg = "Unrecognized credentialRawId";
             goto callback_failed;
         }
     }
-
     contents->UpdateLinkedData(pubkey_cred->linked_device);
     std::cout << "GetAssertion: awaiting potential CTAP UPDATE messages..." << std::endl;
     return;
 
 callback_failed:
+    std::cout << "MC: " << contents->testMsg.c_str() << std::endl;
     contents->status = TestState::RESP_GA_CB_FAILED;
     contents->finished = true;
     contents->cv.notify_one();
@@ -317,6 +355,7 @@ void MCScenario::SetCallbacks()
 void MCScenario::Test()
 {
     std::cout << "[MAKE CREDENTIAL]: START" << std::endl;
+
     wauthn_pubkey_cred_creation_options_s m_options;
     std::memset(&m_options, 0, sizeof(m_options));
 
@@ -328,7 +367,8 @@ void MCScenario::Test()
     else {
         if (m_contents.algorithms[0])
             params.push_back(
-                {WAUTHN_PUBKEY_CRED_TYPE_PUBLIC_KEY, WAUTHN_COSE_ALGORITHM_ECDSA_P256_WITH_SHA256});
+                {WAUTHN_PUBKEY_CRED_TYPE_PUBLIC_KEY,
+                 WAUTHN_COSE_ALGORITHM_ECDSA_P256_WITH_SHA256});
         if (m_contents.algorithms[1])
             params.push_back({WAUTHN_PUBKEY_CRED_TYPE_PUBLIC_KEY,
                               WAUTHN_COSE_ALGORITHM_RSASSA_PKCS1_V1_5_WITH_SHA256});
@@ -353,8 +393,11 @@ void MCScenario::Test()
     }
 
     // Entity ID
+    wauthn_const_buffer_s userId = {reinterpret_cast<const uint8_t *>(m_contents.username),
+                                    strlen(m_contents.username)};
+    m_contents.userId = ToBuffer(userId);
     wauthn_user_entity_s userEntity = {const_cast<char *>(m_contents.username),
-                                       &TestData::USER_ID,
+                                       &userId,
                                        const_cast<char *>(m_contents.username)};
 
     // Authenticator selection data
@@ -375,9 +418,6 @@ void MCScenario::Test()
     m_options.attestation = m_contents.attPref;
 
     m_contents.status = TestState::REG_IN_PROCESS;
-    m_contents.credentialRawId = {};
-    m_contents.userId = ToBuffer(TestData::USER_ID);
-    m_contents.transports = WAUTHN_TRANSPORT_NONE;
     m_contents.linkedData = std::nullopt;
     m_contents.seenLastMCUpdateCb = false;
     m_contents.seenLastGAUpdateCb = false;
@@ -393,12 +433,17 @@ void MCScenario::Test()
                 std::cout << "TestMakeCredential failed with status: "
                           << TestStateToString(m_contents.status) << std::endl;
                 m_contents.status = TestState::REG_FAILED;
+                m_contents.testMsg = "Failed with status: "
+                                     + std::string(TestStateToString(m_contents.status));
                 return;
             }
         } else {
-            std::cout << "wauthn_make_credential command failed, error: " << res
+            std::cout << "wauthn_make_credential command failed, error: "
+                      << get_error_message(res)
                       << "\nTestMakeCredential failed with status: "
                       << TestStateToString(m_contents.status) << std::endl;
+            m_contents.testMsg = "Failed with status: "
+                                 + std::string(TestStateToString(m_contents.status));
             m_contents.status = TestState::REG_FAILED;
             return;
         }
@@ -407,8 +452,9 @@ void MCScenario::Test()
         std::cout << "TestMakeCredential passed!\n";
         m_contents.seenLastGAUpdateCb = false;
     }
-
     std::cout << "[MAKE CREDENTIAL]: END" << std::endl;
+    std::cout << "Current size of createdCreds: " << m_contents.createdCredDescs.size()
+              << std::endl;
 }
 
 void GAScenario::SetCallbacks()
@@ -421,8 +467,56 @@ void GAScenario::SetCallbacks()
 
 void GAScenario::Test()
 {
-    std::cout << "[GET ASSERTION]: START" << std::endl;
+    std::cout << "[GET ASSERTION]: START";
     m_contents.status = TestState::AUTH_IN_PROCESS;
+    // set userId and allowCredentials
+    size_t userIdLength = strlen(m_contents.username);
+    wauthn_const_buffer_s userId = {reinterpret_cast<const uint8_t *>(m_contents.username),
+                                    userIdLength};
+    m_contents.userId = ToBuffer(userId);
+    std::vector<wauthn_pubkey_cred_descriptor_s> vCredDescriptors;
+    std::map<Buffer, wauthn_const_buffer_s> mBuffer;
+    if (userIdLength == 0)
+    {
+        std::cout << "Set allowCredentials with size: " << m_contents.createdCredDescs.size()
+                  << std::endl;
+        for (auto const& cred : m_contents.createdCredDescs)
+        {
+            mBuffer[cred.first] = ToWauthnConstBuff(cred.second.id);
+            vCredDescriptors.push_back({cred.second.type, &mBuffer[cred.first],
+                                        cred.second.transports});
+            std::cout << "userId: " << LowercaseHexStringOf(cred.first)
+                      << ", credId: " << LowercaseHexStringOf(cred.second.id) << std::endl;
+        }
+    }
+    else if(m_contents.createdCredDescs.count(m_contents.userId) == 0)
+    {
+        std::cout << "That username has no registered credentials: "
+                  << m_contents.username << std::endl;
+        m_contents.testMsg = "That username is not registered";
+        m_contents.status = TestState::AUTH_FAILED;
+        return;
+    }
+    else
+    {
+        auto it = m_contents.createdCredDescs.find(m_contents.userId);
+        wauthn_const_buffer_s credId = ToWauthnConstBuff(it->second.id);
+        vCredDescriptors.push_back({it->second.type, &credId, it->second.transports});
+        std::cout << "Set an allowCredential id: " << LowercaseHexStringOf(it->second.id)
+                  << std::endl;
+    }
+
+    wauthn_pubkey_cred_descriptors_s allowCredentials = {vCredDescriptors.size(),
+                                                         vCredDescriptors.data()};
+
+    std::cout << "size: " << allowCredentials.size << std::endl;
+    for (size_t i = 0; i < allowCredentials.size; ++i)
+    {
+        std::cout << "id: " << LowercaseHexStringOf(ToBuffer(*allowCredentials.descriptors[i].id))
+                  << std::endl;
+        std::cout << "type: " << allowCredentials.descriptors[i].type << std::endl;
+        std::cout << "transport: " << allowCredentials.descriptors[i].transports << std::endl;
+    }
 
     wauthn_pubkey_cred_request_options_s m_options;
     std::memset(&m_options, 0, sizeof(m_options));
@@ -436,17 +530,6 @@ void GAScenario::Test()
     wauthn_const_buffer_s tunnelServerDomain;
     wauthn_const_buffer_s identityKey;
 
-    wauthn_const_buffer_s credentialId = ToWauthnConstBuff(m_contents.credentialRawId);
-
-    wauthn_pubkey_cred_descriptor_s pubkeyCredDescriptor;
-    pubkeyCredDescriptor.type = WAUTHN_PUBKEY_CRED_TYPE_PUBLIC_KEY;
-    pubkeyCredDescriptor.id = &credentialId;
-    pubkeyCredDescriptor.transports = m_contents.transports;
-
-    wauthn_pubkey_cred_descriptors_s pubkeyCredDescriptors;
-    pubkeyCredDescriptors.size = 1;
-    pubkeyCredDescriptors.descriptors = &pubkeyCredDescriptor;
-
     wauthn_hybrid_linked_data_s linkedDevice;
     if (m_contents.linkedData) {
         std::cout << "linked data exists\n";
@@ -472,9 +555,9 @@ void GAScenario::Test()
 
     m_options.timeout = TestData::TIMEOUT;
     m_options.rpId = const_cast<char *>(TestData::RP_ID);
+    m_options.allow_credentials = &allowCredentials;
     m_options.user_verification = m_contents.userVerification;
     m_options.attestation = m_contents.attPref;
-    m_options.allow_credentials = &pubkeyCredDescriptors;
     m_options.linked_device = m_contents.linkedData ? &linkedDevice : nullptr;
     m_options.attestation_formats = nullptr;
     m_options.extensions = nullptr;
@@ -489,6 +572,8 @@ void GAScenario::Test()
             if (m_contents.status != TestState::LD_UPDATED) {
                 std::cout << "TestGetAssertion failed with status: "
                           << TestStateToString(m_contents.status) << std::endl;
+                m_contents.testMsg = "Failed with status: "
+                                     + std::string(TestStateToString(m_contents.status));
                 m_contents.status = TestState::AUTH_FAILED;
                 return;
             }
@@ -496,6 +581,8 @@ void GAScenario::Test()
             std::cout
                 << "wauthn_get_assertion command failed\nTestGetAssertion failed with status: "
                 << TestStateToString(m_contents.status) << std::endl;
+            m_contents.testMsg = "Failed with status: "
+                                 + std::string(TestStateToString(m_contents.status));
             m_contents.status = TestState::AUTH_FAILED;
             return;
         }
@@ -505,6 +592,8 @@ void GAScenario::Test()
         m_contents.seenLastGAUpdateCb = false;
     }
     std::cout << "[GET ASSERTION]: END" << std::endl;
+    std::cout << "Current size of createdCreds: " << m_contents.createdCredDescs.size()
+              << std::endl;
 }
 
 } // namespace ManTestScenario
index d970a9029828f3caa5696c41ede19d09d7528a11..4a7b94255169452d621496de94c19406a0680bc5 100644 (file)
@@ -35,7 +35,7 @@ void UIComponent::NextRow(unsigned incY)
 void UIComponent::AddEntry(const std::string &name, Evas_Object **entry)
 {
     int width = 400;
-    int height = 70;
+    int height = 50;
     *entry = elm_entry_add(m_win);
     elm_entry_single_line_set(*entry, EINA_TRUE);
     elm_entry_entry_set(*entry, name.c_str());
@@ -55,7 +55,7 @@ void UIComponent::AddButton(const std::string &name,
                             bool nextRow)
 {
     int width = 170;
-    int height = 50;
+    int height = 30;
     *bt = elm_button_add(m_win);
     elm_object_text_set(*bt, name.c_str());
     elm_object_color_class_color_set(*bt, "bg", cd.r, cd.g, cd.b, cd.d);
@@ -73,13 +73,13 @@ void UIComponent::AddButton(const std::string &name,
 void UIComponent::AddCancelButton(
     const std::string &name, Evas_Object **bt, Evas_Smart_Cb cb, ColorData cd, void *data)
 {
-    int width = 300;
+    int width = 250;
     int height = 100;
     *bt = elm_button_add(m_win);
     elm_object_text_set(*bt, name.c_str());
     elm_object_color_class_color_set(*bt, "bg", cd.r, cd.g, cd.b, cd.d);
     evas_object_smart_callback_add(*bt, "clicked", cb, data);
-    evas_object_move(*bt, 170, 500);
+    evas_object_move(*bt, 340, 550);
     evas_object_resize(*bt, width, height);
 }
 
@@ -117,7 +117,7 @@ void UIComponent::AddImage(Evas_Object **image, const std::string &path)
     int width = 250;
     int height = 250;
     int posX = 340;
-    int posY = 150;
+    int posY = 300;
     *image = elm_image_add(m_win);
     elm_image_file_set(*image, path.c_str(), NULL);
     elm_image_no_scale_set(*image, EINA_TRUE);