[curl] Improve detecting and handling of SSL client certificate

https://bugs.webkit.org/show_bug.cgi?id=125006

Patch by Robert Sipka <sipka@inf.u-szeged.hu> on 2014-01-22
Reviewed by Brent Fulgham.

Add client certificate handling.

* platform/network/ResourceHandle.h:
* platform/network/curl/ResourceError.h:
(WebCore::ResourceError::hasSSLConnectError):
* platform/network/curl/ResourceHandleCurl.cpp:
(WebCore::ResourceHandle::setClientCertificateInfo):
* platform/network/curl/ResourceHandleManager.cpp:
(WebCore::ResourceHandleManager::initializeHandle):
* platform/network/curl/SSLHandle.cpp:
(WebCore::addAllowedClientCertificate):
(WebCore::setSSLClientCertificate):
* platform/network/curl/SSLHandle.h:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@162530 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 97845d09
2014-01-22 Robert Sipka <sipka@inf.u-szeged.hu>
[curl] Improve detecting and handling of SSL client certificate
https://bugs.webkit.org/show_bug.cgi?id=125006
Reviewed by Brent Fulgham.
Add client certificate handling.
* platform/network/ResourceHandle.h:
* platform/network/curl/ResourceError.h:
(WebCore::ResourceError::hasSSLConnectError):
* platform/network/curl/ResourceHandleCurl.cpp:
(WebCore::ResourceHandle::setClientCertificateInfo):
* platform/network/curl/ResourceHandleManager.cpp:
(WebCore::ResourceHandleManager::initializeHandle):
* platform/network/curl/SSLHandle.cpp:
(WebCore::addAllowedClientCertificate):
(WebCore::setSSLClientCertificate):
* platform/network/curl/SSLHandle.h:
2014-01-22 Mihai Maerean <mmaerean@adobe.com>
[CSS Regions] layerOwner in RenderNamedFlowFragment cannot return null
......@@ -152,6 +152,7 @@ public:
#if PLATFORM(WIN) && USE(CURL)
static void setHostAllowsAnyHTTPSCertificate(const String&);
static void setClientCertificateInfo(const String&, const String&, const String&);
#endif
#if PLATFORM(WIN) && USE(CURL) && USE(CF)
static void setClientCertificate(const String& host, CFDataRef);
......
......@@ -27,6 +27,7 @@
#define ResourceError_h
#include "ResourceErrorBase.h"
#include <curl/curl.h>
namespace WebCore {
......@@ -44,6 +45,7 @@ public:
unsigned sslErrors() const { return m_sslErrors; }
void setSSLErrors(unsigned sslVerifyResult) { m_sslErrors = sslVerifyResult; }
bool hasSSLConnectError() const { return errorCode() == CURLE_SSL_CONNECT_ERROR; }
private:
unsigned m_sslErrors;
......
......@@ -30,6 +30,8 @@
#include "CachedResourceLoader.h"
#include "CredentialStorage.h"
#include "FileSystem.h"
#include "Logging.h"
#include "NetworkingContext.h"
#include "NotImplemented.h"
#include "ResourceHandleInternal.h"
......@@ -121,6 +123,14 @@ void ResourceHandle::setHostAllowsAnyHTTPSCertificate(const String& host)
allowsAnyHTTPSCertificateHosts(host.lower());
}
void ResourceHandle::setClientCertificateInfo(const String& host, const String& certificate, const String& key)
{
if (fileExists(certificate))
addAllowedClientCertificate(host, certificate, key);
else
LOG(Network, "Invalid client certificate file: %s!\n", certificate.latin1().data());
}
#if PLATFORM(WIN) && USE(CF)
// FIXME: The CFDataRef will need to be something else when
// building without
......
......@@ -962,6 +962,7 @@ void ResourceHandleManager::initializeHandle(ResourceHandle* job)
curl_easy_setopt(d->m_handle, CURLOPT_DNS_CACHE_TIMEOUT, 60 * 5); // 5 minutes
curl_easy_setopt(d->m_handle, CURLOPT_PROTOCOLS, allowedProtocols);
curl_easy_setopt(d->m_handle, CURLOPT_REDIR_PROTOCOLS, allowedProtocols);
setSSLClientCertificate(job);
if (ignoreSSLErrors)
curl_easy_setopt(d->m_handle, CURLOPT_SSL_VERIFYPEER, false);
......
......@@ -33,10 +33,13 @@
#include <openssl/ssl.h>
#include <openssl/x509_vfy.h>
#include <wtf/ListHashSet.h>
#include <wtf/text/CString.h>
namespace WebCore {
typedef std::tuple<WTF::String, WTF::String> clientCertificate;
static HashMap<String, ListHashSet<String>> allowedHosts;
static HashMap<String, clientCertificate> allowedClientHosts;
void allowsAnyHTTPSCertificateHosts(const String& host)
{
......@@ -44,6 +47,26 @@ void allowsAnyHTTPSCertificateHosts(const String& host)
allowedHosts.set(host, certificates);
}
void addAllowedClientCertificate(const String& host, const String& certificate, const String& key)
{
clientCertificate clientInfo(certificate, key);
allowedClientHosts.set(host.lower(), clientInfo);
}
void setSSLClientCertificate(ResourceHandle* handle)
{
String host = handle->firstRequest().url().host();
HashMap<String, clientCertificate>::iterator it = allowedClientHosts.find(host.lower());
if (it == allowedClientHosts.end())
return;
ResourceHandleInternal* d = handle->getInternal();
clientCertificate clientInfo = it->value;
curl_easy_setopt(d->m_handle, CURLOPT_SSLCERT, std::get<0>(clientInfo).utf8().data());
curl_easy_setopt(d->m_handle, CURLOPT_SSLCERTTYPE, "P12");
curl_easy_setopt(d->m_handle, CURLOPT_SSLCERTPASSWD, std::get<1>(clientInfo).utf8().data());
}
bool sslIgnoreHTTPSCertificate(const String& host, const ListHashSet<String>& certificates)
{
HashMap<String, ListHashSet<String>>::iterator it = allowedHosts.find(host);
......
......@@ -43,9 +43,11 @@ typedef enum {
} SSLCertificateFlags;
void addAllowedClientCertificate(const String&, const String&, const String&);
void allowsAnyHTTPSCertificateHosts(const String&);
bool sslIgnoreHTTPSCertificate(const String&, const String&);
void setSSLVerifyOptions(ResourceHandle*);
void setSSLClientCertificate(ResourceHandle*);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment