/*
 * Copyright (C) 2019 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#import "config.h"

#import "HTTPServer.h"
#import "PlatformUtilities.h"
#import "Test.h"
#import "TestNavigationDelegate.h"
#import "TestWKWebView.h"
#import "WKWebViewConfigurationExtras.h"
#import <WebKit/WKNavigationDelegate.h>
#import <WebKit/WKProcessPoolPrivate.h>
#import <WebKit/WKWebsiteDataRecordPrivate.h>
#import <WebKit/WKWebsiteDataStorePrivate.h>
#import <WebKit/WebKit.h>
#import <WebKit/_WKErrorRecoveryAttempting.h>
#import <WebKit/_WKWebsiteDataStoreConfiguration.h>
#import <wtf/BlockPtr.h>
#import <wtf/Platform.h>
#import <wtf/RetainPtr.h>
#import <wtf/spi/cocoa/SecuritySPI.h>
#import <wtf/text/Base64.h>

static bool navigationFinished;

RetainPtr<SecCertificateRef> testCertificate()
{
    auto certificateBytes = TestWebKitAPI::HTTPServer::testCertificate();
    return adoptCF(SecCertificateCreateWithData(nullptr, (__bridge CFDataRef)[NSData dataWithBytes:certificateBytes.data() length:certificateBytes.size()]));
}

static RetainPtr<SecIdentityRef> createTestIdentity(const Vector<uint8_t>& privateKeyBytes, const Vector<uint8_t>& certificateBytes)
{
    NSData *derEncodedPrivateKey = [NSData dataWithBytes:privateKeyBytes.data() length:privateKeyBytes.size()];
    NSDictionary* options = @{
        (id)kSecAttrKeyType: (id)kSecAttrKeyTypeRSA,
        (id)kSecAttrKeyClass: (id)kSecAttrKeyClassPrivate,
        (id)kSecAttrKeySizeInBits: @4096,
    };
    const NSUInteger pemEncodedPrivateKeyHeaderLength = 26;
    CFErrorRef error = nullptr;
    auto privateKey = adoptCF(SecKeyCreateWithData((__bridge CFDataRef)[derEncodedPrivateKey subdataWithRange:NSMakeRange(pemEncodedPrivateKeyHeaderLength, derEncodedPrivateKey.length - pemEncodedPrivateKeyHeaderLength)], (__bridge CFDictionaryRef)options, &error));
    EXPECT_NULL(error);
    EXPECT_NOT_NULL(privateKey.get());

    auto testCertificate = adoptCF(SecCertificateCreateWithData(nullptr, (__bridge CFDataRef)[NSData dataWithBytes:certificateBytes.data() length:certificateBytes.size()]));

    return adoptCF(SecIdentityCreate(kCFAllocatorDefault, testCertificate.get(), privateKey.get()));
}

RetainPtr<SecIdentityRef> testIdentity()
{
    return createTestIdentity(TestWebKitAPI::HTTPServer::testPrivateKey(), TestWebKitAPI::HTTPServer::testCertificate());
}

RetainPtr<SecIdentityRef> testIdentity2()
{
    // Certificate and private key were generated by running this command:
    // openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
    // and entering this information:
    /*
     Country Name (2 letter code) []:US
     State or Province Name (full name) []:New Mexico
     Locality Name (eg, city) []:Santa Fe
     Organization Name (eg, company) []:Self
     Organizational Unit Name (eg, section) []:Myself
     Common Name (eg, fully qualified host name) []:Me
     Email Address []:me@example.com
     */

    String pemEncodedPrivateKey(""
    "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"
    "hgOy/TdJO/NjmTHBgpITP6lv69QvaV9z");

    String pemEncodedCertificate(""
    "MIIFgDCCA2gCCQD+QY1JRnM3IjANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMC"
    "VVMxEzARBgNVBAgMCk5ldyBNZXhpY28xETAPBgNVBAcMCFNhbnRhIEZlMQ0wCwYD"
    "VQQKDARTZWxmMQ8wDQYDVQQLDAZNeXNlbGYxCzAJBgNVBAMMAk1lMR0wGwYJKoZI"
    "hvcNAQkBFg5tZUBleGFtcGxlLmNvbTAeFw0yMDA3MzEwODU2MDZaFw0yMTA3MzEw"
    "ODU2MDZaMIGBMQswCQYDVQQGEwJVUzETMBEGA1UECAwKTmV3IE1leGljbzERMA8G"
    "A1UEBwwIU2FudGEgRmUxDTALBgNVBAoMBFNlbGYxDzANBgNVBAsMBk15c2VsZjEL"
    "MAkGA1UEAwwCTWUxHTAbBgkqhkiG9w0BCQEWDm1lQGV4YW1wbGUuY29tMIICIjAN"
    "BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAz5ONmkV1MNfOpmQnYZ/UuQM+BzWN"
    "UJrEuX8/Gw/ec0FZo67QKScuydzYbAO6N5RxOqxc/0lC9iX5wIjJWK33W4Xz//cY"
    "hIPvRJBK5v4BNiSWvcFikFEc1Vs5sgfzhBwxDCxnY35EAb1g4hswZ6JTGRgL+1wk"
    "yWDu8haJ2Mj085gzHg22401SUhdsn4LoH9zdoURyMsFYJlLKKsTgKmTaFxpFzDkM"
    "VDwvCkuietvkG9TRNEHSeqDjciBGoEXWKF2W7K5j8+LNdxdm+0Gi3r75enppSRON"
    "Ujl0xYTvDzd0JOsOM5h5IvAGMCoWnAETST3O51D5aU0EVuCmmlUjx1NxG6+6srbU"
    "v1DIlOFqexummb/z3pamAXHdtKWD5C3NQpvSl9R5cGfHKKSoSYGUZ+9pflDK1tDu"
    "s6SCpVMv3VVZIjn4tQ2eB83bZ8LBb3NiC7/GgG+WxKsrcvVhmavoJlo2ZfyCe666"
    "Qx9vLySmw16GSpU8CvdTNUDg5TQoYngcO5gCeRHIQtPfqDVxtJdaYreoFVbanKMm"
    "YryRDN3aEvZyZubHCJVS/oTsEMPjlWPVFi12XhF0uQe9BGbut0NEOC/pasqY5oq9"
    "j+pn6FO9rsbHGSP+cYQF5TfNUgAJ+2RyKI+e2ZvvKKWegR0vBH4XZ+ONg2qeg0Dw"
    "YJhiBLmfMIUoJm0CAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAnH5sdBRTyZEiI9bt"
    "umxSkOsk93V+CxkXl74vm2sjlk3Je3UBFk+QYO9RcbAsM5Olsu8pzAnUJAMhvQZP"
    "xU2CzFAZdNiL1CYEwPKXC7bGwfVrVoIdLHkIhuHOO/5G/KazwTTNrfigEqAONrnr"
    "SHSfaWKy6jpJFRMH28llMFK5Ev4USfDhKZXOB0blprX9Rh2NDgahhNKhWlRBO3/g"
    "L1yW1YOYCMdkV2dOoZEzY4eBG34mCgS72EI8OJYBPVKGtTXD6cPzuf5rW8ueHvEA"
    "DzeBr5E88UpLvFPGfkKdzSH/KOUXUWLW9lmLVPXrL5Jfvc1taVXhveUNIR2vn/ID"
    "LPxlSBKD44Wi989MdehZbI7//rP9S8eZZPKotUUx89epjCRsjmkGcNsjQenTV5B9"
    "lyrsbh99vifR8WsZp5F1aEcmPdWMMZM5pZLPk+ODvTcdqnbcUH4mKVgyq8CM9tiY"
    "46izhou3GSKz3X1eYpYbZHF52dxmOUdvpSoqfmlMF1Egv94crD1xh9asdjg2DnXc"
    "948YxPaFjoOGd6Ync+fv9pJzjTjximbIiWm2r6yt2j9hAuKJXpNOIa4oIMAIGjCi"
    "JAH2nxKGuqtAK2hWbACu61RT5gAqAv/hB9JYnc2OiQ2VmjYkOk2GEdIjn0xSgX7W"
    "mI/hHbxKMG3Rkv9q1Cx+WB/v1t8=");

    auto privateKeyBytes = base64Decode(pemEncodedPrivateKey);
    auto certificateBytes = base64Decode(pemEncodedCertificate);

    return createTestIdentity(WTFMove(*privateKeyBytes), WTFMove(*certificateBytes));
}

