// Copyright (c) 2012 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.

#ifndef QUICHE_QUIC_TEST_TOOLS_CRYPTO_TEST_UTILS_H_
#define QUICHE_QUIC_TEST_TOOLS_CRYPTO_TEST_UTILS_H_

#include <cstdarg>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <utility>
#include <vector>

#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "openssl/evp.h"
#include "quiche/quic/core/crypto/crypto_framer.h"
#include "quiche/quic/core/crypto/quic_random.h"
#include "quiche/quic/core/quic_connection.h"
#include "quiche/quic/core/quic_framer.h"
#include "quiche/quic/core/quic_packets.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/test_tools/quic_test_utils.h"
#include "quiche/common/quiche_callbacks.h"

namespace quic {

class ProofSource;
class ProofVerifier;
class ProofVerifyContext;
class QuicClock;
class QuicConfig;
class QuicCryptoClientStream;
class QuicCryptoServerConfig;
class QuicCryptoServerStreamBase;
class QuicCryptoStream;
class QuicServerId;

namespace test {

class PacketSaver;
class PacketSavingConnection;

namespace crypto_test_utils {

// An interface for a source of callbacks. This is used for invoking
// callbacks asynchronously.
//
// Call the RunPendingCallbacks method regularly to run the callbacks from
// this source.
class CallbackSource {
 public:
  virtual ~CallbackSource() {}

  // Runs pending callbacks from this source. If there is no pending
  // callback, does nothing.
  virtual void RunPendingCallbacks() = 0;
};

// FakeClientOptions bundles together a number of options for configuring
// HandshakeWithFakeClient.
struct FakeClientOptions {
  FakeClientOptions();
  ~FakeClientOptions();

  // If only_tls_versions is set, then the client will only use TLS for the
  // crypto handshake.
  bool only_tls_versions = false;

