// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <openssl/ssl.h>

#include <assert.h>
#include <limits.h>
#include <string.h>

#include <algorithm>

#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/rand.h>

#include "../crypto/err/internal.h"
#include "../crypto/internal.h"
#include "internal.h"


BSSL_NAMESPACE_BEGIN

static int do_tls_write(SSLImpl *ssl, size_t *out_bytes_written, uint8_t type,
                        Span<const uint8_t> in);

int tls_write_app_data(SSLImpl *ssl, bool *out_needs_handshake,
                       size_t *out_bytes_written, Span<const uint8_t> in) {
  assert(ssl_can_write(ssl));
  assert(!ssl->s3->aead_write_ctx->is_null_cipher());

  *out_needs_handshake = false;

  if (ssl->s3->write_shutdown != ssl_shutdown_none) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
    return -1;
  }

  size_t total_bytes_written = ssl->s3->unreported_bytes_written;
  if (in.size() < total_bytes_written) {
    // This can happen if the caller disables `SSL_MODE_ENABLE_PARTIAL_WRITE`,
    // asks us to write some input of length N, we successfully encrypt M bytes
    // and write it, but fail to write the rest. We will report
    // `SSL_ERROR_WANT_WRITE`. If the caller then retries with fewer than M
    // bytes, we cannot satisfy that request. The caller is required to always
    // retry with at least as many bytes as the previous attempt.
    OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_LENGTH);
    return -1;
  }

  in = in.subspan(total_bytes_written);

  const bool is_early_data_write =
      !ssl->server && SSL_in_early_data(ssl) && ssl->s3->hs->can_early_write;
  for (;;) {
    size_t max_send_fragment = ssl->max_send_fragment;
    if (is_early_data_write) {
      SSL_HANDSHAKE *hs = ssl->s3->hs.get();
      if (hs->early_data_written >= hs->early_session->ticket_max_early_data) {
        ssl->s3->unreported_bytes_written = total_bytes_written;
        hs->can_early_write = false;
        *out_needs_handshake = true;
        return -1;
      }
      max_send_fragment = std::min(
          max_send_fragment, size_t{hs->early_session->ticket_max_early_data -
                                    hs->early_data_written});
    }

    const size_t to_write = std::min(max_send_fragment, in.size());
    size_t bytes_written;
    int ret = do_tls_write(ssl, &bytes_written, SSL3_RT_APPLICATION_DATA,
                           in.subspan(0, to_write));
    if (ret <= 0) {
      ssl->s3->unreported_bytes_written = total_bytes_written;
      return ret;
    }

    // Note `bytes_written` may be less than `to_write` if there was a pending
    // record from a smaller write attempt.
    assert(bytes_written <= to_write);
    total_bytes_written += bytes_written;
    in = in.subspan(bytes_written);
    if (is_early_data_write) {
      ssl->s3->hs->early_data_written += bytes_written;
    }

    if (in.empty() || (ssl->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)) {
      ssl->s3->unreported_bytes_written = 0;
      *out_bytes_written = total_bytes_written;
      return 1;
    }
  }
}

// tls_seal_align_prefix_len returns the length of the prefix before the start
// of the bulk of the ciphertext when sealing a record with `ssl`. Callers may
// use this to align buffers.
//
// Note when TLS 1.0 CBC record-splitting is enabled, this includes the one byte
// record and is the offset into second record's ciphertext. Thus sealing a
// small record may result in a smaller output than this value.
//
// TODO(davidben): Is this alignment valuable? Record-splitting makes this a
// mess.
static size_t tls_seal_align_prefix_len(const SSLImpl *ssl) {
  size_t ret =
      SSL3_RT_HEADER_LENGTH + ssl->s3->aead_write_ctx->ExplicitNonceLen();
  if (ssl_needs_record_splitting(ssl)) {
    ret += SSL3_RT_HEADER_LENGTH;
    ret += ssl_cipher_get_record_split_len(ssl->s3->aead_write_ctx->cipher());
  }
  return ret;
}

