Load libwebauthn library with dlopen 97/321097/2
authorInsoon Kim <is46.kim@samsung.com>
Thu, 21 Nov 2024 23:45:42 +0000 (08:45 +0900)
committerBot Blink <blinkbot@samsung.com>
Thu, 28 Nov 2024 03:10:34 +0000 (03:10 +0000)
This commit removes the dependency on libwebauthn libray and loads it
with dlopen when the passkey related feature is invoked at runtime.

Change-Id: Ibb48c29b3934b7b30b2918a14eedae0d7f4d4d3f
Signed-off-by: Insoon Kim <is46.kim@samsung.com>
tizen_src/build/BUILD.gn
tizen_src/chromium_impl/content/browser/browser_efl.gni
tizen_src/chromium_impl/content/browser/webauthn/authenticator_common_tizen.cc
tizen_src/chromium_impl/content/browser/webauthn/authenticator_common_tizen.h
tizen_src/chromium_impl/content/browser/webauthn/tizen_webauthn_proxy.cc [new file with mode: 0644]
tizen_src/chromium_impl/content/browser/webauthn/tizen_webauthn_proxy.h [new file with mode: 0644]

index dfb89d0c6332a35684369bba0332fc991de94ae7..8efcd091b8321584db01083b57ce292392161c67 100644 (file)
@@ -126,15 +126,9 @@ config("ecore-evas-public") {
 }
 
 if (tizen_passkey_support) {
-  config("webauthn") {
-    ldflags = [
-      "-lwebauthn-client",
-      "-lwebauthn-common",
-    ]
-  }
-
   tizen_pkg_config("libwebauthn") {
     packages = [ "webauthn" ]
+    ignore_libs = true
   }
 
   config("capi-media-vision-barcode") {
index 93ad21e28b36a6ff4d919927550a69dedce4ae0c..a66832a27f76b2de099caa396e3d14b95ce555bb 100644 (file)
@@ -35,7 +35,6 @@ if (is_tizen) {
 
   if (tizen_passkey_support) {
     external_content_browser_efl_configs += [
-      "//tizen_src/build:webauthn",
       "//tizen_src/build:libwebauthn",
       "//tizen_src/build:capi-media-vision-barcode",
       "//tizen_src/build:libcapi-media-vision-barcode",
@@ -159,6 +158,8 @@ if (is_tizen) {
     external_content_browser_efl_sources += [
       "//tizen_src/chromium_impl/content/browser/webauthn/authenticator_common_tizen.cc",
       "//tizen_src/chromium_impl/content/browser/webauthn/authenticator_common_tizen.h",
+      "//tizen_src/chromium_impl/content/browser/webauthn/tizen_webauthn_proxy.cc",
+      "//tizen_src/chromium_impl/content/browser/webauthn/tizen_webauthn_proxy.h",
     ]
     external_exclude_content_browser_efl_sources += [
       "webauth/authenticator_common_impl.cc",
index c359d84f6386a5edd5950eb070102d6707d0216f..1a40462907da13cc457ff27ac4d0272a101d7cc4 100644 (file)
@@ -29,6 +29,7 @@
 #include "content/browser/webauth/virtual_authenticator_manager_impl.h"
 #include "content/browser/webauth/virtual_fido_discovery_factory.h"
 #include "content/browser/webauth/webauth_request_security_checker.h"
+#include "content/browser/webauthn/tizen_webauthn_proxy.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
@@ -796,7 +797,8 @@ AuthenticatorCommonTizen::AuthenticatorCommonTizen(
     RenderFrameHost* render_frame_host)
     : render_frame_host_id_(render_frame_host->GetGlobalId()),
       security_checker_(static_cast<RenderFrameHostImpl*>(render_frame_host)
-                            ->GetWebAuthRequestSecurityChecker()) {
+                            ->GetWebAuthRequestSecurityChecker()),
+      tizen_webauthn_proxy_(TizenWebAuthnProxy::Get()) {
   static_cast<RenderFrameHostImpl*>(GetRenderFrameHost())
       ->set_authenticator(weak_factory_.GetWeakPtr());
   // Disable the back-forward cache for any document that makes WebAuthn
@@ -1650,7 +1652,7 @@ void AuthenticatorCommonTizen::ContinueMakeCredential() {
     LOG(INFO) << "[Passkey] TO wauthn_make_credential without linked_device";
   }
   int ret =
-      wauthn_make_credential(&mc_client_data_, &mc_options_, &mc_callbacks_);
+      tizen_webauthn_proxy_->wauthn_make_credential(&mc_client_data_, &mc_options_, &mc_callbacks_);
   if (ret != WAUTHN_ERROR_NONE) {
     Cancel();
   }
@@ -2041,7 +2043,7 @@ void AuthenticatorCommonTizen::ContinueGetAssertion() {
     LOG(INFO) << "[Passkey] TO wauthn_get_assertion without linked_device";
   }
   int ret =
-      wauthn_get_assertion(&ga_client_data_, &ga_options_, &ga_callbacks_);
+      tizen_webauthn_proxy_->wauthn_get_assertion(&ga_client_data_, &ga_options_, &ga_callbacks_);
   if (ret != WAUTHN_ERROR_NONE) {
     Cancel();
   }
@@ -2132,7 +2134,7 @@ void AuthenticatorCommonTizen::IsConditionalMediationAvailable(
 
 void AuthenticatorCommonTizen::Cancel() {
   // Invoke webauthn cancel
-  wauthn_cancel();
+  tizen_webauthn_proxy_->wauthn_cancel();
   CancelWithStatus(blink::mojom::AuthenticatorStatus::ABORT_ERROR);
 }
 
index 73fda8352e9e1359d0cc5df00a59babb9a3718bd..0b16327fe9cfcec90e5b98833e0b3020885c295c 100644 (file)
@@ -2,7 +2,7 @@
 #define AUTHENTICATOR_COMMON_TIZEN_H_
 
 #include <stdint.h>
-#include <webauthn.h>
+#include <webauthn-types.h>
 
 #include <memory>
 #include <string>
@@ -29,6 +29,7 @@ namespace content {
 class BrowserContext;
 class RenderFrameHost;
 class WebAuthRequestSecurityChecker;
+class TizenWebAuthnProxy;
 
 enum class RequestExtension;
 enum class AttestationErasureOption;
@@ -318,6 +319,8 @@ class CONTENT_EXPORT AuthenticatorCommonTizen : public AuthenticatorCommon {
   // only contains a value when a request is being processed.
   std::unique_ptr<RequestState> req_state_;
 
+  std::shared_ptr<TizenWebAuthnProxy> tizen_webauthn_proxy_;
+
   base::WeakPtrFactory<AuthenticatorCommonTizen> weak_factory_{this};
 };
 
diff --git a/tizen_src/chromium_impl/content/browser/webauthn/tizen_webauthn_proxy.cc b/tizen_src/chromium_impl/content/browser/webauthn/tizen_webauthn_proxy.cc
new file mode 100644 (file)
index 0000000..133cc6d
--- /dev/null
@@ -0,0 +1,86 @@
+// Copyright 2024 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <dlfcn.h>
+
+#include "base/logging.h"
+#include "content/browser/webauthn/tizen_webauthn_proxy.h"
+
+#define WEBAUTHN_CLIENT_LIBRARY "libwebauthn-client.so.1"
+
+namespace {
+void* dlsym_helper(void* handle, const char* symbol) {
+  if (!handle) {
+    LOG(ERROR) << "Failed to load " << WEBAUTHN_CLIENT_LIBRARY;
+    return nullptr;
+  }
+  auto func = dlsym(handle, symbol);
+  if (!func) {
+    LOG(ERROR) << "Failed to load " << symbol;
+    return nullptr;
+  }
+  return func;
+}
+}  // namespace
+
+namespace content {
+
+std::shared_ptr<TizenWebAuthnProxy> TizenWebAuthnProxy::tizen_webauthn_proxy_ =
+    nullptr;
+
+std::shared_ptr<TizenWebAuthnProxy> TizenWebAuthnProxy::Get() {
+  if (!tizen_webauthn_proxy_) {
+    tizen_webauthn_proxy_ = std::make_shared<TizenWebAuthnProxy>();
+  }
+  return tizen_webauthn_proxy_;
+}
+
+TizenWebAuthnProxy::TizenWebAuthnProxy() {
+  LOG(INFO) << "TizenWebAuthnProxy";
+  handle_ = dlopen(WEBAUTHN_CLIENT_LIBRARY, RTLD_LAZY);
+  if (!handle_) {
+    LOG(ERROR) << "Failed to load " << WEBAUTHN_CLIENT_LIBRARY;
+  }
+}
+
+TizenWebAuthnProxy::~TizenWebAuthnProxy() {
+  LOG(INFO) << "~TizenWebAuthnProxy";
+  if (handle_) {
+    dlclose(handle_);
+  }
+}
+
+int TizenWebAuthnProxy::wauthn_make_credential(
+    const wauthn_client_data_s* client_data,
+    const wauthn_pubkey_cred_creation_options_s* options,
+    wauthn_mc_callbacks_s* callbacks) {
+  auto func = reinterpret_cast<int (*)(
+      const wauthn_client_data_s*, const wauthn_pubkey_cred_creation_options_s*,
+      wauthn_mc_callbacks_s*)>(dlsym_helper(handle_, "wauthn_make_credential"));
+  if (!func)
+    return WAUTHN_ERROR_NOT_SUPPORTED;
+  return func(client_data, options, callbacks);
+}
+
+int TizenWebAuthnProxy::wauthn_get_assertion(
+    const wauthn_client_data_s* client_data,
+    const wauthn_pubkey_cred_request_options_s* options,
+    wauthn_ga_callbacks_s* callbacks) {
+  auto func = reinterpret_cast<int (*)(
+      const wauthn_client_data_s*, const wauthn_pubkey_cred_request_options_s*,
+      wauthn_ga_callbacks_s*)>(dlsym_helper(handle_, "wauthn_get_assertion"));
+  if (!func)
+    return WAUTHN_ERROR_NOT_SUPPORTED;
+  return func(client_data, options, callbacks);
+}
+
+int TizenWebAuthnProxy::wauthn_cancel() {
+  auto func =
+      reinterpret_cast<int (*)()>(dlsym_helper(handle_, "wauthn_cancel"));
+  if (!func)
+    return WAUTHN_ERROR_NOT_SUPPORTED;
+  return func();
+}
+
+}  // namespace content
diff --git a/tizen_src/chromium_impl/content/browser/webauthn/tizen_webauthn_proxy.h b/tizen_src/chromium_impl/content/browser/webauthn/tizen_webauthn_proxy.h
new file mode 100644 (file)
index 0000000..2b9afc0
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright 2024 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TIZEN_WEBAUTHN_PROXY_H_
+#define TIZEN_WEBAUTHN_PROXY_H_
+
+#include <webauthn-types.h>
+#include <memory>
+
+namespace content {
+
+class TizenWebAuthnProxy {
+ public:
+  static std::shared_ptr<TizenWebAuthnProxy> Get();
+  TizenWebAuthnProxy();
+  ~TizenWebAuthnProxy();
+
+  bool IsLoaded() const { return handle_ != nullptr; }
+
+  int wauthn_make_credential(
+      const wauthn_client_data_s* client_data,
+      const wauthn_pubkey_cred_creation_options_s* options,
+      wauthn_mc_callbacks_s* callbacks);
+
+  int wauthn_get_assertion(const wauthn_client_data_s* client_data,
+                           const wauthn_pubkey_cred_request_options_s* options,
+                           wauthn_ga_callbacks_s* callbacks);
+
+  int wauthn_cancel(void);
+
+ private:
+  void* handle_;
+  static std::shared_ptr<TizenWebAuthnProxy> tizen_webauthn_proxy_;
+};
+
+}  // namespace content
+
+#endif  // TIZEN_WEBAUTHN_PROXY_H_