// Copyright 2015 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 "components/gcm_driver/crypto/gcm_encryption_provider.h"

#include <stddef.h>

#include <sstream>
#include <string>

#include "base/base64url.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/scoped_temp_dir.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "base/test/histogram_tester.h"
#include "components/gcm_driver/common/gcm_messages.h"
#include "components/gcm_driver/crypto/gcm_key_store.h"
#include "components/gcm_driver/crypto/gcm_message_cryptographer.h"
#include "components/gcm_driver/crypto/p256_key_util.h"
#include "crypto/random.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace gcm {
namespace {

const char kExampleAppId[] = "my-app-id";
const char kExampleAuthorizedEntity[] = "my-sender-id";
const char kExampleMessage[] = "Hello, world, this is the GCM Driver!";

const char kValidEncryptionHeader[] =
    "keyid=foo;salt=MTIzNDU2Nzg5MDEyMzQ1Ng;rs=1024";
const char kInvalidEncryptionHeader[] = "keyid";

const char kValidCryptoKeyHeader[] =
    "keyid=foo;dh=BL_UGhfudEkXMUd4U4-D4nP5KHxKjQHsW6j88ybbehXM7fqi1OMFefDUEi0eJ"
    "vsKfyVBWYkQjH-lSPJKxjAyslg";
const char kValidThreeValueCryptoKeyHeader[] =
    "keyid=foo,keyid=bar,keyid=baz;dh=BL_UGhfudEkXMUd4U4-D4nP5KHxKjQHsW6j88ybbe"
    "hXM7fqi1OMFefDUEi0eJvsKfyVBWYkQjH-lSPJKxjAyslg";

const char kInvalidCryptoKeyHeader[] = "keyid";
const char kInvalidThreeValueCryptoKeyHeader[] =
    "keyid=foo,dh=BL_UGhfudEkXMUd4U4-D4nP5KHxKjQHsW6j88ybbehXM7fqi1OMFefDUEi0eJ"
    "vsKfyVBWYkQjH-lSPJKxjAyslg,keyid=baz,dh=BL_UGhfudEkXMUd4U4-D4nP5KHxKjQHsW6"
    "j88ybbehXM7fqi1OMFefDUEi0eJvsKfyVBWYkQjH-lSPJKxjAyslg";

}  // namespace

class GCMEncryptionProviderTest : public ::testing::Test {
 public:
  void SetUp() override {
    ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());

