// Copyright (c) 2017 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 NET_THIRD_PARTY_QUIC_CORE_CRYPTO_QUIC_TLS_ADAPTER_H_
#define NET_THIRD_PARTY_QUIC_CORE_CRYPTO_QUIC_TLS_ADAPTER_H_

#include "net/third_party/quic/core/crypto/crypto_message_parser.h"
#include "net/third_party/quic/core/quic_error_codes.h"
#include "net/third_party/quic/core/quic_types.h"
#include "net/third_party/quic/platform/api/quic_export.h"
#include "net/third_party/quic/platform/api/quic_string.h"
#include "net/third_party/quic/platform/api/quic_string_piece.h"
#include "third_party/boringssl/src/include/openssl/bio.h"

namespace quic {

// QuicTlsAdapter provides an implementation of CryptoMessageParser that takes
// incoming messages and provides them to be read in a BIO (used by the TLS
// stack to read incoming messages). Messages written to the BIO by the TLS
// stack are provided to the QuicTlsAdapter's consumer through the
// OnDataReceived method of the consumer's implementation of
// QuicTlsAdapter::Visitor.
//
// QuicTlsAdapter also provides an implementation of the BIO interface,
// openssl's abstraction used by the TLS stack for I/O. The BIO interface
// provides BIO_read, BIO_write, and BIO_flush methods, with an API very similar
// to Berkeley sockets. This is a non-blocking interface - if data is not
// available for the BIO consumer to read with BIO_read, it returns 0 bytes of
// data, and the BIO consumer must handle waiting for more data and only calling
// BIO_read once data is available to read. With a QuicTlsAdapter, the signal
// that data is available to read is provided by
// QuicTlsAdapter::Visitor::OnDataAvailableForBIO.
//
// In effect, the QuicTlsAdapter moves messages between the QuicCryptoStream and
// the TLS stack. On one end, the QuicTlsAdapter implements CryptoMessageParser
// to take incoming messages and make them available to be read through the BIO,
// and on the other end, it takes messages written to the BIO and once the BIO
// flushes them, sends them out to the QuicStream via the
// QuicTlsAdapter::Visitor.
//
// Data flows from a QuicCryptoStream to the TLS stack like so:
//  1. QuicCryptoStream::OnDataAvailable is called (by QuicStream) when data is
//     available on the stream.
//  2. OnDataAvailable calls CryptoMessageParser::ProcessInput; in the case of a
//     TLS crypto stream, this is QuicTlsAdapter::ProcessInput.
//  3. ProcessInput saves the data to QuicTlsAdapter's read buffer, and signals
//     that data is available to read by calling
//     QuicTlsAdapter::Visitor::OnDataAvailableForBIO.
//  4. TlsHandshaker (which implements QuicTlsAdapter::Visitor) receives the
//     OnDataAvailableForBIO, and has the TLS stack continue its handshake.
//  5. The TLS stack calls BIO_read to read handshake messages, and this call is
//     made on a BIO backed by QuicTlsAdapter.
//  6. BIO_read calls QuicTlsAdapter::BIOReadWrapper, which calls
//     QuicTlsAdapter::Read (on the appropriate instance) which provides the
//     data from the read buffer written to by QuicTlsAdapter::ProcessInput.
//
// Data flows from the TLS stack to the QUIC crypto stream like so:
//  1. The TLS stack makes multiple calls to BIO_write as it generates handshake
//     messages. Via QuicTlsAdapter::BIOWriteWrapper and QuicTlsAdapter::Write,
//     this data gets appended to the QuicTlsAdapter's write buffer.
//  2. Once the TLS stack has written a flight of handshake messages, it calls
//     BIO_flush. This, via QuicTlsAdapter::BIOCtrlWrapper and
//     QuicTlsAdapter::Flush, signals to QuicTlsAdapter's Visitor that data has
//     been received.
//  3. QuicTlsAdapter::Flush calls
//     QuicTlsAdapter::Visitor::OnDataReceivedFromBIO with the contents of the
//     write buffer.
//  4. TlsHandshaker receives the data from OnDataReceivedFromBIO, and writes it
//     to the QUIC crypto stream.
class QUIC_EXPORT QuicTlsAdapter : public CryptoMessageParser {
 public:
  // QuicTlsAdapter::Visitor is notified whenever data is received (in either
  // direction). When data is read from the QUIC crypto stream,
  // Visitor::OnDataAvailableForBIO is called so that the Visitor can continue
  // reading from the BIO. (E.g. in the case of a TlsHandshaker as the Visitor,
  // it would continue the TLS handshake, which uses a BIO for I/O.) When data
  // is written to a QuicTlsAdapter's BIO interface and then flushed,
  // Visitor::OnDataReceivedFromBIO is called to provide the Visitor with the
  // data to write to the QUIC crypto stream.
  class QUIC_EXPORT Visitor {
   public:
    virtual ~Visitor() {}