// do_tls_write writes an SSL record of the given type. On success, it sets
// `*out_bytes_written` to number of bytes successfully written and returns one.
// On error, it returns a value <= 0 from the underlying `BIO`.
static int do_tls_write(SSLImpl *ssl, size_t *out_bytes_written, uint8_t type,
                        Span<const uint8_t> in) {
  // If there is a pending write, the retry must be consistent.
  if (!ssl->s3->pending_write.empty() &&
      (ssl->s3->pending_write.size() > in.size() ||
       (!(ssl->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) &&
        ssl->s3->pending_write.data() != in.data()) ||
       ssl->s3->pending_write_type != type)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_WRITE_RETRY);
    return -1;
  }

  // Flush any unwritten data to the transport. There may be data to flush even
  // if `wpend_tot` is zero.
  int ret = ssl_write_buffer_flush(ssl);
  if (ret <= 0) {
    return ret;
  }

  // If there is a pending write, we just completed it. Report it to the caller.
  if (!ssl->s3->pending_write.empty()) {
    *out_bytes_written = ssl->s3->pending_write.size();
    ssl->s3->pending_write = {};
    return 1;
  }

  SSLBuffer *buf = &ssl->s3->write_buffer;
  if (in.size() > SSL3_RT_MAX_PLAIN_LENGTH || buf->size() > 0) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return -1;
  }

  if (!tls_flush_pending_hs_data(ssl)) {
    return -1;
  }

  // We may have unflushed handshake data that must be written before `in`. This
  // may be a KeyUpdate acknowledgment, 0-RTT key change messages, or a
  // NewSessionTicket.
  Span<const uint8_t> pending_flight;
  if (ssl->s3->pending_flight != nullptr) {
    pending_flight =
        Span(reinterpret_cast<const uint8_t *>(ssl->s3->pending_flight->data),
             ssl->s3->pending_flight->length);
    pending_flight = pending_flight.subspan(ssl->s3->pending_flight_offset);
  }

  size_t max_out = pending_flight.size();
  if (!in.empty()) {
    const size_t max_ciphertext_len = in.size() + SSL_max_seal_overhead(ssl);
    if (max_ciphertext_len < in.size() ||
        max_out + max_ciphertext_len < max_out) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
      return -1;
    }
    max_out += max_ciphertext_len;
  }

  if (max_out == 0) {
    // Nothing to write.
    *out_bytes_written = 0;
    return 1;
  }

  if (!buf->EnsureCap(pending_flight.size() + tls_seal_align_prefix_len(ssl),
                      max_out)) {
    return -1;
  }

  // Copy `pending_flight` to the output.
  if (!pending_flight.empty()) {
    OPENSSL_memcpy(buf->remaining().data(), pending_flight.data(),
                   pending_flight.size());
    ssl->s3->pending_flight.reset();
    ssl->s3->pending_flight_offset = 0;
    buf->DidWrite(pending_flight.size());
  }

  if (!in.empty()) {
    size_t ciphertext_len;
    if (!tls_seal_record(ssl, buf->remaining().data(), &ciphertext_len,
                         buf->remaining().size(), type, in.data(), in.size())) {
      return -1;
    }
    buf->DidWrite(ciphertext_len);
  }

  // Now that we've made progress on the connection, uncork KeyUpdate
  // acknowledgments.
  ssl->s3->key_update_pending = false;

  // Flush the write buffer.
  ret = ssl_write_buffer_flush(ssl);
  if (ret <= 0) {
    // Track the unfinished write.
    if (!in.empty()) {
      ssl->s3->pending_write = in;
      ssl->s3->pending_write_type = type;
    }
    return ret;
  }

  *out_bytes_written = in.size();
  return 1;
}

ssl_open_record_t tls_open_app_data(SSLImpl *ssl, Span<uint8_t> *out,
                                    size_t *out_consumed, uint8_t *out_alert,
                                    Span<uint8_t> in) {
  assert(ssl_can_read(ssl));
  assert(!ssl->s3->aead_read_ctx->is_null_cipher());

  uint8_t type;
  Span<uint8_t> body;
  auto ret = tls_open_record(ssl, &type, &body, out_consumed, out_alert, in);
  if (ret != ssl_open_record_success) {
    return ret;
  }

  const bool is_early_data_read = ssl->server && SSL_in_early_data(ssl);

  if (type == SSL3_RT_HANDSHAKE) {
    // Post-handshake data prior to TLS 1.3 is always renegotiation, which we
    // never accept as a server. Otherwise `tls_get_message` will send
    // `SSL_R_EXCESSIVE_MESSAGE_SIZE`.
    if (ssl->server && ssl_protocol_version(ssl) < TLS1_3_VERSION) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION);
      *out_alert = SSL_AD_NO_RENEGOTIATION;
      return ssl_open_record_error;
    }

    if (!tls_append_handshake_data(ssl, body)) {
      *out_alert = SSL_AD_INTERNAL_ERROR;
      return ssl_open_record_error;
    }
    return ssl_open_record_discard;
  }

  if (type != SSL3_RT_APPLICATION_DATA) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
    *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
    return ssl_open_record_error;
  }

  if (is_early_data_read) {
    if (body.size() > kMaxEarlyDataAccepted - ssl->s3->hs->early_data_read) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MUCH_READ_EARLY_DATA);
      *out_alert = SSL3_AD_UNEXPECTED_MESSAGE;
      return ssl_open_record_error;
    }

    ssl->s3->hs->early_data_read += body.size();
  }

  if (body.empty()) {
    return ssl_open_record_discard;
  }

  *out = body;
  return ssl_open_record_success;
}

