/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.] */

#include <openssl/bio.h>

#include <errno.h>
#include <limits.h>
#include <stddef.h>
#include <string.h>

#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/thread.h>


/* BIO_set initialises a BIO structure to have the given type and sets the
 * reference count to one. It returns one on success or zero on error. */
static int bio_set(BIO *bio, const BIO_METHOD *method) {
  /* This function can be called with a stack allocated |BIO| so we have to
   * assume that the contents of |BIO| are arbitary. This also means that it'll
   * leak memory if you call |BIO_set| twice on the same BIO. */
  memset(bio, 0, sizeof(BIO));

  bio->method = method;
  bio->shutdown = 1;
  bio->references = 1;

  if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data)) {
    return 0;
  }

  if (method->create != NULL) {
    if (!method->create(bio)) {
      CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
      return 0;
    }
  }

  return 1;
}

BIO *BIO_new(const BIO_METHOD *method) {
  BIO *ret = OPENSSL_malloc(sizeof(BIO));
  if (ret == NULL) {
    OPENSSL_PUT_ERROR(BIO, BIO_new, ERR_R_MALLOC_FAILURE);
    return NULL;
  }

  if (!bio_set(ret, method)) {
    OPENSSL_free(ret);
    ret = NULL;
  }

  return ret;
}

int BIO_free(BIO *bio) {
  BIO *next_bio;

  for (; bio != NULL; bio = next_bio) {
    int refs = CRYPTO_add(&bio->references, -1, CRYPTO_LOCK_BIO);
    if (refs > 0) {
      return 0;
    }

    if (bio->callback != NULL) {
      int i = (int)bio->callback(bio, BIO_CB_FREE, NULL, 0, 0, 1);
      if (i <= 0) {
        return i;
      }
    }

    next_bio = BIO_pop(bio);

    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);

    if (bio->method != NULL && bio->method->destroy != NULL) {
      bio->method->destroy(bio);
    }

    OPENSSL_free(bio);
  }
  return 1;
}

void BIO_vfree(BIO *bio) {
  BIO_free(bio);
}

void BIO_free_all(BIO *bio) {
  BIO_free(bio);
}

static int bio_io(BIO *bio, void *buf, int len, size_t method_offset,
                  int callback_flags, size_t *num) {
  int i;
  typedef int (*io_func_t)(BIO *, char *, int);
  io_func_t io_func = NULL;

  if (bio != NULL && bio->method != NULL) {
    io_func =
        *((const io_func_t *)(((const uint8_t *)bio->method) + method_offset));
  }

  if (io_func == NULL) {
    OPENSSL_PUT_ERROR(BIO, bio_io, BIO_R_UNSUPPORTED_METHOD);
    return -2;
  }

  if (bio->callback != NULL) {
    i = (int) bio->callback(bio, callback_flags, buf, len, 0L, 1L);
    if (i <= 0) {
      return i;
    }
  }

  if (!bio->init) {
    OPENSSL_PUT_ERROR(BIO, bio_io, BIO_R_UNINITIALIZED);
    return -2;
  }

  i = 0;
  if (buf != NULL && len > 0) {
    i = io_func(bio, buf, len);
  }

  if (i > 0) {
    *num += i;
  }

  if (bio->callback != NULL) {
    i = (int)(bio->callback(bio, callback_flags | BIO_CB_RETURN, buf, len, 0L,
                            (long)i));
  }

  return i;
}

int BIO_read(BIO *bio, void *buf, int len) {
  return bio_io(bio, buf, len, offsetof(BIO_METHOD, bread), BIO_CB_READ,
                &bio->num_read);
}

int BIO_gets(BIO *bio, char *buf, int len) {
  return bio_io(bio, buf, len, offsetof(BIO_METHOD, bgets), BIO_CB_GETS,
                &bio->num_read);
}

int BIO_write(BIO *bio, const void *in, int inl) {
  return bio_io(bio, (char *)in, inl, offsetof(BIO_METHOD, bwrite),
                BIO_CB_WRITE, &bio->num_write);
}

int BIO_puts(BIO *bio, const char *in) {
  return BIO_write(bio, in, strlen(in));
}

int BIO_flush(BIO *bio) {
  return BIO_ctrl(bio, BIO_CTRL_FLUSH, 0, NULL);
}

long BIO_ctrl(BIO *bio, int cmd, long larg, void *parg) {
  long ret;

  if (bio == NULL) {
    return 0;
  }

  if (bio->method == NULL || bio->method->ctrl == NULL) {
    OPENSSL_PUT_ERROR(BIO, BIO_ctrl, BIO_R_UNSUPPORTED_METHOD);
    return -2;
  }

  if (bio->callback != NULL) {
    ret = bio->callback(bio, BIO_CB_CTRL, parg, cmd, larg, 1);
    if (ret <= 0) {
      return ret;
    }
  }

  ret = bio->method->ctrl(bio, cmd, larg, parg);

  if (bio->callback != NULL) {
    ret = bio->callback(bio, BIO_CB_CTRL | BIO_CB_RETURN, parg, cmd, larg, ret);
  }

  return ret;
}

char *BIO_ptr_ctrl(BIO *b, int cmd, long larg) {
  char *p = NULL;

  if (BIO_ctrl(b, cmd, larg, (void *)&p) <= 0) {
    return NULL;
  }

  return p;
}

long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg) {
  int i = iarg;

  return BIO_ctrl(b, cmd, larg, (void *)&i);
}

int BIO_reset(BIO *bio) {
  return BIO_ctrl(bio, BIO_CTRL_RESET, 0, NULL);
}

void BIO_set_flags(BIO *bio, int flags) {
  bio->flags |= flags;
}

int BIO_test_flags(const BIO *bio, int flags) {
  return bio->flags & flags;
}

