// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ios/web/js_messaging/web_frame_impl.h"

#import <WebKit/WebKit.h>

#import "base/base64.h"
#include "base/bind.h"
#include "base/json/json_reader.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#import "base/strings/sys_string_conversions.h"
#include "base/test/ios/wait_util.h"
#include "base/values.h"
#include "crypto/aead.h"
#import "ios/web/public/test/fakes/fake_web_state.h"
#include "ios/web/public/test/web_test.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/gtest_mac.h"

#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif

using crypto::SymmetricKey;

namespace {
const char kFrameId[] = "1effd8f52a067c8d3a01762d3c41dfd8";

// A base64 encoded sample key.
const char kFrameKey[] = "R7lsXtR74c6R9A9k691gUQ8JAd0be+w//Lntgcbjwrc=";

// Returns a key which can be used to create a WebFrame.
std::unique_ptr<SymmetricKey> CreateKey() {
  std::string decoded_frame_key_string;
  base::Base64Decode(kFrameKey, &decoded_frame_key_string);
  return crypto::SymmetricKey::Import(crypto::SymmetricKey::Algorithm::AES,
                                      decoded_frame_key_string);
}

struct RouteMessageParameters {
  NSString* encoded_message_payload = nil;
  NSString* encoded_message_iv = nil;
  NSString* encoded_function_payload = nil;
  NSString* encoded_function_iv = nil;
  NSString* frame_id = nil;
};

RouteMessageParameters ParametersFromFunctionCallString(
    NSString* function_call) {
  NSRange parameters_start = [function_call rangeOfString:@"("];
  NSRange parameters_end = [function_call rangeOfString:@")"];
  NSMutableString* parameter_string = [[function_call
      substringWithRange:NSMakeRange(parameters_start.location + 1,
                                     parameters_end.location -
                                         parameters_start.location - 1)]
      mutableCopy];
  // Create array string and replace single quotes with double quotes in
  // preparation for JSON serialization.
  [parameter_string insertString:@"[" atIndex:0];
  [parameter_string appendString:@"]"];
  NSString* final_string =
      [parameter_string stringByReplacingOccurrencesOfString:@"'"
                                                  withString:@"\""];

  NSData* data = [final_string dataUsingEncoding:NSUTF8StringEncoding];
  NSError* error = nil;
  NSArray* jsonArray =
      [NSJSONSerialization JSONObjectWithData:data
                                      options:NSJSONReadingMutableContainers |
                                              NSJSONReadingMutableLeaves
                                        error:&error];

  RouteMessageParameters parsed_params;
  if (jsonArray.count == 3 && !error) {
    parsed_params.encoded_message_iv = jsonArray[0][@"iv"];
    parsed_params.encoded_message_payload = jsonArray[0][@"payload"];
    parsed_params.encoded_function_iv = jsonArray[1][@"iv"];
    parsed_params.encoded_function_payload = jsonArray[1][@"payload"];
    parsed_params.frame_id = jsonArray[2];
  }

  return parsed_params;
}

}  // namespace

namespace web {

typedef web::WebTest WebFrameImplTest;

// Tests creation of a WebFrame for the main frame without an encryption key.
TEST_F(WebFrameImplTest, CreateWebFrameForMainFrame) {
  FakeWebState fake_web_state;
  GURL security_origin;
  WebFrameImpl web_frame([[WKFrameInfo alloc] init], kFrameId,
                         /*is_main_frame=*/true, security_origin,
                         &fake_web_state);

  EXPECT_EQ(&fake_web_state, web_frame.GetWebState());
  EXPECT_TRUE(web_frame.IsMainFrame());
  EXPECT_TRUE(web_frame.CanCallJavaScriptFunction());
  EXPECT_EQ(security_origin, web_frame.GetSecurityOrigin());
  EXPECT_EQ(kFrameId, web_frame.GetFrameId());
}

// Tests creation of a WebFrame for the main frame with an encryption key.
TEST_F(WebFrameImplTest, CreateWebFrameForMainFrameWithKey) {
  FakeWebState fake_web_state;
  GURL security_origin;
  WebFrameImpl web_frame([[WKFrameInfo alloc] init], kFrameId,
                         /*is_main_frame=*/true, security_origin,
                         &fake_web_state);
  web_frame.SetEncryptionKey(CreateKey());

  EXPECT_EQ(&fake_web_state, web_frame.GetWebState());
  EXPECT_TRUE(web_frame.IsMainFrame());
  EXPECT_TRUE(web_frame.CanCallJavaScriptFunction());
  EXPECT_EQ(security_origin, web_frame.GetSecurityOrigin());
  EXPECT_EQ(kFrameId, web_frame.GetFrameId());
}

// Tests creation of a WebFrame for a frame which is not the main frame without
// an encryption key.
TEST_F(WebFrameImplTest, CreateWebFrameForIFrame) {
  FakeWebState fake_web_state;
  GURL security_origin;
  WebFrameImpl web_frame([[WKFrameInfo alloc] init], kFrameId,
                         /*is_main_frame=*/false, security_origin,
                         &fake_web_state);

  EXPECT_EQ(&fake_web_state, web_frame.GetWebState());
  EXPECT_FALSE(web_frame.IsMainFrame());
  EXPECT_FALSE(web_frame.CanCallJavaScriptFunction());
  EXPECT_EQ(security_origin, web_frame.GetSecurityOrigin());
  EXPECT_EQ(kFrameId, web_frame.GetFrameId());
}

// Tests creation of a WebFrame for a frame which is not the main frame with an
// encryption key.
TEST_F(WebFrameImplTest, CreateWebFrameForIFrameWithKey) {
  FakeWebState fake_web_state;
  GURL security_origin;
  WebFrameImpl web_frame([[WKFrameInfo alloc] init], kFrameId,
                         /*is_main_frame=*/false, security_origin,
                         &fake_web_state);
  web_frame.SetEncryptionKey(CreateKey());

  EXPECT_EQ(&fake_web_state, web_frame.GetWebState());
  EXPECT_FALSE(web_frame.IsMainFrame());
  EXPECT_TRUE(web_frame.CanCallJavaScriptFunction());
  EXPECT_EQ(security_origin, web_frame.GetSecurityOrigin());
  EXPECT_EQ(kFrameId, web_frame.GetFrameId());
}

// Tests that |CallJavaScriptFunction| encrypts the message and passes it to
// __gCrWeb.message.routeMessage in the main frame.
TEST_F(WebFrameImplTest, CallJavaScriptFunction) {
  FakeWebState fake_web_state;
  GURL security_origin;
  WebFrameImpl web_frame([[WKFrameInfo alloc] init], kFrameId,
                         /*is_main_frame=*/false, security_origin,
                         &fake_web_state);
  web_frame.SetEncryptionKey(CreateKey());

  std::vector<base::Value> function_params;
  function_params.push_back(base::Value("plaintextParam"));
  EXPECT_TRUE(
      web_frame.CallJavaScriptFunction("functionName", function_params));

  NSString* last_script =
      base::SysUTF16ToNSString(fake_web_state.GetLastExecutedJavascript());
  EXPECT_TRUE([last_script hasPrefix:@"__gCrWeb.message.routeMessage"]);
  // Verify the message does not contain the plaintext function name or
  // parameters.
  EXPECT_FALSE([last_script containsString:@"functionName"]);
  EXPECT_FALSE([last_script containsString:@"plaintextParam"]);

  RouteMessageParameters params = ParametersFromFunctionCallString(last_script);

  // Verify that the message and function payload are properly base64 encoded
  // strings.
  std::string decoded_function_payload;
  EXPECT_TRUE(base::Base64Decode(
      base::SysNSStringToUTF8(params.encoded_function_payload),
      &decoded_function_payload));
  std::string decoded_message_payload;
  EXPECT_TRUE(base::Base64Decode(
      base::SysNSStringToUTF8(params.encoded_message_payload),
      &decoded_message_payload));
  // Verify the function does not contain the plaintext function name or
  // parameters.
  EXPECT_FALSE([base::SysUTF8ToNSString(decoded_function_payload)
      containsString:@"functionName"]);
  EXPECT_FALSE([base::SysUTF8ToNSString(decoded_function_payload)
      containsString:@"plaintextParam"]);

  // Verify that the initialization vector is a properly base64 encoded string
  // for both payloads.
  std::string function_iv_string =
      base::SysNSStringToUTF8(params.encoded_function_iv);
  std::string decoded_function_iv;
  EXPECT_TRUE(base::Base64Decode(function_iv_string, &decoded_function_iv));
  std::string message_iv_string =
      base::SysNSStringToUTF8(params.encoded_message_iv);
  std::string decoded_message_iv;
  EXPECT_TRUE(base::Base64Decode(message_iv_string, &decoded_message_iv));

  // Ensure the frame ID matches.
  EXPECT_NSEQ(base::SysUTF8ToNSString(kFrameId), params.frame_id);
}

// Tests that the WebFrame uses different initialization vectors for two
// sequential calls to |CallJavaScriptFunction|.
TEST_F(WebFrameImplTest, CallJavaScriptFunctionUniqueInitializationVector) {
  FakeWebState fake_web_state;
  GURL security_origin;
  WebFrameImpl web_frame([[WKFrameInfo alloc] init], kFrameId,
                         /*is_main_frame=*/false, security_origin,
                         &fake_web_state);
  web_frame.SetEncryptionKey(CreateKey());

  std::vector<base::Value> function_params;
  function_params.push_back(base::Value("plaintextParam"));
  EXPECT_TRUE(
      web_frame.CallJavaScriptFunction("functionName", function_params));

  NSString* last_script1 =
      base::SysUTF16ToNSString(fake_web_state.GetLastExecutedJavascript());
  RouteMessageParameters params1 =
      ParametersFromFunctionCallString(last_script1);

  // Call JavaScript Function again to verify that the same initialization
  // vector is not reused and that the ciphertext is different.
  EXPECT_TRUE(
      web_frame.CallJavaScriptFunction("functionName", function_params));
  NSString* last_script2 =
      base::SysUTF16ToNSString(fake_web_state.GetLastExecutedJavascript());
  RouteMessageParameters params2 =
      ParametersFromFunctionCallString(last_script2);

  EXPECT_NSNE(params1.encoded_function_payload,
              params2.encoded_function_payload);
  EXPECT_NSNE(params1.encoded_function_iv, params2.encoded_function_iv);
}

// Tests that the WebFrame properly encodes and encrypts all parameters for
// |CallJavaScriptFunction|.
TEST_F(WebFrameImplTest, CallJavaScriptFunctionMessageProperlyEncoded) {
  std::unique_ptr<SymmetricKey> key = CreateKey();
  const std::string key_string = key->key();
  // Use an arbitrary nonzero message id to ensure it isn't matching a zero
  // value by chance.
  const int initial_message_id = 11;

  FakeWebState fake_web_state;
  GURL security_origin;
  WebFrameImpl web_frame([[WKFrameInfo alloc] init], kFrameId,
                         /*is_main_frame=*/false, security_origin,
                         &fake_web_state);
  web_frame.SetEncryptionKey(std::move(key));
  web_frame.SetNextMessageId(initial_message_id);

  std::vector<base::Value> function_params;
  std::string plaintext_param("plaintextParam");
  function_params.push_back(base::Value(plaintext_param));
  EXPECT_TRUE(
      web_frame.CallJavaScriptFunction("functionName", function_params));

  NSString* last_script =
      base::SysUTF16ToNSString(fake_web_state.GetLastExecutedJavascript());
  RouteMessageParameters params = ParametersFromFunctionCallString(last_script);

  std::string decoded_function_ciphertext;
  EXPECT_TRUE(base::Base64Decode(
      base::SysNSStringToUTF8(params.encoded_function_payload),
      &decoded_function_ciphertext));

  std::string decoded_function_iv;
  EXPECT_TRUE(
      base::Base64Decode(base::SysNSStringToUTF8(params.encoded_function_iv),
                         &decoded_function_iv));

  std::string decoded_message_ciphertext;
  EXPECT_TRUE(base::Base64Decode(
      base::SysNSStringToUTF8(params.encoded_message_payload),
      &decoded_message_ciphertext));

  std::string decoded_message_iv;
  EXPECT_TRUE(base::Base64Decode(
      base::SysNSStringToUTF8(params.encoded_message_iv), &decoded_message_iv));

  // Decrypt message
  crypto::Aead aead(crypto::Aead::AES_256_GCM);
  aead.Init(&key_string);
  std::string function_plaintext;
  EXPECT_TRUE(aead.Open(decoded_function_ciphertext, decoded_function_iv,
                        base::NumberToString(initial_message_id),
                        &function_plaintext));
  std::string message_plaintext;
  EXPECT_TRUE(aead.Open(decoded_message_ciphertext, decoded_message_iv,
                        /*additional_data=*/"", &message_plaintext));

  base::Optional<base::Value> parsed_function_result =
      base::JSONReader::Read(function_plaintext, false);
  EXPECT_TRUE(parsed_function_result.has_value());
  ASSERT_TRUE(parsed_function_result.value().is_dict());

  const std::string* decrypted_function_name =
      parsed_function_result.value().FindStringKey("functionName");
  ASSERT_TRUE(decrypted_function_name);
  EXPECT_EQ("functionName", *decrypted_function_name);

  base::Value* decrypted_parameters =
      parsed_function_result.value().FindKeyOfType("parameters",
                                                   base::Value::Type::LIST);
  ASSERT_TRUE(decrypted_parameters);
  ASSERT_EQ(function_params.size(), decrypted_parameters->GetList().size());
  EXPECT_EQ(plaintext_param, decrypted_parameters->GetList()[0].GetString());

  base::Optional<base::Value> parsed_message_result =
      base::JSONReader::Read(message_plaintext, false);
  EXPECT_TRUE(parsed_message_result.has_value());
  ASSERT_TRUE(parsed_message_result.value().is_dict());

  base::Optional<int> decrypted_message_id =
      parsed_message_result.value().FindIntKey("messageId");
  ASSERT_TRUE(decrypted_message_id.has_value());
  EXPECT_EQ(decrypted_message_id.value(), initial_message_id);

  base::Optional<bool> decrypted_respond_with_result =
      parsed_message_result.value().FindBoolKey("replyWithResult");
  ASSERT_TRUE(decrypted_respond_with_result.has_value());
  EXPECT_FALSE(decrypted_respond_with_result.value());
}

// Tests that the WebFrame properly encodes and encrypts the respondWithResult
// value when |CallJavaScriptFunction| is called with a callback.
TEST_F(WebFrameImplTest, CallJavaScriptFunctionRespondWithResult) {
  std::unique_ptr<SymmetricKey> key = CreateKey();
  const std::string key_string = key->key();
  // Use an arbitrary nonzero message id to ensure it isn't matching a zero
  // value by chance.
  const int initial_message_id = 11;

  FakeWebState fake_web_state;
  GURL security_origin;
  WebFrameImpl web_frame([[WKFrameInfo alloc] init], kFrameId,
                         /*is_main_frame=*/false, security_origin,
                         &fake_web_state);
  web_frame.SetEncryptionKey(std::move(key));
  web_frame.SetNextMessageId(initial_message_id);

  std::vector<base::Value> function_params;
  std::string plaintext_param("plaintextParam");
  function_params.push_back(base::Value(plaintext_param));
  EXPECT_TRUE(web_frame.CallJavaScriptFunction(
      "functionName", function_params,
      base::BindOnce(^(const base::Value* value){
      }),
      base::TimeDelta::FromSeconds(5)));

  NSString* last_script =
      base::SysUTF16ToNSString(fake_web_state.GetLastExecutedJavascript());
  RouteMessageParameters params = ParametersFromFunctionCallString(last_script);

  std::string decoded_message_ciphertext;
  EXPECT_TRUE(base::Base64Decode(
      base::SysNSStringToUTF8(params.encoded_message_payload),
      &decoded_message_ciphertext));

  std::string decoded_message_iv;
  EXPECT_TRUE(base::Base64Decode(
      base::SysNSStringToUTF8(params.encoded_message_iv), &decoded_message_iv));

  // Decrypt message
  crypto::Aead aead(crypto::Aead::AES_256_GCM);
  aead.Init(&key_string);
  std::string message_plaintext;
  EXPECT_TRUE(aead.Open(decoded_message_ciphertext, decoded_message_iv,
                        /*additional_data=*/"", &message_plaintext));

  base::Optional<base::Value> parsed_result =
      base::JSONReader::Read(message_plaintext, false);
  EXPECT_TRUE(parsed_result.has_value());
  ASSERT_TRUE(parsed_result.value().is_dict());

  base::Optional<bool> decrypted_respond_with_result =
      parsed_result.value().FindBoolKey("replyWithResult");
  ASSERT_TRUE(decrypted_respond_with_result.has_value());
  EXPECT_TRUE(decrypted_respond_with_result.value());
}

// Tests that the WebFrame properly creates JavaScript for the main frame when
// there is no encryption key.
TEST_F(WebFrameImplTest, CallJavaScriptFunctionMainFrameWithoutKey) {
  FakeWebState fake_web_state;
  GURL security_origin;
  WebFrameImpl web_frame([[WKFrameInfo alloc] init], kFrameId,
                         /*is_main_frame=*/true, security_origin,
                         &fake_web_state);

  std::vector<base::Value> function_params;

  EXPECT_TRUE(
      web_frame.CallJavaScriptFunction("functionName", function_params));
  NSString* last_script =
      base::SysUTF16ToNSString(fake_web_state.GetLastExecutedJavascript());
  EXPECT_NSEQ(@"__gCrWeb.functionName()", last_script);

  function_params.push_back(base::Value("param1"));
  EXPECT_TRUE(
      web_frame.CallJavaScriptFunction("functionName", function_params));
  last_script =
      base::SysUTF16ToNSString(fake_web_state.GetLastExecutedJavascript());
  EXPECT_NSEQ(@"__gCrWeb.functionName(\"param1\")", last_script);

  function_params.push_back(base::Value(true));
  function_params.push_back(base::Value(27));
  function_params.push_back(base::Value(3.14));
  EXPECT_TRUE(
      web_frame.CallJavaScriptFunction("functionName", function_params));
  last_script =
      base::SysUTF16ToNSString(fake_web_state.GetLastExecutedJavascript());
  EXPECT_NSEQ(@"__gCrWeb.functionName(\"param1\",true,27,3.14)", last_script);
}

// Tests that the WebFrame does not create JavaScript for an iframe when there
// is no encryption key.
TEST_F(WebFrameImplTest, CallJavaScriptFunctionIFrameFrameWithoutKey) {
  FakeWebState fake_web_state;
  GURL security_origin;
  WebFrameImpl web_frame([[WKFrameInfo alloc] init], kFrameId,
                         /*is_main_frame=*/false, security_origin,
                         &fake_web_state);

  std::vector<base::Value> function_params;
  function_params.push_back(base::Value("plaintextParam"));
  EXPECT_FALSE(
      web_frame.CallJavaScriptFunction("functionName", function_params));

  NSString* last_script =
      base::SysUTF16ToNSString(fake_web_state.GetLastExecutedJavascript());
  EXPECT_EQ(last_script.length, 0ul);
}

}  // namespace web
