Title: [125258] trunk/Source
Revision
125258
Author
carlo...@webkit.org
Date
2012-08-10 00:46:53 -0700 (Fri, 10 Aug 2012)

Log Message

Handle SSL errors for SOUP
https://bugs.webkit.org/show_bug.cgi?id=90267

Reviewed by Martin Robinson.

Source/WebCore:

No new tests, this is covered by existing tests.

* platform/LocalizedStrings.h:
(WebCore): Add unacceptableTLSCertificate() for SOUP.
* platform/efl/LocalizedStringsEfl.cpp:
(WebCore::unacceptableTLSCertificate):
* platform/gtk/LocalizedStringsGtk.cpp:
(WebCore::unacceptableTLSCertificate):
* platform/network/ResourceHandle.h:
* platform/network/soup/ResourceError.h:
(WebCore::ResourceError::ResourceError): Add new constructor for
SSL errors that receives a certificate and TLS errors.
(WebCore::ResourceError::tlsErrors): Return TLS errors.
(WebCore::ResourceError::certificate): Return the certificate.
* platform/network/soup/ResourceHandleSoup.cpp:
(HostTLSCertificates): Helper class to store certificates for a
host.
(WebCore::HostTLSCertificateSet::add): Add a new certificate.
(WebCore::HostTLSCertificateSet::contains): Check whether
certificate is stored.
(WebCore::HostTLSCertificateSet::computeCertificateHash): Compute
the SHA1 of the certificate data.
(WebCore::allowsAnyHTTPSCertificateHosts): Global set to store
hostnames for which SSL errors should be ignored.
(WebCore::clientCertificates): Global map to store client
certificates.
(WebCore::hasUnignoredTLSErrors): Helper function to check whether
current message contains TLS errors that shouldn't be ignored and
certificate hasn't been approved already.
(WebCore::sendRequestCallback): Finish the load with an error in
case of SSL errors not handled by the SoupSession.
(WebCore::ResourceHandle::setHostAllowsAnyHTTPSCertificate): Add
the given hostname to the list of hosts for which SSL errors are
ignored.
(WebCore::ResourceHandle::setClientCertificate): Store the client
certificate for the given host.
(WebCore::ResourceHandle::setIgnoreSSLErrors): Set whether all SSL
errors should be ignored.

Source/WebKit/efl:

Ignore SSL errors by default for compatibility.

* ewk/ewk_main.cpp:
(_ewk_init_body):

Source/WebKit/gtk:

Ignore SSL errors by default for compatibility.

* webkit/webkitglobals.cpp:
(webkitInit):

Source/WebKit2:

Ignore SSL errors by default for compatibility.

* WebProcess/efl/WebProcessMainEfl.cpp:
(WebKit::WebProcessMainEfl):
* WebProcess/gtk/WebProcessMainGtk.cpp:
(WebKit::WebProcessMainGtk):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (125257 => 125258)


--- trunk/Source/WebCore/ChangeLog	2012-08-10 07:42:06 UTC (rev 125257)
+++ trunk/Source/WebCore/ChangeLog	2012-08-10 07:46:53 UTC (rev 125258)
@@ -1,3 +1,49 @@
+2012-08-09  Carlos Garcia Campos  <cgar...@igalia.com>
+
+        Handle SSL errors for SOUP
+        https://bugs.webkit.org/show_bug.cgi?id=90267
+
+        Reviewed by Martin Robinson.
+
+        No new tests, this is covered by existing tests.
+
+        * platform/LocalizedStrings.h:
+        (WebCore): Add unacceptableTLSCertificate() for SOUP.
+        * platform/efl/LocalizedStringsEfl.cpp:
+        (WebCore::unacceptableTLSCertificate):
+        * platform/gtk/LocalizedStringsGtk.cpp:
+        (WebCore::unacceptableTLSCertificate):
+        * platform/network/ResourceHandle.h:
+        * platform/network/soup/ResourceError.h:
+        (WebCore::ResourceError::ResourceError): Add new constructor for
+        SSL errors that receives a certificate and TLS errors.
+        (WebCore::ResourceError::tlsErrors): Return TLS errors.
+        (WebCore::ResourceError::certificate): Return the certificate.
+        * platform/network/soup/ResourceHandleSoup.cpp:
+        (HostTLSCertificates): Helper class to store certificates for a
+        host.
+        (WebCore::HostTLSCertificateSet::add): Add a new certificate.
+        (WebCore::HostTLSCertificateSet::contains): Check whether
+        certificate is stored.
+        (WebCore::HostTLSCertificateSet::computeCertificateHash): Compute
+        the SHA1 of the certificate data.
+        (WebCore::allowsAnyHTTPSCertificateHosts): Global set to store
+        hostnames for which SSL errors should be ignored.
+        (WebCore::clientCertificates): Global map to store client
+        certificates.
+        (WebCore::hasUnignoredTLSErrors): Helper function to check whether
+        current message contains TLS errors that shouldn't be ignored and
+        certificate hasn't been approved already.
+        (WebCore::sendRequestCallback): Finish the load with an error in
+        case of SSL errors not handled by the SoupSession.
+        (WebCore::ResourceHandle::setHostAllowsAnyHTTPSCertificate): Add
+        the given hostname to the list of hosts for which SSL errors are
+        ignored.
+        (WebCore::ResourceHandle::setClientCertificate): Store the client
+        certificate for the given host.
+        (WebCore::ResourceHandle::setIgnoreSSLErrors): Set whether all SSL
+        errors should be ignored.
+
 2012-08-10  Arko Saha  <a...@motorola.com>
 
         itemType.add should treat \t as a space.