  // If only_quic_crypto_versions is set, then the client will only use
  // PROTOCOL_QUIC_CRYPTO for the crypto handshake.
  bool only_quic_crypto_versions = false;
};

// Returns a QuicCryptoServerConfig that is in a reasonable configuration to
// pass into HandshakeWithFakeServer.
std::unique_ptr<QuicCryptoServerConfig> CryptoServerConfigForTesting(
    const std::string& trust_anchor_id = "");

// returns: the number of client hellos that the client sent.
int HandshakeWithFakeServer(QuicConfig* server_quic_config,
                            QuicCryptoServerConfig* crypto_config,
                            MockQuicConnectionHelper* helper,
                            MockAlarmFactory* alarm_factory,
                            PacketSavingConnection* client_conn,
                            QuicCryptoClientStreamBase* client,
                            std::string alpn);

// returns: the number of client hellos that the client sent.
int HandshakeWithFakeClient(MockQuicConnectionHelper* helper,
                            MockAlarmFactory* alarm_factory,
                            PacketSavingConnection* server_conn,
                            QuicCryptoServerStreamBase* server,
                            const QuicServerId& server_id,
                            const FakeClientOptions& options, std::string alpn);

// SetupCryptoServerConfigForTest configures |crypto_config|
// with sensible defaults for testing.
void SetupCryptoServerConfigForTest(const QuicClock* clock, QuicRandom* rand,
                                    QuicCryptoServerConfig* crypto_config);

// Sends the handshake message |message| to stream |stream| with the perspective
// that the message is coming from |perspective|.
void SendHandshakeMessageToStream(QuicCryptoStream* stream,
                                  const CryptoHandshakeMessage& message,
                                  Perspective perspective);

// CommunicateHandshakeMessages moves messages from `client` (or
// `packets_from_client`) to `server` from `server` (or `packets_from_server`)
// to `client` until `clients`'s handshake has completed.
void CommunicateHandshakeMessages(PacketSavingConnection* client_conn,
                                  QuicCryptoStream* client,
                                  PacketSavingConnection* server_conn,
                                  QuicCryptoStream* server);
void CommunicateHandshakeMessages(QuicConnection& client_conn,
                                  QuicCryptoStream& client,
                                  QuicConnection& server_conn,
                                  QuicCryptoStream& server,
                                  PacketProvider& packets_from_client,
                                  PacketProvider& packets_from_server);

// CommunicateHandshakeMessagesUntil:
// 1) Moves messages from `client` (or `packets_from_client`) to `server` until
//    `server_condition` is met.
// 2) Moves messages from `server` (or `packets_from_server`) to `client` until
//    `client_condition` is met.
// 3)  For IETF QUIC, if `process_stream_data` is true, STREAM_FRAME within the
// packet containing crypto messages is also processed.
// 4) Returns true if both conditions are met.
// 5) Returns false if either connection is closed or there is no more packet to
// deliver before both conditions are met.
// TODO(ericorth): If the callers are eventually converted and these overloads
// are merged, consider also converting `process_stream_data` to an enum.
bool CommunicateHandshakeMessagesUntil(
    PacketSavingConnection* client_conn, QuicCryptoStream* client,
    quiche::UnretainedCallback<bool()> client_condition,
    PacketSavingConnection* server_conn, QuicCryptoStream* server,
    quiche::UnretainedCallback<bool()> server_condition,
    bool process_stream_data);
bool CommunicateHandshakeMessagesUntil(
    QuicConnection& client_conn, QuicCryptoStream& client,
    quiche::UnretainedCallback<bool()> client_condition,
    QuicConnection& server_conn, QuicCryptoStream& server,
    quiche::UnretainedCallback<bool()> server_condition,
    bool process_stream_data, PacketProvider& packets_from_client,
    PacketProvider& packets_from_server);

// AdvanceHandshake attempts to move all current messages:
// * Starting at `client_i`, from `client` to `server`
// * Starting at `server_i`, from `server` to `client`
//
// Returns the total number of messages attempted to be moved so far from each
// of `client` and `server` (number moved in this call plus `client_i` or
// `server_i`).
std::pair<size_t, size_t> AdvanceHandshake(PacketSavingConnection* client_conn,
                                           QuicCryptoStream* client,
                                           size_t client_i,
                                           PacketSavingConnection* server_conn,
                                           QuicCryptoStream* server,
                                           size_t server_i);

// AdvanceHandshake attempts to move all messages from `packets_from_client` to
// `server` and from `packets_from_server` to `client`.
void AdvanceHandshake(
    absl::Span<const QuicEncryptedPacket* const> packets_from_client,
    QuicConnection& client_conn, QuicCryptoStream& client,
    absl::Span<const QuicEncryptedPacket* const> packets_from_server,
    QuicConnection& server_conn, QuicCryptoStream& server);

// Returns the value for the tag |tag| in the tag value map of |message|.
std::string GetValueForTag(const CryptoHandshakeMessage& message, QuicTag tag);

// Returns a new |ProofSource| that serves up test certificates. If
// |trust_anchor_id| is provided, test certificates will be associated
// with it as described at
// https://tlswg.org/tls-trust-anchor-ids/draft-ietf-tls-trust-anchor-ids.html#section-4.1.
std::unique_ptr<ProofSource> ProofSourceForTesting(
    const std::string& trust_anchor_id = "");

// Returns a new |ProofVerifier| that uses the QUIC testing root CA.
std::unique_ptr<ProofVerifier> ProofVerifierForTesting();

// Returns the hostname used by the proof source and the proof verifier above.
std::string CertificateHostnameForTesting();

// Returns a hash of the leaf test certificate.
uint64_t LeafCertHashForTesting();

// Returns a |ProofVerifyContext| that must be used with the verifier
// returned by |ProofVerifierForTesting|.
std::unique_ptr<ProofVerifyContext> ProofVerifyContextForTesting();

// Creates a minimal dummy reject message that will pass the client-config
// validation tests. This will include a server config, but no certs, proof
// source address token, or server nonce.
void FillInDummyReject(CryptoHandshakeMessage* rej);

// ParseTag returns a QuicTag from parsing |tagstr|. |tagstr| may either be
// in the format "EXMP" (i.e. ASCII format), or "#11223344" (an explicit hex
// format). It QUICHE_CHECK fails if there's a parse error.
QuicTag ParseTag(const char* tagstr);

// Message constructs a CHLO message from a provided vector of tag/value pairs.
// The first of each pair is the tag of a tag/value and is given as an argument
// to |ParseTag|. The second is the value of the tag/value pair and is either a
// hex dump, preceeded by a '#', or a raw value. If minimum_size_bytes is
// provided then the message will be padded to this minimum size.
//
//   CreateCHLO(
//       {{"NOCE", "#11223344"},
//        {"SNI", "www.example.com"}},
//       optional_minimum_size_bytes);
CryptoHandshakeMessage CreateCHLO(
    std::vector<std::pair<std::string, std::string>> tags_and_values);
CryptoHandshakeMessage CreateCHLO(
    std::vector<std::pair<std::string, std::string>> tags_and_values,
    int minimum_size_bytes);

// Return an inchoate CHLO with some basic tag value pairs.
CryptoHandshakeMessage GenerateDefaultInchoateCHLO(
    const QuicClock* clock, QuicTransportVersion version,
    QuicCryptoServerConfig* crypto_config);

// Takes a inchoate CHLO, returns a full CHLO in |out| which can pass
// |crypto_config|'s validation.
void GenerateFullCHLO(
    const CryptoHandshakeMessage& inchoate_chlo,
    QuicCryptoServerConfig* crypto_config, QuicSocketAddress server_addr,
    QuicSocketAddress client_addr, QuicTransportVersion transport_version,
    const QuicClock* clock,
    quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config,
    QuicCompressedCertsCache* compressed_certs_cache,
    CryptoHandshakeMessage* out);

void CompareClientAndServerKeys(QuicCryptoClientStreamBase* client,
                                QuicCryptoServerStreamBase* server);

// Return a CHLO nonce in hexadecimal.
std::string GenerateClientNonceHex(const QuicClock* clock,
                                   QuicCryptoServerConfig* crypto_config);

// Return a CHLO PUBS in hexadecimal.
std::string GenerateClientPublicValuesHex();

}  // namespace crypto_test_utils

}  // namespace test

}  // namespace quic

#endif  // QUICHE_QUIC_TEST_TOOLS_CRYPTO_TEST_UTILS_H_