int BIO_should_read(const BIO *bio) {
  return BIO_test_flags(bio, BIO_FLAGS_READ);
}

int BIO_should_write(const BIO *bio) {
  return BIO_test_flags(bio, BIO_FLAGS_WRITE);
}

int BIO_should_retry(const BIO *bio) {
  return BIO_test_flags(bio, BIO_FLAGS_SHOULD_RETRY);
}

int BIO_should_io_special(const BIO *bio) {
  return BIO_test_flags(bio, BIO_FLAGS_IO_SPECIAL);
}

int BIO_get_retry_reason(const BIO *bio) { return bio->retry_reason; }

void BIO_clear_flags(BIO *bio, int flags) {
  bio->flags &= ~flags;
}

void BIO_set_retry_read(BIO *bio) {
  bio->flags |= BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY;
}

void BIO_set_retry_write(BIO *bio) {
  bio->flags |= BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY;
}

static const int kRetryFlags = BIO_FLAGS_RWS | BIO_FLAGS_SHOULD_RETRY;

int BIO_get_retry_flags(BIO *bio) {
  return bio->flags & kRetryFlags;
}

void BIO_clear_retry_flags(BIO *bio) {
  bio->flags &= ~kRetryFlags;
  bio->retry_reason = 0;
}

int BIO_method_type(const BIO *bio) { return bio->method->type; }

void BIO_copy_next_retry(BIO *bio) {
  BIO_clear_retry_flags(bio);
  BIO_set_flags(bio, BIO_get_retry_flags(bio->next_bio));
  bio->retry_reason = bio->next_bio->retry_reason;
}

long BIO_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) {
  long ret;
  bio_info_cb cb;

  if (bio == NULL) {
    return 0;
  }

  if (bio->method == NULL || bio->method->callback_ctrl == NULL) {
    OPENSSL_PUT_ERROR(BIO, BIO_callback_ctrl, BIO_R_UNSUPPORTED_METHOD);
    return 0;
  }

  cb = bio->callback;

  if (cb != NULL) {
    ret = cb(bio, BIO_CB_CTRL, (void *)&fp, cmd, 0, 1L);
    if (ret <= 0) {
      return ret;
    }
  }

  ret = bio->method->callback_ctrl(bio, cmd, fp);

  if (cb != NULL) {
    ret = cb(bio, BIO_CB_CTRL | BIO_CB_RETURN, (void *)&fp, cmd, 0, ret);
  }

  return ret;
}

size_t BIO_pending(const BIO *bio) {
  return BIO_ctrl((BIO *) bio, BIO_CTRL_PENDING, 0, NULL);
}

size_t BIO_ctrl_pending(const BIO *bio) {
  return BIO_pending(bio);
}

size_t BIO_wpending(const BIO *bio) {
  return BIO_ctrl((BIO *) bio, BIO_CTRL_WPENDING, 0, NULL);
}

int BIO_set_close(BIO *bio, int close_flag) {
  return BIO_ctrl(bio, BIO_CTRL_SET_CLOSE, close_flag, NULL);
}

void BIO_set_callback(BIO *bio, bio_info_cb callback_func) {
  bio->callback = callback_func;
}

void BIO_set_callback_arg(BIO *bio, char *arg) {
  bio->cb_arg = arg;
}

char *BIO_get_callback_arg(const BIO *bio) {
  return bio->cb_arg;
}

OPENSSL_EXPORT size_t BIO_number_read(const BIO *bio) {
  return bio->num_read;
}

OPENSSL_EXPORT size_t BIO_number_written(const BIO *bio) {
  return bio->num_write;
}

BIO *BIO_push(BIO *bio, BIO *appended_bio) {
  BIO *last_bio;

  if (bio == NULL) {
    return bio;
  }

  last_bio = bio;
  while (last_bio->next_bio != NULL) {
    last_bio = last_bio->next_bio;
  }

  last_bio->next_bio = appended_bio;
  /* TODO(fork): this seems very suspect. If we got rid of BIO SSL, we could
   * get rid of this. */
  BIO_ctrl(bio, BIO_CTRL_PUSH, 0, bio);

  return bio;
}

BIO *BIO_pop(BIO *bio) {
  BIO *ret;

  if (bio == NULL) {
    return NULL;
  }
  ret = bio->next_bio;
  BIO_ctrl(bio, BIO_CTRL_POP, 0, bio);
  bio->next_bio = NULL;
  return ret;
}

BIO *BIO_next(BIO *bio) {
  if (!bio) {
    return NULL;
  }
  return bio->next_bio;
}

BIO *BIO_find_type(BIO *bio, int type) {
  int method_type, mask;

  if (!bio) {
    return NULL;
  }
  mask = type & 0xff;

  do {
    if (bio->method != NULL) {
      method_type = bio->method->type;

      if (!mask) {
        if (method_type & type) {
          return bio;
        }
      } else if (method_type == type) {
        return bio;
      }
    }
    bio = bio->next_bio;
  } while (bio != NULL);

  return NULL;
}

int BIO_indent(BIO *bio, unsigned indent, unsigned max_indent) {
  if (indent > max_indent) {
    indent = max_indent;
  }

  while (indent--) {
    if (BIO_puts(bio, " ") != 1) {
      return 0;
    }
  }
  return 1;
}

void BIO_print_errors_fp(FILE *out) {
  BIO *bio = BIO_new_fp(out, BIO_NOCLOSE);
  BIO_print_errors(bio);
  BIO_free(bio);
}

static int print_bio(const char *str, size_t len, void *bio) {
  return BIO_write((BIO *)bio, str, len);
}

void BIO_print_errors(BIO *bio) {
  ERR_print_errors_cb(print_bio, bio);
}
