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

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

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

#include "internal.h"


struct crypto_ex_data_func_st {
  long argl;   // Arbitary long
  void *argp;  // Arbitary void pointer
  CRYPTO_EX_free *free_func;
  // next points to the next |CRYPTO_EX_DATA_FUNCS| or NULL if this is the last
  // one. It may only be read if synchronized with a read from |num_funcs|.
  CRYPTO_EX_DATA_FUNCS *next;
};

int CRYPTO_get_ex_new_index_ex(CRYPTO_EX_DATA_CLASS *ex_data_class, long argl,
                               void *argp, CRYPTO_EX_free *free_func) {
  CRYPTO_EX_DATA_FUNCS *funcs = reinterpret_cast<CRYPTO_EX_DATA_FUNCS *>(
      OPENSSL_malloc(sizeof(CRYPTO_EX_DATA_FUNCS)));
  if (funcs == NULL) {
    return -1;
  }

  funcs->argl = argl;
  funcs->argp = argp;
  funcs->free_func = free_func;
  funcs->next = NULL;

  CRYPTO_MUTEX_lock_write(&ex_data_class->lock);

  uint32_t num_funcs = CRYPTO_atomic_load_u32(&ex_data_class->num_funcs);
  // The index must fit in |int|.
  if (num_funcs > (size_t)(INT_MAX - ex_data_class->num_reserved)) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_OVERFLOW);
    CRYPTO_MUTEX_unlock_write(&ex_data_class->lock);
    return -1;
  }

  // Append |funcs| to the linked list.
  if (ex_data_class->last == NULL) {
    assert(num_funcs == 0);
    ex_data_class->funcs = funcs;
    ex_data_class->last = funcs;
  } else {
    ex_data_class->last->next = funcs;
    ex_data_class->last = funcs;
  }

  CRYPTO_atomic_store_u32(&ex_data_class->num_funcs, num_funcs + 1);
  CRYPTO_MUTEX_unlock_write(&ex_data_class->lock);
  return (int)num_funcs + ex_data_class->num_reserved;
}

int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int index, void *val) {
  if (index < 0) {
    // A caller that can accidentally pass in an invalid index into this
    // function will hit an memory error if |index| happened to be valid, and
    // expected |val| to be of a different type.
    abort();
  }

  if (ad->sk == NULL) {
    ad->sk = sk_void_new_null();
    if (ad->sk == NULL) {
      return 0;
    }
  }

  // Add NULL values until the stack is long enough.
  for (size_t i = sk_void_num(ad->sk); i <= (size_t)index; i++) {
    if (!sk_void_push(ad->sk, NULL)) {
      return 0;
    }
  }

  sk_void_set(ad->sk, (size_t)index, val);
  return 1;
}

void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx) {
  if (ad->sk == NULL || idx < 0 || (size_t)idx >= sk_void_num(ad->sk)) {
    return NULL;
  }
  return sk_void_value(ad->sk, idx);
}

void CRYPTO_new_ex_data(CRYPTO_EX_DATA *ad) { ad->sk = NULL; }

void CRYPTO_free_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class,
                         CRYPTO_EX_DATA *ad) {
  if (ad->sk == NULL) {
    // Nothing to do.
    return;
  }

  uint32_t num_funcs = CRYPTO_atomic_load_u32(&ex_data_class->num_funcs);
  // |CRYPTO_get_ex_new_index_ex| will not allocate indices beyond |INT_MAX|.
  assert(num_funcs <= (size_t)(INT_MAX - ex_data_class->num_reserved));

  // Defer dereferencing |ex_data_class->funcs| and |funcs->next|. It must come
  // after the |num_funcs| comparison to be correctly synchronized.
  CRYPTO_EX_DATA_FUNCS *const *funcs = &ex_data_class->funcs;
  for (uint32_t i = 0; i < num_funcs; i++) {
    if ((*funcs)->free_func != NULL) {
      int index = (int)i + ex_data_class->num_reserved;
      void *ptr = CRYPTO_get_ex_data(ad, index);
      (*funcs)->free_func(/*parent=*/nullptr, ptr, /*ad*/ nullptr, index,
                          (*funcs)->argl, (*funcs)->argp);
    }
    funcs = &(*funcs)->next;
  }

  sk_void_free(ad->sk);
  ad->sk = NULL;
}

void CRYPTO_cleanup_all_ex_data(void) {}