Modified: trunk/Source/WebCore/platform/LocalizedStrings.h (125257 => 125258)


--- trunk/Source/WebCore/platform/LocalizedStrings.h	2012-08-10 07:42:06 UTC (rev 125257)
+++ trunk/Source/WebCore/platform/LocalizedStrings.h	2012-08-10 07:46:53 UTC (rev 125258)
@@ -220,6 +220,9 @@
     String dateFormatMonthText();
     String dateFormatDayInMonthText();
 #endif
+#if USE(SOUP)
+    String unacceptableTLSCertificate();
+#endif
 
 #if !PLATFORM(CHROMIUM)
 #define WEB_UI_STRING(string, description) WebCore::localizedString(string)

Modified: trunk/Source/WebCore/platform/efl/LocalizedStringsEfl.cpp (125257 => 125258)


--- trunk/Source/WebCore/platform/efl/LocalizedStringsEfl.cpp	2012-08-10 07:42:06 UTC (rev 125257)
+++ trunk/Source/WebCore/platform/efl/LocalizedStringsEfl.cpp	2012-08-10 07:46:53 UTC (rev 125258)
@@ -572,6 +572,11 @@
     return String();
 }
 
+String unacceptableTLSCertificate()
+{
+    return String::fromUTF8("Unacceptable TLS certificate");
+}
+
 String localizedString(const char* key)
 {
     return String::fromUTF8(key, strlen(key));

Modified: trunk/Source/WebCore/platform/gtk/LocalizedStringsGtk.cpp (125257 => 125258)


--- trunk/Source/WebCore/platform/gtk/LocalizedStringsGtk.cpp	2012-08-10 07:42:06 UTC (rev 125257)
+++ trunk/Source/WebCore/platform/gtk/LocalizedStringsGtk.cpp	2012-08-10 07:46:53 UTC (rev 125258)
@@ -723,6 +723,11 @@
     return String::fromUTF8(_("step mismatch"));
 }
 
+String unacceptableTLSCertificate()
+{
+    return String::fromUTF8(_("Unacceptable TLS certificate"));
+}
+
 String localizedString(const char* key)
 {
     return String::fromUTF8(key, strlen(key));

Modified: trunk/Source/WebCore/platform/network/ResourceHandle.h (125257 => 125258)


--- trunk/Source/WebCore/platform/network/ResourceHandle.h	2012-08-10 07:42:06 UTC (rev 125257)
+++ trunk/Source/WebCore/platform/network/ResourceHandle.h	2012-08-10 07:46:53 UTC (rev 125258)
@@ -168,6 +168,9 @@
 
 #if USE(SOUP)
     static SoupSession* defaultSession();
+    static void setHostAllowsAnyHTTPSCertificate(const String&);
+    static void setClientCertificate(const String& host, GTlsCertificate*);
+    static void setIgnoreSSLErrors(bool);
 #endif
 
     // Used to work around the fact that you don't get any more NSURLConnection callbacks until you return from the one you're in.

Modified: trunk/Source/WebCore/platform/network/soup/ResourceError.h (125257 => 125258)


--- trunk/Source/WebCore/platform/network/soup/ResourceError.h	2012-08-10 07:42:06 UTC (rev 125257)
+++ trunk/Source/WebCore/platform/network/soup/ResourceError.h	2012-08-10 07:46:53 UTC (rev 125258)
@@ -27,20 +27,39 @@
 #define ResourceError_h
 
 #include "ResourceErrorBase.h"
+#include <wtf/gobject/GRefPtr.h>
 
+typedef struct _GTlsCertificate GTlsCertificate;
+
 namespace WebCore {
 
 class ResourceError : public ResourceErrorBase
 {
 public:
     ResourceError()
+        : m_tlsErrors(0)
     {
     }
 
     ResourceError(const String& domain, int errorCode, const String& failingURL, const String& localizedDescription)
         : ResourceErrorBase(domain, errorCode, failingURL, localizedDescription)
+        , m_tlsErrors(0)
     {
     }
+
+    ResourceError(const String& domain, int errorCode, const String& failingURL, const String& localizedDescription, unsigned tlsErrors, GTlsCertificate* certificate)
+        : ResourceErrorBase(domain, errorCode, failingURL, localizedDescription)
+        , m_tlsErrors(tlsErrors)
+        , m_certificate(certificate)
+    {
+    }
+
+    unsigned tlsErrors() const { return m_tlsErrors; }
+    GTlsCertificate* certificate() const { return m_certificate.get(); }
+
+private:
+    unsigned m_tlsErrors;
+    GRefPtr<GTlsCertificate> m_certificate;
 };
 
 }

Modified: trunk/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp (125257 => 125258)


--- trunk/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp	2012-08-10 07:42:06 UTC (rev 125257)
+++ trunk/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp	2012-08-10 07:46:53 UTC (rev 125258)
@@ -34,6 +34,7 @@
 #include "Frame.h"
 #include "GOwnPtrSoup.h"
 #include "HTTPParsers.h"
+#include "LocalizedStrings.h"
 #include "Logging.h"
 #include "MIMETypeRegistry.h"
 #include "NotImplemented.h"
@@ -55,7 +56,9 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <wtf/SHA1.h>
 #include <wtf/gobject/GRefPtr.h>
+#include <wtf/text/Base64.h>
 #include <wtf/text/CString.h>
 
 #if ENABLE(BLOB)
@@ -158,6 +161,42 @@
     GRefPtr<GMainLoop> m_mainLoop;
 };
 
+class HostTLSCertificateSet {
+public:
+    void add(GTlsCertificate* certificate)
+    {
+        String certificateHash = computeCertificateHash(certificate);
+        if (!certificateHash.isEmpty())
+            m_certificates.add(certificateHash);
+    }
+
+    bool contains(GTlsCertificate* certificate)
+    {
+        return m_certificates.contains(computeCertificateHash(certificate));
+    }
+
+private:
+    static String computeCertificateHash(GTlsCertificate* certificate)
+    {
+        GByteArray* data = ""
+        g_object_get(G_OBJECT(certificate), "certificate", &data, NULL);
+        if (!data)
+            return String();
+
+        static const size_t sha1HashSize = 20;
+        GRefPtr<GByteArray> certificateData = adoptGRef(data);
+        SHA1 sha1;
+        sha1.addBytes(certificateData->data, certificateData->len);
+
+        Vector<uint8_t, sha1HashSize> digest;
+        sha1.computeHash(digest);
+
+        return base64Encode(reinterpret_cast<const char*>(digest.data()), sha1HashSize);
+    }
+
+    HashSet<String> m_certificates;
+};
+
 static void cleanupSoupRequestOperation(ResourceHandle*, bool isDestroying);
 static void sendRequestCallback(GObject*, GAsyncResult*, gpointer);
 static void readCallback(GObject*, GAsyncResult*, gpointer);
@@ -167,6 +206,21 @@
 static int  milisecondsSinceRequest(double requestTime);
 #endif
 
+static bool gIgnoreSSLErrors = false;
+
+static HashSet<String>& allowsAnyHTTPSCertificateHosts()
+{
+    DEFINE_STATIC_LOCAL(HashSet<String>, hosts, ());
+    return hosts;
+}
+
+typedef HashMap<String, HostTLSCertificateSet> CertificatesMap;
+static CertificatesMap& clientCertificates()
+{
+    DEFINE_STATIC_LOCAL(CertificatesMap, certificates, ());
+    return certificates;
+}
+
 ResourceHandleInternal::~ResourceHandleInternal()
 {
 }
@@ -349,6 +403,13 @@
                          String::fromUTF8(error->message));
 }
 
+static inline bool hasUnignoredTLSErrors(ResourceHandle* handle)
+{
+    return handle->getInternal()->m_response.soupMessageTLSErrors()
+        && !gIgnoreSSLErrors
+        && !allowsAnyHTTPSCertificateHosts().contains(handle->firstRequest().url().host().lower());
+}
+
 static void sendRequestCallback(GObject* source, GAsyncResult* res, gpointer data)
 {
     RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(data);
@@ -384,6 +445,18 @@
             d->m_response.setSniffedContentType(sniffedType);
         }
         d->m_response.updateFromSoupMessage(soupMessage);
+
+        if (hasUnignoredTLSErrors(handle.get())) {
+            CertificatesMap::iterator iter = clientCertificates().find(handle->firstRequest().url().host().lower());
+            if (iter == clientCertificates().end() || !iter->second.contains(d->m_response.soupMessageCertificate())) {
+                GOwnPtr<char> uri(soup_uri_to_string(soup_request_get_uri(d->m_soupRequest.get()), FALSE));
+                client->didFail(handle.get(), ResourceError(g_quark_to_string(SOUP_HTTP_ERROR), SOUP_STATUS_SSL_FAILED,
+                                                            uri.get(), unacceptableTLSCertificate(),
+                                                            d->m_response.soupMessageTLSErrors(), d->m_response.soupMessageCertificate()));
+                cleanupSoupRequestOperation(handle.get());
+                return;
+            }
+        }
     } else {
         d->m_response.setURL(handle->firstRequest().url());
         const gchar* contentType = soup_request_get_content_type(d->m_soupRequest.get());
@@ -739,6 +812,21 @@
         g_cancellable_cancel(d->m_cancellable.get());
 }
 
+void ResourceHandle::setHostAllowsAnyHTTPSCertificate(const String& host)
+{
+    allowsAnyHTTPSCertificateHosts().add(host.lower());
+}
+
+void ResourceHandle::setClientCertificate(const String& host, GTlsCertificate* certificate)
+{
+    clientCertificates().add(host.lower(), HostTLSCertificateSet()).iterator->second.add(certificate);
+}
+
+void ResourceHandle::setIgnoreSSLErrors(bool ignoreSSLErrors)
+{
+    gIgnoreSSLErrors = ignoreSSLErrors;
+}
+
 static bool hasBeenSent(ResourceHandle* handle)
 {
     ResourceHandleInternal* d = handle->getInternal();

Modified: trunk/Source/WebKit/efl/ChangeLog (125257 => 125258)


--- trunk/Source/WebKit/efl/ChangeLog	2012-08-10 07:42:06 UTC (rev 125257)
+++ trunk/Source/WebKit/efl/ChangeLog	2012-08-10 07:46:53 UTC (rev 125258)
@@ -1,3 +1,15 @@
+2012-08-09  Carlos Garcia Campos  <cgar...@igalia.com>
+
+        Handle SSL errors for SOUP
+        https://bugs.webkit.org/show_bug.cgi?id=90267
+
+        Reviewed by Martin Robinson.
+
+        Ignore SSL errors by default for compatibility.
+
+        * ewk/ewk_main.cpp:
+        (_ewk_init_body):
+
 2012-08-07  Ryuan Choi  <ryuan.c...@samsung.com>
 
         [EFL] Remove PlatformTouchEventEfl and PlatformTouchPointEfl

Modified: trunk/Source/WebKit/efl/ewk/ewk_main.cpp (125257 => 125258)


--- trunk/Source/WebKit/efl/ewk/ewk_main.cpp	2012-08-10 07:42:06 UTC (rev 125257)
+++ trunk/Source/WebKit/efl/ewk/ewk_main.cpp	2012-08-10 07:46:53 UTC (rev 125258)
@@ -176,5 +176,7 @@
     SoupSessionFeature* auth_dialog = static_cast<SoupSessionFeature*>(g_object_new(EWK_TYPE_SOUP_AUTH_DIALOG, 0));
     soup_session_add_feature(session, auth_dialog);
 
+    WebCore::ResourceHandle::setIgnoreSSLErrors(true);
+
     return true;
 }

