- Introduce WebSDI and Mutual Authenticate Feature.
- Add Dynamic Certificate Feature.
- Refactoring root Certificate & WRT client Certificate.
- Remove duplicate functions of certificate loading.
- Refactoring the client certificate selection code for WRT.
- Change the kDefaultCertPublic path and kDefaultCertPrivate.
- DefaultClientCert path setting based on Tizen version
This patch is migrated from Tizen7.0:
https://review.tizen.org/gerrit/#/c/platform/framework/web/chromium-efl/+/281524/
Change-Id: Ic401ea8f94d02b2f7b7d9d383bc03c99092d9bf7
Signed-off-by: jingjieli <jingjie.li@samsung.com>
delegate_->CancelCertificateSelection();
return;
}
-
+#if !BUILDFLAG(IS_TIZEN_TV)
// Note that if |client_cert_store_| is NULL, we intentionally fall through to
// SelectClientCertificate(). This is for platforms where the client cert
// matching is not performed by Chrome. Those platforms handle the cert
delegate_->ContinueWithCertificate(nullptr, nullptr);
return;
}
+#else
+ LOG(INFO) << "Try to get client certificates";
+#endif
// SelectClientCertificate() may call back into |delegate_| synchronously and
// destroy this object, so guard the cancellation callback logic by a WeakPtr.
return GetPrimaryPage().did_first_visually_non_empty_paint();
}
+#if BUILDFLAG(IS_TIZEN_TV)
+void WebContentsImpl::AddDynamicCertificatePath(const std::string& host,
+ const std::string& cert_path) {
+ GetContentClient()->browser()->AddDynamicCertificatePath(host, cert_path);
+}
+#endif
+
void WebContentsImpl::OnDidDownloadImage(
base::WeakPtr<RenderFrameHostImpl> rfh,
ImageDownloadCallback callback,
service_manager::InterfaceProvider* GetJavaInterfaces() override;
#endif
bool HasRecentInteractiveInputEvent() override;
+#if BUILDFLAG(IS_TIZEN_TV)
+ void AddDynamicCertificatePath(const std::string& host,
+ const std::string& cert_path) override;
+#endif
void SetIgnoreInputEvents(bool ignore_input_events) override;
bool HasActiveEffectivelyFullscreenVideo() override;
void WriteIntoTrace(perfetto::TracedValue context) override;
net::ClientCertIdentityList client_certs,
std::unique_ptr<ClientCertificateDelegate> delegate);
+#if BUILDFLAG(IS_TIZEN_TV)
+ // Add host and cert_path to map.
+ // When we get the "Certificate Request" packet from server,
+ // We find the matched cert path to host in the map.
+ virtual void AddDynamicCertificatePath(const std::string& host,
+ const std::string& cert_path) {}
+#endif
+
// Returns a class to get notifications about media event. The embedder can
// return nullptr if they're not interested.
virtual MediaObserver* GetMediaObserver();
// user activation work.
virtual bool HasRecentInteractiveInputEvent() = 0;
+#if BUILDFLAG(IS_TIZEN_TV)
+ virtual void AddDynamicCertificatePath(const std::string& host,
+ const std::string& cert_path) = 0;
+#endif
+
// Sets a flag that causes the WebContents to ignore input events.
virtual void SetIgnoreInputEvents(bool ignore_input_events) = 0;
#include <utility>
#include "base/check_op.h"
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "base/logging.h"
+#endif
#include "crypto/openssl_util.h"
#include "third_party/boringssl/src/include/openssl/bn.h"
#include "third_party/boringssl/src/include/openssl/bytestring.h"
#include "third_party/boringssl/src/include/openssl/evp.h"
#include "third_party/boringssl/src/include/openssl/mem.h"
#include "third_party/boringssl/src/include/openssl/pkcs8.h"
-
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "third_party/boringssl/src/include/openssl/pem.h"
+#endif
namespace crypto {
ECPrivateKey::~ECPrivateKey() = default;
ECPrivateKey::ECPrivateKey() = default;
+#if BUILDFLAG(IS_TIZEN_TV)
+bool ECPrivateKey::ConvertPEMtoDERFromPrivateKey(const std::string& key_buffer,
+ std::vector<uint8_t>* output) {
+ bssl::UniquePtr<BIO> in(
+ BIO_new_mem_buf(const_cast<char*>(key_buffer.data()), key_buffer.size()));
+ if (!in) {
+ LOG(ERROR) << "Can't create a memory BIO";
+ return false;
+ }
+
+ bssl::UniquePtr<BIO> out(BIO_new(BIO_s_mem()));
+ if (!out) {
+ LOG(ERROR) << "BIO_new for converting a format of private key failed";
+ return false;
+ }
+
+ EVP_PKEY* pkey = PEM_read_bio_PrivateKey(in.get(), NULL, NULL, NULL);
+ if (!pkey) {
+ LOG(ERROR) << "Can't load private key";
+ return false;
+ }
+
+ int ret = i2d_PKCS8PrivateKeyInfo_bio(out.get(), pkey);
+ EVP_PKEY_free(pkey);
+ if (!ret) {
+ LOG(ERROR) << "Can't convert a format of private key";
+ return false;
+ }
+
+ char* data = nullptr;
+ long len = BIO_get_mem_data(out.get(), &data);
+
+ if (!data || len < 0) {
+ LOG(ERROR) << "Can't get der data from BIO";
+ return false;
+ }
+
+ output->assign(data, data + len);
+ return true;
+}
+#endif
} // namespace crypto
// Exports the public key as an EC point in X9.62 uncompressed form. Note this
// includes the leading 0x04 byte.
bool ExportRawPublicKey(std::string* output) const;
+#if BUILDFLAG(IS_TIZEN_TV)
+ static bool ConvertPEMtoDERFromPrivateKey(const std::string& key_buffer,
+ std::vector<uint8_t>* output);
+#endif
private:
// Constructor is private. Use one of the Create*() methods above instead.
#include "net/cert/cert_database.h"
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "base/logging.h"
+#endif
#include "base/memory/singleton.h"
#include "base/observer_list_threadsafe.h"
#include "build/build_config.h"
#include "net/cert/x509_util_nss.h"
#endif
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "crypto/ec_private_key.h"
+#include "net/cert/x509_certificate.h"
+#endif
namespace net {
// static
}
#endif
+#if BUILDFLAG(IS_TIZEN_TV)
+int CertDatabase::CheckUserCert(CERTCertificate* cert_obj) {
+ if (!cert_obj)
+ return ERR_CERT_INVALID;
+ // Check if the private key corresponding to the certificate exist
+ // We shouldn't accept any random client certificate sent by a CA.
+ // Note: The NSS source documentation wrongly suggests that this
+ // also imports the certificate if the private key exists. This
+ // doesn't seem to be the case.
+ PK11SlotInfo* slot = PK11_KeyForCertExists(cert_obj, NULL, NULL);
+ if (!slot)
+ return ERR_NO_PRIVATE_KEY_FOR_CERT;
+ PK11_FreeSlot(slot);
+ return OK;
+}
+
+int CertDatabase::AddUserCert(CERTCertificate* cert_obj) {
+ if (!cert_obj)
+ return ERR_CERT_INVALID;
+
+ CK_OBJECT_HANDLE key;
+ crypto::ScopedPK11Slot slot(PK11_KeyForCertExists(cert_obj, &key, NULL));
+ if (!slot.get())
+ return ERR_NO_PRIVATE_KEY_FOR_CERT;
+
+ std::string nickname =
+ x509_util::GetDefaultUniqueNickname(cert_obj, USER_CERT, slot.get());
+
+ // If an user cert was already imported in db,
+ // some error was occured in a second attempt to import that user cert.
+ // User cert that already imported doesn't need to import every time
+ // because a db is reused.
+ if (cert_obj->isperm) {
+ LOG(INFO) << "User cert already exists ("
+ << PK11_GetSlotName(cert_obj->slot) << "): \"" << nickname
+ << "\"";
+ return OK;
+ }
+
+ SECStatus result_value =
+ PK11_ImportCert(slot.get(), cert_obj, key, nickname.c_str(), PR_FALSE);
+ if (result_value != SECSuccess) {
+ LOG(ERROR) << "Couldn't import user certificate. " << PORT_GetError();
+ return ERR_ADD_USER_CERT_FAILED;
+ }
+ NotifyObserversCertDBChanged();
+ return OK;
+}
+
+bool CertDatabase::ImportPrivateKey(const std::string& key_buffer) {
+ std::vector<uint8> output;
+ if (!crypto::ECPrivateKey::ConvertPEMtoDERFromPrivateKey(key_buffer,
+ &output)) {
+ LOG(ERROR) << "Private Key Convert fail";
+ return false;
+ }
+
+ SECItem der_private_key_info;
+ SECStatus result_value;
+ PK11SlotInfo* slot = PK11_GetInternalKeySlot();
+
+ der_private_key_info.data = output.data();
+ der_private_key_info.len = output.size();
+
+ result_value = PK11_ImportDERPrivateKeyInfo(
+ slot, &der_private_key_info, NULL, NULL, PR_TRUE, PR_TRUE, KU_ALL, NULL);
+
+ if (result_value != SECSuccess) {
+ LOG(ERROR) << "Couldn't import Private Key. " << PORT_GetError();
+ return false;
+ }
+
+ LOG(INFO) << "Imported Private Key";
+ return true;
+}
+#endif
+
void CertDatabase::AddObserver(Observer* observer) {
observer_list_->AddObserver(observer);
}
typedef struct CERTCertificateStr CERTCertificate;
#endif
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "base/files/file_util.h"
+#include "net/cert/x509_certificate.h"
+#endif
+
namespace base {
template <typename T> struct DefaultSingletonTraits;
// notifications from other DB interfaces.
void NotifyObserversCertDBChanged();
+#if BUILDFLAG(IS_TIZEN_TV)
+ // Check whether this is a valid user cert that we have the private key for.
+ // Returns OK or a network error code such as ERR_CERT_CONTAINS_ERRORS.
+ int CheckUserCert(CERTCertificate* cert);
+
+ // Store user (client) certificate. Assumes CheckUserCert has already passed.
+ // Returns OK, or ERR_ADD_USER_CERT_FAILED if there was a problem saving to
+ // the platform cert database, or possibly other network error codes.
+ int AddUserCert(CERTCertificate* cert);
+
+ // Store Private Key to support mutual authentication.
+ // Returns OK if successful, or False if there was a problem.
+ bool ImportPrivateKey(const std::string& key_buffer);
+#endif
+
private:
friend struct base::DefaultSingletonTraits<CertDatabase>;
"//tizen_src/chromium_impl/content/browser/input_picker/input_picker_base.h",
"//tizen_src/chromium_impl/content/browser/javascript_dialog/javascript_modal_dialog.cc",
"//tizen_src/chromium_impl/content/browser/javascript_dialog/javascript_modal_dialog.h",
- "//tizen_src/chromium_impl/content/browser/public/browser/web_contents_efl_delegate.h",
+
"//tizen_src/chromium_impl/content/browser/renderer_host/edge_effect.cc",
"//tizen_src/chromium_impl/content/browser/renderer_host/edge_effect.h",
"//tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_offscreen_helper_efl.cc",
"//tizen_src/chromium_impl/content/browser/web_contents/web_drag_source_efl.h",
"//tizen_src/chromium_impl/content/browser/inspector/devtools_util_manager.cc",
"//tizen_src/chromium_impl/content/browser/inspector/devtools_util_manager.h",
+ "//tizen_src/chromium_impl/content/public/browser/certificates_utils.cc",
+ "//tizen_src/chromium_impl/content/public/browser/certificates_utils.h",
+ "//tizen_src/chromium_impl/content/public/browser/web_contents_efl_delegate.h",
+ "//tizen_src/chromium_impl/content/public/browser/web_contents_view_efl_delegate.h",
]
external_content_browser_efl_sources += [
--- /dev/null
+// Copyright 2022 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 "certificates_utils.h"
+
+#include "base/files/file_enumerator.h"
+#include "base/files/file_util.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "net/base/net_errors.h"
+#include "net/cert/cert_database.h"
+#include "net/cert/x509_util_nss.h"
+
+#if BUILDFLAG(IS_TIZEN_TV)
+#include <fstream>
+#include "base/command_line.h"
+#include "chromium_impl/build/tizen_version.h"
+#include "content/public/browser/content_browser_client.h"
+#include "crypto/nss_crypto_module_delegate.h"
+#include "ewk/efl_integration/common/content_switches_efl.h"
+#include "net/ssl/ssl_cert_request_info.h"
+#include "net/ssl/ssl_platform_key_nss.h"
+#include "net/ssl/ssl_private_key.h"
+#include "tizen_src/chromium_impl/tizen/vconf_handle.h"
+#include "web_product/web_product_tv.h"
+#endif
+
+namespace {
+#if BUILDFLAG(IS_TIZEN_TV)
+#if TIZEN_VERSION_EQ(5, 5, 0) // Tizen 5.5
+const char* kDefaultCertPublic = "/usr/share/cert/SamsungDeviceCertificate.pem";
+#elif TIZEN_VERSION_EQ(6, 0, 0) // Tizen 6.0
+const char* kDefaultCertPublic =
+ "/usr/share/sdp/pepper-key/SamsungDeviceCertificate.pem";
+#else
+const char* kDefaultCertPublic =
+ "/usr/share/sdp/psa-init-key/SamsungDeviceCertificate.pem";
+#endif
+const char* kDefaultCertPrivate = "SamsungDeviceCertificateKey.pem";
+const char* kICSAppId = "org.tizen.ics"; // ATSC 3.0
+const char* kICSDataName = "modelcert";
+const char* kICSTestDataName = "modelcert_test";
+const char* kICSTestUrl = "eurofins-digitaltesting.com";
+const char* kIntegratedCertPath = "/opt/data/cert/vdca.pem";
+const char* kWebSDIPublicKeyDataName = "CFL";
+const char* kWebSDIPrivateKeyDataName = "PFL";
+const char* VCONFKEY_CERT_VERSION = "db/certificate/version";
+std::unordered_map<std::string, std::string> dynamic_cert_map;
+#endif
+
+net::ScopedCERTCertificateList GetCertListFromFile(
+ const base::FilePath& file_path) {
+ std::string cert_data;
+ net::ScopedCERTCertificateList cert_list;
+ if (base::ReadFileToString(file_path, &cert_data)) {
+ cert_list = net::x509_util::CreateCERTCertificateListFromBytes(
+ cert_data.data(), cert_data.size(), net::X509Certificate::FORMAT_AUTO);
+ } else {
+ LOG(ERROR) << "Could not read file \"" << file_path.AsUTF8Unsafe()
+ << "\" for loading CA certs. Please check permissions!";
+ }
+ return cert_list;
+}
+
+#if BUILDFLAG(IS_TIZEN_TV)
+std::string ParseCertVersion(std::string ca_file) {
+ std::ifstream ca_file_(ca_file);
+ std::string ca_file_info;
+ std::getline(ca_file_, ca_file_info);
+ std::vector<std::string> version_str = base::SplitString(
+ ca_file_info, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+
+ return version_str.size() > 2 ? version_str[2] : std::string();
+}
+
+bool IsLoadedCert(std::string old_cert_version, std::string new_cert_version) {
+ return base::EqualsCaseInsensitiveASCII(old_cert_version, new_cert_version);
+}
+
+bool CheckIfIntegratedCert(std::string ca_file_path) {
+ return ca_file_path == kIntegratedCertPath;
+}
+
+scoped_refptr<net::X509Certificate> MakeDynamicClientCert(
+ const std::string& host) {
+ auto iter = dynamic_cert_map.find(host);
+
+ LOG(INFO) << "[Dynamic Cert] host : " << host;
+ if (iter == dynamic_cert_map.end())
+ return nullptr;
+
+ LOG(INFO) << "[Dynamic Cert] matched cert key path or data name for"
+ " secure storage: "
+ << iter->second;
+ scoped_refptr<net::X509Certificate> client_cert;
+ if (client_cert = MakeClientCertFromSecureStorage(iter->second, iter->second))
+ return client_cert;
+
+ LOG(INFO) << "[Dynamic Cert] Try to get cert and key from file system";
+ base::FilePath dynamic_cert_path(iter->second);
+ std::string dynamic_cert_buffer;
+ if (!base::ReadFileToString(dynamic_cert_path, &dynamic_cert_buffer)) {
+ LOG(ERROR) << "[Dynamic Cert] Could not read file \"" << iter->second
+ << "\" for parsing client cert list. Please check permissions!";
+ return nullptr;
+ }
+ if (!dynamic_cert_buffer.empty()) {
+ client_cert = ImportKeyAndCreateClientCertChain(
+ std::string(), std::string(), dynamic_cert_buffer, dynamic_cert_buffer);
+ }
+ return client_cert;
+}
+#endif
+
+} // namespace
+
+#if BUILDFLAG(IS_TIZEN_TV)
+scoped_refptr<net::X509Certificate> ImportKeyAndCreateClientCertChain(
+ std::string cert_file,
+ std::string key_file,
+ std::string cert_buffer,
+ const std::string& key_buffer) {
+ net::ScopedCERTCertificateList public_cert_list;
+ if (!net::CertDatabase::GetInstance()->ImportPrivateKey(key_buffer)) {
+ LOG(ERROR) << "Private Key could not be added \"" << key_file << "\"";
+ return nullptr;
+ }
+
+ if (cert_buffer.empty()) {
+ LOG(INFO) << "Public Key from Secure Storage is NULL, "
+ "Get it in File like previous way.";
+ base::FilePath public_file_path(cert_file);
+ if (!base::ReadFileToString(public_file_path, &cert_buffer)) {
+ LOG(ERROR)
+ << "Could not read file \"" << public_file_path.AsUTF8Unsafe()
+ << "\" for parsing client cert list. Please check permissions!";
+ return nullptr;
+ }
+ }
+
+ public_cert_list = net::x509_util::CreateCERTCertificateListFromBytes(
+ cert_buffer.data(), cert_buffer.size(),
+ net::X509Certificate::FORMAT_AUTO);
+
+ std::vector<std::string> certificates;
+ for (const auto& cert : public_cert_list) {
+ std::string der_encoded_cert;
+ if (!net::x509_util::GetDEREncoded(cert.get(), &der_encoded_cert)) {
+ return nullptr;
+ }
+ certificates.push_back(der_encoded_cert);
+ }
+
+ std::vector<base::StringPiece> cert_pieces(certificates.size());
+ for (unsigned i = 0; i < certificates.size(); i++) {
+ cert_pieces[i] = base::StringPiece(certificates[i]);
+ }
+
+ return net::X509Certificate::CreateFromDERCertChain(cert_pieces);
+}
+
+scoped_refptr<net::X509Certificate> MakeClientCertFromSecureStorage(
+ std::string cert_file,
+ std::string key_file) {
+ std::string cert_buffer;
+ std::string key_buffer;
+
+ wp_tv_create();
+ Wp_Bool ret = wp_tv_create_feature(FEATURE_SECURITY);
+ if (ret) {
+ cert_buffer = wp_tv_get_key_from_secure_storage(cert_file);
+ key_buffer = wp_tv_get_key_from_secure_storage(key_file);
+ } else {
+ LOG(ERROR) << "wp_tv_create_feature fail";
+ }
+ wp_tv_destroy_feature(FEATURE_SECURITY);
+
+ if (key_buffer.empty()) {
+ LOG(ERROR) << "Private Key from Secure Storage is NULL. \"" << key_file
+ << "\"";
+ return nullptr;
+ }
+
+ return ImportKeyAndCreateClientCertChain(cert_file, key_file, cert_buffer,
+ key_buffer);
+}
+
+void AddDynamicClientCertificate(const std::string& host,
+ const std::string& certificate_path) {
+ LOG(ERROR) << "Add dynamic client certificate, host = " << host
+ << ", certificate_path = " << certificate_path;
+ dynamic_cert_map[host] = certificate_path;
+}
+
+scoped_refptr<net::SSLPrivateKey> GetPrivateKey(
+ scoped_refptr<net::X509Certificate> client_cert) {
+ if (!client_cert)
+ return nullptr;
+
+ auto nss_cert = net::x509_util::CreateCERTCertificateFromX509Certificate(
+ client_cert.get());
+ if (!nss_cert)
+ return nullptr;
+
+ auto cert_db = net::CertDatabase::GetInstance();
+ int err_code = cert_db->CheckUserCert(nss_cert.get());
+ if (net::OK != err_code) {
+ LOG(ERROR) << "User certificate is not valid. Error code : " << err_code;
+ return nullptr;
+ }
+
+ err_code = cert_db->AddUserCert(nss_cert.get());
+ if (net::OK != err_code) {
+ LOG(ERROR) << "User certificate could not be added. Error code : "
+ << err_code;
+ return nullptr;
+ }
+
+ return net::FetchClientCertPrivateKey(client_cert.get(), nss_cert.get(),
+ nullptr);
+}
+
+scoped_refptr<net::X509Certificate> GetClientCertificate(
+ bool enabled_websdi,
+ net::SSLCertRequestInfo* cert_request_info) {
+ scoped_refptr<net::X509Certificate> client_cert;
+ std::string host = cert_request_info->host_and_port.host();
+ std::string tizen_app_id =
+ base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ switches::kTizenAppId);
+
+ LOG(INFO) << "[Client Authentication] SelectClientCertificate, WEBSDI = "
+ << enabled_websdi << ", app ID : " << tizen_app_id;
+ client_cert = MakeDynamicClientCert(host);
+ if (!client_cert && enabled_websdi) {
+ LOG(INFO) << "[Client Authentication] Get a Client Cert for WebSDI";
+ client_cert = MakeClientCertFromSecureStorage(kWebSDIPublicKeyDataName,
+ kWebSDIPrivateKeyDataName);
+ } else if (!client_cert && tizen_app_id == kICSAppId) {
+ LOG(INFO) << "[Client Authentication] Get a Client Cert for ICS";
+ std::string data_name;
+ if (host.find(kICSTestUrl) != std::string::npos)
+ data_name = kICSTestDataName;
+ else
+ data_name = kICSDataName;
+
+ client_cert = MakeClientCertFromSecureStorage(data_name, data_name);
+ }
+
+ if (!client_cert) {
+ LOG(INFO) << "[Default Cert] Try to Load Default Client Certificate";
+ client_cert = MakeClientCertFromSecureStorage(kDefaultCertPublic,
+ kDefaultCertPrivate);
+ }
+
+ if (!client_cert) {
+ LOG(ERROR) << "[Client Authentication] client_cert is null, "
+ "Client Authentication will be failed";
+ return nullptr;
+ }
+
+ if (client_cert->HasExpired()) {
+ LOG(ERROR)
+ << "[Client Authentication] client_cert error: ERR_CERT_DATE_INVALID, "
+ "Client Authentication will be failed";
+ return nullptr;
+ }
+ return client_cert;
+}
+
+#endif // BUILDFLAG(IS_TIZEN_TV)
+
+void AddServerCert(const std::string& certificate_path) {
+ std::string ca_file_path = certificate_path;
+#if BUILDFLAG(IS_TIZEN_TV)
+ if (certificate_path.empty())
+ ca_file_path = kIntegratedCertPath;
+
+ base::FilePath cert_file_path(ca_file_path);
+ if (!base::PathExists(cert_file_path))
+ return;
+
+ std::string cert_version = VconfHandle(VCONFKEY_CERT_VERSION).Str();
+ std::string old_cert_version;
+ if (!cert_version.empty()) {
+ old_cert_version = cert_version;
+ }
+
+ bool isintegratedCert = false;
+ std::string new_cert_version;
+#endif
+
+ std::vector<std::string> paths = base::SplitString(
+ ca_file_path, ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+ for (const auto& path : paths) {
+#if BUILDFLAG(IS_TIZEN_TV)
+ if ((isintegratedCert = CheckIfIntegratedCert(path)) == true) {
+ new_cert_version = ParseCertVersion(path);
+ if (IsLoadedCert(old_cert_version, new_cert_version)) {
+ LOG(INFO) << "skip loading certificates because it is already loaded";
+ continue;
+ }
+ }
+#endif
+ base::FilePath file_path(path);
+ base::File file(file_path, base::File::FLAG_OPEN);
+ base::File::Info file_info;
+ // Check if path is accessible
+ if (file.IsValid() && file.GetInfo(&file_info)) {
+ if (file_info.is_directory) {
+ base::FileEnumerator files(
+ file_path, true,
+ base::FileEnumerator::FILES | base::FileEnumerator::SHOW_SYM_LINKS,
+ "@(*.crt|*.pem)");
+ files.SetExtMatchToFlag();
+ for (base::FilePath cert_file = files.Next(); !cert_file.empty();
+ cert_file = files.Next()) {
+ for (const auto& ca_cert : GetCertListFromFile(cert_file)) {
+ net::CertDatabase::GetInstance()->ImportCACert(ca_cert.get());
+ }
+ }
+ } else {
+ for (const auto& ca_cert : GetCertListFromFile(file_path)) {
+ net::CertDatabase::GetInstance()->ImportCACert(ca_cert.get());
+ }
+ }
+#if BUILDFLAG(IS_TIZEN_TV)
+ if (isintegratedCert)
+ VconfHandle(VCONFKEY_CERT_VERSION).Set(new_cert_version);
+#endif
+ } else { // Stat returned non-zero, path not accesible
+ LOG(ERROR) << "Could not access path \"" << path
+ << "\" for loading CA certs. Please check permissions!";
+ }
+ }
+}
--- /dev/null
+// Copyright 2022 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 CERTIFICATES_UTILS_H_
+#define CERTIFICATES_UTILS_H_
+#include <string>
+#include "build/build_config.h"
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "base/memory/scoped_refptr.h"
+
+namespace net {
+class SSLCertRequestInfo;
+class SSLPrivateKey;
+class X509Certificate;
+} // namespace net
+
+scoped_refptr<net::X509Certificate> ImportKeyAndCreateClientCertChain(
+ std::string cert_file,
+ std::string key_file,
+ std::string cert_buffer,
+ const std::string& key_buffer);
+scoped_refptr<net::X509Certificate> MakeClientCertFromSecureStorage(
+ std::string cert_file,
+ std::string key_file);
+void AddDynamicClientCertificate(const std::string& host,
+ const std::string& certificate_path);
+scoped_refptr<net::SSLPrivateKey> GetPrivateKey(
+ scoped_refptr<net::X509Certificate> client_cert);
+scoped_refptr<net::X509Certificate> GetClientCertificate(
+ bool enabled_websdi,
+ net::SSLCertRequestInfo* cert_request_info);
+#endif
+
+void AddServerCert(const std::string& certificate_path);
+
+#endif // CERTIFICATES_UTILS_H_
public_configs += [ "//tizen_src/build:ui-gadget-public" ]
configs += [ "//tizen_src/build:notification" ]
configs += [ "//tizen_src/build:libnotification" ]
+ if(tizen_product_tv) {
+ configs += [ "//tizen_src/build:WebProduct" ]
+ }
deps = [
"//base/:base_static",
"//components/autofill/content/browser",
#include "net/cert/x509_util_nss.h"
#include "network_delegate_efl.h"
#include "permission_controller_delegate_efl.h"
+#include "tizen_src/chromium_impl/content/public/browser/certificates_utils.h"
#if BUILDFLAG(IS_TIZEN_TV)
#include "content/common/zygote/zygote_communication_linux.h"
NOTIMPLEMENTED();
}
-net::ScopedCERTCertificateList GetCertListFromFile(
- const base::FilePath& file_path) {
- std::string cert_data;
- net::ScopedCERTCertificateList cert_list;
- if (base::ReadFileToString(file_path, &cert_data)) {
- cert_list = net::x509_util::CreateCERTCertificateListFromBytes(
- cert_data.data(), cert_data.size(), net::X509Certificate::FORMAT_AUTO);
- } else {
- LOG(ERROR) << "Could not read file \"" << file_path.AsUTF8Unsafe()
- << "\" for loading CA certs. Please check permissions!";
- }
- return cert_list;
-}
void SendToAllRenderers(IPC::Message* message) {
content::RenderProcessHost::iterator it =
return;
file_system_context->default_file_task_runner()->PostTask(
- FROM_HERE,
- base::BindOnce(&BrowserContextEfl::ReadCertificateAndAdd,
- base::Owned(new std::string(certificate_path))));
-}
-
-void BrowserContextEfl::ReadCertificateAndAdd(
- const std::string* certificate_path) {
- std::vector<std::string> paths = base::SplitString(
- *certificate_path, ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
- for (const auto& path : paths) {
- base::FilePath file_path(path);
- base::File file(file_path, base::File::FLAG_OPEN);
- base::File::Info file_info;
- // Check if path is accessible
- if (file.IsValid() && file.GetInfo(&file_info)) {
- if (file_info.is_directory) {
- base::FileEnumerator files(
- file_path, true,
- base::FileEnumerator::FILES | base::FileEnumerator::SHOW_SYM_LINKS,
- "@(*.crt|*.pem)");
- files.SetExtMatchToFlag();
- for (base::FilePath cert_file = files.Next(); !cert_file.empty();
- cert_file = files.Next()) {
- for (const auto& ca_cert : GetCertListFromFile(cert_file)) {
- net::CertDatabase::GetInstance()->ImportCACert(ca_cert.get());
- }
- }
- } else {
- for (const auto& ca_cert : GetCertListFromFile(file_path)) {
- net::CertDatabase::GetInstance()->ImportCACert(ca_cert.get());
- }
- }
- } else { // Stat returned non-zero, path not accessible
- LOG(ERROR) << "Could not access path \"" << path
- << "\" for loading CA certs. Please check permissions!";
- }
- }
+ FROM_HERE, base::BindOnce(&AddServerCert, certificate_path));
}
void BrowserContextEfl::InitVisitedLinkWriter() {
#endif
private:
- // certificate_path should be either be a directory with CA certs, a CA cert
- // file or a colon-separated list of those. CA cert files should have *.crt
- // extension. Directories are traversed recursively.
- static void ReadCertificateAndAdd(const std::string* certificate_path);
SSLHostStateDelegate* GetSSLHostStateDelegate() override;
PermissionControllerDelegate* GetPermissionControllerDelegate() override;
mutable std::unique_ptr<GeolocationPermissionContextEfl>
#if BUILDFLAG(IS_TIZEN_TV)
#include "wrt/hbbtv_widget_host.h"
+#include "content/public/browser/client_certificate_delegate.h"
+#include "tizen_src/chromium_impl/content/public/browser/certificates_utils.h"
+#include "web_product_tv.h"
#endif
using web_contents_utils::WebContentsFromFrameID;
ContentBrowserClientEfl::ContentBrowserClientEfl()
: notification_controller_(new NotificationControllerEfl),
- accept_langs_helper_(new AcceptLanguagesHelper) {
+ accept_langs_helper_(new AcceptLanguagesHelper)
+#if BUILDFLAG(IS_TIZEN_TV)
+ ,
+ enabled_websdi_(false)
+#endif
+{
#if BUILDFLAG(IS_TIZEN)
PlatformLanguageChanged(nullptr, this);
vconf_notify_key_changed(VCONFKEY_LANGSET, PlatformLanguageChanged, this);
}
ContentBrowserClientEfl::~ContentBrowserClientEfl() {
+#if BUILDFLAG(IS_TIZEN_TV)
+ wp_tv_destroy_feature(FEATURE_SECURITY);
+#endif
#if BUILDFLAG(IS_TIZEN)
vconf_ignore_key_changed(VCONFKEY_LANGSET, PlatformLanguageChanged);
#endif
return result;
}
+#if BUILDFLAG(IS_TIZEN_TV)
+base::OnceClosure ContentBrowserClientEfl::SelectClientCertificate(
+ WebContents* web_contents,
+ net::SSLCertRequestInfo* cert_request_info,
+ net::ClientCertIdentityList client_certs,
+ std::unique_ptr<ClientCertificateDelegate> delegate) {
+ scoped_refptr<net::X509Certificate> client_cert;
+ scoped_refptr<net::SSLPrivateKey> private_key;
+
+ const EWebContext* const context =
+ static_cast<BrowserContextEfl*>(web_contents->GetBrowserContext())
+ ->WebContext();
+
+ client_cert = GetClientCertificate(enabled_websdi_, cert_request_info);
+ if (client_cert) {
+ private_key = GetPrivateKey(client_cert);
+ delegate->ContinueWithCertificate(std::move(client_cert),
+ std::move(private_key));
+ }
+
+ return base::OnceClosure();
+}
+
+void ContentBrowserClientEfl::AddDynamicCertificatePath(
+ const std::string& host,
+ const std::string& cert_path) {
+ AddDynamicClientCertificate(host, cert_path);
+}
+#endif
+
} // namespace content
std::string GetAcceptLangs(BrowserContext* context) override;
void EnableAppControl(bool enabled) { enabled_app_control = enabled; }
+#if BUILDFLAG(IS_TIZEN_TV)
+ void AddDynamicCertificatePath(const std::string& host,
+ const std::string& cert_path) override;
+ base::OnceClosure SelectClientCertificate(
+ WebContents* web_contents,
+ net::SSLCertRequestInfo* cert_request_info,
+ net::ClientCertIdentityList client_certs,
+ std::unique_ptr<ClientCertificateDelegate> delegate) override;
+
+ void SetWebSDI(bool enable) { enabled_websdi_ = enable; }
+ bool GetWebSDI() const { return enabled_websdi_; }
+#endif
private:
bool WillCreateURLLoaderFactory(
scoped_refptr<SharedURLLoaderFactoryEfl> shared_url_loader_factory_;
std::unique_ptr<AcceptLanguagesHelper> accept_langs_helper_;
+#if BUILDFLAG(IS_TIZEN_TV)
+ bool enabled_websdi_;
+#endif
bool shutting_down_ = false;
bool enabled_app_control = true;
};
return app_control.Proceed();
}
+#if BUILDFLAG(IS_TIZEN_TV)
+void EWebView::AddDynamicCertificatePath(const std::string& host,
+ const std::string& cert_path) {
+ web_contents_->AddDynamicCertificatePath(host, cert_path);
+}
+#endif
+
bool EWebView::SetVisibility(bool enable) {
if (!web_contents_)
return false;
void DrawLabel(Evas_Object* image, Eina_Rectangle rect);
void DeactivateAtk(bool deactivated);
void ClearLabels();
+ void AddDynamicCertificatePath(const std::string& host,
+ const std::string& cert_path);
#endif // IS_TIZEN_TV
void SetDidChangeThemeColorCallback(
void ewk_context_websdi_set(Eina_Bool enable)
{
- LOG_EWK_API_MOCKUP();
+#if BUILDFLAG(IS_TIZEN_TV)
+ LOG(INFO) << "This App use WebSDI for client authentication [" << enable << "]";
+ ContentBrowserClientEfl* cbce = GetContentBrowserClient();
+ EINA_SAFETY_ON_NULL_RETURN(cbce);
+ cbce->SetWebSDI(enable);
+#else
+ LOG_EWK_API_MOCKUP("Only for Tizen TV");
+#endif
}
Eina_Bool ewk_context_websdi_get()
{
- LOG_EWK_API_MOCKUP();
+#if BUILDFLAG(IS_TIZEN_TV)
+ const ContentBrowserClientEfl* cbce = GetContentBrowserClient();
+ EINA_SAFETY_ON_NULL_RETURN_VAL(cbce, EINA_FALSE);
+ return cbce->GetWebSDI();
+#else
+ LOG_EWK_API_MOCKUP("Only for Tizen TV");
return false;
+#endif
}
void ewk_context_disable_nosniff_set(Ewk_Context* context, Eina_Bool enable)
void ewk_view_add_dynamic_certificate_path(const Evas_Object *ewkView, const char* host, const char* cert_path)
{
+#if BUILDFLAG(IS_TIZEN_TV)
+ EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl);
+ impl->AddDynamicCertificatePath(std::string(host), std::string(cert_path));
+#else
LOG_EWK_API_MOCKUP();
+#endif
}
void ewk_view_atk_deactivation_by_app(Evas_Object* view, Eina_Bool enable)