Changeset 206807 in webkit


Ignore:
Timestamp:
Oct 5, 2016 2:43:28 AM (8 years ago)
Author:
Carlos Garcia Campos
Message:

[SOUP] Move global TLS errors handling from ResourceHandle to SoupNetworkSession
https://bugs.webkit.org/show_bug.cgi?id=162910

Reviewed by Alex Christensen.

Source/WebCore:

So that it will be shared with network session code. Also remove setHostAllowsAnyHTTPSCertificate() that we have
never actually used.

  • platform/network/ResourceHandle.h:
  • platform/network/soup/ResourceHandleSoup.cpp:

(WebCore::tlsErrorsChangedCallback): Use SoupNetworkSession::checkTLSErrors().

  • platform/network/soup/SoupNetworkSession.cpp:

(WebCore::HostTLSCertificateSet::add):
(WebCore::HostTLSCertificateSet::contains):
(WebCore::HostTLSCertificateSet::computeCertificateHash):
(WebCore::clientCertificates):
(WebCore::SoupNetworkSession::setShouldIgnoreTLSErrors):
(WebCore::SoupNetworkSession::checkTLSErrors):
(WebCore::SoupNetworkSession::allowSpecificHTTPSCertificateForHost):

  • platform/network/soup/SoupNetworkSession.h:

Source/WebKit2:

Use SoupNetworkSession instead of ResourceHandle.

  • NetworkProcess/soup/NetworkProcessSoup.cpp:

(WebKit::NetworkProcess::setIgnoreTLSErrors):
(WebKit::NetworkProcess::allowSpecificHTTPSCertificateForHost):

