Created
August 29, 2013 13:45
-
-
Save noamr/6378298 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/Source/WebCore/platform/network/soup/ClientCertificateManager.cpp b/Source/WebCore/platform/network/soup/ClientCertificateManager.cpp | |
new file mode 100644 | |
index 0000000..23d9e50 | |
--- /dev/null | |
+++ b/Source/WebCore/platform/network/soup/ClientCertificateManager.cpp | |
@@ -0,0 +1,54 @@ | |
+#include "config.h" | |
+#include "ClientCertificateManager.h" | |
+ | |
+#include <wtf/text/CString.h> | |
+#include <wtf/text/StringBuilder.h> | |
+#include <wtf/text/WTFString.h> | |
+ | |
+static const String ClientCertificatesFolderPath(NIX_CERTIFICATES_FOLDER); | |
+ | |
+using namespace WebCore; | |
+ | |
+namespace WebCore { | |
+ | |
+String WebClientCertificateManager::getClientCertificateForServer(const String& serverName, uint16_t port) | |
+{ | |
+ if (ClientCertificatesFolderPath.isNull()) { | |
+ return String(); | |
+ } | |
+ | |
+ StringBuilder certificatePathBuilder; | |
+ | |
+ certificatePathBuilder.append(ClientCertificatesFolderPath); | |
+ certificatePathBuilder.append("/"); | |
+ | |
+ certificatePathBuilder.append(serverName); | |
+ certificatePathBuilder.append(":"); | |
+ certificatePathBuilder.append(String::number(port)); | |
+ | |
+ const CString certificatePath = certificatePathBuilder.toString().utf8(); | |
+ | |
+ FILE *fd = fopen(certificatePath.data(), "r"); | |
+ | |
+ if (!fd) | |
+ return String(); | |
+ | |
+ String data; | |
+ size_t r; | |
+ | |
+ do { | |
+ unsigned char buf[4096]; | |
+ r = fread(buf, sizeof(char), sizeof(buf), fd); | |
+ data.append(buf, r); | |
+ } while (r != 0); | |
+ | |
+ if (ferror(fd)) { | |
+ data = String(); | |
+ } | |
+ | |
+ fclose(fd); | |
+ | |
+ return data; | |
+} | |
+ | |
+} // namespace WebKit | |
diff --git a/Source/WebCore/platform/network/soup/ClientCertificateManager.h b/Source/WebCore/platform/network/soup/ClientCertificateManager.h | |
new file mode 100644 | |
index 0000000..d3e77f1 | |
--- /dev/null | |
+++ b/Source/WebCore/platform/network/soup/ClientCertificateManager.h | |
@@ -0,0 +1,15 @@ | |
+#ifndef WebClientCertificateManager_h | |
+#define WebClientCertificateManager_h | |
+ | |
+#include <wtf/text/WTFString.h> | |
+ | |
+namespace WebCore { | |
+ | |
+class WebClientCertificateManager { | |
+public: | |
+ static String getClientCertificateForServer(const String&, uint16_t); | |
+}; | |
+ | |
+} // namespace WebKit | |
+ | |
+#endif // WebClientCertificateManager_h | |
diff --git a/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp b/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp | |
index 5d27e12..7f16227 100644 | |
--- a/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp | |
+++ b/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp | |
@@ -31,6 +31,7 @@ | |
#include "CachedResourceLoader.h" | |
#include "ChromeClient.h" | |
+#include "ClientCertificateManager.h" | |
#include "CookieJarSoup.h" | |
#include "CredentialStorage.h" | |
#include "FileSystem.h" | |
@@ -862,6 +863,29 @@ static void requestStartedCallback(SoupSession*, SoupMessage* soupMessage, SoupS | |
} | |
} | |
+static void networkEventClientCertificateCallback(SoupMessage* msg, GSocketClientEvent event, GIOStream* connection, gpointer data) | |
+{ | |
+ if (event != G_SOCKET_CLIENT_TLS_HANDSHAKING) | |
+ return; | |
+ | |
+ GRefPtr<SoupAddress> msgAddress(soup_message_get_address(msg)); | |
+ | |
+ String serverName(soup_address_get_name(msgAddress.get())); | |
+ uint16_t serverPort(soup_address_get_port(msgAddress.get())); | |
+ | |
+ const CString certData = WebClientCertificateManager::getClientCertificateForServer(serverName, serverPort).latin1(); | |
+ | |
+ // getClientCertificateForServer returns a null String if no certificate is | |
+ // found, but apparently calling latin1() on it makes it an empty CString | |
+ if (certData.length() > 0) { | |
+ GOwnPtr<GError> error; | |
+ GRefPtr<GTlsCertificate> clientCert(g_tls_certificate_new_from_pem(certData.data(), certData.length(), &error.outPtr())); | |
+ | |
+ if (!error) | |
+ g_tls_connection_set_certificate(G_TLS_CONNECTION(connection), clientCert.get()); | |
+ } | |
+} | |
+ | |
static void networkEventCallback(SoupMessage*, GSocketClientEvent event, GIOStream*, gpointer data) | |
{ | |
ResourceHandle* handle = static_cast<ResourceHandle*>(data); | |
@@ -974,6 +998,8 @@ static bool createSoupMessageForHandleAndRequest(ResourceHandle* handle, const R | |
soup_message_set_flags(d->m_soupMessage.get(), static_cast<SoupMessageFlags>(soup_message_get_flags(d->m_soupMessage.get()) | SOUP_MESSAGE_NO_REDIRECT)); | |
+ g_signal_connect(d->m_soupMessage.get(), "network-event", G_CALLBACK(networkEventClientCertificateCallback), handle); | |
+ | |
#if ENABLE(WEB_TIMING) | |
d->m_response.setResourceLoadTiming(ResourceLoadTiming::create()); | |
g_signal_connect(d->m_soupMessage.get(), "network-event", G_CALLBACK(networkEventCallback), handle); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment