// 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 <string>
#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 = "", int num_certs_in_chain = 1);

// 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_