static RetainPtr<NSURLCredential> credentialWithIdentity()
{
    auto identity = testIdentity();
    EXPECT_NOT_NULL(identity);
    
    return [NSURLCredential credentialWithIdentity:identity.get() certificates:@[(id)testCertificate().get()] persistence:NSURLCredentialPersistenceNone];
}

@interface ChallengeDelegate : NSObject <WKNavigationDelegate>
@end

@implementation ChallengeDelegate

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
    navigationFinished = true;
}

- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler
{
    NSURLProtectionSpace *protectionSpace = challenge.protectionSpace;
    EXPECT_NULL(challenge.proposedCredential);
    EXPECT_EQ(challenge.previousFailureCount, 0);
    EXPECT_TRUE([protectionSpace.realm isEqualToString:@"testrealm"]);
    EXPECT_FALSE(protectionSpace.receivesCredentialSecurely);
    EXPECT_FALSE(protectionSpace.isProxy);
    EXPECT_TRUE([protectionSpace.host isEqualToString:@"127.0.0.1"]);
    EXPECT_NULL(protectionSpace.proxyType);
    EXPECT_TRUE([protectionSpace.protocol isEqualToString:NSURLProtectionSpaceHTTP]);
    EXPECT_TRUE([protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic]);
    EXPECT_EQ([(NSHTTPURLResponse *)challenge.failureResponse statusCode], 401);

    completionHandler(NSURLSessionAuthChallengeUseCredential, credentialWithIdentity().get());
}

@end

TEST(Challenge, SecIdentity)
{
    using namespace TestWebKitAPI;
    HTTPServer server(HTTPServer::respondWithChallengeThenOK);

    auto webView = adoptNS([WKWebView new]);
    auto delegate = adoptNS([ChallengeDelegate new]);
    [webView setNavigationDelegate:delegate.get()];

    // Make sure no credential left by previous tests.
    auto protectionSpace = adoptNS([[NSURLProtectionSpace alloc] initWithHost:@"127.0.0.1" port:server.port() protocol:NSURLProtectionSpaceHTTP realm:@"testrealm" authenticationMethod:NSURLAuthenticationMethodHTTPBasic]);
    [[webView configuration].processPool _clearPermanentCredentialsForProtectionSpace:protectionSpace.get()];

    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://127.0.0.1:%d/", server.port()]]]];

    Util::run(&navigationFinished);
}

TEST(Challenge, DeallocateDuringChallenge)
{
    using namespace TestWebKitAPI;
    HTTPServer server({{ "/", { "hi" }}}, HTTPServer::Protocol::Https);

    auto delegate = adoptNS([TestNavigationDelegate new]);
    delegate.get().didReceiveAuthenticationChallenge = ^(WKWebView *, NSURLAuthenticationChallenge *challenge, void (^completionHandler)(NSURLSessionAuthChallengeDisposition, NSURLCredential *)) {
        completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
    };

    @autoreleasepool {
        Vector<RetainPtr<WKWebView>> views;
        for (size_t i = 0; i < 100; i++)
            views.append(adoptNS([WKWebView new]));
        for (auto& view : views) {
            [view setNavigationDelegate:delegate.get()];
            [view loadRequest:server.request()];
        }
        Util::spinRunLoop(10);
    }
    Util::spinRunLoop(1000);
}

