/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "secerr.h"
#include "ssl.h"
#include "sslerr.h"
#include "sslproto.h"

#include "gtest_utils.h"
#include "nss_scoped_ptrs.h"
#include "tls_connect.h"
#include "tls_filter.h"
#include "tls_parser.h"

namespace nss_test {

// This class cuts every unencrypted handshake record into two parts.
class RecordFragmenter : public PacketFilter {
 public:
  RecordFragmenter(bool is_dtls13)
      : is_dtls13_(is_dtls13), sequence_number_(0), splitting_(true) {}

 private:
  class HandshakeSplitter {
   public:
    HandshakeSplitter(bool is_dtls13, const DataBuffer& input,
                      DataBuffer* output, uint64_t* sequence_number)
        : is_dtls13_(is_dtls13),
          input_(input),
          output_(output),
          cursor_(0),
          sequence_number_(sequence_number) {}

   private:
    void WriteRecord(TlsRecordHeader& record_header,
                     DataBuffer& record_fragment) {
      TlsRecordHeader fragment_header(
          record_header.variant(), record_header.version(),
          record_header.content_type(), *sequence_number_);
      ++*sequence_number_;
      if (::g_ssl_gtest_verbose) {
        std::cerr << "Fragment: " << fragment_header << ' ' << record_fragment
                  << std::endl;
      }
      cursor_ = fragment_header.Write(output_, cursor_, record_fragment);
    }

    bool SplitRecord(TlsRecordHeader& record_header, DataBuffer& record) {
      TlsParser parser(record);
      while (parser.remaining()) {
        TlsHandshakeFilter::HandshakeHeader handshake_header;
        DataBuffer handshake_body;
        bool complete = false;
        if (!handshake_header.Parse(&parser, record_header, DataBuffer(),
                                    &handshake_body, &complete)) {
          ADD_FAILURE() << "couldn't parse handshake header";
          return false;
        }
        if (!complete) {
          ADD_FAILURE() << "don't want to deal with fragmented messages";
          return false;
        }

        DataBuffer record_fragment;
        // We can't fragment handshake records that are too small.
        if (handshake_body.len() < 2) {
          handshake_header.Write(&record_fragment, 0U, handshake_body);
          WriteRecord(record_header, record_fragment);
          continue;
        }

        size_t cut = handshake_body.len() / 2;
        handshake_header.WriteFragment(&record_fragment, 0U, handshake_body, 0U,
                                       cut);
        WriteRecord(record_header, record_fragment);

        handshake_header.WriteFragment(&record_fragment, 0U, handshake_body,
                                       cut, handshake_body.len() - cut);
        WriteRecord(record_header, record_fragment);
      }
      return true;
    }

   public:
    bool Split() {
      TlsParser parser(input_);
      while (parser.remaining()) {
        TlsRecordHeader header;
        DataBuffer record;
        if (!header.Parse(is_dtls13_, 0, &parser, &record)) {
          ADD_FAILURE() << "bad record header";
          return false;
        }

        if (::g_ssl_gtest_verbose) {
          std::cerr << "Record: " << header << ' ' << record << std::endl;
        }

        // Don't touch packets from a non-zero epoch.  Leave these unmodified.
        if ((header.sequence_number() >> 48) != 0ULL) {
          cursor_ = header.Write(output_, cursor_, record);
          continue;
        }

        // Just rewrite the sequence number (CCS only).
        if (header.content_type() != ssl_ct_handshake) {
          EXPECT_EQ(ssl_ct_change_cipher_spec, header.content_type());
          WriteRecord(header, record);
          continue;
        }

        if (!SplitRecord(header, record)) {
          return false;
        }
      }
      return true;
    }

   private:
    bool is_dtls13_;
    const DataBuffer& input_;
    DataBuffer* output_;
    size_t cursor_;
    uint64_t* sequence_number_;
  };

 protected:
  virtual PacketFilter::Action Filter(const DataBuffer& input,
                                      DataBuffer* output) override {
    if (!splitting_) {
      return KEEP;
    }

    output->Allocate(input.len());
    HandshakeSplitter splitter(is_dtls13_, input, output, &sequence_number_);
    if (!splitter.Split()) {
      // If splitting fails, we obviously reached encrypted packets.
      // Stop splitting from that point onward.
      splitting_ = false;
      return KEEP;
    }

    return CHANGE;
  }

 private:
  bool is_dtls13_;
  uint64_t sequence_number_;
  bool splitting_;
};

TEST_P(TlsConnectDatagram, FragmentClientPackets) {
  bool is_dtls13 = version_ >= SSL_LIBRARY_VERSION_TLS_1_3;
  client_->SetFilter(std::make_shared<RecordFragmenter>(is_dtls13));
  Connect();
  SendReceive();
}

TEST_P(TlsConnectDatagram, FragmentServerPackets) {
  bool is_dtls13 = version_ >= SSL_LIBRARY_VERSION_TLS_1_3;
  server_->SetFilter(std::make_shared<RecordFragmenter>(is_dtls13));
  Connect();
  SendReceive();
}

}  // namespace nss_test
