Changeset 265150 in webkit


Ignore:
Timestamp:
Jul 31, 2020 10:54:46 AM (4 years ago)
Author:
youenn@apple.com
Message:

Update service worker if certificate info does not match when soft updating
https://bugs.webkit.org/show_bug.cgi?id=214988

Reviewed by Alex Christensen.

Source/WebCore:

In case service worker certificate info does not match, treat it as if the script changed.
This is a convenient way to update the service worker and the stored registration database.
Covered by API test.

  • platform/network/cf/CertificateInfo.h:
  • platform/network/cf/CertificateInfoCFNet.cpp:

(WebCore::certificatesMatch):

  • workers/service/server/SWServerJobQueue.cpp:

(WebCore::doCertificatesMatch):
(WebCore::SWServerJobQueue::scriptFetchFinished):

  • workers/service/server/SWServerWorker.h:

(WebCore::SWServerWorker::certificateInfo const):

Source/WebKit:

Make sure service worker soft updater gathers certificate info.

  • NetworkProcess/ServiceWorker/ServiceWorkerSoftUpdateLoader.cpp:

(WebKit::ServiceWorkerSoftUpdateLoader::loadFromNetwork):
(WebKit::ServiceWorkerSoftUpdateLoader::didReceiveResponse):

  • NetworkProcess/cocoa/NetworkSessionCocoa.mm:

(WebKit::NetworkSessionCocoa::allowsSpecificHTTPSCertificateForHost):

Tools:

Update HTTPServer to pass two optional parameters:

  • A port number to listen to if provided
  • A custom server identity to use if provided

The API test is loading an URL on a first server.
This triggers registration of a service worker.
It then stops this server and launches a second server on the same port with a different certificate.
A second page is loaded on the same URL.
This triggers the case of updating a service worker certificate info.

  • TestWebKitAPI/Tests/WebKitCocoa/Challenge.mm:

(createTestIdentity):
(testIdentity):
(testIdentity2):

  • TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:
  • TestWebKitAPI/cocoa/HTTPServer.h:
  • TestWebKitAPI/cocoa/HTTPServer.mm:

(TestWebKitAPI::HTTPServer::listenerParameters):
(TestWebKitAPI::HTTPServer::HTTPServer):