@interface ClientCertificateDelegate : NSObject <WKNavigationDelegate> {
    Vector<RetainPtr<NSString>> _authenticationMethods;
}
- (const Vector<RetainPtr<NSString>>&)authenticationMethods;
@end

@implementation ClientCertificateDelegate

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
    navigationFinished = true;
}

- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler
{
    _authenticationMethods.append(challenge.protectionSpace.authenticationMethod);

    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
        return completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
    
    EXPECT_TRUE([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodClientCertificate]);
    completionHandler(NSURLSessionAuthChallengeUseCredential, credentialWithIdentity().get());
}

- (const Vector<RetainPtr<NSString>>&)authenticationMethods
{
    return _authenticationMethods;
}

@end

#if HAVE(SEC_KEY_PROXY)
TEST(Challenge, ClientCertificate)
{
    using namespace TestWebKitAPI;
    HTTPServer server({ { "/", { "hello" } } }, HTTPServer::Protocol::Https, [](sec_protocol_metadata_t, sec_trust_t, sec_protocol_verify_complete_t complete) {
        complete(true);
    });

    auto webView = adoptNS([WKWebView new]);
    auto delegate = adoptNS([ClientCertificateDelegate new]);
    [webView setNavigationDelegate:delegate.get()];
    [webView loadRequest:server.request()];
    
    Util::run(&navigationFinished);
    auto& methods = [delegate authenticationMethods];
    EXPECT_EQ(methods.size(), 2ull);
    EXPECT_TRUE([methods[0] isEqualToString:NSURLAuthenticationMethodServerTrust]);
    EXPECT_TRUE([methods[1] isEqualToString:NSURLAuthenticationMethodClientCertificate]);
}
#endif

static bool receivedSecondChallenge;
static RetainPtr<NSURLCredential> persistentCredential;

@interface ProposedCredentialDelegate : NSObject <WKNavigationDelegate>
@end

@implementation ProposedCredentialDelegate

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
    navigationFinished = true;
}

- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler
{
    static bool firstChallenge = true;
    if (firstChallenge) {
        firstChallenge = false;
        persistentCredential = adoptNS([[NSURLCredential alloc] initWithUser:@"testuser" password:@"testpassword" persistence:NSURLCredentialPersistencePermanent]);
        return completionHandler(NSURLSessionAuthChallengeUseCredential, persistentCredential.get());
        
    }
    receivedSecondChallenge = true;
    return completionHandler(NSURLSessionAuthChallengeUseCredential, nil);
}

@end

TEST(Challenge, BasicProposedCredential)
{
    using namespace TestWebKitAPI;
    HTTPServer server(HTTPServer::respondWithChallengeThenOK);
    auto configuration = retainPtr([WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BasicProposedCredentialPlugIn"]);
    auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
    auto delegate = adoptNS([ProposedCredentialDelegate new]);
    [webView setNavigationDelegate:delegate.get()];

    // Make sure no credential left by previous tests.
    auto protectionSpace = adoptNS([[NSURLProtectionSpace alloc] initWithHost:@"127.0.0.1" port:server.port() protocol:NSURLProtectionSpaceHTTP realm:@"testrealm" authenticationMethod:NSURLAuthenticationMethodHTTPBasic]);
    [[webView configuration].processPool _clearPermanentCredentialsForProtectionSpace:protectionSpace.get()];

    RetainPtr<NSURLRequest> request = server.request();
    [webView loadRequest:request.get()];
    Util::run(&navigationFinished);
    navigationFinished = false;
    [webView loadRequest:request.get()];
    Util::run(&navigationFinished);
    EXPECT_TRUE(receivedSecondChallenge);

    // Clear persistent credentials created by this test.
    [[webView configuration].processPool _clearPermanentCredentialsForProtectionSpace:protectionSpace.get()];
}

TEST(Challenge, BasicPersistentCredential)
{
    using namespace TestWebKitAPI;
    HTTPServer server(HTTPServer::respondWithChallengeThenOK);
    auto delegate = adoptNS([TestNavigationDelegate new]);
    __block RetainPtr<NSURLProtectionSpace> protectionSpace;
    auto credentialStorage = [NSURLCredentialStorage sharedCredentialStorage];
    delegate.get().didReceiveAuthenticationChallenge = ^(WKWebView *, NSURLAuthenticationChallenge *challenge, void (^completionHandler)(NSURLSessionAuthChallengeDisposition, NSURLCredential *)) {
        protectionSpace = challenge.protectionSpace;
        NSURLCredential *existingCredential = [credentialStorage defaultCredentialForProtectionSpace:protectionSpace.get()];
        EXPECT_NULL(existingCredential);
        EXPECT_WK_STREQ(protectionSpace.get().authenticationMethod, NSURLAuthenticationMethodHTTPBasic);
        completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialWithUser:@"testuser" password:@"testpassword" persistence:NSURLCredentialPersistencePermanent]);
    };
    auto webView = adoptNS([WKWebView new]);
    webView.get().navigationDelegate = delegate.get();
    [webView loadRequest:server.request()];
    [delegate waitForDidFinishNavigation];

    NSURLCredential *storedCredential = nil;
    while (!storedCredential) {
        storedCredential = [[NSURLCredentialStorage sharedCredentialStorage] defaultCredentialForProtectionSpace:protectionSpace.get()];
        Util::spinRunLoop();
    }
    EXPECT_NOT_NULL(storedCredential);
    EXPECT_WK_STREQ(storedCredential.user, "testuser");
    EXPECT_WK_STREQ(storedCredential.password, "testpassword");
    EXPECT_EQ(storedCredential.persistence, NSURLCredentialPersistencePermanent);

    [credentialStorage removeCredential:storedCredential forProtectionSpace:protectionSpace.get()];
    NSURLCredential *removedCredential = [credentialStorage defaultCredentialForProtectionSpace:protectionSpace.get()];
    EXPECT_NULL(removedCredential);
}

