/* Copyright (c) 2014, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#if !defined(_POSIX_C_SOURCE)
#define _POSIX_C_SOURCE 201410L
#endif

#include <openssl/base.h>

#if !defined(OPENSSL_WINDOWS)
#include <arpa/inet.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#else
#include <io.h>
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <winsock2.h>
#include <ws2tcpip.h>
OPENSSL_MSVC_PRAGMA(warning(pop))
#endif

#include <openssl/bio.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/mem.h>

#include <algorithm>

#include "../internal.h"


#if !defined(OPENSSL_WINDOWS)
static int closesocket(int sock) {
  return close(sock);
}

static void PrintSocketError(const char *func) {
  perror(func);
}
#else
static void PrintSocketError(const char *func) {
  fprintf(stderr, "%s: %d\n", func, WSAGetLastError());
}
#endif

class ScopedSocket {
 public:
  ScopedSocket(int sock) : sock_(sock) {}
  ~ScopedSocket() {
    closesocket(sock_);
  }

 private:
  const int sock_;
};

static bool TestSocketConnect() {
  static const char kTestMessage[] = "test";

  int listening_sock = socket(AF_INET, SOCK_STREAM, 0);
  if (listening_sock == -1) {
    PrintSocketError("socket");
    return false;
  }
  ScopedSocket listening_sock_closer(listening_sock);

  struct sockaddr_in sin;
  memset(&sin, 0, sizeof(sin));
  sin.sin_family = AF_INET;
  if (!inet_pton(AF_INET, "127.0.0.1", &sin.sin_addr)) {
    PrintSocketError("inet_pton");
    return false;
  }
  if (bind(listening_sock, (struct sockaddr *)&sin, sizeof(sin)) != 0) {
    PrintSocketError("bind");
    return false;
  }
  if (listen(listening_sock, 1)) {
    PrintSocketError("listen");
    return false;
  }
  socklen_t sockaddr_len = sizeof(sin);
  if (getsockname(listening_sock, (struct sockaddr *)&sin, &sockaddr_len) ||
      sockaddr_len != sizeof(sin)) {
    PrintSocketError("getsockname");
    return false;
  }

  char hostname[80];
  BIO_snprintf(hostname, sizeof(hostname), "%s:%d", "127.0.0.1",
               ntohs(sin.sin_port));
  bssl::UniquePtr<BIO> bio(BIO_new_connect(hostname));
  if (!bio) {
    fprintf(stderr, "BIO_new_connect failed.\n");
    return false;
  }

  if (BIO_write(bio.get(), kTestMessage, sizeof(kTestMessage)) !=
      sizeof(kTestMessage)) {
    fprintf(stderr, "BIO_write failed.\n");
    ERR_print_errors_fp(stderr);
    return false;
  }

  int sock = accept(listening_sock, (struct sockaddr *) &sin, &sockaddr_len);
  if (sock == -1) {
    PrintSocketError("accept");
    return false;
  }
  ScopedSocket sock_closer(sock);

  char buf[5];
  if (recv(sock, buf, sizeof(buf), 0) != sizeof(kTestMessage)) {
    PrintSocketError("read");
    return false;
  }
  if (memcmp(buf, kTestMessage, sizeof(kTestMessage))) {
    return false;
  }

  return true;
}


// BioReadZeroCopyWrapper is a wrapper around the zero-copy APIs to make
// testing easier.
static size_t BioReadZeroCopyWrapper(BIO *bio, uint8_t *data, size_t len) {
  uint8_t *read_buf;
  size_t read_buf_offset;
  size_t available_bytes;
  size_t len_read = 0;

  do {
    if (!BIO_zero_copy_get_read_buf(bio, &read_buf, &read_buf_offset,
                                    &available_bytes)) {
      return 0;
    }

    available_bytes = std::min(available_bytes, len - len_read);
    memmove(data + len_read, read_buf + read_buf_offset, available_bytes);

    BIO_zero_copy_get_read_buf_done(bio, available_bytes);

    len_read += available_bytes;
  } while (len - len_read > 0 && available_bytes > 0);

  return len_read;
}

// BioWriteZeroCopyWrapper is a wrapper around the zero-copy APIs to make
// testing easier.
static size_t BioWriteZeroCopyWrapper(BIO *bio, const uint8_t *data,
                                      size_t len) {
  uint8_t *write_buf;
  size_t write_buf_offset;
  size_t available_bytes;
  size_t len_written = 0;

  do {
    if (!BIO_zero_copy_get_write_buf(bio, &write_buf, &write_buf_offset,
                                     &available_bytes)) {
      return 0;
    }

    available_bytes = std::min(available_bytes, len - len_written);
    memmove(write_buf + write_buf_offset, data + len_written, available_bytes);

    BIO_zero_copy_get_write_buf_done(bio, available_bytes);

    len_written += available_bytes;
  } while (len - len_written > 0 && available_bytes > 0);

  return len_written;
}

static bool TestZeroCopyBioPairs() {
  // Test read and write, especially triggering the ring buffer wrap-around.
  uint8_t bio1_application_send_buffer[1024];
  uint8_t bio2_application_recv_buffer[1024];

  const size_t kLengths[] = {254, 255, 256, 257, 510, 511, 512, 513};

  // These trigger ring buffer wrap around.
  const size_t kPartialLengths[] = {0, 1, 2, 3, 128, 255, 256, 257, 511, 512};

  static const size_t kBufferSize = 512;

  srand(1);
  for (size_t i = 0; i < sizeof(bio1_application_send_buffer); i++) {
    bio1_application_send_buffer[i] = rand() & 255;
  }

  // Transfer bytes from bio1_application_send_buffer to
  // bio2_application_recv_buffer in various ways.
  for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kLengths); i++) {
    for (size_t j = 0; j < OPENSSL_ARRAY_SIZE(kPartialLengths); j++) {
      size_t total_write = 0;
      size_t total_read = 0;

      BIO *bio1, *bio2;
      if (!BIO_new_bio_pair(&bio1, kBufferSize, &bio2, kBufferSize)) {
        return false;
      }
      bssl::UniquePtr<BIO> bio1_scoper(bio1);
      bssl::UniquePtr<BIO> bio2_scoper(bio2);

      total_write += BioWriteZeroCopyWrapper(
          bio1, bio1_application_send_buffer, kLengths[i]);

      // This tests interleaved read/write calls. Do a read between zero copy
      // write calls.
      uint8_t *write_buf;
      size_t write_buf_offset;
      size_t available_bytes;
      if (!BIO_zero_copy_get_write_buf(bio1, &write_buf, &write_buf_offset,
                                       &available_bytes)) {
        return false;
      }

      // Free kPartialLengths[j] bytes in the beginning of bio1 write buffer.
      // This enables ring buffer wrap around for the next write.
      total_read += BIO_read(bio2, bio2_application_recv_buffer + total_read,
                             kPartialLengths[j]);

      size_t interleaved_write_len = std::min(kPartialLengths[j],
                                              available_bytes);

      // Write the data for the interleaved write call. If the buffer becomes
      // empty after a read, the write offset is normally set to 0. Check that
      // this does not happen for interleaved read/write and that
      // |write_buf_offset| is still valid.
      memcpy(write_buf + write_buf_offset,
             bio1_application_send_buffer + total_write, interleaved_write_len);
      if (BIO_zero_copy_get_write_buf_done(bio1, interleaved_write_len)) {
        total_write += interleaved_write_len;
      }

      // Do another write in case |write_buf_offset| was wrapped.
      total_write += BioWriteZeroCopyWrapper(
          bio1, bio1_application_send_buffer + total_write,
          kPartialLengths[j] - interleaved_write_len);

      // Drain the rest.
      size_t bytes_left = BIO_pending(bio2);
      total_read += BioReadZeroCopyWrapper(
          bio2, bio2_application_recv_buffer + total_read, bytes_left);

      if (total_read != total_write) {
        fprintf(stderr, "Lengths not equal in round (%u, %u)\n", (unsigned)i,
                (unsigned)j);
        return false;
      }
      if (total_read > kLengths[i] + kPartialLengths[j]) {
        fprintf(stderr, "Bad lengths in round (%u, %u)\n", (unsigned)i,
                (unsigned)j);
        return false;
      }
      if (memcmp(bio1_application_send_buffer, bio2_application_recv_buffer,
                 total_read) != 0) {
        fprintf(stderr, "Buffers not equal in round (%u, %u)\n", (unsigned)i,
                (unsigned)j);
        return false;
      }
    }
  }

  return true;
}

static bool TestPrintf() {
  // Test a short output, a very long one, and various sizes around
  // 256 (the size of the buffer) to ensure edge cases are correct.
  static const size_t kLengths[] = { 5, 250, 251, 252, 253, 254, 1023 };

  bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
  if (!bio) {
    fprintf(stderr, "BIO_new failed\n");
    return false;
  }

  for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kLengths); i++) {
    char string[1024];
    if (kLengths[i] >= sizeof(string)) {
      fprintf(stderr, "Bad test string length\n");
      return false;
    }
    memset(string, 'a', sizeof(string));
    string[kLengths[i]] = '\0';

    int ret = BIO_printf(bio.get(), "test %s", string);
    if (ret < 0 || static_cast<size_t>(ret) != 5 + kLengths[i]) {
      fprintf(stderr, "BIO_printf failed: %d\n", ret);
      return false;
    }
    const uint8_t *contents;
    size_t len;
    if (!BIO_mem_contents(bio.get(), &contents, &len)) {
      fprintf(stderr, "BIO_mem_contents failed\n");
      return false;
    }
    if (len != 5 + kLengths[i] ||
        strncmp((const char *)contents, "test ", 5) != 0 ||
        strncmp((const char *)contents + 5, string, kLengths[i]) != 0) {
      fprintf(stderr, "Contents did not match: %.*s\n", (int)len, contents);
      return false;
    }

    if (!BIO_reset(bio.get())) {
      fprintf(stderr, "BIO_reset failed\n");
      return false;
    }
  }

  return true;
}

static bool ReadASN1(bool should_succeed, const uint8_t *data, size_t data_len,
                     size_t expected_len, size_t max_len) {
  bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(data, data_len));

  uint8_t *out;
  size_t out_len;
  int ok = BIO_read_asn1(bio.get(), &out, &out_len, max_len);
  if (!ok) {
    out = nullptr;
  }
  bssl::UniquePtr<uint8_t> out_storage(out);

  if (should_succeed != (ok == 1)) {
    return false;
  }

  if (should_succeed &&
      (out_len != expected_len || memcmp(data, out, expected_len) != 0)) {
    return false;
  }

  return true;
}

static bool TestASN1() {
  static const uint8_t kData1[] = {0x30, 2, 1, 2, 0, 0};
  static const uint8_t kData2[] = {0x30, 3, 1, 2};  /* truncated */
  static const uint8_t kData3[] = {0x30, 0x81, 1, 1};  /* should be short len */
  static const uint8_t kData4[] = {0x30, 0x82, 0, 1, 1};  /* zero padded. */

  if (!ReadASN1(true, kData1, sizeof(kData1), 4, 100) ||
      !ReadASN1(false, kData2, sizeof(kData2), 0, 100) ||
      !ReadASN1(false, kData3, sizeof(kData3), 0, 100) ||
      !ReadASN1(false, kData4, sizeof(kData4), 0, 100)) {
    return false;
  }

  static const size_t kLargePayloadLen = 8000;
  static const uint8_t kLargePrefix[] = {0x30, 0x82, kLargePayloadLen >> 8,
                                         kLargePayloadLen & 0xff};
  bssl::UniquePtr<uint8_t> large(reinterpret_cast<uint8_t *>(
      OPENSSL_malloc(sizeof(kLargePrefix) + kLargePayloadLen)));
  if (!large) {
    return false;
  }
  memset(large.get() + sizeof(kLargePrefix), 0, kLargePayloadLen);
  memcpy(large.get(), kLargePrefix, sizeof(kLargePrefix));

  if (!ReadASN1(true, large.get(), sizeof(kLargePrefix) + kLargePayloadLen,
                sizeof(kLargePrefix) + kLargePayloadLen,
                kLargePayloadLen * 2)) {
    fprintf(stderr, "Large payload test failed.\n");
    return false;
  }

  if (!ReadASN1(false, large.get(), sizeof(kLargePrefix) + kLargePayloadLen,
                sizeof(kLargePrefix) + kLargePayloadLen,
                kLargePayloadLen - 1)) {
    fprintf(stderr, "max_len test failed.\n");
    return false;
  }

  static const uint8_t kIndefPrefix[] = {0x30, 0x80};
  memcpy(large.get(), kIndefPrefix, sizeof(kIndefPrefix));
  if (!ReadASN1(true, large.get(), sizeof(kLargePrefix) + kLargePayloadLen,
                sizeof(kLargePrefix) + kLargePayloadLen,
                kLargePayloadLen*2)) {
    fprintf(stderr, "indefinite length test failed.\n");
    return false;
  }

  if (!ReadASN1(false, large.get(), sizeof(kLargePrefix) + kLargePayloadLen,
                sizeof(kLargePrefix) + kLargePayloadLen,
                kLargePayloadLen-1)) {
    fprintf(stderr, "indefinite length, max_len test failed.\n");
    return false;
  }

  return true;
}

int main(void) {
  CRYPTO_library_init();

#if defined(OPENSSL_WINDOWS)
  // Initialize Winsock.
  WORD wsa_version = MAKEWORD(2, 2);
  WSADATA wsa_data;
  int wsa_err = WSAStartup(wsa_version, &wsa_data);
  if (wsa_err != 0) {
    fprintf(stderr, "WSAStartup failed: %d\n", wsa_err);
    return 1;
  }
  if (wsa_data.wVersion != wsa_version) {
    fprintf(stderr, "Didn't get expected version: %x\n", wsa_data.wVersion);
    return 1;
  }
#endif

  if (!TestSocketConnect() ||
      !TestPrintf() ||
      !TestZeroCopyBioPairs() ||
      !TestASN1()) {
    return 1;
  }

  printf("PASS\n");
  return 0;
}
