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

#include "quic/core/crypto/crypto_framer.h"

#include <string>
#include <utility>

#include "absl/base/attributes.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "quic/core/crypto/crypto_protocol.h"
#include "quic/core/quic_data_reader.h"
#include "quic/core/quic_data_writer.h"
#include "quic/core/quic_packets.h"
#include "quic/platform/api/quic_logging.h"
#include "common/quiche_endian.h"

namespace quic {

namespace {

const size_t kQuicTagSize = sizeof(QuicTag);
const size_t kCryptoEndOffsetSize = sizeof(uint32_t);
const size_t kNumEntriesSize = sizeof(uint16_t);

// OneShotVisitor is a framer visitor that records a single handshake message.
class OneShotVisitor : public CryptoFramerVisitorInterface {
 public:
  OneShotVisitor() : error_(false) {}

  void OnError(CryptoFramer* /*framer*/) override { error_ = true; }

  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
    out_ = std::make_unique<CryptoHandshakeMessage>(message);
  }

  bool error() const { return error_; }

  std::unique_ptr<CryptoHandshakeMessage> release() { return std::move(out_); }

 private:
  std::unique_ptr<CryptoHandshakeMessage> out_;
  bool error_;
};

}  // namespace

CryptoFramer::CryptoFramer()
    : visitor_(nullptr),
      error_detail_(""),
      num_entries_(0),
      values_len_(0),
      process_truncated_messages_(false) {
  Clear();
}

CryptoFramer::~CryptoFramer() {}

// static
std::unique_ptr<CryptoHandshakeMessage> CryptoFramer::ParseMessage(
    absl::string_view in) {
  OneShotVisitor visitor;
  CryptoFramer framer;

  framer.set_visitor(&visitor);
  if (!framer.ProcessInput(in) || visitor.error() ||
      framer.InputBytesRemaining()) {
    return nullptr;
  }

  return visitor.release();
}

QuicErrorCode CryptoFramer::error() const {
  return error_;
}

const std::string& CryptoFramer::error_detail() const {
  return error_detail_;
}

bool CryptoFramer::ProcessInput(absl::string_view input,
                                EncryptionLevel /*level*/) {
  return ProcessInput(input);
}

bool CryptoFramer::ProcessInput(absl::string_view input) {
  QUICHE_DCHECK_EQ(QUIC_NO_ERROR, error_);
  if (error_ != QUIC_NO_ERROR) {
    return false;
  }
  error_ = Process(input);
  if (error_ != QUIC_NO_ERROR) {
    QUICHE_DCHECK(!error_detail_.empty());
    visitor_->OnError(this);
    return false;
  }

  return true;
}

size_t CryptoFramer::InputBytesRemaining() const {
  return buffer_.length();
}

bool CryptoFramer::HasTag(QuicTag tag) const {
  if (state_ != STATE_READING_VALUES) {
    return false;
  }
  for (const auto& it : tags_and_lengths_) {
    if (it.first == tag) {
      return true;
    }
  }
  return false;
}

void CryptoFramer::ForceHandshake() {
  QuicDataReader reader(buffer_.data(), buffer_.length(),
                        quiche::HOST_BYTE_ORDER);
  for (const std::pair<QuicTag, size_t>& item : tags_and_lengths_) {
    absl::string_view value;
    if (reader.BytesRemaining() < item.second) {
      break;
    }
    reader.ReadStringPiece(&value, item.second);
    message_.SetStringPiece(item.first, value);
  }
  visitor_->OnHandshakeMessage(message_);
}

// static
std::unique_ptr<QuicData> CryptoFramer::ConstructHandshakeMessage(
    const CryptoHandshakeMessage& message) {
  size_t num_entries = message.tag_value_map().size();
  size_t pad_length = 0;
  bool need_pad_tag = false;
  bool need_pad_value = false;

  size_t len = message.size();
  if (len < message.minimum_size()) {
    need_pad_tag = true;
    need_pad_value = true;
    num_entries++;

    size_t delta = message.minimum_size() - len;
    const size_t overhead = kQuicTagSize + kCryptoEndOffsetSize;
    if (delta > overhead) {
      pad_length = delta - overhead;
    }
    len += overhead + pad_length;
  }

  if (num_entries > kMaxEntries) {
    return nullptr;
  }

  std::unique_ptr<char[]> buffer(new char[len]);
  QuicDataWriter writer(len, buffer.get(), quiche::HOST_BYTE_ORDER);
  if (!writer.WriteTag(message.tag())) {
    QUICHE_DCHECK(false) << "Failed to write message tag.";
    return nullptr;
  }
  if (!writer.WriteUInt16(static_cast<uint16_t>(num_entries))) {
    QUICHE_DCHECK(false) << "Failed to write size.";
    return nullptr;
  }
  if (!writer.WriteUInt16(0)) {
    QUICHE_DCHECK(false) << "Failed to write padding.";
    return nullptr;
  }

  uint32_t end_offset = 0;
  // Tags and offsets
  for (auto it = message.tag_value_map().begin();
       it != message.tag_value_map().end(); ++it) {
    if (it->first == kPAD && need_pad_tag) {
      // Existing PAD tags are only checked when padding needs to be added
      // because parts of the code may need to reserialize received messages
      // and those messages may, legitimately include padding.
      QUICHE_DCHECK(false)
          << "Message needed padding but already contained a PAD tag";
      return nullptr;
    }

    if (it->first > kPAD && need_pad_tag) {
      need_pad_tag = false;
      if (!WritePadTag(&writer, pad_length, &end_offset)) {
        return nullptr;
      }
    }

    if (!writer.WriteTag(it->first)) {
      QUICHE_DCHECK(false) << "Failed to write tag.";
      return nullptr;
    }
    end_offset += it->second.length();
    if (!writer.WriteUInt32(end_offset)) {
      QUICHE_DCHECK(false) << "Failed to write end offset.";
      return nullptr;
    }
  }

  if (need_pad_tag) {
    if (!WritePadTag(&writer, pad_length, &end_offset)) {
      return nullptr;
    }
  }

  // Values
  for (auto it = message.tag_value_map().begin();
       it != message.tag_value_map().end(); ++it) {
    if (it->first > kPAD && need_pad_value) {
      need_pad_value = false;
      if (!writer.WriteRepeatedByte('-', pad_length)) {
        QUICHE_DCHECK(false) << "Failed to write padding.";
        return nullptr;
      }
    }

    if (!writer.WriteBytes(it->second.data(), it->second.length())) {
      QUICHE_DCHECK(false) << "Failed to write value.";
      return nullptr;
    }
  }

  if (need_pad_value) {
    if (!writer.WriteRepeatedByte('-', pad_length)) {
      QUICHE_DCHECK(false) << "Failed to write padding.";
      return nullptr;
    }
  }

  return std::make_unique<QuicData>(buffer.release(), len, true);
}