static void verifyCertificateAndPublicKey(SecTrustRef trust)
{
    EXPECT_NOT_NULL(trust);

    auto compareData = [] (const RetainPtr<CFDataRef>& data, const Vector<uint8_t>& expected) {
        size_t length = CFDataGetLength(data.get());
        EXPECT_EQ(length, expected.size());
        if (length != expected.size())
            return;
        const UInt8* bytes = CFDataGetBytePtr(data.get());
        for (size_t i = 0; i < length; ++i)
            EXPECT_EQ(expected[i], bytes[i]);
    };

    auto publicKey = adoptCF(SecKeyCopyExternalRepresentation(adoptCF(SecTrustCopyPublicKey(trust)).get(), nullptr));
    compareData(publicKey, {
        0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xde, 0xb8, 0x4d, 0xe1, 0x23, 0xe0, 0xf1,
        0x56, 0x3f, 0x3e, 0xd1, 0x83, 0x34, 0xa6, 0x37, 0x4f, 0xd2, 0x48, 0x4a, 0x06, 0xf2, 0xf1, 0x81,
        0x8c, 0x27, 0x1d, 0x2f, 0x3b, 0xe6, 0x19, 0x15, 0x99, 0xb7, 0x1b, 0x77, 0xec, 0x4d, 0x4b, 0x32,
        0xbc, 0x3c, 0x84, 0x1f, 0x0a, 0xa9, 0xe5, 0xa6, 0xc2, 0x65, 0x10, 0x7f, 0x07, 0x2d, 0x4f, 0xc1,
        0x69, 0x0d, 0xad, 0xfc, 0x67, 0xfd, 0x73, 0xfc, 0x3f, 0x4d, 0xf8, 0x24, 0xf9, 0x44, 0xea, 0x2a,
        0xd5, 0x8a, 0xe0, 0x18, 0x42, 0xba, 0x94, 0x87, 0xa9, 0x3b, 0x65, 0x1f, 0x02, 0xa4, 0xe3, 0x39,
        0x18, 0x47, 0x11, 0x66, 0x00, 0x14, 0x24, 0x61, 0x90, 0xc0, 0xd9, 0x4e, 0x90, 0x4c, 0x1a, 0x1e,
        0x73, 0x06, 0x73, 0xc4, 0xac, 0x1e, 0xea, 0xe0, 0x0c, 0xf8, 0x79, 0x5c, 0x1a, 0x60, 0x6c, 0x3c,
        0xad, 0x77, 0xb0, 0x49, 0xb8, 0x1d, 0x4d, 0xa0, 0x8f, 0xca, 0x26, 0x68, 0x5c, 0x6a, 0x39, 0x00,
        0xb9, 0x5d, 0xef, 0x6a, 0xb4, 0xbe, 0xb8, 0xf2, 0xe8, 0x7c, 0xf1, 0xcd, 0xa9, 0xef, 0x9c, 0x2f,
        0xc8, 0x4d, 0x9e, 0x36, 0x50, 0xc0, 0x75, 0x9a, 0xac, 0xfe, 0x39, 0x92, 0xce, 0x1e, 0x05, 0xc3,
        0x83, 0xee, 0xdc, 0x2a, 0xc6, 0xe1, 0xe7, 0x56, 0x6f, 0xc5, 0x58, 0x4a, 0xe9, 0x63, 0xc5, 0xac,
        0xe6, 0xcd, 0x4c, 0xac, 0xf4, 0xe1, 0x51, 0xd0, 0xda, 0x86, 0x31, 0x0c, 0x7f, 0xe6, 0x1f, 0x0c,
        0x9f, 0x4a, 0x2f, 0xcc, 0xb7, 0xd3, 0x8c, 0x92, 0xf0, 0x9f, 0x1f, 0x78, 0x2c, 0x58, 0x7d, 0xc1,
        0xf8, 0x06, 0xf8, 0x0b, 0xb4, 0x99, 0x81, 0x34, 0x72, 0x60, 0x8f, 0x77, 0x8d, 0x0f, 0xf1, 0x0c,
        0x66, 0x32, 0x60, 0xcf, 0x61, 0x6c, 0x06, 0x3a, 0xc9, 0x93, 0xc9, 0x0a, 0x0f, 0x7d, 0x5c, 0xc3,
        0xee, 0x16, 0xa7, 0xc5, 0x05, 0xe2, 0xc9, 0x16, 0x5c, 0x27, 0xf8, 0xeb, 0xe9, 0x8d, 0x38, 0x7a,
        0x75, 0xdc, 0xf7, 0x92, 0x09, 0x92, 0xf2, 0x17, 0x86, 0x40, 0x1d, 0xac, 0xd4, 0x56, 0x49, 0xc3,
        0x3d, 0xc7, 0x36, 0x60, 0xda, 0xd6, 0x55, 0x5d, 0x62, 0xea, 0x7d, 0xd3, 0xd7, 0x99, 0x08, 0xd1,
        0x3e, 0x59, 0xed, 0xbb, 0x2d, 0x76, 0x60, 0x0b, 0xb9, 0x29, 0x04, 0xd9, 0xcb, 0x89, 0x49, 0x53,
        0x4e, 0xea, 0x04, 0x7e, 0x66, 0xc5, 0x51, 0x4e, 0x77, 0xae, 0x43, 0x1c, 0x16, 0x4d, 0x4d, 0x0c,
        0x34, 0x48, 0x40, 0x3c, 0x53, 0x97, 0xd8, 0x18, 0x46, 0x3f, 0x97, 0xa2, 0xb2, 0x01, 0x14, 0xce,
        0x49, 0xf1, 0x30, 0x97, 0x5d, 0x14, 0x39, 0xfd, 0x5b, 0x19, 0x25, 0xbb, 0x52, 0x61, 0x82, 0x4c,
        0xc0, 0x48, 0x0f, 0xfe, 0xdc, 0x09, 0xa5, 0xac, 0x56, 0x4c, 0x3e, 0x13, 0xa1, 0x8c, 0x4b, 0xa5,
        0xd3, 0x38, 0xe0, 0x35, 0x1e, 0x51, 0x06, 0x5d, 0x46, 0xf0, 0x7c, 0xfd, 0xd8, 0xb0, 0x31, 0xe5,
        0x41, 0x03, 0x06, 0xd7, 0x4b, 0x83, 0xbd, 0x48, 0xf8, 0x8f, 0x00, 0xcd, 0x03, 0xa1, 0x77, 0xa2,
        0xed, 0x05, 0xe9, 0x04, 0x0b, 0x10, 0x35, 0xea, 0x94, 0x9a, 0xa6, 0x98, 0x39, 0xbd, 0xc5, 0xbd,
        0x67, 0xff, 0x0d, 0xe9, 0x99, 0x6c, 0x1e, 0x76, 0x76, 0x17, 0x3b, 0x40, 0xd2, 0x70, 0x8e, 0x7e,
        0x59, 0x28, 0x3b, 0xd8, 0x9e, 0x8c, 0xea, 0x5c, 0xb8, 0x53, 0x78, 0x11, 0x56, 0x03, 0xc4, 0x8b,
        0x70, 0x72, 0xd2, 0xb0, 0xd4, 0xb0, 0x9e, 0x34, 0x3f, 0xec, 0xe2, 0x49, 0xa8, 0x45, 0x19, 0xd7,
        0x6d, 0x7e, 0xe4, 0xf4, 0xee, 0x9c, 0x23, 0x55, 0x14, 0x58, 0xce, 0x7d, 0xe4, 0x6b, 0x2e, 0xe6,
        0xd3, 0xda, 0xdf, 0x73, 0x39, 0x01, 0x91, 0x42, 0x6a, 0xfd, 0xa0, 0x39, 0x5b, 0x98, 0x76, 0x3a,
        0x69, 0x4b, 0x41, 0xce, 0x7e, 0x8e, 0x61, 0xbf, 0xa7, 0x02, 0x03, 0x01, 0x00, 0x01
    });
    
    EXPECT_EQ(1, SecTrustGetCertificateCount(trust));

#if HAVE(SEC_TRUST_COPY_CERTIFICATE_CHAIN)
    auto certificate = adoptCF(SecCertificateCopyData((SecCertificateRef)CFArrayGetValueAtIndex(adoptCF(SecTrustCopyCertificateChain(trust)).get(), 0)));
#else
    auto certificate = adoptCF(SecCertificateCopyData(SecTrustGetCertificateAtIndex(trust, 0)));
#endif
    compareData(certificate, {
        0x30, 0x82, 0x05, 0x80, 0x30, 0x82, 0x03, 0x68, 0x02, 0x09, 0x00, 0x8a, 0x1e, 0x23, 0xd1, 0x53,
        0x93, 0x10, 0xb8, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
        0x05, 0x00, 0x30, 0x81, 0x81, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
        0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x4e, 0x65, 0x77,
        0x20, 0x4d, 0x65, 0x78, 0x69, 0x63, 0x6f, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07,
        0x0c, 0x08, 0x53, 0x61, 0x6e, 0x74, 0x61, 0x20, 0x46, 0x65, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03,
        0x55, 0x04, 0x0a, 0x0c, 0x04, 0x53, 0x65, 0x6c, 0x66, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55,
        0x04, 0x0b, 0x0c, 0x06, 0x4d, 0x79, 0x73, 0x65, 0x6c, 0x66, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
        0x55, 0x04, 0x03, 0x0c, 0x02, 0x4d, 0x65, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x09, 0x2a, 0x86, 0x48,
        0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x0e, 0x6d, 0x65, 0x40, 0x65, 0x78, 0x61, 0x6d, 0x70,
        0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x33, 0x32, 0x33,
        0x30, 0x35, 0x35, 0x30, 0x31, 0x34, 0x5a, 0x17, 0x0d, 0x32, 0x30, 0x30, 0x33, 0x32, 0x32, 0x30,
        0x35, 0x35, 0x30, 0x31, 0x34, 0x5a, 0x30, 0x81, 0x81, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
        0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c,
        0x0a, 0x4e, 0x65, 0x77, 0x20, 0x4d, 0x65, 0x78, 0x69, 0x63, 0x6f, 0x31, 0x11, 0x30, 0x0f, 0x06,
        0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x53, 0x61, 0x6e, 0x74, 0x61, 0x20, 0x46, 0x65, 0x31, 0x0d,
        0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x04, 0x53, 0x65, 0x6c, 0x66, 0x31, 0x0f, 0x30,
        0x0d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x06, 0x4d, 0x79, 0x73, 0x65, 0x6c, 0x66, 0x31, 0x0b,
        0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x02, 0x4d, 0x65, 0x31, 0x1d, 0x30, 0x1b, 0x06,
        0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x0e, 0x6d, 0x65, 0x40, 0x65,
        0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d,
        0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02,
        0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xde, 0xb8, 0x4d, 0xe1, 0x23,
        0xe0, 0xf1, 0x56, 0x3f, 0x3e, 0xd1, 0x83, 0x34, 0xa6, 0x37, 0x4f, 0xd2, 0x48, 0x4a, 0x06, 0xf2,
        0xf1, 0x81, 0x8c, 0x27, 0x1d, 0x2f, 0x3b, 0xe6, 0x19, 0x15, 0x99, 0xb7, 0x1b, 0x77, 0xec, 0x4d,
        0x4b, 0x32, 0xbc, 0x3c, 0x84, 0x1f, 0x0a, 0xa9, 0xe5, 0xa6, 0xc2, 0x65, 0x10, 0x7f, 0x07, 0x2d,
        0x4f, 0xc1, 0x69, 0x0d, 0xad, 0xfc, 0x67, 0xfd, 0x73, 0xfc, 0x3f, 0x4d, 0xf8, 0x24, 0xf9, 0x44,
        0xea, 0x2a, 0xd5, 0x8a, 0xe0, 0x18, 0x42, 0xba, 0x94, 0x87, 0xa9, 0x3b, 0x65, 0x1f, 0x02, 0xa4,
        0xe3, 0x39, 0x18, 0x47, 0x11, 0x66, 0x00, 0x14, 0x24, 0x61, 0x90, 0xc0, 0xd9, 0x4e, 0x90, 0x4c,
        0x1a, 0x1e, 0x73, 0x06, 0x73, 0xc4, 0xac, 0x1e, 0xea, 0xe0, 0x0c, 0xf8, 0x79, 0x5c, 0x1a, 0x60,
        0x6c, 0x3c, 0xad, 0x77, 0xb0, 0x49, 0xb8, 0x1d, 0x4d, 0xa0, 0x8f, 0xca, 0x26, 0x68, 0x5c, 0x6a,
        0x39, 0x00, 0xb9, 0x5d, 0xef, 0x6a, 0xb4, 0xbe, 0xb8, 0xf2, 0xe8, 0x7c, 0xf1, 0xcd, 0xa9, 0xef,
        0x9c, 0x2f, 0xc8, 0x4d, 0x9e, 0x36, 0x50, 0xc0, 0x75, 0x9a, 0xac, 0xfe, 0x39, 0x92, 0xce, 0x1e,
        0x05, 0xc3, 0x83, 0xee, 0xdc, 0x2a, 0xc6, 0xe1, 0xe7, 0x56, 0x6f, 0xc5, 0x58, 0x4a, 0xe9, 0x63,
        0xc5, 0xac, 0xe6, 0xcd, 0x4c, 0xac, 0xf4, 0xe1, 0x51, 0xd0, 0xda, 0x86, 0x31, 0x0c, 0x7f, 0xe6,
        0x1f, 0x0c, 0x9f, 0x4a, 0x2f, 0xcc, 0xb7, 0xd3, 0x8c, 0x92, 0xf0, 0x9f, 0x1f, 0x78, 0x2c, 0x58,
        0x7d, 0xc1, 0xf8, 0x06, 0xf8, 0x0b, 0xb4, 0x99, 0x81, 0x34, 0x72, 0x60, 0x8f, 0x77, 0x8d, 0x0f,
        0xf1, 0x0c, 0x66, 0x32, 0x60, 0xcf, 0x61, 0x6c, 0x06, 0x3a, 0xc9, 0x93, 0xc9, 0x0a, 0x0f, 0x7d,
        0x5c, 0xc3, 0xee, 0x16, 0xa7, 0xc5, 0x05, 0xe2, 0xc9, 0x16, 0x5c, 0x27, 0xf8, 0xeb, 0xe9, 0x8d,
        0x38, 0x7a, 0x75, 0xdc, 0xf7, 0x92, 0x09, 0x92, 0xf2, 0x17, 0x86, 0x40, 0x1d, 0xac, 0xd4, 0x56,
        0x49, 0xc3, 0x3d, 0xc7, 0x36, 0x60, 0xda, 0xd6, 0x55, 0x5d, 0x62, 0xea, 0x7d, 0xd3, 0xd7, 0x99,
        0x08, 0xd1, 0x3e, 0x59, 0xed, 0xbb, 0x2d, 0x76, 0x60, 0x0b, 0xb9, 0x29, 0x04, 0xd9, 0xcb, 0x89,
        0x49, 0x53, 0x4e, 0xea, 0x04, 0x7e, 0x66, 0xc5, 0x51, 0x4e, 0x77, 0xae, 0x43, 0x1c, 0x16, 0x4d,
        0x4d, 0x0c, 0x34, 0x48, 0x40, 0x3c, 0x53, 0x97, 0xd8, 0x18, 0x46, 0x3f, 0x97, 0xa2, 0xb2, 0x01,
        0x14, 0xce, 0x49, 0xf1, 0x30, 0x97, 0x5d, 0x14, 0x39, 0xfd, 0x5b, 0x19, 0x25, 0xbb, 0x52, 0x61,
        0x82, 0x4c, 0xc0, 0x48, 0x0f, 0xfe, 0xdc, 0x09, 0xa5, 0xac, 0x56, 0x4c, 0x3e, 0x13, 0xa1, 0x8c,
        0x4b, 0xa5, 0xd3, 0x38, 0xe0, 0x35, 0x1e, 0x51, 0x06, 0x5d, 0x46, 0xf0, 0x7c, 0xfd, 0xd8, 0xb0,
        0x31, 0xe5, 0x41, 0x03, 0x06, 0xd7, 0x4b, 0x83, 0xbd, 0x48, 0xf8, 0x8f, 0x00, 0xcd, 0x03, 0xa1,
        0x77, 0xa2, 0xed, 0x05, 0xe9, 0x04, 0x0b, 0x10, 0x35, 0xea, 0x94, 0x9a, 0xa6, 0x98, 0x39, 0xbd,
        0xc5, 0xbd, 0x67, 0xff, 0x0d, 0xe9, 0x99, 0x6c, 0x1e, 0x76, 0x76, 0x17, 0x3b, 0x40, 0xd2, 0x70,
        0x8e, 0x7e, 0x59, 0x28, 0x3b, 0xd8, 0x9e, 0x8c, 0xea, 0x5c, 0xb8, 0x53, 0x78, 0x11, 0x56, 0x03,
        0xc4, 0x8b, 0x70, 0x72, 0xd2, 0xb0, 0xd4, 0xb0, 0x9e, 0x34, 0x3f, 0xec, 0xe2, 0x49, 0xa8, 0x45,
        0x19, 0xd7, 0x6d, 0x7e, 0xe4, 0xf4, 0xee, 0x9c, 0x23, 0x55, 0x14, 0x58, 0xce, 0x7d, 0xe4, 0x6b,
        0x2e, 0xe6, 0xd3, 0xda, 0xdf, 0x73, 0x39, 0x01, 0x91, 0x42, 0x6a, 0xfd, 0xa0, 0x39, 0x5b, 0x98,
        0x76, 0x3a, 0x69, 0x4b, 0x41, 0xce, 0x7e, 0x8e, 0x61, 0xbf, 0xa7, 0x02, 0x03, 0x01, 0x00, 0x01,
        0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
        0x82, 0x02, 0x01, 0x00, 0x63, 0xc1, 0x16, 0x68, 0x01, 0x44, 0x7f, 0x0e, 0xce, 0x57, 0xea, 0x03,
        0x5d, 0x46, 0x52, 0x21, 0x85, 0xea, 0xdc, 0x41, 0xf6, 0x13, 0x9a, 0x77, 0xab, 0x7f, 0x00, 0x84,
        0x83, 0x8b, 0x46, 0x30, 0x6e, 0x07, 0xeb, 0xad, 0xca, 0xee, 0xd0, 0xea, 0xbc, 0x4c, 0x30, 0x7b,
        0xb0, 0xd9, 0x3b, 0x6c, 0x37, 0xec, 0xdb, 0x01, 0x1e, 0xf2, 0xae, 0x37, 0xec, 0xb1, 0xe0, 0x37,
        0xe1, 0x33, 0x35, 0xc5, 0xee, 0x0d, 0x93, 0xb3, 0x55, 0x34, 0x74, 0x68, 0x65, 0x0f, 0x82, 0xd0,
        0x8a, 0x9f, 0xf5, 0xfb, 0xdc, 0x8a, 0x83, 0x2f, 0x4f, 0x5b, 0x53, 0xae, 0x66, 0xb4, 0x32, 0x12,
        0x92, 0x8c, 0x54, 0x29, 0xc7, 0xe3, 0xef, 0xc8, 0xb5, 0x5b, 0x0f, 0xb6, 0x1d, 0x3f, 0xce, 0x8b,
        0x99, 0xe7, 0xa1, 0x2a, 0xa5, 0x3b, 0x87, 0x5a, 0x4b, 0x18, 0x08, 0x86, 0xc2, 0x3a, 0x1a, 0x67,
        0xd6, 0x1b, 0x87, 0xa2, 0xae, 0xab, 0xf3, 0x13, 0x00, 0x7c, 0xb7, 0x0f, 0xcf, 0xb0, 0x93, 0xb0,
        0x77, 0xe9, 0x50, 0x71, 0x17, 0xa7, 0x62, 0x56, 0x55, 0x0f, 0x64, 0x96, 0x50, 0x58, 0xa2, 0x72,
        0x30, 0xac, 0xbd, 0x1b, 0x7b, 0x33, 0x7b, 0x56, 0x46, 0xb7, 0xd5, 0x9e, 0x13, 0x40, 0x0c, 0xbe,
        0x43, 0x76, 0x1c, 0x87, 0x9f, 0xd0, 0x74, 0xca, 0x09, 0x46, 0x77, 0x78, 0x1b, 0xde, 0x70, 0xe3,
        0x22, 0x8f, 0x12, 0xf4, 0x5a, 0x15, 0xa8, 0xe5, 0x0c, 0x9f, 0xe6, 0x4e, 0xb2, 0x94, 0x26, 0x94,
        0xd9, 0xfc, 0x7e, 0x33, 0xc0, 0xdf, 0x0d, 0xcc, 0x05, 0xa3, 0xbb, 0x52, 0x80, 0xbc, 0x52, 0x2b,
        0x71, 0x82, 0x16, 0x9c, 0x4f, 0x7e, 0x20, 0xed, 0xe9, 0x09, 0x3c, 0x73, 0xdb, 0x50, 0x9f, 0x94,
        0xb5, 0x81, 0x8d, 0xed, 0xe8, 0xb2, 0x6e, 0xc1, 0x50, 0x85, 0xc1, 0x42, 0x17, 0x94, 0xd9, 0x01,
        0x24, 0x3e, 0xfe, 0x71, 0x9d, 0x59, 0xfe, 0xd0, 0xab, 0x12, 0x1c, 0xe3, 0xdd, 0x80, 0xa4, 0xd2,
        0xe5, 0x14, 0xf0, 0x28, 0x9f, 0xa1, 0x4f, 0xb8, 0x14, 0x6f, 0x87, 0x18, 0x53, 0xfe, 0x48, 0xfc,
        0xed, 0xb1, 0x81, 0x34, 0xe7, 0x99, 0x92, 0x8f, 0x7f, 0x84, 0xb2, 0x1f, 0xa8, 0xca, 0x85, 0x41,
        0x80, 0x11, 0xfd, 0xd2, 0xc1, 0x36, 0x4f, 0x58, 0xb4, 0x78, 0xd2, 0x3c, 0x7f, 0xad, 0x68, 0x4a,
        0x0c, 0x18, 0x15, 0xe1, 0xec, 0x7f, 0xb7, 0xc2, 0xef, 0x55, 0xc4, 0x5c, 0xb1, 0x51, 0xf8, 0x6c,
        0x0d, 0x76, 0x6c, 0x2a, 0x96, 0x6c, 0x25, 0x0d, 0x91, 0x29, 0x4e, 0xee, 0xc1, 0xa0, 0xd3, 0x7e,
        0xab, 0xbf, 0x93, 0x7e, 0x4d, 0x4c, 0x46, 0x42, 0x65, 0x2f, 0x53, 0xc7, 0xe9, 0x8b, 0xbf, 0x20,
        0xf8, 0x59, 0x88, 0xd8, 0x78, 0xb7, 0x22, 0x2a, 0x0c, 0xeb, 0x65, 0x61, 0xfc, 0xe9, 0xe7, 0xbe,
        0xc0, 0xf8, 0xe5, 0x14, 0xfa, 0xae, 0x4f, 0x3d, 0x11, 0x51, 0x22, 0xca, 0xa1, 0x78, 0xec, 0x6d,
        0x98, 0xd9, 0x47, 0xc7, 0x85, 0x33, 0x77, 0x85, 0x37, 0x21, 0x37, 0xe6, 0xa2, 0x02, 0x5a, 0xce,
        0x3a, 0xb0, 0x60, 0xed, 0xaf, 0x88, 0x16, 0x58, 0xe2, 0x35, 0x10, 0x9b, 0x26, 0x6c, 0xef, 0x97,
        0x87, 0xfe, 0x38, 0x94, 0x14, 0x75, 0x91, 0xb2, 0x16, 0xb7, 0x01, 0xd9, 0xd6, 0xe4, 0xb5, 0x9a,
        0x1b, 0x73, 0xc5, 0x9d, 0x86, 0xd6, 0xf2, 0xea, 0xc7, 0xd0, 0xd4, 0x89, 0x1b, 0xf5, 0xbe, 0xff,
        0xd0, 0xc0, 0xf9, 0x8e, 0xc0, 0x6b, 0x47, 0x2c, 0xe1, 0x33, 0xe9, 0xb8, 0x11, 0x99, 0xd0, 0xd5,
        0x35, 0x5b, 0xde, 0x0e, 0xa0, 0x23, 0x28, 0xe2, 0x59, 0x0e, 0xe8, 0x7f, 0xf2, 0xe8, 0xb7, 0xae,
        0xde, 0xf8, 0xd9, 0x0f, 0x7c, 0xbd, 0x91, 0x99, 0x3b, 0x9a, 0xb7, 0xbd, 0x5c, 0x7c, 0x24, 0x23,
        0xc3, 0x1d, 0x2b, 0x9b,
    });
}