ssl_open_record_t tls_open_change_cipher_spec(SSLImpl *ssl,
                                              size_t *out_consumed,
                                              uint8_t *out_alert,
                                              Span<uint8_t> in) {
  uint8_t type;
  Span<uint8_t> body;
  auto ret = tls_open_record(ssl, &type, &body, out_consumed, out_alert, in);
  if (ret != ssl_open_record_success) {
    return ret;
  }

  if (type != SSL3_RT_CHANGE_CIPHER_SPEC) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
    *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
    return ssl_open_record_error;
  }

  if (body.size() != 1 || body[0] != SSL3_MT_CCS) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return ssl_open_record_error;
  }

  ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_CHANGE_CIPHER_SPEC, body);
  return ssl_open_record_success;
}

void ssl_send_alert(SSLImpl *ssl, int level, int desc) {
  // This function is called in response to a fatal error from the peer. Ignore
  // any failures writing the alert and report only the original error. In
  // particular, if the transport uses `SSL_write`, our existing error will be
  // clobbered so we must save and restore the error queue. See
  // https://crbug.com/959305.
  //
  // TODO(davidben): Return the alert out of the handshake, rather than calling
  // this function internally everywhere.
  //
  // TODO(davidben): This does not allow retrying if the alert hit EAGAIN. See
  // https://crbug.com/boringssl/130.
  UniquePtr<ERR_SAVE_STATE> err_state(ERR_save_state());
  ssl_send_alert_impl(ssl, level, desc);
  ERR_restore_state(err_state.get());
}

int ssl_send_alert_impl(SSLImpl *ssl, int level, int desc) {
  // It is illegal to send an alert when we've already sent a closing one.
  if (ssl->s3->write_shutdown != ssl_shutdown_none) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
    return -1;
  }

  if (level == SSL3_AL_WARNING && desc == SSL_AD_CLOSE_NOTIFY) {
    ssl->s3->write_shutdown = ssl_shutdown_close_notify;
  } else {
    assert(level == SSL3_AL_FATAL);
    assert(desc != SSL_AD_CLOSE_NOTIFY);
    ssl->s3->write_shutdown = ssl_shutdown_error;
  }

  ssl->s3->alert_dispatch = true;
  ssl->s3->send_alert[0] = level;
  ssl->s3->send_alert[1] = desc;
  if (ssl->s3->write_buffer.empty()) {
    // Nothing is being written out, so the alert may be dispatched
    // immediately.
    return ssl->method->dispatch_alert(ssl);
  }

  // The alert will be dispatched later.
  return -1;
}

int tls_dispatch_alert(SSLImpl *ssl) {
  if (SSL_is_quic(ssl)) {
    if (!ssl->quic_method->send_alert(ssl, ssl->s3->quic_write_level,
                                      ssl->s3->send_alert[1])) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR);
      return 0;
    }
  } else {
    size_t bytes_written;
    int ret =
        do_tls_write(ssl, &bytes_written, SSL3_RT_ALERT, ssl->s3->send_alert);
    if (ret <= 0) {
      return ret;
    }
    assert(bytes_written == 2);
  }

  ssl->s3->alert_dispatch = false;

  // If the alert is fatal, flush the BIO now.
  if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) {
    BIO_flush(ssl->wbio.get());
  }

  ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_ALERT, ssl->s3->send_alert);

  int alert = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1];
  ssl_do_info_callback(ssl, SSL_CB_WRITE_ALERT, alert);

  return 1;
}

BSSL_NAMESPACE_END
