/*
 * 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 "TestNavigationDelegate.h"
#import "TestWKWebView.h"
#import "WebCoreTestSupport.h"
#import <WebKit/WKProcessPoolPrivate.h>
#import <WebKit/WKWebsiteDataStorePrivate.h>
#import <WebKit/WebKit.h>
#import <WebKit/_WKWebsiteDataStoreConfiguration.h>
#import <wtf/RetainPtr.h>
#import <wtf/text/StringConcatenateNumbers.h>

#if PLATFORM(IOS_FAMILY)
#import <WebKit/WebUIKitSupport.h>
#import <WebKit/WebCoreThread.h>
#endif

@interface TLSObserver : NSObject
- (void)waitUntilNegotiatedLegacyTLSChanged;
@end

@implementation TLSObserver {
    bool _negotiatedLegacyTLSChanged;
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    EXPECT_WK_STREQ(keyPath, "_negotiatedLegacyTLS");
    _negotiatedLegacyTLSChanged = true;
}

- (void)waitUntilNegotiatedLegacyTLSChanged
{
    _negotiatedLegacyTLSChanged = false;
    while (!_negotiatedLegacyTLSChanged)
        TestWebKitAPI::Util::spinRunLoop();
}

@end

@interface TLSNavigationDelegate : NSObject <WKNavigationDelegate>
- (void)waitForDidFinishNavigation;
- (void)waitForDidFailProvisionalNavigation;
- (NSURL *)waitForDidNegotiateModernTLS;
- (bool)receivedShouldAllowDeprecatedTLS;
@property (nonatomic) bool shouldAllowDeprecatedTLS;
@end

@implementation TLSNavigationDelegate {
    bool _navigationFinished;
    bool _navigationFailed;
    bool _receivedShouldAllowDeprecatedTLS;
    RetainPtr<NSURL> _negotiatedModernTLS;
}

- (void)waitForDidFinishNavigation
{
    while (!_navigationFinished)
        TestWebKitAPI::Util::spinRunLoop();
}

- (void)waitForDidFailProvisionalNavigation
{
    while (!_navigationFailed)
        TestWebKitAPI::Util::spinRunLoop();
}

- (NSURL *)waitForDidNegotiateModernTLS
{
    while (!_negotiatedModernTLS)
        TestWebKitAPI::Util::spinRunLoop();
    return _negotiatedModernTLS.autorelease();
}

- (bool)receivedShouldAllowDeprecatedTLS
{
    return _receivedShouldAllowDeprecatedTLS;
}

- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * credential))completionHandler
{
    EXPECT_WK_STREQ(challenge.protectionSpace.authenticationMethod, NSURLAuthenticationMethodServerTrust);
    completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
}

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

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

- (void)webView:(WKWebView *)webView authenticationChallenge:(NSURLAuthenticationChallenge *)challenge shouldAllowDeprecatedTLS:(void (^)(BOOL))completionHandler
{
    _receivedShouldAllowDeprecatedTLS = true;
    completionHandler([self shouldAllowDeprecatedTLS]);
}

- (void)_webView:(WKWebView *)webView didNegotiateModernTLSForURL:(NSURL *)url
{
    _negotiatedModernTLS = url;
}

@end


namespace TestWebKitAPI {

const uint16_t tls1_1 = 0x0302;

TEST(TLSVersion, DefaultBehavior)
{
    HTTPServer server(HTTPServer::respondWithOK, HTTPServer::Protocol::HttpsWithLegacyTLS);
    auto delegate = adoptNS([TestNavigationDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    [webView setNavigationDelegate:delegate.get()];
    [delegate setDidReceiveAuthenticationChallenge:^(WKWebView *, NSURLAuthenticationChallenge *challenge, void (^callback)(NSURLSessionAuthChallengeDisposition, NSURLCredential *)) {
        EXPECT_WK_STREQ(challenge.protectionSpace.authenticationMethod, NSURLAuthenticationMethodServerTrust);
        callback(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://127.0.0.1:%d/", server.port()]]]];
    [delegate waitForDidFinishNavigation];
}

#if HAVE(TLS_VERSION_DURING_CHALLENGE)

RetainPtr<WKWebView> makeWebViewWith(WKWebsiteDataStore *store, RetainPtr<TestNavigationDelegate> delegate)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    [configuration setWebsiteDataStore:store];
    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    [webView setNavigationDelegate:delegate.get()];
    [delegate setDidReceiveAuthenticationChallenge:^(WKWebView *, NSURLAuthenticationChallenge *challenge, void (^callback)(NSURLSessionAuthChallengeDisposition, NSURLCredential *)) {
        EXPECT_WK_STREQ(challenge.protectionSpace.authenticationMethod, NSURLAuthenticationMethodServerTrust);
        callback(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
    }];
    return webView;
};

TEST(TLSVersion, NetworkSession)
{
    HTTPServer server(HTTPServer::respondWithOK, HTTPServer::Protocol::HttpsWithLegacyTLS);
    auto delegate = adoptNS([TestNavigationDelegate new]);
    {
        auto webView = makeWebViewWith([WKWebsiteDataStore defaultDataStore], delegate);
        [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://127.0.0.1:%d/", server.port()]]]];
        [delegate waitForDidFinishNavigation];
    }
    {
        auto webView = makeWebViewWith([WKWebsiteDataStore nonPersistentDataStore], delegate);
        [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://127.0.0.1:%d/", server.port()]]]];
        [delegate waitForDidFinishNavigation];
    }
    {
        auto configuration = adoptNS([[_WKWebsiteDataStoreConfiguration alloc] initNonPersistentConfiguration]);
        [configuration setLegacyTLSEnabled:NO];
        auto dataStore = adoptNS([[WKWebsiteDataStore alloc] _initWithConfiguration:configuration.get()]);
        auto webView = makeWebViewWith(dataStore.get(), delegate);
        [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://127.0.0.1:%d/", server.port()]]]];
        [delegate waitForDidFailProvisionalNavigation];
    }
}

TEST(TLSVersion, NetworkSessionNSUserDefaults)
{
    NSString *defaultsKey = @"WebKitEnableLegacyTLS";
    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:defaultsKey];

    HTTPServer server(HTTPServer::respondWithOK, HTTPServer::Protocol::HttpsWithLegacyTLS);
    auto delegate = adoptNS([TestNavigationDelegate new]);
    {
        auto webView = makeWebViewWith([WKWebsiteDataStore defaultDataStore], delegate);
        [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://127.0.0.1:%d/", server.port()]]]];
        [delegate waitForDidFailProvisionalNavigation];
    }
    {
        auto webView = makeWebViewWith([WKWebsiteDataStore nonPersistentDataStore], delegate);
        [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://127.0.0.1:%d/", server.port()]]]];
        [delegate waitForDidFailProvisionalNavigation];
    }
    [[NSUserDefaults standardUserDefaults] removeObjectForKey:defaultsKey];
}

TEST(TLSVersion, ShouldAllowDeprecatedTLS)
{
    HTTPServer server(HTTPServer::respondWithOK, HTTPServer::Protocol::HttpsWithLegacyTLS);
    {
        auto delegate = adoptNS([TLSNavigationDelegate new]);
        auto webView = adoptNS([WKWebView new]);
        [webView setNavigationDelegate:delegate.get()];
        [webView loadRequest:server.request()];
        [delegate waitForDidFailProvisionalNavigation];
        EXPECT_TRUE([delegate receivedShouldAllowDeprecatedTLS]);
    }
    {
        auto delegate = adoptNS([TLSNavigationDelegate new]);
        delegate.get().shouldAllowDeprecatedTLS = YES;
        auto webView = adoptNS([WKWebView new]);
        [webView setNavigationDelegate:delegate.get()];
        [webView loadRequest:server.request()];
        [delegate waitForDidFinishNavigation];
        EXPECT_TRUE([delegate receivedShouldAllowDeprecatedTLS]);
    }
}

TEST(TLSVersion, Preconnect)
{
    bool connectionAttempted = false;
    HTTPServer server([&](const Connection&) {
        connectionAttempted = true;
    }, HTTPServer::Protocol::HttpsWithLegacyTLS);

    auto webView = adoptNS([WKWebView new]);
    [webView loadHTMLString:makeString("<head><link rel='preconnect' href='https://127.0.0.1:", server.port(), "/'></link></head>") baseURL:nil];

    auto delegate = adoptNS([TestNavigationDelegate new]);
    [webView setNavigationDelegate:delegate.get()];
    [delegate setDidReceiveAuthenticationChallenge:^(WKWebView *, NSURLAuthenticationChallenge *challenge, void (^callback)(NSURLSessionAuthChallengeDisposition, NSURLCredential *)) {
        EXPECT_TRUE(false);
        callback(NSURLSessionAuthChallengeUseCredential, nil);
    }];

    TestWebKitAPI::Util::run(&connectionAttempted);
}

#endif // HAVE(TLS_VERSION_DURING_CHALLENGE)

static std::pair<RetainPtr<WKWebView>, RetainPtr<TestNavigationDelegate>> webViewWithNavigationDelegate()
{
    auto delegate = adoptNS([TestNavigationDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    [webView setNavigationDelegate:delegate.get()];
    [delegate setDidReceiveAuthenticationChallenge:^(WKWebView *, NSURLAuthenticationChallenge *challenge, void (^callback)(NSURLSessionAuthChallengeDisposition, NSURLCredential *)) {
        EXPECT_WK_STREQ(challenge.protectionSpace.authenticationMethod, NSURLAuthenticationMethodServerTrust);
        callback(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
    }];
    return { webView, delegate };
}

TEST(TLSVersion, NegotiatedLegacyTLS)
{
    HTTPServer server({
        { "/", { "hello" } }
    }, HTTPServer::Protocol::HttpsWithLegacyTLS);

    auto [webView, delegate] = webViewWithNavigationDelegate();
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://127.0.0.1:%d/", server.port()]]];
    [webView loadRequest:request];

    auto observer = adoptNS([TLSObserver new]);
    [webView addObserver:observer.get() forKeyPath:@"_negotiatedLegacyTLS" options:NSKeyValueObservingOptionNew context:nil];
    
    EXPECT_FALSE([webView _negotiatedLegacyTLS]);
    [observer waitUntilNegotiatedLegacyTLSChanged];
    EXPECT_TRUE([webView _negotiatedLegacyTLS]);

    [webView loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]];
    [observer waitUntilNegotiatedLegacyTLSChanged];
    EXPECT_FALSE([webView _negotiatedLegacyTLS]);

    [webView loadRequest:request];
    [observer waitUntilNegotiatedLegacyTLSChanged];
    EXPECT_TRUE([webView _negotiatedLegacyTLS]);

    [webView removeObserver:observer.get() forKeyPath:@"_negotiatedLegacyTLS"];
}

TEST(TLSVersion, NavigateBack)
{
    HTTPServer legacyTLSServer({
        { "/", { "hello" } }
    }, HTTPServer::Protocol::HttpsWithLegacyTLS);

    HTTPServer modernTLSServer({
        { "/", { "hello" } }
    }, HTTPServer::Protocol::Https);
    
    auto [webView, delegate] = webViewWithNavigationDelegate();
    auto observer = adoptNS([TLSObserver new]);
    [webView addObserver:observer.get() forKeyPath:@"_negotiatedLegacyTLS" options:NSKeyValueObservingOptionNew context:nil];

    [webView loadRequest:legacyTLSServer.request()];
    EXPECT_FALSE([webView _negotiatedLegacyTLS]);
    [delegate waitForDidFinishNavigation];
    EXPECT_TRUE([webView _negotiatedLegacyTLS]);

    [webView loadRequest:modernTLSServer.request()];
    [delegate waitForDidFinishNavigation];
    EXPECT_FALSE([webView _negotiatedLegacyTLS]);

    [webView goBack];
    [observer waitUntilNegotiatedLegacyTLSChanged];
    EXPECT_TRUE([webView _negotiatedLegacyTLS]);

    [webView removeObserver:observer.get() forKeyPath:@"_negotiatedLegacyTLS"];
}

TEST(TLSVersion, BackForwardNegotiatedLegacyTLS)
{
    HTTPServer secureServer({
        { "/", { "hello" }}
    }, HTTPServer::Protocol::Https);
    HTTPServer insecureServer({
        { "/", { "hello" } }
    }, HTTPServer::Protocol::HttpsWithLegacyTLS);
    HTTPServer mixedContentServer({
        { "/", { {{ "Content-Type", "text/html" }}, makeString("<img src='https://127.0.0.1:", insecureServer.port(), "/'></img>") } },
    }, HTTPServer::Protocol::Https);

    auto [webView, delegate] = webViewWithNavigationDelegate();
    EXPECT_FALSE([webView _negotiatedLegacyTLS]);

    [webView loadRequest:secureServer.request()];
    [delegate waitForDidFinishNavigation];
    EXPECT_FALSE([webView _negotiatedLegacyTLS]);

    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://localhost:%d/", mixedContentServer.port()]]]];
    [delegate waitForDidFinishNavigation];
    while (![webView _negotiatedLegacyTLS])
        TestWebKitAPI::Util::spinRunLoop();
    EXPECT_TRUE([webView _negotiatedLegacyTLS]);

    [webView goBack];
    [delegate waitForDidFinishNavigation];
    EXPECT_FALSE([webView _negotiatedLegacyTLS]);

    [webView goForward];
    [delegate waitForDidFinishNavigation];
    while (![webView _negotiatedLegacyTLS])
        TestWebKitAPI::Util::spinRunLoop();
    EXPECT_TRUE([webView _negotiatedLegacyTLS]);
}

TEST(TLSVersion, Subresource)
{
    HTTPServer legacyTLSServer({
        { "/", { "hello" } }
    }, HTTPServer::Protocol::HttpsWithLegacyTLS);

    HTTPServer modernTLSServer({
        { "/", { makeString("<script>fetch('https://127.0.0.1:", legacyTLSServer.port(), "/',{mode:'no-cors'})</script>") } },
        { "/pageWithoutSubresource", { "hello" }}
    }, HTTPServer::Protocol::Https);
    
    auto [webView, delegate] = webViewWithNavigationDelegate();
    auto observer = adoptNS([TLSObserver new]);
    [webView addObserver:observer.get() forKeyPath:@"_negotiatedLegacyTLS" options:NSKeyValueObservingOptionNew context:nil];

    EXPECT_FALSE([webView _negotiatedLegacyTLS]);
    [webView loadRequest:modernTLSServer.request()];
    while (![webView _negotiatedLegacyTLS])
        [observer waitUntilNegotiatedLegacyTLSChanged];
    
    EXPECT_TRUE([webView _negotiatedLegacyTLS]);
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://127.0.0.1:%d/pageWithoutSubresource", modernTLSServer.port()]]]];
    [delegate waitForDidFinishNavigation];
    EXPECT_FALSE([webView _negotiatedLegacyTLS]);

    [webView goBack];
    [delegate waitForDidFinishNavigation];
    EXPECT_TRUE([webView _negotiatedLegacyTLS]);

    [webView removeObserver:observer.get() forKeyPath:@"_negotiatedLegacyTLS"];
}

TEST(TLSVersion, DidNegotiateModernTLS)
{
    HTTPServer server({
        { "/", { "hello" }}
    }, HTTPServer::Protocol::Https);

    auto delegate = adoptNS([TLSNavigationDelegate new]);
    auto configuration = adoptNS([WKWebViewConfiguration new]);
    auto dataStoreConfiguration = adoptNS([_WKWebsiteDataStoreConfiguration new]);
    [dataStoreConfiguration setFastServerTrustEvaluationEnabled:YES];
    [configuration setWebsiteDataStore:adoptNS([[WKWebsiteDataStore alloc] _initWithConfiguration:dataStoreConfiguration.get()]).get()];
    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    [webView setNavigationDelegate:delegate.get()];
    [webView loadRequest:server.request()];
    NSURL *url = [delegate waitForDidNegotiateModernTLS];
    EXPECT_WK_STREQ(url.host, "127.0.0.1");
    EXPECT_EQ(url.port.unsignedShortValue, server.port());
}

TEST(TLSVersion, BackForwardHasOnlySecureContent)
{
    HTTPServer secureServer({
        { "/", { "hello" }}
    }, HTTPServer::Protocol::Https);
    HTTPServer insecureServer({
        { "/", { "hello" } }
    });
    HTTPServer mixedContentServer({
        { "/", { {{ "Content-Type", "text/html" }}, makeString("<img src='http://127.0.0.1:", insecureServer.port(), "/'></img>") } },
    }, HTTPServer::Protocol::Https);

    auto [webView, delegate] = webViewWithNavigationDelegate();
    EXPECT_FALSE([webView hasOnlySecureContent]);

    [webView loadRequest:secureServer.request()];
    [delegate waitForDidFinishNavigation];
    EXPECT_TRUE([webView hasOnlySecureContent]);

    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://localhost:%d/", mixedContentServer.port()]]]];
    [delegate waitForDidFinishNavigation];
    while ([webView hasOnlySecureContent])
        TestWebKitAPI::Util::spinRunLoop();
    EXPECT_FALSE([webView hasOnlySecureContent]);

    [webView goBack];
    [delegate waitForDidFinishNavigation];
    EXPECT_TRUE([webView hasOnlySecureContent]);

    [webView goForward];
    [delegate waitForDidFinishNavigation];
    while ([webView hasOnlySecureContent])
        TestWebKitAPI::Util::spinRunLoop();
    EXPECT_FALSE([webView hasOnlySecureContent]);
}

#if HAVE(TLS_VERSION_DURING_CHALLENGE)

TEST(TLSVersion, LegacySubresources)
{
    HTTPServer legacyServer({
        { "/frame", { "shouldn't load with fastServerTrustEvaluationEnabled" }}
    }, HTTPServer::Protocol::HttpsWithLegacyTLS);

    HTTPServer modernServer({
        { "/", { makeString("<iframe src='https://127.0.0.1:", legacyServer.port(), "/frame'/>") }}
    }, HTTPServer::Protocol::Https);

    auto dataStoreConfiguration = adoptNS([[_WKWebsiteDataStoreConfiguration alloc] initNonPersistentConfiguration]);
    [dataStoreConfiguration setFastServerTrustEvaluationEnabled:YES];
    auto webViewConfiguration = adoptNS([WKWebViewConfiguration new]);
    [webViewConfiguration setWebsiteDataStore:adoptNS([[WKWebsiteDataStore alloc] _initWithConfiguration:dataStoreConfiguration.get()]).get()];
    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);

    auto delegate = adoptNS([TestNavigationDelegate new]);
    [delegate setDidReceiveAuthenticationChallenge:^(WKWebView *, NSURLAuthenticationChallenge *challenge, void (^callback)(NSURLSessionAuthChallengeDisposition, NSURLCredential *)) {
        EXPECT_WK_STREQ(challenge.protectionSpace.authenticationMethod, NSURLAuthenticationMethodServerTrust);
        callback(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
    }];
    [webView setNavigationDelegate:delegate.get()];

    [webView loadRequest:modernServer.request()];
    [delegate waitForDidFinishNavigation];

    EXPECT_EQ(legacyServer.totalRequests(), 0u);
    EXPECT_EQ(modernServer.totalRequests(), 1u);

    auto defaultWebView = adoptNS([WKWebView new]);
    [defaultWebView setNavigationDelegate:delegate.get()];
    [defaultWebView loadRequest:modernServer.request()];
    [delegate waitForDidFinishNavigation];
    EXPECT_EQ(legacyServer.totalRequests(), 1u);
    EXPECT_EQ(modernServer.totalRequests(), 2u);
}

#endif // HAVE(TLS_VERSION_DURING_CHALLENGE)

}