Modified: trunk/Source/WebKit/gtk/ChangeLog (125257 => 125258)


--- trunk/Source/WebKit/gtk/ChangeLog	2012-08-10 07:42:06 UTC (rev 125257)
+++ trunk/Source/WebKit/gtk/ChangeLog	2012-08-10 07:46:53 UTC (rev 125258)
@@ -1,3 +1,15 @@
+2012-08-09  Carlos Garcia Campos  <cgar...@igalia.com>
+
+        Handle SSL errors for SOUP
+        https://bugs.webkit.org/show_bug.cgi?id=90267
+
+        Reviewed by Martin Robinson.
+
+        Ignore SSL errors by default for compatibility.
+
+        * webkit/webkitglobals.cpp:
+        (webkitInit):
+
 2012-08-07  Carlos Garcia Campos  <cgar...@igalia.com>
 
         Unreviewed. Fix GTK+ build with GTK2 after r120918.

Modified: trunk/Source/WebKit/gtk/webkit/webkitglobals.cpp (125257 => 125258)


--- trunk/Source/WebKit/gtk/webkit/webkitglobals.cpp	2012-08-10 07:42:06 UTC (rev 125257)
+++ trunk/Source/WebKit/gtk/webkit/webkitglobals.cpp	2012-08-10 07:46:53 UTC (rev 125258)
@@ -531,6 +531,8 @@
     soup_session_add_feature(session, authDialog);
     g_object_unref(authDialog);
 
+    WebCore::ResourceHandle::setIgnoreSSLErrors(true);
+
 #if USE(CLUTTER)
     gtk_clutter_init(0, 0);
 #endif

Modified: trunk/Source/WebKit2/ChangeLog (125257 => 125258)


--- trunk/Source/WebKit2/ChangeLog	2012-08-10 07:42:06 UTC (rev 125257)
+++ trunk/Source/WebKit2/ChangeLog	2012-08-10 07:46:53 UTC (rev 125258)
@@ -1,3 +1,17 @@
+2012-08-09  Carlos Garcia Campos  <cgar...@igalia.com>
+
+        Handle SSL errors for SOUP
+        https://bugs.webkit.org/show_bug.cgi?id=90267
+
+        Reviewed by Martin Robinson.
+
+        Ignore SSL errors by default for compatibility.
+
+        * WebProcess/efl/WebProcessMainEfl.cpp:
+        (WebKit::WebProcessMainEfl):
+        * WebProcess/gtk/WebProcessMainGtk.cpp:
+        (WebKit::WebProcessMainGtk):
+
 2012-08-09  Alexey Proskuryakov  <a...@apple.com>
 
         [WK2] Add a process model constant for multiple processes

Modified: trunk/Source/WebKit2/WebProcess/efl/WebProcessMainEfl.cpp (125257 => 125258)


--- trunk/Source/WebKit2/WebProcess/efl/WebProcessMainEfl.cpp	2012-08-10 07:42:06 UTC (rev 125257)
+++ trunk/Source/WebKit2/WebProcess/efl/WebProcessMainEfl.cpp	2012-08-10 07:46:53 UTC (rev 125258)
@@ -84,6 +84,8 @@
     CoordinatedGraphicsLayer::initFactory();
 #endif
 
+    WebCore::ResourceHandle::setIgnoreSSLErrors(true);
+
     int socket = atoi(argv[1]);
     WebProcess::shared().initialize(socket, RunLoop::main());
     RunLoop::run();

Modified: trunk/Source/WebKit2/WebProcess/gtk/WebProcessMainGtk.cpp (125257 => 125258)


--- trunk/Source/WebKit2/WebProcess/gtk/WebProcessMainGtk.cpp	2012-08-10 07:42:06 UTC (rev 125257)
+++ trunk/Source/WebKit2/WebProcess/gtk/WebProcessMainGtk.cpp	2012-08-10 07:46:53 UTC (rev 125258)
@@ -80,6 +80,9 @@
     soup_session_add_feature(session, SOUP_SESSION_FEATURE(soupCache.get()));
     soup_cache_load(soupCache.get());
 
+    // This is for compatibility, it will be removed when UI process can handle SSL errors.
+    WebCore::ResourceHandle::setIgnoreSSLErrors(true);
+
     RunLoop::run();
 
     return 0;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to