From be0fb77baf98f773928b4ff9d08a13c83f189564 Mon Sep 17 00:00:00 2001 From: Vijith Kini Date: Fri, 7 Dec 2018 09:30:38 +0530 Subject: Add in-memory client cert store implementation Qt applications using webengine can now use a specific client certificate without affecting(or using) the native certificate store. It sounds useful for consumer applications where the application wants to identify itself to the server as the application and not as a specific user. Change-Id: Ib4fcdfd48e00051e3215f90be8701978902b1fbf Reviewed-by: Leena Miettinen Reviewed-by: Allan Sandfeld Jensen --- src/core/api/core_api.pro | 1 + src/core/api/qwebengineclientcertificatestore.h | 77 +++++++ src/core/client_cert_override_key.cpp | 137 ++++++++++++ src/core/client_cert_override_key_p.h | 52 +++++ src/core/client_cert_override_p.h | 63 ++++++ src/core/content_browser_client_qt.cpp | 26 +-- src/core/core_chromium.pri | 4 + src/core/qtwebengine.gni | 1 + src/core/qwebengineclientcertificatestore.cpp | 282 ++++++++++++++++++++++++ 9 files changed, 620 insertions(+), 23 deletions(-) create mode 100644 src/core/api/qwebengineclientcertificatestore.h create mode 100644 src/core/client_cert_override_key.cpp create mode 100644 src/core/client_cert_override_key_p.h create mode 100644 src/core/client_cert_override_p.h create mode 100644 src/core/qwebengineclientcertificatestore.cpp (limited to 'src') diff --git a/src/core/api/core_api.pro b/src/core/api/core_api.pro index 38dc6b39d..b5bb93847 100644 --- a/src/core/api/core_api.pro +++ b/src/core/api/core_api.pro @@ -32,6 +32,7 @@ gcc: QMAKE_CXXFLAGS_WARN_ON = -Wno-unused-parameter HEADERS = \ qwebenginecallback.h \ qwebenginecallback_p.h \ + qwebengineclientcertificatestore.h \ qtwebenginecoreglobal.h \ qtwebenginecoreglobal_p.h \ qwebenginecookiestore.h \ diff --git a/src/core/api/qwebengineclientcertificatestore.h b/src/core/api/qwebengineclientcertificatestore.h new file mode 100644 index 000000000..82607ea70 --- /dev/null +++ b/src/core/api/qwebengineclientcertificatestore.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWEBENGINECLIENTCERTIFICATESTORE_H +#define QWEBENGINECLIENTCERTIFICATESTORE_H + +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +struct QWebEngineClientCertificateStoreData; + +class QWEBENGINECORE_EXPORT QWebEngineClientCertificateStore { + +public: + struct Entry { + QSslKey privateKey; + QSslCertificate certificate; + }; + + static QWebEngineClientCertificateStore *getInstance(); + void add(const QSslCertificate &certificate, const QSslKey &privateKey); + QList toList() const; + void remove(Entry entry); + void clear(); + +private: + static QWebEngineClientCertificateStore *m_instance; + Q_DISABLE_COPY(QWebEngineClientCertificateStore) + + QWebEngineClientCertificateStore(); + ~QWebEngineClientCertificateStore(); + QWebEngineClientCertificateStoreData *d_ptr; +}; + +QT_END_NAMESPACE + +#endif // QWebEngineClientCertificateStore_H diff --git a/src/core/client_cert_override_key.cpp b/src/core/client_cert_override_key.cpp new file mode 100644 index 000000000..99ddf7466 --- /dev/null +++ b/src/core/client_cert_override_key.cpp @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CLIENT_CERT_OVERRIDE_KEY_H +#define CLIENT_CERT_OVERRIDE_KEY_H + +#include "client_cert_override_key_p.h" + +#include "third_party/boringssl/src/include/openssl/ssl.h" +#include "third_party/boringssl/src/include/openssl/digest.h" +#include "third_party/boringssl/src/include/openssl/evp.h" +#include "third_party/boringssl/src/include/openssl/rsa.h" +#include "third_party/boringssl/src/include/openssl/pem.h" + +#include +#include + +#include "base/logging.h" +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "net/base/net_errors.h" +#include "net/ssl/ssl_platform_key_util.h" +#include "net/ssl/ssl_private_key.h" +#include "net/ssl/threaded_ssl_private_key.h" + +namespace net { + +namespace { + +class SSLPlatformKeyOverride : public ThreadedSSLPrivateKey::Delegate { +public: + SSLPlatformKeyOverride(const QByteArray &sslKeyInBytes) + { + mem_ = BIO_new_mem_buf(sslKeyInBytes, -1); + key_ = PEM_read_bio_PrivateKey(mem_, NULL, 0, NULL); + } + + ~SSLPlatformKeyOverride() override { + if (key_) + EVP_PKEY_free(key_); + if (mem_) + BIO_free(mem_); + } + + Error Sign(uint16_t algorithm, + base::span input, + std::vector* signature) override { + bssl::ScopedEVP_MD_CTX ctx; + EVP_PKEY_CTX* pctx; + if (!EVP_DigestSignInit(ctx.get(), &pctx, + SSL_get_signature_algorithm_digest(algorithm), + nullptr, key_)) { + return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; + } + + if (SSL_is_signature_algorithm_rsa_pss(algorithm)) { + if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) || + !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1 /* hash length */)) { + return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; + } + } + size_t sig_len = 0; + if (!EVP_DigestSign(ctx.get(), NULL, &sig_len, input.data(), input.size())) + return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; + signature->resize(sig_len); + if (!EVP_DigestSign(ctx.get(), signature->data(), &sig_len, input.data(), + input.size())) { + return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; + } + signature->resize(sig_len); + return OK; + } + + std::vector GetAlgorithmPreferences() override { + return { + SSL_SIGN_RSA_PKCS1_SHA1, SSL_SIGN_RSA_PKCS1_SHA512, + SSL_SIGN_RSA_PKCS1_SHA384, SSL_SIGN_RSA_PKCS1_SHA256, + }; + } + +private: + EVP_PKEY* key_; + BIO * mem_; + + DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyOverride); +}; + +} // namespace + +scoped_refptr WrapOpenSSLPrivateKey(const QByteArray &sslKeyInBytes) { + if (sslKeyInBytes.isEmpty()) + return nullptr; + + return base::MakeRefCounted( + std::make_unique(sslKeyInBytes), + GetSSLPlatformKeyTaskRunner()); +} + +} // namespace net + +#endif diff --git a/src/core/client_cert_override_key_p.h b/src/core/client_cert_override_key_p.h new file mode 100644 index 000000000..7ac610be4 --- /dev/null +++ b/src/core/client_cert_override_key_p.h @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CLIENT_CERT_OVERRIDE_KEY_P_H +#define CLIENT_CERT_OVERRIDE_KEY_P_H + +#include "net/ssl/ssl_private_key.h" + +#include + +namespace net { + class SSLPrivateKey; + scoped_refptr WrapOpenSSLPrivateKey(const QByteArray &sslKeyInBytes); +} // namespace net + +#endif diff --git a/src/core/client_cert_override_p.h b/src/core/client_cert_override_p.h new file mode 100644 index 000000000..b222bf810 --- /dev/null +++ b/src/core/client_cert_override_p.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CLIENT_CERT_OVERRIDE_P_H +#define CLIENT_CERT_OVERRIDE_P_H + +#include "net/ssl/client_cert_store.h" +#include "base/callback_forward.h" +#include "net/cert/x509_certificate.h" + +namespace net { +class SSLCertRequestInfo; +class ClientCertOverrideStore : public ClientCertStore +{ +public: + ClientCertOverrideStore(); + virtual ~ClientCertOverrideStore() override; + void GetClientCerts(const SSLCertRequestInfo &cert_request_info, + const ClientCertListCallback &callback) override; +private: + std::unique_ptr getNativeStore(); +}; +} // namespace net + +#endif + + diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp index beec6dd26..b5b2ca0fd 100644 --- a/src/core/content_browser_client_qt.cpp +++ b/src/core/content_browser_client_qt.cpp @@ -85,6 +85,7 @@ #include "qtwebengine/grit/qt_webengine_resources.h" +#include "client_cert_override_p.h" #include "profile_adapter.h" #include "browser_main_parts_qt.h" #include "browser_message_filter_qt.h" @@ -113,18 +114,6 @@ #include "ui/base/resource/resource_bundle.h" #endif -#if defined(USE_NSS_CERTS) -#include "net/ssl/client_cert_store_nss.h" -#endif - -#if defined(OS_WIN) -#include "net/ssl/client_cert_store_win.h" -#endif - -#if defined(OS_MACOSX) -#include "net/ssl/client_cert_store_mac.h" -#endif - #if QT_CONFIG(webengine_pepper_plugins) #include "content/public/browser/browser_ppapi_host.h" #include "ppapi/host/ppapi_host.h" @@ -381,17 +370,8 @@ std::unique_ptr ContentBrowserClientQt::CreateClientCertSt { if (!resource_context) return nullptr; -#if defined(USE_NSS_CERTS) - // FIXME: Give it a proper callback for a password delegate. - return std::unique_ptr( - new net::ClientCertStoreNSS(net::ClientCertStoreNSS::PasswordDelegateFactory())); -#elif defined(OS_WIN) - return std::unique_ptr(new net::ClientCertStoreWin()); -#elif defined(OS_MACOSX) - return std::unique_ptr(new net::ClientCertStoreMac()); -#else - return nullptr; -#endif + + return std::unique_ptr(new net::ClientCertOverrideStore()); } std::string ContentBrowserClientQt::GetApplicationLocale() diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri index 0aa7fd567..65ca793f9 100644 --- a/src/core/core_chromium.pri +++ b/src/core/core_chromium.pri @@ -48,6 +48,7 @@ SOURCES = \ browser_message_filter_qt.cpp \ certificate_error_controller.cpp \ chromium_overrides.cpp \ + client_cert_override_key.cpp \ client_cert_select_controller.cpp \ clipboard_qt.cpp \ color_chooser_qt.cpp \ @@ -102,6 +103,7 @@ SOURCES = \ profile_io_data_qt.cpp \ quota_permission_context_qt.cpp \ quota_request_controller_impl.cpp \ + qwebengineclientcertificatestore.cpp \ register_protocol_handler_request_controller_impl.cpp \ render_view_context_menu_qt.cpp \ render_view_observer_host_qt.cpp \ @@ -141,6 +143,8 @@ HEADERS = \ certificate_error_controller_p.h \ certificate_error_controller.h \ chromium_overrides.h \ + client_cert_override_key_p.h \ + client_cert_override_p.h \ client_cert_select_controller.h \ clipboard_qt.h \ color_chooser_qt.h \ diff --git a/src/core/qtwebengine.gni b/src/core/qtwebengine.gni index 14da1e6cf..57dfbec40 100644 --- a/src/core/qtwebengine.gni +++ b/src/core/qtwebengine.gni @@ -9,6 +9,7 @@ chromium_version = exec_script("//build/util/version.py", [ "-f", rebase_path("/ include_dirs = [ "//skia/config", "//third_party", + "//third_party/boringssl/src/include", "//third_party/skia/include/core" ] diff --git a/src/core/qwebengineclientcertificatestore.cpp b/src/core/qwebengineclientcertificatestore.cpp new file mode 100644 index 000000000..fb6cba78f --- /dev/null +++ b/src/core/qwebengineclientcertificatestore.cpp @@ -0,0 +1,282 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "api/qwebengineclientcertificatestore.h" +#include "client_cert_override_key_p.h" +#include "client_cert_override_p.h" + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/task_scheduler/post_task.h" +#include "base/callback_forward.h" + +#include "net/ssl/client_cert_store.h" +#include "net/ssl/ssl_cert_request_info.h" +#include "net/cert/x509_certificate.h" + +#include "third_party/boringssl/src/include/openssl/pem.h" +#include "third_party/boringssl/src/include/openssl/err.h" +#include "third_party/boringssl/src/include/openssl/evp.h" + +#if defined(USE_NSS_CERTS) +#include "net/ssl/client_cert_store_nss.h" +#endif + +#if defined(OS_WIN) +#include "net/ssl/client_cert_store_win.h" +#endif + +#if defined(OS_MACOSX) +#include "net/ssl/client_cert_store_mac.h" +#endif + +#include +#include + +QT_BEGIN_NAMESPACE + +typedef struct OverrideData { + QSslKey key; + QSslCertificate certificate; + scoped_refptr certPtr; + scoped_refptr keyPtr; +} OverrideData; + +struct QWebEngineClientCertificateStoreData { + QList deletedCerts; +}; + +static QList ClientCertOverrideData; +QWebEngineClientCertificateStore *QWebEngineClientCertificateStore::m_instance = NULL; + +/*! + \class QWebEngineClientCertificateStore::Entry + \inmodule QtWebEngineCore + \since 5.13 + \brief This structure holds the certificate and the private key. +*/ + +/*! + \class QWebEngineClientCertificateStore + \inmodule QtWebEngineCore + \since 5.13 + \brief The QWebEngineClientCertificateStore class provides an in-memory store for client certificates. + + The class allows to store client certificates in an in-memory store. + When a web site requests an SSL client certificate, the QWebEnginePage::selectClientCertificate + signal is emitted with matching certificates from the native certificate store or the in-memory store. + The getInstance() method can be used to access the single instance of the class. +*/ + +QWebEngineClientCertificateStore::QWebEngineClientCertificateStore() +{ + this->d_ptr = new QWebEngineClientCertificateStoreData; +} + +/*! + Destroys this QWebEngineClientCertificateStore object. +*/ + +QWebEngineClientCertificateStore::~QWebEngineClientCertificateStore() +{ + // Just in case user has not deleted in-memory certificates + clear(); + + qDeleteAll(d_ptr->deletedCerts); + delete d_ptr; +} + +/*! + Returns an in-memory client certificate store. +*/ + +QWebEngineClientCertificateStore *QWebEngineClientCertificateStore::getInstance() +{ + if (!m_instance) + m_instance = new QWebEngineClientCertificateStore; + return m_instance; +} + +/*! + Adds a \a certificate with the \a privateKey to the in-memory client certificate store. +*/ + +void QWebEngineClientCertificateStore::add(const QSslCertificate &certificate, const QSslKey &privateKey) +{ + + QByteArray sslKeyInBytes = privateKey.toPem(); + QByteArray certInBytes = certificate.toDer(); + + OverrideData* data = new OverrideData; + data->keyPtr = net::WrapOpenSSLPrivateKey(sslKeyInBytes); + data->certPtr = net::X509Certificate::CreateFromBytes( + certInBytes.data(), certInBytes.length()); + data->key = privateKey; + data->certificate = certificate; + ClientCertOverrideData.append(data); +} + +/*! + Returns a list of private and public keys of client certificates in the in-memory store. + Returns an empty list if the in-memory store does not contain certificates. +*/ + +QList QWebEngineClientCertificateStore::toList() const +{ + QList certificateList; + for (auto data : ClientCertOverrideData) { + Entry entry; + entry.certificate = data->certificate; + entry.privateKey = data->key; + certificateList.append(entry); + } + return certificateList; +} + +/*! + Deletes all the instances of the client certificate in the in-memory client certificate store + that matches the certificate in the \a entry. +*/ + +void QWebEngineClientCertificateStore::remove(Entry entry) +{ + QMutableListIterator iterator(ClientCertOverrideData); + while (iterator.hasNext()) { + auto overrideData = iterator.next(); + if (entry.certificate.toDer() == overrideData->certificate.toDer()) { + d_ptr->deletedCerts.append(overrideData); + iterator.remove(); + } + } +} + +/*! + Clears all the client certificates from the in-memory store. +*/ + +void QWebEngineClientCertificateStore::clear() +{ + for (auto data : ClientCertOverrideData) + d_ptr->deletedCerts.append(data); + ClientCertOverrideData.clear(); +} + +QT_END_NAMESPACE + +namespace net { + +namespace { + +class ClientCertIdentityOverride : public ClientCertIdentity { +public: + ClientCertIdentityOverride( + scoped_refptr cert, + scoped_refptr key) + : ClientCertIdentity(std::move(cert)), + key_(std::move(key)) {} + ~ClientCertIdentityOverride() override = default; + + void AcquirePrivateKey( + const base::Callback)>& + private_key_callback) override + { + private_key_callback.Run(key_); + } + +#if defined(OS_MACOSX) + SecIdentityRef sec_identity_ref() const override + { + return nullptr; + } +#endif + +private: + scoped_refptr key_; +}; + +} // namespace + + +ClientCertOverrideStore::ClientCertOverrideStore() + : ClientCertStore() +{ +} + +ClientCertOverrideStore::~ClientCertOverrideStore() +{ +} + +void ClientCertOverrideStore::GetClientCerts(const SSLCertRequestInfo &cert_request_info, + const ClientCertListCallback &callback) +{ + // Look for certificates in memory store + for (int i = 0; i < ClientCertOverrideData.length(); i++) { + scoped_refptr cert = ClientCertOverrideData[i]->certPtr; + if (cert != NULL && cert->IsIssuedByEncoded(cert_request_info.cert_authorities)) { + ClientCertIdentityList selected_identities; + selected_identities.push_back(std::make_unique(cert, ClientCertOverrideData[i]->keyPtr)); + callback.Run(std::move(selected_identities)); + return; + } + } + + // Continue with native cert store if matching certificate is not found in memory + std::unique_ptr store = getNativeStore(); + if (store != NULL) { + store->GetClientCerts(cert_request_info, callback); + return; + } + + callback.Run(ClientCertIdentityList()); + return; +} + +std::unique_ptr ClientCertOverrideStore::getNativeStore() +{ +#if defined(USE_NSS_CERTS) + return std::unique_ptr(new net::ClientCertStoreNSS(net::ClientCertStoreNSS::PasswordDelegateFactory())); +#elif defined(OS_WIN) + return std::unique_ptr(new net::ClientCertStoreWin()); +#elif defined(OS_MACOSX) + return std::unique_ptr(new net::ClientCertStoreMac()); +#else + return nullptr; +#endif +} +} -- cgit v1.2.3