// Copyright (c) 2013 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 "net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange.h"

#include <memory>
#include <string>
#include <utility>

#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"

namespace quic {
namespace test {

class Curve25519KeyExchangeTest : public QuicTest {
 public:
  // Holds the result of a key exchange callback.
  class TestCallbackResult {
   public:
    void set_ok(bool ok) { ok_ = ok; }
    bool ok() { return ok_; }

   private:
    bool ok_ = false;
  };

  // Key exchange callback which sets the result into the specified
  // TestCallbackResult.
  class TestCallback : public AsynchronousKeyExchange::Callback {
   public:
    TestCallback(TestCallbackResult* result) : result_(result) {}
    virtual ~TestCallback() = default;

    void Run(bool ok) { result_->set_ok(ok); }

   private:
    TestCallbackResult* result_;
  };
};

// SharedKey just tests that the basic key exchange identity holds: that both
// parties end up with the same key.
TEST_F(Curve25519KeyExchangeTest, SharedKey) {
  QuicRandom* const rand = QuicRandom::GetInstance();

  for (int i = 0; i < 5; i++) {
    const std::string alice_key(Curve25519KeyExchange::NewPrivateKey(rand));
    const std::string bob_key(Curve25519KeyExchange::NewPrivateKey(rand));

    std::unique_ptr<Curve25519KeyExchange> alice(
        Curve25519KeyExchange::New(alice_key));
    std::unique_ptr<Curve25519KeyExchange> bob(
        Curve25519KeyExchange::New(bob_key));

    const QuicStringPiece alice_public(alice->public_value());
    const QuicStringPiece bob_public(bob->public_value());

    std::string alice_shared, bob_shared;
    ASSERT_TRUE(alice->CalculateSharedKeySync(bob_public, &alice_shared));
    ASSERT_TRUE(bob->CalculateSharedKeySync(alice_public, &bob_shared));
    ASSERT_EQ(alice_shared, bob_shared);
  }
}

// SharedKeyAsync just tests that the basic asynchronous key exchange identity
// holds: that both parties end up with the same key.
TEST_F(Curve25519KeyExchangeTest, SharedKeyAsync) {
  QuicRandom* const rand = QuicRandom::GetInstance();

  for (int i = 0; i < 5; i++) {
    const std::string alice_key(Curve25519KeyExchange::NewPrivateKey(rand));
    const std::string bob_key(Curve25519KeyExchange::NewPrivateKey(rand));

    std::unique_ptr<Curve25519KeyExchange> alice(
        Curve25519KeyExchange::New(alice_key));
    std::unique_ptr<Curve25519KeyExchange> bob(
        Curve25519KeyExchange::New(bob_key));

    const QuicStringPiece alice_public(alice->public_value());
    const QuicStringPiece bob_public(bob->public_value());

    std::string alice_shared, bob_shared;
    TestCallbackResult alice_result;
    ASSERT_FALSE(alice_result.ok());
    alice->CalculateSharedKeyAsync(
        bob_public, &alice_shared,
        std::make_unique<TestCallback>(&alice_result));
    ASSERT_TRUE(alice_result.ok());
    TestCallbackResult bob_result;
    ASSERT_FALSE(bob_result.ok());
    bob->CalculateSharedKeyAsync(alice_public, &bob_shared,
                                 std::make_unique<TestCallback>(&bob_result));
    ASSERT_TRUE(bob_result.ok());
    ASSERT_EQ(alice_shared, bob_shared);
    ASSERT_NE(0u, alice_shared.length());
    ASSERT_NE(0u, bob_shared.length());
  }
}

}  // namespace test
}  // namespace quic