    encryption_provider_.reset(new GCMEncryptionProvider);
    encryption_provider_->Init(scoped_temp_dir_.GetPath(),
                               message_loop_.task_runner());
  }

  void TearDown() override {
    encryption_provider_.reset();

    // |encryption_provider_| owns a ProtoDatabaseImpl whose destructor deletes
    // the underlying LevelDB database on the task runner.
    base::RunLoop().RunUntilIdle();
  }

  // To be used as a callback for GCMEncryptionProvider::GetEncryptionInfo().
  void DidGetEncryptionInfo(std::string* p256dh_out,
                            std::string* auth_secret_out,
                            const std::string& p256dh,
                            const std::string& auth_secret) {
    *p256dh_out = p256dh;
    *auth_secret_out = auth_secret;
  }

  // To be used as a callback for GCMKeyStore::{GetKeys,CreateKeys}.
  void HandleKeysCallback(KeyPair* pair_out,
                          std::string* auth_secret_out,
                          const KeyPair& pair,
                          const std::string& auth_secret) {
    *pair_out = pair;
    *auth_secret_out = auth_secret;
  }

 protected:
  // Decrypts the |message| and then synchronously waits until either the
  // success or failure callbacks has been invoked.
  void Decrypt(const IncomingMessage& message) {
    encryption_provider_->DecryptMessage(
        kExampleAppId, message,
        base::Bind(&GCMEncryptionProviderTest::DidDecryptMessage,
                   base::Unretained(this)));

    // The encryption keys will be read asynchronously.
    base::RunLoop().RunUntilIdle();
  }

  // Checks that the underlying key store has a key for the |kExampleAppId| +
  // authorized entity pair if and only if |should_have_key| is true. Must wrap
  // with ASSERT/EXPECT_NO_FATAL_FAILURE.
  void CheckHasKey(const std::string& authorized_entity, bool should_have_key) {
    KeyPair pair;
    std::string auth_secret;
    encryption_provider()->key_store_->GetKeys(
        kExampleAppId, authorized_entity,
        false /* fallback_to_empty_authorized_entity */,
        base::Bind(&GCMEncryptionProviderTest::HandleKeysCallback,
                   base::Unretained(this), &pair, &auth_secret));

    base::RunLoop().RunUntilIdle();

    if (should_have_key) {
      ASSERT_GT(pair.public_key().size(), 0u);
      ASSERT_GT(pair.private_key().size(), 0u);
      ASSERT_GT(auth_secret.size(), 0u);
    } else {
      ASSERT_EQ(0u, pair.public_key().size());
      ASSERT_EQ(0u, pair.private_key().size());
      ASSERT_EQ(0u, auth_secret.size());
    }
  }

  // Returns the result of the previous decryption operation.
  GCMEncryptionProvider::DecryptionResult decryption_result() {
    return decryption_result_;
  }

  // Returns the message resulting from the previous decryption operation.
  const IncomingMessage& decrypted_message() { return decrypted_message_; }

  GCMEncryptionProvider* encryption_provider() {
    return encryption_provider_.get();
  }

  // Performs a full round-trip test of the encryption feature. Must wrap this
  // in ASSERT_NO_FATAL_FAILURE.
  void TestEncryptionRoundTrip(const std::string& app_id,
                               const std::string& authorized_entity);

 private:
  void DidDecryptMessage(GCMEncryptionProvider::DecryptionResult result,
                         const IncomingMessage& message) {
    decryption_result_ = result;
    decrypted_message_ = message;
  }

  base::MessageLoop message_loop_;
  base::ScopedTempDir scoped_temp_dir_;
  base::HistogramTester histogram_tester_;

  std::unique_ptr<GCMEncryptionProvider> encryption_provider_;

  GCMEncryptionProvider::DecryptionResult decryption_result_ =
      GCMEncryptionProvider::DECRYPTION_RESULT_UNENCRYPTED;

  IncomingMessage decrypted_message_;
};

TEST_F(GCMEncryptionProviderTest, IsEncryptedMessage) {
  // Both the Encryption and Encryption-Key headers must be present, and the raw
  // data must be non-empty for a message to be considered encrypted.

  IncomingMessage empty_message;
  EXPECT_FALSE(encryption_provider()->IsEncryptedMessage(empty_message));

  IncomingMessage single_header_message;
  single_header_message.data["encryption"] = "";
  EXPECT_FALSE(encryption_provider()->IsEncryptedMessage(
                   single_header_message));

  IncomingMessage double_header_message;
  double_header_message.data["encryption"] = "";
  double_header_message.data["crypto-key"] = "";
  EXPECT_FALSE(encryption_provider()->IsEncryptedMessage(
                   double_header_message));

  IncomingMessage double_header_with_data_message;
  double_header_with_data_message.data["encryption"] = "";
  double_header_with_data_message.data["crypto-key"] = "";
  double_header_with_data_message.raw_data = "foo";
  EXPECT_TRUE(encryption_provider()->IsEncryptedMessage(
                  double_header_with_data_message));
}

TEST_F(GCMEncryptionProviderTest, VerifiesEncryptionHeaderParsing) {
  // The Encryption header must be parsable and contain valid values.
  // Note that this is more extensively tested in EncryptionHeaderParsersTest.

  IncomingMessage invalid_message;
  invalid_message.data["encryption"] = kInvalidEncryptionHeader;
  invalid_message.data["crypto-key"] = kValidCryptoKeyHeader;
  invalid_message.raw_data = "foo";

  ASSERT_NO_FATAL_FAILURE(Decrypt(invalid_message));
  EXPECT_EQ(GCMEncryptionProvider::DECRYPTION_RESULT_INVALID_ENCRYPTION_HEADER,
            decryption_result());

  IncomingMessage valid_message;
  valid_message.data["encryption"] = kValidEncryptionHeader;
  valid_message.data["crypto-key"] = kInvalidCryptoKeyHeader;
  valid_message.raw_data = "foo";

  ASSERT_NO_FATAL_FAILURE(Decrypt(valid_message));
  EXPECT_NE(GCMEncryptionProvider::DECRYPTION_RESULT_INVALID_ENCRYPTION_HEADER,
            decryption_result());
}

TEST_F(GCMEncryptionProviderTest, VerifiesCryptoKeyHeaderParsing) {
  // The Crypto-Key header must be parsable and contain valid values.
  // Note that this is more extensively tested in EncryptionHeaderParsersTest.

  IncomingMessage invalid_message;
  invalid_message.data["encryption"] = kValidEncryptionHeader;
  invalid_message.data["crypto-key"] = kInvalidCryptoKeyHeader;
  invalid_message.raw_data = "foo";

  ASSERT_NO_FATAL_FAILURE(Decrypt(invalid_message));
  EXPECT_EQ(GCMEncryptionProvider::DECRYPTION_RESULT_INVALID_CRYPTO_KEY_HEADER,
            decryption_result());

  IncomingMessage valid_message;
  valid_message.data["encryption"] = kValidEncryptionHeader;
  valid_message.data["crypto-key"] = kValidCryptoKeyHeader;
  valid_message.raw_data = "foo";

  ASSERT_NO_FATAL_FAILURE(Decrypt(valid_message));
  EXPECT_NE(GCMEncryptionProvider::DECRYPTION_RESULT_INVALID_CRYPTO_KEY_HEADER,
            decryption_result());
}

TEST_F(GCMEncryptionProviderTest, VerifiesCryptoKeyHeaderParsingThirdValue) {
  // The Crypto-Key header must be parsable and contain valid values, in which
  // values will be ignored unless they contain a "dh" property.

  IncomingMessage valid_message;
  valid_message.data["encryption"] = kValidEncryptionHeader;
  valid_message.data["crypto-key"] = kValidThreeValueCryptoKeyHeader;
  valid_message.raw_data = "foo";

  ASSERT_NO_FATAL_FAILURE(Decrypt(valid_message));
  EXPECT_NE(GCMEncryptionProvider::DECRYPTION_RESULT_INVALID_CRYPTO_KEY_HEADER,
            decryption_result());
}

TEST_F(GCMEncryptionProviderTest, VerifiesCryptoKeyHeaderSingleDhEntry) {
  // The Crypto-Key header must include at most one value that contains the
  // "dh" property. Having more than once occurrence is forbidden.

  IncomingMessage valid_message;
  valid_message.data["encryption"] = kValidEncryptionHeader;
  valid_message.data["crypto-key"] = kInvalidThreeValueCryptoKeyHeader;
  valid_message.raw_data = "foo";

  ASSERT_NO_FATAL_FAILURE(Decrypt(valid_message));
  EXPECT_EQ(GCMEncryptionProvider::DECRYPTION_RESULT_INVALID_CRYPTO_KEY_HEADER,
            decryption_result());
}

TEST_F(GCMEncryptionProviderTest, VerifiesExistingKeys) {
  // When both headers are valid, the encryption keys still must be known to
  // the GCM key store before the message can be decrypted.

  IncomingMessage message;
  message.data["encryption"] = kValidEncryptionHeader;
  message.data["crypto-key"] = kValidCryptoKeyHeader;
  message.raw_data = "foo";

  ASSERT_NO_FATAL_FAILURE(Decrypt(message));
  EXPECT_EQ(GCMEncryptionProvider::DECRYPTION_RESULT_NO_KEYS,
            decryption_result());

  std::string public_key, auth_secret;
  encryption_provider()->GetEncryptionInfo(
      kExampleAppId, "" /* empty authorized entity for non-InstanceID */,
      base::Bind(&GCMEncryptionProviderTest::DidGetEncryptionInfo,
                 base::Unretained(this), &public_key, &auth_secret));

  // Getting (or creating) the public key will be done asynchronously.
  base::RunLoop().RunUntilIdle();

  ASSERT_GT(public_key.size(), 0u);
  ASSERT_GT(auth_secret.size(), 0u);

  ASSERT_NO_FATAL_FAILURE(Decrypt(message));
  EXPECT_NE(GCMEncryptionProvider::DECRYPTION_RESULT_NO_KEYS,
            decryption_result());
}

TEST_F(GCMEncryptionProviderTest, VerifiesKeyRemovalGCMRegistration) {
  // Removing encryption info for an InstanceID token shouldn't affect a
  // non-InstanceID GCM registration.

  // Non-InstanceID callers pass an empty string for authorized_entity.
  std::string authorized_entity_gcm = "";
  std::string authorized_entity_1 = kExampleAuthorizedEntity + std::string("1");
  std::string authorized_entity_2 = kExampleAuthorizedEntity + std::string("2");

  // Should create encryption info.
  std::string public_key, auth_secret;
  encryption_provider()->GetEncryptionInfo(
      kExampleAppId, authorized_entity_gcm,
      base::Bind(&GCMEncryptionProviderTest::DidGetEncryptionInfo,
                 base::Unretained(this), &public_key, &auth_secret));

  base::RunLoop().RunUntilIdle();

  // Should get encryption info created above.
  std::string read_public_key, read_auth_secret;
  encryption_provider()->GetEncryptionInfo(
      kExampleAppId, authorized_entity_gcm,
      base::Bind(&GCMEncryptionProviderTest::DidGetEncryptionInfo,
                 base::Unretained(this), &read_public_key, &read_auth_secret));

  base::RunLoop().RunUntilIdle();

  EXPECT_GT(public_key.size(), 0u);
  EXPECT_GT(auth_secret.size(), 0u);
  EXPECT_EQ(public_key, read_public_key);
  EXPECT_EQ(auth_secret, read_auth_secret);

  ASSERT_NO_FATAL_FAILURE(CheckHasKey(authorized_entity_gcm, true));

  encryption_provider()->RemoveEncryptionInfo(
      kExampleAppId, authorized_entity_1, base::Bind(&base::DoNothing));

  base::RunLoop().RunUntilIdle();

  ASSERT_NO_FATAL_FAILURE(CheckHasKey(authorized_entity_gcm, true));

  encryption_provider()->RemoveEncryptionInfo(kExampleAppId, "*",
                                              base::Bind(&base::DoNothing));

  base::RunLoop().RunUntilIdle();

  ASSERT_NO_FATAL_FAILURE(CheckHasKey(authorized_entity_gcm, true));

  encryption_provider()->RemoveEncryptionInfo(
      kExampleAppId, authorized_entity_gcm, base::Bind(&base::DoNothing));

  base::RunLoop().RunUntilIdle();

  ASSERT_NO_FATAL_FAILURE(CheckHasKey(authorized_entity_gcm, false));
}

TEST_F(GCMEncryptionProviderTest, VerifiesKeyRemovalInstanceIDToken) {
  // Removing encryption info for a non-InstanceID GCM registration shouldn't
  // affect an InstanceID token.

  // Non-InstanceID callers pass an empty string for authorized_entity.
  std::string authorized_entity_gcm = "";
  std::string authorized_entity_1 = kExampleAuthorizedEntity + std::string("1");
  std::string authorized_entity_2 = kExampleAuthorizedEntity + std::string("2");

  std::string public_key_1, auth_secret_1;
  encryption_provider()->GetEncryptionInfo(
      kExampleAppId, authorized_entity_1,
      base::Bind(&GCMEncryptionProviderTest::DidGetEncryptionInfo,
                 base::Unretained(this), &public_key_1, &auth_secret_1));

  base::RunLoop().RunUntilIdle();

  EXPECT_GT(public_key_1.size(), 0u);
  EXPECT_GT(auth_secret_1.size(), 0u);

  ASSERT_NO_FATAL_FAILURE(CheckHasKey(authorized_entity_1, true));
  ASSERT_NO_FATAL_FAILURE(CheckHasKey(authorized_entity_2, false));

  std::string public_key_2, auth_secret_2;
  encryption_provider()->GetEncryptionInfo(
      kExampleAppId, authorized_entity_2,
      base::Bind(&GCMEncryptionProviderTest::DidGetEncryptionInfo,
                 base::Unretained(this), &public_key_2, &auth_secret_2));

  base::RunLoop().RunUntilIdle();

  EXPECT_GT(public_key_2.size(), 0u);
  EXPECT_GT(auth_secret_2.size(), 0u);
  EXPECT_NE(public_key_1, public_key_2);
  EXPECT_NE(auth_secret_1, auth_secret_2);

  ASSERT_NO_FATAL_FAILURE(CheckHasKey(authorized_entity_1, true));
  ASSERT_NO_FATAL_FAILURE(CheckHasKey(authorized_entity_2, true));

  std::string read_public_key_1, read_auth_secret_1;
  encryption_provider()->GetEncryptionInfo(
      kExampleAppId, authorized_entity_1,
      base::Bind(&GCMEncryptionProviderTest::DidGetEncryptionInfo,
                 base::Unretained(this), &read_public_key_1,
                 &read_auth_secret_1));

  base::RunLoop().RunUntilIdle();

  // Should have returned existing info for authorized_entity_1.
  EXPECT_EQ(public_key_1, read_public_key_1);
  EXPECT_EQ(auth_secret_1, read_auth_secret_1);

  encryption_provider()->RemoveEncryptionInfo(
      kExampleAppId, authorized_entity_gcm, base::Bind(&base::DoNothing));

  base::RunLoop().RunUntilIdle();

  ASSERT_NO_FATAL_FAILURE(CheckHasKey(authorized_entity_1, true));
  ASSERT_NO_FATAL_FAILURE(CheckHasKey(authorized_entity_2, true));

  encryption_provider()->RemoveEncryptionInfo(
      kExampleAppId, authorized_entity_1, base::Bind(&base::DoNothing));

  base::RunLoop().RunUntilIdle();

  ASSERT_NO_FATAL_FAILURE(CheckHasKey(authorized_entity_1, false));
  ASSERT_NO_FATAL_FAILURE(CheckHasKey(authorized_entity_2, true));

  std::string public_key_1_refreshed, auth_secret_1_refreshed;
  encryption_provider()->GetEncryptionInfo(
      kExampleAppId, authorized_entity_1,
      base::Bind(&GCMEncryptionProviderTest::DidGetEncryptionInfo,
                 base::Unretained(this), &public_key_1_refreshed,
                 &auth_secret_1_refreshed));

  base::RunLoop().RunUntilIdle();

  // Since the info was removed, GetEncryptionInfo should have created new info.
  EXPECT_GT(public_key_1_refreshed.size(), 0u);
  EXPECT_GT(auth_secret_1_refreshed.size(), 0u);
  EXPECT_NE(public_key_1, public_key_1_refreshed);
  EXPECT_NE(auth_secret_1, auth_secret_1_refreshed);
  EXPECT_NE(public_key_2, public_key_1_refreshed);
  EXPECT_NE(auth_secret_2, auth_secret_1_refreshed);

  ASSERT_NO_FATAL_FAILURE(CheckHasKey(authorized_entity_1, true));
  ASSERT_NO_FATAL_FAILURE(CheckHasKey(authorized_entity_2, true));

  encryption_provider()->RemoveEncryptionInfo(kExampleAppId, "*",
                                              base::Bind(&base::DoNothing));

  base::RunLoop().RunUntilIdle();

  ASSERT_NO_FATAL_FAILURE(CheckHasKey(authorized_entity_1, false));
  ASSERT_NO_FATAL_FAILURE(CheckHasKey(authorized_entity_2, false));
}

void GCMEncryptionProviderTest::TestEncryptionRoundTrip(
    const std::string& app_id,
    const std::string& authorized_entity) {
  // Performs a full round-trip of the encryption feature, including getting a
  // public/private key-pair and performing the cryptographic operations. This
  // is more of an integration test than a unit test.

  KeyPair pair, server_pair;
  std::string auth_secret, server_authentication;

  // Retrieve the public/private key-pair immediately from the key store, given
  // that the GCMEncryptionProvider will only share the public key with users.
  // Also create a second pair, which will act as the server's keys.
  encryption_provider()->key_store_->CreateKeys(
      app_id, authorized_entity,
      base::Bind(&GCMEncryptionProviderTest::HandleKeysCallback,
                 base::Unretained(this), &pair, &auth_secret));

  encryption_provider()->key_store_->CreateKeys(
      "server-" + app_id, authorized_entity,
      base::Bind(&GCMEncryptionProviderTest::HandleKeysCallback,
                 base::Unretained(this), &server_pair, &server_authentication));

  // Creating the public keys will be done asynchronously.
  base::RunLoop().RunUntilIdle();

  ASSERT_GT(pair.public_key().size(), 0u);
  ASSERT_GT(server_pair.public_key().size(), 0u);

  ASSERT_GT(pair.private_key().size(), 0u);
  ASSERT_GT(server_pair.private_key().size(), 0u);

  std::string salt;

  // Creates a cryptographically secure salt of |salt_size| octets in size, and
  // calculate the shared secret for the message.
  crypto::RandBytes(base::WriteInto(&salt, 16 + 1), 16);

  std::string shared_secret;
  ASSERT_TRUE(ComputeSharedP256Secret(
      pair.private_key(), pair.public_key_x509(), server_pair.public_key(),
      &shared_secret));

  IncomingMessage message;
  size_t record_size;

  message.sender_id = kExampleAuthorizedEntity;

  // Encrypts the |kExampleMessage| using the generated shared key and the
  // random |salt|, storing the result in |record_size| and the message.
  GCMMessageCryptographer cryptographer(
      pair.public_key(), server_pair.public_key(), auth_secret);

  ASSERT_TRUE(cryptographer.Encrypt(kExampleMessage, shared_secret, salt,
                                    &record_size, &message.raw_data));

  std::string encoded_salt, encoded_key;

  // Compile the incoming GCM message, including the required headers.
  base::Base64UrlEncode(
      salt, base::Base64UrlEncodePolicy::INCLUDE_PADDING, &encoded_salt);
  base::Base64UrlEncode(
      server_pair.public_key(), base::Base64UrlEncodePolicy::INCLUDE_PADDING,
      &encoded_key);

  std::stringstream encryption_header;
  encryption_header << "rs=" << base::SizeTToString(record_size) << ";";
  encryption_header << "salt=" << encoded_salt;

  message.data["encryption"] = encryption_header.str();
  message.data["crypto-key"] = "dh=" + encoded_key;

  ASSERT_TRUE(encryption_provider()->IsEncryptedMessage(message));

  // Decrypt the message, and expect everything to go wonderfully well.
  ASSERT_NO_FATAL_FAILURE(Decrypt(message));
  ASSERT_EQ(GCMEncryptionProvider::DECRYPTION_RESULT_DECRYPTED,
            decryption_result());

  EXPECT_TRUE(decrypted_message().decrypted);
  EXPECT_EQ(kExampleMessage, decrypted_message().raw_data);
}

TEST_F(GCMEncryptionProviderTest, EncryptionRoundTripGCMRegistration) {
  // GCMEncryptionProvider::DecryptMessage should succeed when the message was
  // sent to a non-InstanceID GCM registration (empty authorized_entity).
  ASSERT_NO_FATAL_FAILURE(TestEncryptionRoundTrip(
      kExampleAppId, "" /* empty authorized entity for non-InstanceID */));
}

TEST_F(GCMEncryptionProviderTest, EncryptionRoundTripInstanceIDToken) {
  // GCMEncryptionProvider::DecryptMessage should succeed when the message was
  // sent to an InstanceID token (non-empty authorized_entity).
  ASSERT_NO_FATAL_FAILURE(
      TestEncryptionRoundTrip(kExampleAppId, kExampleAuthorizedEntity));
}

}  // namespace gcm