    // OnDataAvailableForBIO is called when QuicTlsAdapter has received data
    // (via ProcessInput) that is now available to be read by the BIO.
    virtual void OnDataAvailableForBIO() = 0;

    // OnDataReceivedFromBIO is called when data is written to the BIO. For
    // example, when the TLS stack writes messages to the BIO and then flushes
    // them, the resulting data will be made available to the Visitor via this
    // method, so that the Visitor can write the messages to the QuicStream. The
    // stringpiece |data| is only valid during the execution of this function;
    // implementations must consume all of |data|.
    virtual void OnDataReceivedFromBIO(const QuicStringPiece& data) = 0;
  };

  // Constructs a QuicTlsAdapter that will notify |visitor| when data is
  // available in either direction. The provided Visitor must outlive the
  // QuicTlsAdapter.
  explicit QuicTlsAdapter(Visitor* visitor);

  ~QuicTlsAdapter() override;

  QuicErrorCode error() const override;
  const QuicString& error_detail() const override;
  bool ProcessInput(QuicStringPiece input, EncryptionLevel level) override;
  size_t InputBytesRemaining() const override;

  BIO* bio() { return bio_.get(); }

 private:
  // The following methods, Read, Write, and Flush, are used to implement the
  // BIO.

  // Read copies up to |len| bytes from |read_buffer_| into |out|. It returns
  // the number of bytes copied, zero on EOF, or a negative number on error.
  int Read(char* out, int len);

  // Write appends |len| bytes from |in| to |write_buffer_|. It returns |len|,
  // or a negative number on error.
  int Write(const char* in, int len);

  // Flush calls Visitor::OnDataReceivedFromBIO with the data in
  // |write_buffer_| and then empties the buffer.
  void Flush();

  // Used by the static BIO*Wrapper methods to get the QuicTlsAdapter instance
  // to call Read/Write/Flush on.
  static QuicTlsAdapter* GetAdapter(BIO* bio);

  // Functions used to build a BIO_METHOD vtable. BIOReadWrapper calls Read,
  // BIOWriteWrapper calls Write, and BIOCtrlWrapper calls Flush if |cmd| is
  // |BIO_CTRL_FLUSH|.

  static int BIOReadWrapper(BIO* bio, char* out, int len);
  static int BIOWriteWrapper(BIO* bio, const char* in, int len);
  // BIOCtrlWrapper has the type it does so it can be used as the |ctrl| field
  // in a BIO_METHOD struct, hence the use of long as an argument  and return
  // type.
  // NOLINTNEXTLINE
  static long BIOCtrlWrapper(BIO* bio, int cmd, long larg, void* parg);

  static const BIO_METHOD kBIOMethod;

  // Visitor to call when QuicTlsAdapter receives data (in either direction).
  Visitor* visitor_;
  bssl::UniquePtr<BIO> bio_;

  // Buffer of data received from ProcessInput waiting to be read by the BIO.
  QuicString read_buffer_;

  // Buffer of data received from the BIO waiting to be handed off to
  // Visitor::OnDataReceivedFromBIO.
  QuicString write_buffer_;

  QuicString error_detail_;
};

}  // namespace quic

#endif  // NET_THIRD_PARTY_QUIC_CORE_CRYPTO_QUIC_TLS_ADAPTER_H_