void CryptoFramer::Clear() {
  message_.Clear();
  tags_and_lengths_.clear();
  error_ = QUIC_NO_ERROR;
  error_detail_ = "";
  state_ = STATE_READING_TAG;
}

QuicErrorCode CryptoFramer::Process(absl::string_view input) {
  // Add this data to the buffer.
  buffer_.append(input.data(), input.length());
  QuicDataReader reader(buffer_.data(), buffer_.length(),
                        quiche::HOST_BYTE_ORDER);

  switch (state_) {
    case STATE_READING_TAG:
      if (reader.BytesRemaining() < kQuicTagSize) {
        break;
      }
      QuicTag message_tag;
      reader.ReadTag(&message_tag);
      message_.set_tag(message_tag);
      state_ = STATE_READING_NUM_ENTRIES;
      ABSL_FALLTHROUGH_INTENDED;
    case STATE_READING_NUM_ENTRIES:
      if (reader.BytesRemaining() < kNumEntriesSize + sizeof(uint16_t)) {
        break;
      }
      reader.ReadUInt16(&num_entries_);
      if (num_entries_ > kMaxEntries) {
        error_detail_ = absl::StrCat(num_entries_, " entries");
        return QUIC_CRYPTO_TOO_MANY_ENTRIES;
      }
      uint16_t padding;
      reader.ReadUInt16(&padding);

      tags_and_lengths_.reserve(num_entries_);
      state_ = STATE_READING_TAGS_AND_LENGTHS;
      values_len_ = 0;
      ABSL_FALLTHROUGH_INTENDED;
    case STATE_READING_TAGS_AND_LENGTHS: {
      if (reader.BytesRemaining() <
          num_entries_ * (kQuicTagSize + kCryptoEndOffsetSize)) {
        break;
      }

      uint32_t last_end_offset = 0;
      for (unsigned i = 0; i < num_entries_; ++i) {
        QuicTag tag;
        reader.ReadTag(&tag);
        if (i > 0 && tag <= tags_and_lengths_[i - 1].first) {
          if (tag == tags_and_lengths_[i - 1].first) {
            error_detail_ = absl::StrCat("Duplicate tag:", tag);
            return QUIC_CRYPTO_DUPLICATE_TAG;
          }
          error_detail_ = absl::StrCat("Tag ", tag, " out of order");
          return QUIC_CRYPTO_TAGS_OUT_OF_ORDER;
        }

        uint32_t end_offset;
        reader.ReadUInt32(&end_offset);

        if (end_offset < last_end_offset) {
          error_detail_ =
              absl::StrCat("End offset: ", end_offset, " vs ", last_end_offset);
          return QUIC_CRYPTO_TAGS_OUT_OF_ORDER;
        }
        tags_and_lengths_.push_back(std::make_pair(
            tag, static_cast<size_t>(end_offset - last_end_offset)));
        last_end_offset = end_offset;
      }
      values_len_ = last_end_offset;
      state_ = STATE_READING_VALUES;
      ABSL_FALLTHROUGH_INTENDED;
    }
    case STATE_READING_VALUES:
      if (reader.BytesRemaining() < values_len_) {
        if (!process_truncated_messages_) {
          break;
        }
        QUIC_LOG(ERROR) << "Trunacted message. Missing "
                        << values_len_ - reader.BytesRemaining() << " bytes.";
      }
      for (const std::pair<QuicTag, size_t>& item : tags_and_lengths_) {
        absl::string_view value;
        if (!reader.ReadStringPiece(&value, item.second)) {
          QUICHE_DCHECK(process_truncated_messages_);
          // Store an empty value.
          message_.SetStringPiece(item.first, "");
          continue;
        }
        message_.SetStringPiece(item.first, value);
      }
      visitor_->OnHandshakeMessage(message_);
      Clear();
      state_ = STATE_READING_TAG;
      break;
  }
  // Save any remaining data.
  buffer_ = std::string(reader.PeekRemainingPayload());
  return QUIC_NO_ERROR;
}

// static
bool CryptoFramer::WritePadTag(QuicDataWriter* writer,
                               size_t pad_length,
                               uint32_t* end_offset) {
  if (!writer->WriteTag(kPAD)) {
    QUICHE_DCHECK(false) << "Failed to write tag.";
    return false;
  }
  *end_offset += pad_length;
  if (!writer->WriteUInt32(*end_offset)) {
    QUICHE_DCHECK(false) << "Failed to write end offset.";
    return false;
  }
  return true;
}

}  // namespace quic