Location:
trunk
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r265149 r265150  
     12020-07-31  Youenn Fablet  <youenn@apple.com>
     2
     3        Update service worker if certificate info does not match when soft updating
     4        https://bugs.webkit.org/show_bug.cgi?id=214988
     5
     6        Reviewed by Alex Christensen.
     7
     8        In case service worker certificate info does not match, treat it as if the script changed.
     9        This is a convenient way to update the service worker and the stored registration database.
     10        Covered by API test.
     11
     12        * platform/network/cf/CertificateInfo.h:
     13        * platform/network/cf/CertificateInfoCFNet.cpp:
     14        (WebCore::certificatesMatch):
     15        * workers/service/server/SWServerJobQueue.cpp:
     16        (WebCore::doCertificatesMatch):
     17        (WebCore::SWServerJobQueue::scriptFetchFinished):
     18        * workers/service/server/SWServerWorker.h:
     19        (WebCore::SWServerWorker::certificateInfo const):
     20
    1212020-07-31  Sihui Liu  <sihui_liu@appe.com>
    222
  • trunk/Source/WebCore/platform/network/cf/CertificateInfo.h

    r264724 r265150  
    9898};
    9999
     100WEBCORE_EXPORT bool certificatesMatch(SecTrustRef, SecTrustRef);
     101
    100102} // namespace WebCore
    101103
  • trunk/Source/WebCore/platform/network/cf/CertificateInfoCFNet.cpp

    r264686 r265150  
    3333namespace WebCore {
    3434
     35bool certificatesMatch(SecTrustRef trust1, SecTrustRef trust2)
     36{
     37    if (!trust1 || !trust2)
     38        return false;
     39
     40    CFIndex count1 = SecTrustGetCertificateCount(trust1);
     41    CFIndex count2 = SecTrustGetCertificateCount(trust2);
     42    if (count1 != count2)
     43        return false;
     44
     45    for (CFIndex i = 0; i < count1; i++) {
     46        auto cert1 = SecTrustGetCertificateAtIndex(trust1, i);
     47        auto cert2 = SecTrustGetCertificateAtIndex(trust2, i);
     48        RELEASE_ASSERT(cert1);
     49        RELEASE_ASSERT(cert2);
     50        if (!CFEqual(cert1, cert2))
     51            return false;
     52    }
     53
     54    return true;
     55}
     56
    3557#if PLATFORM(COCOA)
    3658RetainPtr<CFArrayRef> CertificateInfo::certificateChainFromSecTrust(SecTrustRef trust)
  • trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp

    r264724 r265150  
    5858}
    5959
     60static bool doCertificatesMatch(const CertificateInfo& first, const CertificateInfo& second)
     61{
     62#if PLATFORM(COCOA) && HAVE(SEC_TRUST_SERIALIZATION)
     63    return first.trust() == second.trust() || certificatesMatch(first.trust(), second.trust());
     64#else
     65    // FIXME: Add support for certificate matching in CertificateInfo.
     66    return true;
     67#endif
     68}
     69
    6070void SWServerJobQueue::scriptFetchFinished(const ServiceWorkerFetchResult& result)
    6171{
     
    8999    // flag set, and script's source text is a byte-for-byte match with newestWorker's script resource's source
    90100    // text, then:
    91     if (newestWorker && equalIgnoringFragmentIdentifier(newestWorker->scriptURL(), job.scriptURL) && result.script == newestWorker->script()) {
     101    if (newestWorker && equalIgnoringFragmentIdentifier(newestWorker->scriptURL(), job.scriptURL) && result.script == newestWorker->script() && doCertificatesMatch(result.certificateInfo, newestWorker->certificateInfo())) {
     102        RELEASE_LOG(ServiceWorker, "%p - SWServerJobQueue::scriptFetchFinished, script and certificate are matching for registration ID: %llu", this, registration->identifier().toUInt64());
    92103        // FIXME: for non classic scripts, check the script’s module record's [[ECMAScriptCode]].
    93104
  • trunk/Source/WebCore/workers/service/server/SWServerWorker.h

    r264724 r265150  
    8282    const URL& scriptURL() const { return m_data.scriptURL; }
    8383    const String& script() const { return m_script; }
     84    const CertificateInfo& certificateInfo() const { return m_certificateInfo; }
    8485    WorkerType type() const { return m_data.type; }
    8586
  • trunk/Source/WebKit/ChangeLog

    r265149 r265150  
     12020-07-31  Youenn Fablet  <youenn@apple.com>
     2
     3        Update service worker if certificate info does not match when soft updating
     4        https://bugs.webkit.org/show_bug.cgi?id=214988
     5
     6        Reviewed by Alex Christensen.
     7
     8        Make sure service worker soft updater gathers certificate info.
     9
     10        * NetworkProcess/ServiceWorker/ServiceWorkerSoftUpdateLoader.cpp:
     11        (WebKit::ServiceWorkerSoftUpdateLoader::loadFromNetwork):
     12        (WebKit::ServiceWorkerSoftUpdateLoader::didReceiveResponse):
     13        * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
     14        (WebKit::NetworkSessionCocoa::allowsSpecificHTTPSCertificateForHost):
     15
    1162020-07-31  Sihui Liu  <sihui_liu@appe.com>
    217
  • trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerSoftUpdateLoader.cpp

    r264724 r265150  
    126126    parameters.contentSniffingPolicy = ContentSniffingPolicy::DoNotSniffContent;
    127127    parameters.contentEncodingSniffingPolicy = ContentEncodingSniffingPolicy::Sniff;
     128    parameters.needsCertificateInfo = true;
    128129    parameters.request = WTFMove(request);
    129130    m_networkLoad = makeUnique<NetworkLoad>(*this, nullptr, WTFMove(parameters), session);
     
    138139void ServiceWorkerSoftUpdateLoader::didReceiveResponse(ResourceResponse&& response, ResponseCompletionHandler&& completionHandler)
    139140{
    140     // FIXME: If the certificate info changes but the script content does not, treat that as an update.
    141     m_certificateInfo = response.certificateInfo() ? *response.certificateInfo() : CertificateInfo();
     141    m_certificateInfo = *response.certificateInfo();
    142142    if (response.httpStatusCode() == 304 && m_cacheEntry) {
    143143        loadWithCacheEntry(*m_cacheEntry);
  • trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm

    r265063 r265150  
    14721472}
    14731473
    1474 static bool certificatesMatch(SecTrustRef trust1, SecTrustRef trust2)
    1475 {
    1476     if (!trust1 || !trust2)
    1477         return false;
    1478 
    1479     CFIndex count1 = SecTrustGetCertificateCount(trust1);
    1480     CFIndex count2 = SecTrustGetCertificateCount(trust2);
    1481     if (count1 != count2)
    1482         return false;
    1483 
    1484     for (CFIndex i = 0; i < count1; i++) {
    1485         auto cert1 = SecTrustGetCertificateAtIndex(trust1, i);
    1486         auto cert2 = SecTrustGetCertificateAtIndex(trust2, i);
    1487         RELEASE_ASSERT(cert1);
    1488         RELEASE_ASSERT(cert2);
    1489         if (!CFEqual(cert1, cert2))
    1490             return false;
    1491     }
    1492 
    1493     return true;
    1494 }
    1495 
    14961474bool NetworkSessionCocoa::allowsSpecificHTTPSCertificateForHost(const WebCore::AuthenticationChallenge& challenge)
    14971475{
     
    15091487    RetainPtr<SecTrustRef> trust = adoptCF(trustRef);
    15101488
    1511     return certificatesMatch(trust.get(), challenge.nsURLAuthenticationChallenge().protectionSpace.serverTrust);
     1489    return WebCore::certificatesMatch(trust.get(), challenge.nsURLAuthenticationChallenge().protectionSpace.serverTrust);
    15121490}
    15131491
  • trunk/Tools/ChangeLog

    r265149 r265150  
     12020-07-31  Youenn Fablet  <youenn@apple.com>
     2
     3        Update service worker if certificate info does not match when soft updating
     4        https://bugs.webkit.org/show_bug.cgi?id=214988
     5
     6        Reviewed by Alex Christensen.
     7
     8        Update HTTPServer to pass two optional parameters:
     9        - A port number to listen to if provided
     10        - A custom server identity to use if provided
     11
     12        The API test is loading an URL on a first server.
     13        This triggers registration of a service worker.
     14        It then stops this server and launches a second server on the same port with a different certificate.
     15        A second page is loaded on the same URL.
     16        This triggers the case of updating a service worker certificate info.
     17
     18        * TestWebKitAPI/Tests/WebKitCocoa/Challenge.mm:
     19        (createTestIdentity):
     20        (testIdentity):
     21        (testIdentity2):
     22        * TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:
     23        * TestWebKitAPI/cocoa/HTTPServer.h:
     24        * TestWebKitAPI/cocoa/HTTPServer.mm:
     25        (TestWebKitAPI::HTTPServer::listenerParameters):
     26        (TestWebKitAPI::HTTPServer::HTTPServer):
     27
    1282020-07-31  Sihui Liu  <sihui_liu@appe.com>
    229
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/Challenge.mm

    r262985 r265150  
    4444#import <wtf/RetainPtr.h>
    4545#import <wtf/spi/cocoa/SecuritySPI.h>
     46#import <wtf/text/Base64.h>
    4647
    4748static bool navigationFinished;
     
    5354}
    5455
    55 RetainPtr<SecIdentityRef> testIdentity()
    56 {
    57     auto privateKeyBytes = TestWebKitAPI::TCPServer::testPrivateKey();
     56static RetainPtr<SecIdentityRef> createTestIdentity(const Vector<uint8_t>& privateKeyBytes, const Vector<uint8_t>& certificateBytes)
     57{
    5858    NSData *derEncodedPrivateKey = [NSData dataWithBytes:privateKeyBytes.data() length:privateKeyBytes.size()];
    5959    NSDictionary* options = @{
     
    6868    EXPECT_NOT_NULL(privateKey.get());
    6969
    70     return adoptCF(SecIdentityCreate(kCFAllocatorDefault, testCertificate().get(), privateKey.get()));
     70    auto testCertificate = adoptCF(SecCertificateCreateWithData(nullptr, (__bridge CFDataRef)[NSData dataWithBytes:certificateBytes.data() length:certificateBytes.size()]));
     71
     72    return adoptCF(SecIdentityCreate(kCFAllocatorDefault, testCertificate.get(), privateKey.get()));
     73}
     74
     75RetainPtr<SecIdentityRef> testIdentity()
     76{
     77    return createTestIdentity(TestWebKitAPI::TCPServer::testPrivateKey(), TestWebKitAPI::TCPServer::testCertificate());
     78}
     79
     80RetainPtr<SecIdentityRef> testIdentity2()
     81{
     82    // Certificate and private key were generated by running this command:
     83    // openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
     84    // and entering this information:
     85    /*
     86     Country Name (2 letter code) []:US
     87     State or Province Name (full name) []:New Mexico
     88     Locality Name (eg, city) []:Santa Fe
     89     Organization Name (eg, company) []:Self
     90     Organizational Unit Name (eg, section) []:Myself
     91     Common Name (eg, fully qualified host name) []:Me
     92     Email Address []:me@example.com
     93     */
     94
     95    String pemEncodedPrivateKey(""
     96    "MIIJRAIBADANBgkqhkiG9w0BAQEFAASCCS4wggkqAgEAAoICAQDPk42aRXUw186m"
     97    "ZCdhn9S5Az4HNY1QmsS5fz8bD95zQVmjrtApJy7J3NhsA7o3lHE6rFz/SUL2JfnA"
     98    "iMlYrfdbhfP/9xiEg+9EkErm/gE2JJa9wWKQURzVWzmyB/OEHDEMLGdjfkQBvWDi"
     99    "GzBnolMZGAv7XCTJYO7yFonYyPTzmDMeDbbjTVJSF2yfgugf3N2hRHIywVgmUsoq"
     100    "xOAqZNoXGkXMOQxUPC8KS6J62+Qb1NE0QdJ6oONyIEagRdYoXZbsrmPz4s13F2b7"
     101    "QaLevvl6emlJE41SOXTFhO8PN3Qk6w4zmHki8AYwKhacARNJPc7nUPlpTQRW4Kaa"
     102    "VSPHU3Ebr7qyttS/UMiU4Wp7G6aZv/PelqYBcd20pYPkLc1Cm9KX1HlwZ8copKhJ"
     103    "gZRn72l+UMrW0O6zpIKlUy/dVVkiOfi1DZ4HzdtnwsFvc2ILv8aAb5bEqyty9WGZ"
     104    "q+gmWjZl/IJ7rrpDH28vJKbDXoZKlTwK91M1QODlNChieBw7mAJ5EchC09+oNXG0"
     105    "l1pit6gVVtqcoyZivJEM3doS9nJm5scIlVL+hOwQw+OVY9UWLXZeEXS5B70EZu63"
     106    "Q0Q4L+lqypjmir2P6mfoU72uxscZI/5xhAXlN81SAAn7ZHIoj57Zm+8opZ6BHS8E"
     107    "fhdn442Dap6DQPBgmGIEuZ8whSgmbQIDAQABAoICAQCWxHR4VfS9qjHVly8ncEDA"
     108    "tMMr11Cx+AflN7AtRsRq8E9cXQ+ipGwOgJLNOZPa5L2tQR426g5x3Llfh7q+53Sf"
     109    "jFbiVqX/MhjqsudEib91hPPcFYcyjUelDCKG1dGg5h0V23aoxEA/Bz9EWz04OKWk"
     110    "t1uUkaPChN5pBcfPpn6MI8MVFB7/T9z39T2XSiyxX+m2RZGwndAZ3c4rbF3pTOE/"
     111    "IH0LzW/QCvqbvr3gALDZKiVdkGWBXjR1Y04JAVCAdyG0/SFqNhTIaD4LRuw2X32y"
     112    "4RBx3Hqr+0F+aYR9h+ibHANvpFJv9uh3uUo8u2c3rmYGi0Dso90AASHhPO/Eyi1+"
     113    "/yvoqyvyLg3WjPt2CIPGPegc2LSXNS3BL6SKSuhAbyVZzLfJKxwBMi4WXwR0hjw5"
     114    "mc6sqCUiECoIPq3TiOy7X3IPDbDB4gkM1Y3loIq6Wexv2qA0PYjzFXYp4kAEkn+P"
     115    "l++25iE9ZevsYlYTwnGBXzateva6uVLEstdN2MoDcQEgQOIwXkZphttfds+69DEw"
     116    "Ow6TYZ+bGPCLNeZibX7W3ykyBcjjqq4ajtPH0T9ihEjH3IuHCoR5toJyUigXZLIW"
     117    "AczeBHHw6xPKj6ZOGUPpqUgkl0Eo91sjPmjekFyWADFv7ROs796GgcynfI6Gkrud"
     118    "i8sPNO46fCqaPeDz/PO+PQKCAQEA/YzTA25v7ClPRVDc4JdXFYB2ZsYV4fJzp3KP"
     119    "qSVEio59+jDepbEqkJCmxj803pzoOXVv8BGpdSonxQydOAMbGqol+YSMy5xqIRdi"
     120    "06Ku7+maPTp4o7mHoPtRZzD5WfEGMZGedkdDdhYJb0+CiEFcSTRJpdeHo2W54Tqx"
     121    "/xW9VriqQi4O2rL2N2PNp+XpignqJjd9SjAOOweYg2Uln7bVjtXTmIe5PrKNo7b1"
     122    "GuZxRod8EdtK9mk6K6BxLN3XIL1oOzWgpfqhJRV5ZGIKXHPCqt4//aad81FhCcSW"
     123    "wBjEsBppYtDSaLqyWsmj09AIdz5AlASyUv9kuWH9PONJMIcM5wKCAQEA0ZUCY4Ft"
     124    "/91QqaAysmu7UYXl44127K34G22JdmrpiC5Uuyb5LwtFvWb20nx3jR0mcsI+2GDG"
     125    "EguseYt4ZaiRf44oKmy+3ra2Qv2fgFJcbTb0pa0WK1/pBpKXELG9UsT2V8Ye0Tjv"
     126    "PdLJP2tjXHdNc78w4HqIypxpKEfWc7Os77HuQDtzji4A0n4j2JYlgdDOWPv53exs"
     127    "3ZbglX/AV2XrpstuP1/mqSpozlGaHxsqMXMbQbQ/QGolLgQJR7g9nR9mbO5uRS3c"
     128    "vlZmHjZQjBE52EUKAUL+fTdtXSQ+OFSaCro+uIxCLiKrZaJ9+W1lEDGNIjk7YISi"
     129    "u73A5HxuyEkTiwKCAQBUSyksDt8uyF0OUl/cWvQcteSnLlvADnbcyH1yYm1zEwRW"
     130    "1UBwHYJlJXIMnp7ZE5kw4RYh3f1UcnteS19Ja97q8n5Fgge8+XdfIQM+EOvP3v3k"
     131    "NTg+VkP9BRB/Gg0MFdFVUXA5KmAHNjRUyT5ARlqEC9ogRJNXg05Uzsq2X2ffGO2h"
     132    "quZNVwn8SDXrB8iol7s8kV4Z9/gDL/dIV6w2ePZu0i/SmezAJ2RndT/vfYVTSV+6"
     133    "IAm/+iPYtTJrFCWdQNsSNDYAeF5ykb0V3nJLYkDpxZHIpkgEyJ1WPgFQQ+vAEEfR"
     134    "DlOldcwt2rOYi6UE37FghF80sKuv5h/myjle5McpAoIBAQCtdIXllNlVSfXYbZ2H"
     135    "zWHattbs3cfvWoxdJur99r4Q10eJHVhedxXhC7Z7vkezosyPbfRVYMKNbNvyPFwI"
     136    "xtqklyLm+dl+ufleuEmqCoA0Y6dW90nB3D8gEXK1fmUSe7DmNDKNNnHK2Ql2U4qI"
     137    "nLSddz8cik1sYsclb08tsycNulVVE98vbSOBEqTYPGwOZKJjQygpY+M2Agkdsf2e"
     138    "V9wQz40PJm/g0hirqR3FYNYq1vlYB7XRugfLbcvAb9uOjs5WmX7qAmsPnLInjwxa"
     139    "4Gbfd0QwhyHYwGbjD3vvYxWai0odsveS916jXzijlsZuAJSuHm/mEeAdQY7Di7ik"
     140    "StbBAoIBAQDpceQhclaiLfcyYrL0kj51K8ntLDfqOWIHEpQ2Ol8P4nJmSAtUqK3p"
     141    "BDEmVTybsiwHd7slTjGdaZ5jHKvTNF0fcAe853IYol1FTyD6tV13kukbq88Gh+xy"
     142    "miK1TXtLlWN06r43anQqZyRbu5IoHmHAybpk4Stq29wOSBoZdyarQWkloyiYJKdX"
     143    "oDdkKF8cwoBeAeiRLkT45stRNklBg4VlgCFELPOcWYMFOoSkQg19VS/VaHi48t+z"
     144    "668Bn1U3U9d/iNCXFM78iKqoJCBoURyirmG/tI6gfJiLn05Tz6nYz31Y40Fm1Swg"
     145    "hgOy/TdJO/NjmTHBgpITP6lv69QvaV9z");
     146
     147    String pemEncodedCertificate(""
     148    "MIIFgDCCA2gCCQD+QY1JRnM3IjANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMC"
     149    "VVMxEzARBgNVBAgMCk5ldyBNZXhpY28xETAPBgNVBAcMCFNhbnRhIEZlMQ0wCwYD"
     150    "VQQKDARTZWxmMQ8wDQYDVQQLDAZNeXNlbGYxCzAJBgNVBAMMAk1lMR0wGwYJKoZI"
     151    "hvcNAQkBFg5tZUBleGFtcGxlLmNvbTAeFw0yMDA3MzEwODU2MDZaFw0yMTA3MzEw"
     152    "ODU2MDZaMIGBMQswCQYDVQQGEwJVUzETMBEGA1UECAwKTmV3IE1leGljbzERMA8G"
     153    "A1UEBwwIU2FudGEgRmUxDTALBgNVBAoMBFNlbGYxDzANBgNVBAsMBk15c2VsZjEL"
     154    "MAkGA1UEAwwCTWUxHTAbBgkqhkiG9w0BCQEWDm1lQGV4YW1wbGUuY29tMIICIjAN"
     155    "BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAz5ONmkV1MNfOpmQnYZ/UuQM+BzWN"
     156    "UJrEuX8/Gw/ec0FZo67QKScuydzYbAO6N5RxOqxc/0lC9iX5wIjJWK33W4Xz//cY"
     157    "hIPvRJBK5v4BNiSWvcFikFEc1Vs5sgfzhBwxDCxnY35EAb1g4hswZ6JTGRgL+1wk"
     158    "yWDu8haJ2Mj085gzHg22401SUhdsn4LoH9zdoURyMsFYJlLKKsTgKmTaFxpFzDkM"
     159    "VDwvCkuietvkG9TRNEHSeqDjciBGoEXWKF2W7K5j8+LNdxdm+0Gi3r75enppSRON"
     160    "Ujl0xYTvDzd0JOsOM5h5IvAGMCoWnAETST3O51D5aU0EVuCmmlUjx1NxG6+6srbU"
     161    "v1DIlOFqexummb/z3pamAXHdtKWD5C3NQpvSl9R5cGfHKKSoSYGUZ+9pflDK1tDu"
     162    "s6SCpVMv3VVZIjn4tQ2eB83bZ8LBb3NiC7/GgG+WxKsrcvVhmavoJlo2ZfyCe666"
     163    "Qx9vLySmw16GSpU8CvdTNUDg5TQoYngcO5gCeRHIQtPfqDVxtJdaYreoFVbanKMm"
     164    "YryRDN3aEvZyZubHCJVS/oTsEMPjlWPVFi12XhF0uQe9BGbut0NEOC/pasqY5oq9"
     165    "j+pn6FO9rsbHGSP+cYQF5TfNUgAJ+2RyKI+e2ZvvKKWegR0vBH4XZ+ONg2qeg0Dw"
     166    "YJhiBLmfMIUoJm0CAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAnH5sdBRTyZEiI9bt"
     167    "umxSkOsk93V+CxkXl74vm2sjlk3Je3UBFk+QYO9RcbAsM5Olsu8pzAnUJAMhvQZP"
     168    "xU2CzFAZdNiL1CYEwPKXC7bGwfVrVoIdLHkIhuHOO/5G/KazwTTNrfigEqAONrnr"
     169    "SHSfaWKy6jpJFRMH28llMFK5Ev4USfDhKZXOB0blprX9Rh2NDgahhNKhWlRBO3/g"
     170    "L1yW1YOYCMdkV2dOoZEzY4eBG34mCgS72EI8OJYBPVKGtTXD6cPzuf5rW8ueHvEA"
     171    "DzeBr5E88UpLvFPGfkKdzSH/KOUXUWLW9lmLVPXrL5Jfvc1taVXhveUNIR2vn/ID"
     172    "LPxlSBKD44Wi989MdehZbI7//rP9S8eZZPKotUUx89epjCRsjmkGcNsjQenTV5B9"
     173    "lyrsbh99vifR8WsZp5F1aEcmPdWMMZM5pZLPk+ODvTcdqnbcUH4mKVgyq8CM9tiY"
     174    "46izhou3GSKz3X1eYpYbZHF52dxmOUdvpSoqfmlMF1Egv94crD1xh9asdjg2DnXc"
     175    "948YxPaFjoOGd6Ync+fv9pJzjTjximbIiWm2r6yt2j9hAuKJXpNOIa4oIMAIGjCi"
     176    "JAH2nxKGuqtAK2hWbACu61RT5gAqAv/hB9JYnc2OiQ2VmjYkOk2GEdIjn0xSgX7W"
     177    "mI/hHbxKMG3Rkv9q1Cx+WB/v1t8=");
     178
     179    Vector<uint8_t> privateKeyBytes;
     180    base64Decode(pemEncodedPrivateKey, privateKeyBytes, WTF::Base64DecodeOptions::Base64Default);
     181
     182    Vector<uint8_t> certificateBytes;
     183    base64Decode(pemEncodedCertificate, certificateBytes, WTF::Base64DecodeOptions::Base64Default);
     184
     185    return createTestIdentity(privateKeyBytes, certificateBytes);
    71186}
    72187
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm

    r264724 r265150  
    22242224}
    22252225
     2226TEST(ServiceWorkers, ChangeOfServerCertificate)
     2227{
     2228    __block bool removedAnyExistingData = false;
     2229    [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() {
     2230        removedAnyExistingData = true;
     2231    }];
     2232    TestWebKitAPI::Util::run(&removedAnyExistingData);
     2233
     2234    static const char* main =
     2235    "<script>"
     2236    "async function test() {"
     2237    "    try {"
     2238    "        const registration = await navigator.serviceWorker.register('/sw.js');"
     2239    "        if (registration.active) {"
     2240    "            registration.onupdatefound = () => alert('new worker');"
     2241    "            setTimeout(() => alert('no update found'), 5000);"
     2242    "            return;"
     2243    "        }"
     2244    "        worker = registration.installing;"
     2245    "        worker.addEventListener('statechange', () => {"
     2246    "            if (worker.state == 'activated')"
     2247    "                alert('successfully registered');"
     2248    "        });"
     2249    "    } catch(e) {"
     2250    "        alert('Exception: ' + e);"
     2251    "    }"
     2252    "}"
     2253    "window.onload = test;"
     2254    "</script>";
     2255    static const char* js = "";
     2256
     2257    auto delegate = adoptNS([TestNavigationDelegate new]);
     2258    [delegate setDidReceiveAuthenticationChallenge:^(WKWebView *, NSURLAuthenticationChallenge *challenge, void (^callback)(NSURLSessionAuthChallengeDisposition, NSURLCredential *)) {
     2259        EXPECT_WK_STREQ(challenge.protectionSpace.authenticationMethod, NSURLAuthenticationMethodServerTrust);
     2260        callback(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
     2261    }];
     2262
     2263    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     2264    auto webView1 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
     2265    auto webView2 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
     2266
     2267    webView1.get().navigationDelegate = delegate.get();
     2268    webView2.get().navigationDelegate = delegate.get();
     2269
     2270    uint16_t serverPort;
     2271
     2272    // Load webView1 with a first server.
     2273    {
     2274        TestWebKitAPI::HTTPServer server1({
     2275            { "/", { main } },
     2276            { "/sw.js", { {{ "Content-Type", "application/javascript" }}, js } }
     2277        }, TestWebKitAPI::HTTPServer::Protocol::Https, nullptr, testIdentity());
     2278        serverPort = server1.port();
     2279
     2280        [webView1 loadRequest:server1.request()];
     2281        EXPECT_WK_STREQ([webView1 _test_waitForAlert], "successfully registered");
     2282
     2283        server1.cancel();
     2284    }
     2285
     2286    // Load webView2 with a second server on same port with a different certificate
     2287    // This should trigger installing a new worker.
     2288    {
     2289        TestWebKitAPI::HTTPServer server2({
     2290            { "/", { main } },
     2291            { "/sw.js", { {{ "Content-Type", "application/javascript" }}, js } }
     2292        }, TestWebKitAPI::HTTPServer::Protocol::Https, nullptr, testIdentity2(), serverPort);
     2293
     2294        [webView2 loadRequest:server2.request()];
     2295        EXPECT_WK_STREQ([webView2 _test_waitForAlert], "new worker");
     2296    }
     2297}
     2298
    22262299#endif // HAVE(NETWORK_FRAMEWORK) && HAVE(TLS_PROTOCOL_VERSION_T)
  • trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.h

    r264687 r265150  
    4747    using CertificateVerifier = Function<void(sec_protocol_metadata_t, sec_trust_t, sec_protocol_verify_complete_t)>;
    4848
    49     HTTPServer(std::initializer_list<std::pair<String, HTTPResponse>>, Protocol = Protocol::Http, CertificateVerifier&& = nullptr);
     49    HTTPServer(std::initializer_list<std::pair<String, HTTPResponse>>, Protocol = Protocol::Http, CertificateVerifier&& = nullptr, RetainPtr<SecIdentityRef>&& = nullptr, Optional<uint16_t> port = { });
    5050    HTTPServer(Function<void(Connection)>&&, Protocol = Protocol::Http);
    5151    ~HTTPServer();
     
    5858   
    5959private:
    60     static RetainPtr<nw_parameters_t> listenerParameters(Protocol, CertificateVerifier&&);
     60    static RetainPtr<nw_parameters_t> listenerParameters(Protocol, CertificateVerifier&&, RetainPtr<SecIdentityRef>&&, Optional<uint16_t> port);
    6161    static void respondToRequests(Connection, Ref<RequestData>);
    6262
     
    171171
    172172RetainPtr<SecIdentityRef> testIdentity();
     173RetainPtr<SecIdentityRef> testIdentity2();
  • trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.mm

    r264687 r265150  
    5353};
    5454
    55 RetainPtr<nw_parameters_t> HTTPServer::listenerParameters(Protocol protocol, CertificateVerifier&& verifier)
    56 {
    57     auto configureTLS = protocol == Protocol::Http ? makeBlockPtr(NW_PARAMETERS_DISABLE_PROTOCOL) : makeBlockPtr([protocol, verifier = WTFMove(verifier)] (nw_protocol_options_t protocolOptions) mutable {
     55RetainPtr<nw_parameters_t> HTTPServer::listenerParameters(Protocol protocol, CertificateVerifier&& verifier, RetainPtr<SecIdentityRef>&& customTestIdentity, Optional<uint16_t> port)
     56{
     57    if (protocol != Protocol::Http && !customTestIdentity)
     58        customTestIdentity = testIdentity();
     59    auto configureTLS = protocol == Protocol::Http ? makeBlockPtr(NW_PARAMETERS_DISABLE_PROTOCOL) : makeBlockPtr([protocol, verifier = WTFMove(verifier), testIdentity = WTFMove(customTestIdentity)] (nw_protocol_options_t protocolOptions) mutable {
    5860#if HAVE(TLS_PROTOCOL_VERSION_T)
    5961        auto options = adoptNS(nw_tls_copy_sec_protocol_options(protocolOptions));
    60         auto identity = adoptNS(sec_identity_create(testIdentity().get()));
     62        auto identity = adoptNS(sec_identity_create(testIdentity.get()));
    6163        sec_protocol_options_set_local_identity(options.get(), identity.get());
    6264        if (protocol == Protocol::HttpsWithLegacyTLS)
     
    7577#endif
    7678    });
    77     return adoptNS(nw_parameters_create_secure_tcp(configureTLS.get(), NW_PARAMETERS_DEFAULT_CONFIGURATION));
     79    auto parameters = adoptNS(nw_parameters_create_secure_tcp(configureTLS.get(), NW_PARAMETERS_DEFAULT_CONFIGURATION));
     80    if (port)
     81        nw_parameters_set_local_endpoint(parameters.get(), nw_endpoint_create_host("::", makeString(*port).utf8().data()));
     82    return parameters;
    7883}
    7984
     
    105110}
    106111
    107 HTTPServer::HTTPServer(std::initializer_list<std::pair<String, HTTPResponse>> responses, Protocol protocol, CertificateVerifier&& verifier)
     112HTTPServer::HTTPServer(std::initializer_list<std::pair<String, HTTPResponse>> responses, Protocol protocol, CertificateVerifier&& verifier, RetainPtr<SecIdentityRef>&& identity, Optional<uint16_t> port)
    108113    : m_requestData(adoptRef(*new RequestData(responses)))
    109     , m_listener(adoptNS(nw_listener_create(listenerParameters(protocol, WTFMove(verifier)).get())))
     114    , m_listener(adoptNS(nw_listener_create(listenerParameters(protocol, WTFMove(verifier), WTFMove(identity), port).get())))
    110115    , m_protocol(protocol)
    111116{
     
    122127HTTPServer::HTTPServer(Function<void(Connection)>&& connectionHandler, Protocol protocol)
    123128    : m_requestData(adoptRef(*new RequestData({ })))
    124     , m_listener(adoptNS(nw_listener_create(listenerParameters(protocol, nullptr).get())))
     129    , m_listener(adoptNS(nw_listener_create(listenerParameters(protocol, nullptr, nullptr, { }).get())))
    125130    , m_protocol(protocol)
    126131{
Note: See TracChangeset for help on using the changeset viewer.