/*
 *  Copyright 2016 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/p2p/quic/quictransportchannel.h"

#include <utility>

#include "net/quic/crypto/proof_source.h"
#include "net/quic/crypto/proof_verifier.h"
#include "net/quic/crypto/quic_crypto_client_config.h"
#include "net/quic/crypto/quic_crypto_server_config.h"
#include "net/quic/quic_connection.h"
#include "net/quic/quic_crypto_client_stream.h"
#include "net/quic/quic_crypto_server_stream.h"
#include "net/quic/quic_packet_writer.h"
#include "net/quic/quic_protocol.h"
#include "webrtc/p2p/base/common.h"
#include "webrtc/rtc_base/checks.h"
#include "webrtc/rtc_base/helpers.h"
#include "webrtc/rtc_base/logging.h"
#include "webrtc/rtc_base/socket.h"
#include "webrtc/rtc_base/thread.h"

namespace {

// QUIC public header constants for net::QuicConnection. These are arbitrary
// given that |channel_| only receives packets specific to this channel,
// in which case we already know the QUIC packets have the correct destination.
const net::QuicConnectionId kConnectionId = 0;
const net::IPAddress kConnectionIpAddress(0, 0, 0, 0);
const net::IPEndPoint kConnectionIpEndpoint(kConnectionIpAddress, 0);

// Arbitrary server port number for net::QuicCryptoClientConfig.
const int kQuicServerPort = 0;

// QUIC connection timeout. This is large so that |channel_| can
// be responsible for connection timeout.
const int kIdleConnectionStateLifetime = 1000;  // seconds

// Length of HKDF input keying material, equal to its number of bytes.
// https://tools.ietf.org/html/rfc5869#section-2.2.
// TODO(mikescarlett): Verify that input keying material length is correct.
const size_t kInputKeyingMaterialLength = 32;

// We don't pull the RTP constants from rtputils.h, to avoid a layer violation.
const size_t kMinRtpPacketLen = 12;

bool IsRtpPacket(const char* data, size_t len) {
  const uint8_t* u = reinterpret_cast<const uint8_t*>(data);
  return (len >= kMinRtpPacketLen && (u[0] & 0xC0) == 0x80);
}

// Function for detecting QUIC packets based off
// https://tools.ietf.org/html/draft-tsvwg-quic-protocol-02#section-6.
const size_t kMinQuicPacketLen = 2;

bool IsQuicPacket(const char* data, size_t len) {
  const uint8_t* u = reinterpret_cast<const uint8_t*>(data);
  return (len >= kMinQuicPacketLen && (u[0] & 0x80) == 0);
}

// Used by QuicCryptoServerConfig to provide dummy proof credentials.
// TODO(mikescarlett): Remove when secure P2P QUIC handshake is possible.
class DummyProofSource : public net::ProofSource {
 public:
  DummyProofSource() {}
  ~DummyProofSource() override {}

  // ProofSource override.
  bool GetProof(const net::IPAddress& server_ip,
                const std::string& hostname,
                const std::string& server_config,
                net::QuicVersion quic_version,
                base::StringPiece chlo_hash,
                bool ecdsa_ok,
                scoped_refptr<net::ProofSource::Chain>* out_chain,
                std::string* out_signature,
                std::string* out_leaf_cert_sct) override {
    LOG(LS_INFO) << "GetProof() providing dummy credentials for insecure QUIC";
    std::vector<std::string> certs;
    certs.push_back("Dummy cert");
    *out_chain = new ProofSource::Chain(certs);
    *out_signature = "Dummy signature";
    *out_leaf_cert_sct = "Dummy timestamp";
    return true;
  }
};

// Used by QuicCryptoClientConfig to ignore the peer's credentials
// and establish an insecure QUIC connection.
// TODO(mikescarlett): Remove when secure P2P QUIC handshake is possible.
class InsecureProofVerifier : public net::ProofVerifier {
 public:
  InsecureProofVerifier() {}
  ~InsecureProofVerifier() override {}

  // ProofVerifier override.
  net::QuicAsyncStatus VerifyProof(
      const std::string& hostname,
      const uint16_t port,
      const std::string& server_config,
      net::QuicVersion quic_version,
      base::StringPiece chlo_hash,
      const std::vector<std::string>& certs,
      const std::string& cert_sct,
      const std::string& signature,
      const net::ProofVerifyContext* context,
      std::string* error_details,
      std::unique_ptr<net::ProofVerifyDetails>* verify_details,
      net::ProofVerifierCallback* callback) override {
    LOG(LS_INFO) << "VerifyProof() ignoring credentials and returning success";
    return net::QUIC_SUCCESS;
  }
};

}  // namespace

namespace cricket {

QuicTransportChannel::QuicTransportChannel(TransportChannelImpl* channel)
    : TransportChannelImpl(channel->transport_name(), channel->component()),
      network_thread_(rtc::Thread::Current()),
      channel_(channel),
      helper_(network_thread_) {
  channel_->SignalWritableState.connect(this,
                                        &QuicTransportChannel::OnWritableState);
  channel_->SignalReadPacket.connect(this, &QuicTransportChannel::OnReadPacket);
  channel_->SignalSentPacket.connect(this, &QuicTransportChannel::OnSentPacket);
  channel_->SignalReadyToSend.connect(this,
                                      &QuicTransportChannel::OnReadyToSend);
  channel_->SignalGatheringState.connect(
      this, &QuicTransportChannel::OnGatheringState);
  channel_->SignalCandidateGathered.connect(
      this, &QuicTransportChannel::OnCandidateGathered);
  channel_->SignalRoleConflict.connect(this,
                                       &QuicTransportChannel::OnRoleConflict);
  channel_->SignalRouteChange.connect(this,
                                      &QuicTransportChannel::OnRouteChange);
  channel_->SignalSelectedCandidatePairChanged.connect(
      this, &QuicTransportChannel::OnSelectedCandidatePairChanged);
  channel_->SignalStateChanged.connect(
      this, &QuicTransportChannel::OnChannelStateChanged);
  channel_->SignalReceivingState.connect(
      this, &QuicTransportChannel::OnReceivingState);

  // Set the QUIC connection timeout.
  config_.SetIdleConnectionStateLifetime(
      net::QuicTime::Delta::FromSeconds(kIdleConnectionStateLifetime),
      net::QuicTime::Delta::FromSeconds(kIdleConnectionStateLifetime));
  // Set the bytes reserved for the QUIC connection ID to zero.
  config_.SetBytesForConnectionIdToSend(0);
}

QuicTransportChannel::~QuicTransportChannel() {}

bool QuicTransportChannel::SetLocalCertificate(
    const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
  if (!certificate) {
    LOG_J(LS_ERROR, this)
        << "No local certificate was supplied. Not doing QUIC.";
    return false;
  }
  if (!local_certificate_) {
    local_certificate_ = certificate;
    return true;
  }
  if (certificate == local_certificate_) {
    // This may happen during renegotiation.
    LOG_J(LS_INFO, this) << "Ignoring identical certificate";
    return true;
  }
  LOG_J(LS_ERROR, this)
      << "Local certificate of the QUIC connection already set. "
         "Can't change the local certificate once it's active.";
  return false;
}

rtc::scoped_refptr<rtc::RTCCertificate>
QuicTransportChannel::GetLocalCertificate() const {
  return local_certificate_;
}

bool QuicTransportChannel::SetSslRole(rtc::SSLRole role) {
  if (ssl_role_ && *ssl_role_ == role) {
    LOG_J(LS_WARNING, this) << "Ignoring SSL Role identical to current role.";
    return true;
  }
  if (quic_state_ != QUIC_TRANSPORT_CONNECTED) {
    ssl_role_ = rtc::Optional<rtc::SSLRole>(role);
    return true;
  }
  LOG_J(LS_ERROR, this)
      << "SSL Role can't be reversed after the session is setup.";
  return false;
}

bool QuicTransportChannel::GetSslRole(rtc::SSLRole* role) const {
  if (!ssl_role_) {
    return false;
  }
  *role = *ssl_role_;
  return true;
}

bool QuicTransportChannel::SetRemoteFingerprint(const std::string& digest_alg,
                                                const uint8_t* digest,
                                                size_t digest_len) {
  if (digest_alg.empty()) {
    RTC_DCHECK(!digest_len);
    LOG_J(LS_ERROR, this) << "Remote peer doesn't support digest algorithm.";
    return false;
  }
  std::string remote_fingerprint_value(reinterpret_cast<const char*>(digest),
                                       digest_len);
  // Once we have the local certificate, the same remote fingerprint can be set
  // multiple times. This may happen during renegotiation.
  if (remote_fingerprint_ &&
      remote_fingerprint_->value == remote_fingerprint_value &&
      remote_fingerprint_->algorithm == digest_alg) {
    LOG_J(LS_INFO, this)
        << "Ignoring identical remote fingerprint and algorithm";
    return true;
  }
  remote_fingerprint_ = rtc::Optional<RemoteFingerprint>(RemoteFingerprint());
  remote_fingerprint_->value = remote_fingerprint_value;
  remote_fingerprint_->algorithm = digest_alg;
  return true;
}

bool QuicTransportChannel::ExportKeyingMaterial(const std::string& label,
                                                const uint8_t* context,
                                                size_t context_len,
                                                bool use_context,
                                                uint8_t* result,
                                                size_t result_len) {
  std::string quic_context(reinterpret_cast<const char*>(context), context_len);
  std::string quic_result;
  if (!quic_->ExportKeyingMaterial(label, quic_context, result_len,
                                   &quic_result)) {
    return false;
  }
  quic_result.copy(reinterpret_cast<char*>(result), result_len);
  return true;
}

bool QuicTransportChannel::GetSrtpCryptoSuite(int* cipher) {
  *cipher = rtc::SRTP_AES128_CM_SHA1_80;
  return true;
}

// Called from upper layers to send a media packet.
int QuicTransportChannel::SendPacket(const char* data,
                                     size_t size,
                                     const rtc::PacketOptions& options,
                                     int flags) {
  if ((flags & PF_SRTP_BYPASS) && IsRtpPacket(data, size)) {
    return channel_->SendPacket(data, size, options);
  }
  LOG(LS_ERROR) << "Failed to send an invalid SRTP bypass packet using QUIC.";
  return -1;
}

// The state transition logic here is as follows:
//     - Before the QUIC handshake is complete, the QUIC channel is unwritable.
//     - When |channel_| goes writable we start the QUIC handshake.
//     - Once the QUIC handshake completes, the state is that of the
//       |channel_| again.
void QuicTransportChannel::OnWritableState(TransportChannel* channel) {
  RTC_DCHECK(rtc::Thread::Current() == network_thread_);
  RTC_DCHECK(channel == channel_.get());
  LOG_J(LS_VERBOSE, this)
      << "QuicTransportChannel: channel writable state changed to "
      << channel_->writable();
  switch (quic_state_) {
    case QUIC_TRANSPORT_NEW:
      // Start the QUIC handshake when |channel_| is writable.
      // This will fail if the SSL role or remote fingerprint are not set.
      // Otherwise failure could result from network or QUIC errors.
      MaybeStartQuic();
      break;
    case QUIC_TRANSPORT_CONNECTED:
      // Note: SignalWritableState fired by set_writable.
      set_writable(channel_->writable());
      if (HasDataToWrite()) {
        OnCanWrite();
      }
      break;
    case QUIC_TRANSPORT_CONNECTING:
      // This channel is not writable until the QUIC handshake finishes. It
      // might have been write blocked.
      if (HasDataToWrite()) {
        OnCanWrite();
      }
      break;
    case QUIC_TRANSPORT_CLOSED:
      // TODO(mikescarlett): Allow the QUIC connection to be reset if it drops
      // due to a non-failure.
      break;
  }
}

void QuicTransportChannel::OnReceivingState(TransportChannel* channel) {
  RTC_DCHECK(rtc::Thread::Current() == network_thread_);
  RTC_DCHECK(channel == channel_.get());
  LOG_J(LS_VERBOSE, this)
      << "QuicTransportChannel: channel receiving state changed to "
      << channel_->receiving();
  if (quic_state_ == QUIC_TRANSPORT_CONNECTED) {
    // Note: SignalReceivingState fired by set_receiving.
    set_receiving(channel_->receiving());
  }
}

void QuicTransportChannel::OnReadPacket(TransportChannel* channel,
                                        const char* data,
                                        size_t size,
                                        const rtc::PacketTime& packet_time,
                                        int flags) {
  RTC_DCHECK(rtc::Thread::Current() == network_thread_);
  RTC_DCHECK(channel == channel_.get());
  RTC_DCHECK(flags == 0);

  switch (quic_state_) {
    case QUIC_TRANSPORT_NEW:
      // This would occur if other peer is ready to start QUIC but this peer
      // hasn't started QUIC.
      LOG_J(LS_INFO, this) << "Dropping packet received before QUIC started.";
      break;
    case QUIC_TRANSPORT_CONNECTING:
    case QUIC_TRANSPORT_CONNECTED:
      // We should only get QUIC or SRTP packets; STUN's already been demuxed.
      // Is this potentially a QUIC packet?
      if (IsQuicPacket(data, size)) {
        if (!HandleQuicPacket(data, size)) {
          LOG_J(LS_ERROR, this) << "Failed to handle QUIC packet.";
          return;
        }
      } else {
        // If this is an RTP packet, signal upwards as a bypass packet.
        if (!IsRtpPacket(data, size)) {
          LOG_J(LS_ERROR, this)
              << "Received unexpected non-QUIC, non-RTP packet.";
          return;
        }
        SignalReadPacket(this, data, size, packet_time, PF_SRTP_BYPASS);
      }
      break;
    case QUIC_TRANSPORT_CLOSED:
      // This shouldn't be happening. Drop the packet.
      break;
  }
}

void QuicTransportChannel::OnSentPacket(TransportChannel* channel,
                                        const rtc::SentPacket& sent_packet) {
  RTC_DCHECK(rtc::Thread::Current() == network_thread_);
  SignalSentPacket(this, sent_packet);
}

void QuicTransportChannel::OnReadyToSend(TransportChannel* channel) {
  if (writable()) {
    SignalReadyToSend(this);
  }
}

void QuicTransportChannel::OnGatheringState(TransportChannelImpl* channel) {
  RTC_DCHECK(channel == channel_.get());
  SignalGatheringState(this);
}

void QuicTransportChannel::OnCandidateGathered(TransportChannelImpl* channel,
                                               const Candidate& c) {
  RTC_DCHECK(channel == channel_.get());
  SignalCandidateGathered(this, c);
}

void QuicTransportChannel::OnRoleConflict(TransportChannelImpl* channel) {
  RTC_DCHECK(channel == channel_.get());
  SignalRoleConflict(this);
}

void QuicTransportChannel::OnRouteChange(TransportChannel* channel,
                                         const Candidate& candidate) {
  RTC_DCHECK(channel == channel_.get());
  SignalRouteChange(this, candidate);
}

void QuicTransportChannel::OnSelectedCandidatePairChanged(
    TransportChannel* channel,
    CandidatePairInterface* selected_candidate_pair,
    int last_sent_packet_id,
    bool ready_to_send) {
  RTC_DCHECK(channel == channel_.get());
  SignalSelectedCandidatePairChanged(this, selected_candidate_pair,
                                     last_sent_packet_id, ready_to_send);
}

void QuicTransportChannel::OnChannelStateChanged(
    TransportChannelImpl* channel) {
  RTC_DCHECK(channel == channel_.get());
  SignalStateChanged(this);
}

bool QuicTransportChannel::MaybeStartQuic() {
  if (!channel_->writable()) {
    LOG_J(LS_ERROR, this) << "Couldn't start QUIC handshake.";
    return false;
  }
  if (!CreateQuicSession() || !StartQuicHandshake()) {
    LOG_J(LS_WARNING, this)
        << "Underlying channel is writable but cannot start "
           "the QUIC handshake.";
    return false;
  }
  // Verify connection is not closed due to QUIC bug or network failure.
  // A closed connection should not happen since |channel_| is writable.
  if (!quic_->connection()->connected()) {
    LOG_J(LS_ERROR, this)
        << "QUIC connection should not be closed if underlying "
           "channel is writable.";
    return false;
  }
  // Indicate that |quic_| is ready to receive QUIC packets.
  set_quic_state(QUIC_TRANSPORT_CONNECTING);
  return true;
}

bool QuicTransportChannel::CreateQuicSession() {
  if (!ssl_role_ || !remote_fingerprint_) {
    return false;
  }
  net::Perspective perspective = (*ssl_role_ == rtc::SSL_CLIENT)
                                     ? net::Perspective::IS_CLIENT
                                     : net::Perspective::IS_SERVER;
  bool owns_writer = false;
  std::unique_ptr<net::QuicConnection> connection(new net::QuicConnection(
      kConnectionId, kConnectionIpEndpoint, &helper_, this, owns_writer,
      perspective, net::QuicSupportedVersions()));
  quic_.reset(new QuicSession(std::move(connection), config_));
  quic_->SignalHandshakeComplete.connect(
      this, &QuicTransportChannel::OnHandshakeComplete);
  quic_->SignalConnectionClosed.connect(
      this, &QuicTransportChannel::OnConnectionClosed);
  quic_->SignalIncomingStream.connect(this,
                                      &QuicTransportChannel::OnIncomingStream);
  return true;
}

bool QuicTransportChannel::StartQuicHandshake() {
  if (*ssl_role_ == rtc::SSL_CLIENT) {
    // Unique identifier for remote peer.
    net::QuicServerId server_id(remote_fingerprint_->value, kQuicServerPort);
    // Perform authentication of remote peer; owned by QuicCryptoClientConfig.
    // TODO(mikescarlett): Actually verify proof.
    net::ProofVerifier* proof_verifier = new InsecureProofVerifier();
    quic_crypto_client_config_.reset(
        new net::QuicCryptoClientConfig(proof_verifier));
    net::QuicCryptoClientStream* crypto_stream =
        new net::QuicCryptoClientStream(server_id, quic_.get(),
                                        new net::ProofVerifyContext(),
                                        quic_crypto_client_config_.get(), this);
    quic_->StartClientHandshake(crypto_stream);
    LOG_J(LS_INFO, this) << "QuicTransportChannel: Started client handshake.";
  } else {
    RTC_DCHECK_EQ(*ssl_role_, rtc::SSL_SERVER);
    // Provide credentials to remote peer; owned by QuicCryptoServerConfig.
    // TODO(mikescarlett): Actually provide credentials.
    net::ProofSource* proof_source = new DummyProofSource();
    // Input keying material to HKDF, per http://tools.ietf.org/html/rfc5869.
    // This is pseudorandom so that HKDF-Extract outputs a pseudorandom key,
    // since QuicCryptoServerConfig does not use a salt value.
    std::string source_address_token_secret;
    if (!rtc::CreateRandomString(kInputKeyingMaterialLength,
                                 &source_address_token_secret)) {
      LOG_J(LS_ERROR, this)
          << "Error generating input keying material for HKDF.";
      return false;
    }
    quic_crypto_server_config_.reset(new net::QuicCryptoServerConfig(
        source_address_token_secret, helper_.GetRandomGenerator(),
        proof_source));
    // Provide server with serialized config string to prove ownership.
    net::QuicCryptoServerConfig::ConfigOptions options;
    quic_crypto_server_config_->AddDefaultConfig(helper_.GetRandomGenerator(),
                                                 helper_.GetClock(), options);
    quic_compressed_certs_cache_.reset(new net::QuicCompressedCertsCache(
        net::QuicCompressedCertsCache::kQuicCompressedCertsCacheSize));
    // TODO(mikescarlett): Add support for stateless rejects.
    bool use_stateless_rejects_if_peer_supported = false;
    net::QuicCryptoServerStream* crypto_stream =
        new net::QuicCryptoServerStream(quic_crypto_server_config_.get(),
                                        quic_compressed_certs_cache_.get(),
                                        use_stateless_rejects_if_peer_supported,
                                        quic_.get());
    quic_->StartServerHandshake(crypto_stream);
    LOG_J(LS_INFO, this) << "QuicTransportChannel: Started server handshake.";
  }
  return true;
}

bool QuicTransportChannel::HandleQuicPacket(const char* data, size_t size) {
  RTC_DCHECK(rtc::Thread::Current() == network_thread_);
  return quic_->OnReadPacket(data, size);
}

net::WriteResult QuicTransportChannel::WritePacket(
    const char* buffer,
    size_t buf_len,
    const net::IPAddress& self_address,
    const net::IPEndPoint& peer_address,
    net::PerPacketOptions* options) {
  // QUIC should never call this if IsWriteBlocked, but just in case...
  if (IsWriteBlocked()) {
    return net::WriteResult(net::WRITE_STATUS_BLOCKED, EWOULDBLOCK);
  }
  // TODO(mikescarlett): Figure out how to tell QUIC "I dropped your packet, but
  // don't block" without the QUIC connection tearing itself down.
  int sent = channel_->SendPacket(buffer, buf_len, rtc::PacketOptions());
  int bytes_written = sent > 0 ? sent : 0;
  return net::WriteResult(net::WRITE_STATUS_OK, bytes_written);
}

// TODO(mikescarlett): Implement check for whether |channel_| is currently
// write blocked so that |quic_| does not try to write packet. This is
// necessary because |channel_| can be writable yet write blocked and
// channel_->GetError() is not flushed when there is no error.
bool QuicTransportChannel::IsWriteBlocked() const {
  return !channel_->writable();
}

void QuicTransportChannel::OnHandshakeComplete() {
  set_quic_state(QUIC_TRANSPORT_CONNECTED);
  set_writable(true);
  // OnReceivingState might have been called before the QUIC channel was
  // connected, in which case the QUIC channel is now receiving.
  if (channel_->receiving()) {
    set_receiving(true);
  }
}

void QuicTransportChannel::OnConnectionClosed(net::QuicErrorCode error,
                                              bool from_peer) {
  LOG_J(LS_INFO, this) << "Connection closed by "
                       << (from_peer ? "other" : "this") << " peer "
                       << "with QUIC error " << error;
  // TODO(mikescarlett): Allow the QUIC session to be reset when the connection
  // does not close due to failure.
  set_quic_state(QUIC_TRANSPORT_CLOSED);
  set_writable(false);
  SignalClosed();
}

void QuicTransportChannel::OnProofValid(
    const net::QuicCryptoClientConfig::CachedState& cached) {
  LOG_J(LS_INFO, this) << "Cached proof marked valid";
}

void QuicTransportChannel::OnProofVerifyDetailsAvailable(
    const net::ProofVerifyDetails& verify_details) {
  LOG_J(LS_INFO, this) << "Proof verify details available from"
                       << " QuicCryptoClientStream";
}

bool QuicTransportChannel::HasDataToWrite() const {
  return quic_ && quic_->HasDataToWrite();
}

void QuicTransportChannel::OnCanWrite() {
  RTC_DCHECK(quic_ != nullptr);
  quic_->connection()->OnCanWrite();
}

void QuicTransportChannel::set_quic_state(QuicTransportState state) {
  LOG_J(LS_VERBOSE, this) << "set_quic_state from:" << quic_state_ << " to "
                          << state;
  quic_state_ = state;
}

ReliableQuicStream* QuicTransportChannel::CreateQuicStream() {
  if (quic_) {
    net::SpdyPriority priority = 0;  // Priority of the QUIC stream
    return quic_->CreateOutgoingDynamicStream(priority);
  }
  return nullptr;
}

void QuicTransportChannel::OnIncomingStream(ReliableQuicStream* stream) {
  SignalIncomingStream(stream);
}

}  // namespace cricket