@interface ServerTrustDelegate : NSObject <WKNavigationDelegate>
- (void)waitForDidFinishNavigation;
- (NSError *)waitForDidFailProvisionalNavigationError;
- (size_t)authenticationChallengeCount;
@end

@implementation ServerTrustDelegate {
    size_t _authenticationChallengeCount;
    bool _navigationFinished;
    RetainPtr<NSError> _provisionalNavigationFailedError;
}

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
    _navigationFinished = true;
}

- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error
{
    _provisionalNavigationFailedError = error;
}

- (void)waitForDidFinishNavigation
{
    TestWebKitAPI::Util::run(&_navigationFinished);
}

- (NSError *)waitForDidFailProvisionalNavigationError
{
    while (!_provisionalNavigationFailedError)
        TestWebKitAPI::Util::spinRunLoop();
    return _provisionalNavigationFailedError.autorelease();
}

- (size_t)authenticationChallengeCount
{
    return _authenticationChallengeCount;
}

- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
{
    _authenticationChallengeCount++;
    SecTrustRef trust = challenge.protectionSpace.serverTrust;
    verifyCertificateAndPublicKey(trust);
    completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:trust]);
}

@end

namespace TestWebKitAPI {

TEST(WebKit, ServerTrust)
{
    HTTPServer server(HTTPServer::respondWithOK, HTTPServer::Protocol::Https);

    auto webView = adoptNS([WKWebView new]);
    auto delegate = adoptNS([ServerTrustDelegate new]);
    [webView setNavigationDelegate:delegate.get()];

    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://localhost:%d/", server.port()]]]];
    [delegate waitForDidFinishNavigation];

    verifyCertificateAndPublicKey([webView serverTrust]);
    EXPECT_EQ([delegate authenticationChallengeCount], 1u);
}

TEST(WebKit, FastServerTrust)
{
    HTTPServer server(HTTPServer::respondWithOK, HTTPServer::Protocol::Https);
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto dataStoreConfiguration = adoptNS([[_WKWebsiteDataStoreConfiguration alloc] init]);
    [dataStoreConfiguration setFastServerTrustEvaluationEnabled:YES];
    [configuration setWebsiteDataStore:adoptNS([[WKWebsiteDataStore alloc] _initWithConfiguration:dataStoreConfiguration.get()]).get()];
    auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
    auto delegate = adoptNS([ServerTrustDelegate new]);
    [webView setNavigationDelegate:delegate.get()];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://localhost:%d/", server.port()]]]];
    [delegate waitForDidFinishNavigation];
    EXPECT_EQ([delegate authenticationChallengeCount], 1ull);
}

TEST(WebKit, ErrorSecureCoding)
{
    HTTPServer server({{ "/", { HTTPResponse::TerminateConnection::Yes }}});
    auto webView = [[WKWebView new] autorelease];
    auto delegate = [[TestNavigationDelegate new] autorelease];
    webView.navigationDelegate = delegate;
    [webView loadRequest:server.request()];
    NSError *error = [delegate waitForDidFailProvisionalNavigation];

    EXPECT_WK_STREQ(NSStringFromClass([error.userInfo[_WKRecoveryAttempterErrorKey] class]), @"WKReloadFrameErrorRecoveryAttempter");
    auto archiver = adoptNS([[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]);
    [archiver encodeObject:error forKey:NSKeyedArchiveRootObjectKey];
    [archiver finishEncoding];
    auto unarchiver = adoptNS([[NSKeyedUnarchiver alloc] initForReadingFromData:archiver.get().encodedData error:nullptr]);
    NSError *decodedError = [unarchiver decodeObjectOfClasses:[NSSet setWithObjects:[NSDictionary class], [NSString class], [NSError class], NSClassFromString(@"WKReloadFrameErrorRecoveryAttempter"), nil] forKey:NSKeyedArchiveRootObjectKey];
    EXPECT_EQ(decodedError.code, NSURLErrorNetworkConnectionLost);
    EXPECT_WK_STREQ(decodedError.domain, NSURLErrorDomain);
    EXPECT_WK_STREQ(NSStringFromClass([decodedError.userInfo[_WKRecoveryAttempterErrorKey] class]), @"WKReloadFrameErrorRecoveryAttempter");
}

} // namespace TestWebKitAPI