Location:
trunk/Source
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r206805 r206807  
     12016-10-05  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [SOUP] Move global TLS errors handling from ResourceHandle to SoupNetworkSession
     4        https://bugs.webkit.org/show_bug.cgi?id=162910
     5
     6        Reviewed by Alex Christensen.
     7
     8        So that it will be shared with network session code. Also remove setHostAllowsAnyHTTPSCertificate() that we have
     9        never actually used.
     10
     11        * platform/network/ResourceHandle.h:
     12        * platform/network/soup/ResourceHandleSoup.cpp:
     13        (WebCore::tlsErrorsChangedCallback): Use SoupNetworkSession::checkTLSErrors().
     14        * platform/network/soup/SoupNetworkSession.cpp:
     15        (WebCore::HostTLSCertificateSet::add):
     16        (WebCore::HostTLSCertificateSet::contains):
     17        (WebCore::HostTLSCertificateSet::computeCertificateHash):
     18        (WebCore::clientCertificates):
     19        (WebCore::SoupNetworkSession::setShouldIgnoreTLSErrors):
     20        (WebCore::SoupNetworkSession::checkTLSErrors):
     21        (WebCore::SoupNetworkSession::allowSpecificHTTPSCertificateForHost):
     22        * platform/network/soup/SoupNetworkSession.h:
     23
    1242016-10-05  Carlos Garcia Campos  <cgarcia@igalia.com>
    225
  • trunk/Source/WebCore/platform/network/ResourceHandle.h

    r204429 r206807  
    186186    size_t currentStreamPosition() const;
    187187    void didStartRequest();
    188     static void setHostAllowsAnyHTTPSCertificate(const String&);
    189     static void setClientCertificate(const String& host, GTlsCertificate*);
    190     static void setIgnoreSSLErrors(bool);
    191188    double m_requestTime;
    192189#endif
  • trunk/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp

    r206805 r206807  
    5959#endif
    6060#include <wtf/CurrentTime.h>
    61 #include <wtf/SHA1.h>
    6261#include <wtf/glib/GRefPtr.h>
    63 #include <wtf/text/Base64.h>
    6462#include <wtf/text/CString.h>
    6563
     
    6765
    6866static const size_t gDefaultReadBufferSize = 8192;
    69 
    70 class HostTLSCertificateSet {
    71 public:
    72     void add(GTlsCertificate* certificate)
    73     {
    74         String certificateHash = computeCertificateHash(certificate);
    75         if (!certificateHash.isEmpty())
    76             m_certificates.add(certificateHash);
    77     }
    78 
    79     bool contains(GTlsCertificate* certificate)
    80     {
    81         return m_certificates.contains(computeCertificateHash(certificate));
    82     }
    83 
    84 private:
    85     static String computeCertificateHash(GTlsCertificate* certificate)
    86     {
    87         GRefPtr<GByteArray> certificateData;
    88         g_object_get(G_OBJECT(certificate), "certificate", &certificateData.outPtr(), NULL);
    89         if (!certificateData)
    90             return String();
    91 
    92         SHA1 sha1;
    93         sha1.addBytes(certificateData->data, certificateData->len);
    94 
    95         SHA1::Digest digest;
    96         sha1.computeHash(digest);
    97 
    98         return base64Encode(reinterpret_cast<const char*>(digest.data()), SHA1::hashSize);
    99     }
    100 
    101     HashSet<String> m_certificates;
    102 };
    10367
    10468static bool createSoupRequestAndMessageForHandle(ResourceHandle*, const ResourceRequest&);
     
    11074#endif
    11175static void continueAfterDidReceiveResponse(ResourceHandle*);
    112 
    113 static bool gIgnoreSSLErrors = false;
    114 
    115 typedef HashSet<String, ASCIICaseInsensitiveHash> HostsSet;
    116 static HostsSet& allowsAnyHTTPSCertificateHosts()
    117 {
    118     DEPRECATED_DEFINE_STATIC_LOCAL(HostsSet, hosts, ());
    119     return hosts;
    120 }
    121 
    122 typedef HashMap<String, HostTLSCertificateSet, ASCIICaseInsensitiveHash> CertificatesMap;
    123 static CertificatesMap& clientCertificates()
    124 {
    125     DEPRECATED_DEFINE_STATIC_LOCAL(CertificatesMap, certificates, ());
    126     return certificates;
    127 }
    12876
    12977ResourceHandleInternal::~ResourceHandleInternal()
     
    181129}
    182130
    183 static bool handleUnignoredTLSErrors(ResourceHandle* handle, SoupMessage* message)
    184 {
    185     if (gIgnoreSSLErrors)
    186         return false;
    187 
    188     GTlsCertificate* certificate = nullptr;
    189     GTlsCertificateFlags tlsErrors = static_cast<GTlsCertificateFlags>(0);
    190     soup_message_get_https_status(message, &certificate, &tlsErrors);
    191     if (!tlsErrors)
    192         return false;
    193 
    194     String host = handle->firstRequest().url().host();
    195     if (allowsAnyHTTPSCertificateHosts().contains(host))
    196         return false;
    197 
    198     // We aren't ignoring errors globally, but the user may have already decided to accept this certificate.
    199     auto it = clientCertificates().find(host);
    200     if (it != clientCertificates().end() && it->value.contains(certificate))
    201         return false;
    202 
    203     ResourceHandleInternal* d = handle->getInternal();
    204     handle->client()->didFail(handle, ResourceError::tlsError(d->m_soupRequest.get(), tlsErrors, certificate));
    205     return true;
    206 }
    207 
    208131static void tlsErrorsChangedCallback(SoupMessage* message, GParamSpec*, gpointer data)
    209132{
     
    212135        return;
    213136
    214     if (handleUnignoredTLSErrors(handle.get(), message))
     137    SoupNetworkSession::checkTLSErrors(handle->getInternal()->m_soupRequest.get(), message, [handle] (const ResourceError& error) {
     138        if (error.isNull())
     139            return;
     140
     141        handle->client()->didFail(handle.get(), error);
    215142        handle->cancel();
     143    });
    216144}
    217145
     
    849777}
    850778
    851 void ResourceHandle::setHostAllowsAnyHTTPSCertificate(const String& host)
    852 {
    853     allowsAnyHTTPSCertificateHosts().add(host);
    854 }
    855 
    856 void ResourceHandle::setClientCertificate(const String& host, GTlsCertificate* certificate)
    857 {
    858     clientCertificates().add(host, HostTLSCertificateSet()).iterator->value.add(certificate);
    859 }
    860 
    861 void ResourceHandle::setIgnoreSSLErrors(bool ignoreSSLErrors)
    862 {
    863     gIgnoreSSLErrors = ignoreSSLErrors;
    864 }
    865 
    866779void ResourceHandle::continueDidReceiveAuthenticationChallenge(const Credential& credentialFromPersistentStorage)
    867780{
  • trunk/Source/WebCore/platform/network/soup/SoupNetworkSession.cpp

    r206772 r206807  
    3838#include <glib/gstdio.h>
    3939#include <libsoup/soup.h>
     40#include <wtf/HashSet.h>
    4041#include <wtf/NeverDestroyed.h>
     42#include <wtf/SHA1.h>
     43#include <wtf/text/Base64.h>
    4144#include <wtf/text/CString.h>
    4245#include <wtf/text/StringBuilder.h>
     
    4447namespace WebCore {
    4548
     49static bool gIgnoreTLSErrors;
     50
    4651#if !LOG_DISABLED
    4752inline static void soupLogPrinter(SoupLogger*, SoupLoggerLogLevel, char direction, const char* data, gpointer)
     
    5055}
    5156#endif
     57
     58class HostTLSCertificateSet {
     59public:
     60    void add(GTlsCertificate* certificate)
     61    {
     62        String certificateHash = computeCertificateHash(certificate);
     63        if (!certificateHash.isEmpty())
     64            m_certificates.add(certificateHash);
     65    }
     66
     67    bool contains(GTlsCertificate* certificate) const
     68    {
     69        return m_certificates.contains(computeCertificateHash(certificate));
     70    }
     71
     72private:
     73    static String computeCertificateHash(GTlsCertificate* certificate)
     74    {
     75        GRefPtr<GByteArray> certificateData;
     76        g_object_get(G_OBJECT(certificate), "certificate", &certificateData.outPtr(), nullptr);
     77        if (!certificateData)
     78            return String();
     79
     80        SHA1 sha1;
     81        sha1.addBytes(certificateData->data, certificateData->len);
     82
     83        SHA1::Digest digest;
     84        sha1.computeHash(digest);
     85
     86        return base64Encode(reinterpret_cast<const char*>(digest.data()), SHA1::hashSize);
     87    }
     88
     89    HashSet<String> m_certificates;
     90};
     91
     92static HashMap<String, HostTLSCertificateSet, ASCIICaseInsensitiveHash>& clientCertificates()
     93{
     94    static NeverDestroyed<HashMap<String, HostTLSCertificateSet, ASCIICaseInsensitiveHash>> certificates;
     95    return certificates;
     96}
    5297
    5398SoupNetworkSession& SoupNetworkSession::defaultSession()
     
    280325}
    281326
     327void SoupNetworkSession::setShouldIgnoreTLSErrors(bool ignoreTLSErrors)
     328{
     329    gIgnoreTLSErrors = ignoreTLSErrors;
     330}
     331
     332void SoupNetworkSession::checkTLSErrors(SoupRequest* soupRequest, SoupMessage* message, std::function<void (const ResourceError&)>&& completionHandler)
     333{
     334    if (gIgnoreTLSErrors) {
     335        completionHandler({ });
     336        return;
     337    }
     338
     339    GTlsCertificate* certificate = nullptr;
     340    GTlsCertificateFlags tlsErrors = static_cast<GTlsCertificateFlags>(0);
     341    soup_message_get_https_status(message, &certificate, &tlsErrors);
     342    if (!tlsErrors) {
     343        completionHandler({ });
     344        return;
     345    }
     346
     347    URL url(soup_request_get_uri(soupRequest));
     348    auto it = clientCertificates().find(url.host());
     349    if (it != clientCertificates().end() && it->value.contains(certificate)) {
     350        completionHandler({ });
     351        return;
     352    }
     353
     354    completionHandler(ResourceError::tlsError(soupRequest, tlsErrors, certificate));
     355}
     356
     357void SoupNetworkSession::allowSpecificHTTPSCertificateForHost(const CertificateInfo& certificateInfo, const String& host)
     358{
     359    clientCertificates().add(host, HostTLSCertificateSet()).iterator->value.add(certificateInfo.certificate());
     360}
     361
    282362} // namespace WebCore
    283363
  • trunk/Source/WebCore/platform/network/soup/SoupNetworkSession.h

    r206772 r206807  
    3434typedef struct _SoupCache SoupCache;
    3535typedef struct _SoupCookieJar SoupCookieJar;
     36typedef struct _SoupMessage SoupMessage;
     37typedef struct _SoupRequest SoupRequest;
    3638typedef struct _SoupSession SoupSession;
    3739
    3840namespace WebCore {
     41
     42class CertificateInfo;
     43class ResourceError;
    3944
    4045class SoupNetworkSession {
     
    5964    void setAcceptLanguages(const Vector<String>&);
    6065
     66    static void setShouldIgnoreTLSErrors(bool);
     67    static void checkTLSErrors(SoupRequest*, SoupMessage*, std::function<void (const ResourceError&)>&&);
     68    static void allowSpecificHTTPSCertificateForHost(const CertificateInfo&, const String& host);
     69
    6170private:
    6271    friend class NeverDestroyed<SoupNetworkSession>;
  • trunk/Source/WebKit2/ChangeLog

    r206806 r206807  
     12016-10-05  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [SOUP] Move global TLS errors handling from ResourceHandle to SoupNetworkSession
     4        https://bugs.webkit.org/show_bug.cgi?id=162910
     5
     6        Reviewed by Alex Christensen.
     7
     8        Use SoupNetworkSession instead of ResourceHandle.
     9
     10        * NetworkProcess/soup/NetworkProcessSoup.cpp:
     11        (WebKit::NetworkProcess::setIgnoreTLSErrors):
     12        (WebKit::NetworkProcess::allowSpecificHTTPSCertificateForHost):
     13
    1142016-10-05  Carlos Garcia Campos  <cgarcia@igalia.com>
    215
  • trunk/Source/WebKit2/NetworkProcess/soup/NetworkProcessSoup.cpp

    r205556 r206807  
    8484void NetworkProcess::setIgnoreTLSErrors(bool ignoreTLSErrors)
    8585{
    86     ResourceHandle::setIgnoreSSLErrors(ignoreTLSErrors);
     86    SoupNetworkSession::setShouldIgnoreTLSErrors(ignoreTLSErrors);
    8787}
    8888
    8989void NetworkProcess::allowSpecificHTTPSCertificateForHost(const CertificateInfo& certificateInfo, const String& host)
    9090{
    91     ResourceHandle::setClientCertificate(host, certificateInfo.certificate());
     91    SoupNetworkSession::allowSpecificHTTPSCertificateForHost(certificateInfo, host);
    9292}
    9393
Note: See TracChangeset for help on using the changeset viewer.