/* 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/opensslconf.h>
#include <string.h>

#ifndef OPENSSL_NO_POSIX_IO
#include <sys/stat.h>
#endif

#ifdef OPENSSL_SYS_STARBOARD
#include "starboard/configuration_constants.h"
#define LIST_SEPARATOR_CHAR kSbPathSepChar
#endif

#ifdef NATIVE_TARGET_BUILD
#define LIST_SEPARATOR_CHAR ':'
#endif

#include <sys/types.h>

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

#if !defined(OPENSSL_TRUSTY)

#include "../internal.h"
#include "internal.h"

typedef struct lookup_dir_hashes_st {
  unsigned long hash;
  int suffix;
} BY_DIR_HASH;

typedef struct lookup_dir_entry_st {
  char *dir;
  int dir_type;
  STACK_OF(BY_DIR_HASH) *hashes;
} BY_DIR_ENTRY;

typedef struct lookup_dir_st {
  BUF_MEM *buffer;
  STACK_OF(BY_DIR_ENTRY) *dirs;
} BY_DIR;

DEFINE_STACK_OF(BY_DIR_HASH)
DEFINE_STACK_OF(BY_DIR_ENTRY)

static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
                    char **ret);
static int new_dir(X509_LOOKUP *lu);
static void free_dir(X509_LOOKUP *lu);
static int add_cert_dir(BY_DIR *ctx, const char *dir, int type);
static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
                               X509_OBJECT *ret);
static X509_LOOKUP_METHOD x509_dir_lookup = {
    "Load certs from files in a directory",
    new_dir,              // new
    free_dir,             // free
    NULL,                 // init
    NULL,                 // shutdown
    dir_ctrl,             // ctrl
    get_cert_by_subject,  // get_by_subject
};

X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void) { return &x509_dir_lookup; }

static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
                    char **retp) {
  int ret = 0;
  char *dir = NULL;

  BY_DIR *ld = ctx->method_data;

  switch (cmd) {
    case X509_L_ADD_DIR:
      if (argl == X509_FILETYPE_DEFAULT) {
#if defined(COBALT)
            // We don't expect to use the default certs dir.
            OPENSSL_PUT_ERROR(X509, X509_R_LOADING_CERT_DIR);
#else
            dir = (char *)OPENSSL_port_getenv(X509_get_default_cert_dir_env());
        if (dir) {
          ret = add_cert_dir(ld, dir, X509_FILETYPE_PEM);
        } else {
          ret =
              add_cert_dir(ld, X509_get_default_cert_dir(), X509_FILETYPE_PEM);
        }
        if (!ret) {
          OPENSSL_PUT_ERROR(X509, X509_R_LOADING_CERT_DIR);
        }
#endif
      } else {
        ret = add_cert_dir(ld, argp, (int)argl);
      }
      break;
  }
  return ret;
}

static int new_dir(X509_LOOKUP *lu) {
  BY_DIR *a;

  if ((a = (BY_DIR *)OPENSSL_malloc(sizeof(BY_DIR))) == NULL) {
    return 0;
  }
  if ((a->buffer = BUF_MEM_new()) == NULL) {
    OPENSSL_free(a);
    return 0;
  }
  a->dirs = NULL;
  lu->method_data = a;
  return 1;
}

static void by_dir_hash_free(BY_DIR_HASH *hash) { OPENSSL_free(hash); }

static int by_dir_hash_cmp(const BY_DIR_HASH *const *a,
                           const BY_DIR_HASH *const *b) {
  if ((*a)->hash > (*b)->hash) {
    return 1;
  }
  if ((*a)->hash < (*b)->hash) {
    return -1;
  }
  return 0;
}

static void by_dir_entry_free(BY_DIR_ENTRY *ent) {
  if (ent != NULL) {
    OPENSSL_free(ent->dir);
    sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free);
    OPENSSL_free(ent);
  }
}

static void free_dir(X509_LOOKUP *lu) {
  BY_DIR *a = lu->method_data;
  if (a != NULL) {
    sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free);
    BUF_MEM_free(a->buffer);
    OPENSSL_free(a);
  }
}

static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) {
  size_t j, len;
  const char *s, *ss, *p;

  if (dir == NULL || !*dir) {
    OPENSSL_PUT_ERROR(X509, X509_R_INVALID_DIRECTORY);
    return 0;
  }

  s = dir;
  p = s;
  do {
      if ((*p == LIST_SEPARATOR_CHAR) || (*p == '\0')) {
      BY_DIR_ENTRY *ent;
      ss = s;
      s = p + 1;
      len = p - ss;
      if (len == 0) {
        continue;
      }
      for (j = 0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++) {
        ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j);
        if (strlen(ent->dir) == len && strncmp(ent->dir, ss, len) == 0) {
          break;
        }
      }
      if (j < sk_BY_DIR_ENTRY_num(ctx->dirs)) {
        continue;
      }
      if (ctx->dirs == NULL) {
        ctx->dirs = sk_BY_DIR_ENTRY_new_null();
        if (!ctx->dirs) {
          return 0;
        }
      }
      ent = OPENSSL_malloc(sizeof(BY_DIR_ENTRY));
      if (!ent) {
        return 0;
      }
      ent->dir_type = type;
      ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp);
      ent->dir = OPENSSL_malloc(len + 1);
      if (!ent->dir || !ent->hashes) {
        by_dir_entry_free(ent);
        return 0;
      }
      OPENSSL_strlcpy(ent->dir, ss, len + 1);
      if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) {
        by_dir_entry_free(ent);
        return 0;
      }
    }
  } while (*p++ != '\0');
  return 1;
}

// g_ent_hashes_lock protects the |hashes| member of all |BY_DIR_ENTRY|
// objects.
static struct CRYPTO_STATIC_MUTEX g_ent_hashes_lock = CRYPTO_STATIC_MUTEX_INIT;

static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
                               X509_OBJECT *ret) {
  union {
    struct {
      X509 st_x509;
      X509_CINF st_x509_cinf;
    } x509;
    struct {
      X509_CRL st_crl;
      X509_CRL_INFO st_crl_info;
    } crl;
  } data;
  int ok = 0;
  size_t i;
  int j, k;
  unsigned long h;
  unsigned long hash_array[2];
  int hash_index;
  BUF_MEM *b = NULL;
  X509_OBJECT stmp, *tmp;
  const char *postfix = "";

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

  stmp.type = type;
  if (type == X509_LU_X509) {
    data.x509.st_x509.cert_info = &data.x509.st_x509_cinf;
    data.x509.st_x509_cinf.subject = name;
    stmp.data.x509 = &data.x509.st_x509;
    postfix = "";
  } else if (type == X509_LU_CRL) {
    data.crl.st_crl.crl = &data.crl.st_crl_info;
    data.crl.st_crl_info.issuer = name;
    stmp.data.crl = &data.crl.st_crl;
    postfix = "r";
  } else {
    OPENSSL_PUT_ERROR(X509, X509_R_WRONG_LOOKUP_TYPE);
    goto finish;
  }

  if ((b = BUF_MEM_new()) == NULL) {
    OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
    goto finish;
  }

  BY_DIR *ctx = xl->method_data;

  hash_array[0] = X509_NAME_hash(name);
  hash_array[1] = X509_NAME_hash_old(name);
  for (hash_index = 0; hash_index < 2; ++hash_index) {
    h = hash_array[hash_index];
    for (i = 0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) {
      BY_DIR_ENTRY *ent;
      size_t idx;
      BY_DIR_HASH htmp, *hent;
      ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i);
      j = strlen(ent->dir) + 1 + 8 + 6 + 1 + 1;
      if (!BUF_MEM_grow(b, j)) {
        goto finish;
      }
      if (type == X509_LU_CRL && ent->hashes) {
        htmp.hash = h;
        CRYPTO_STATIC_MUTEX_lock_read(&g_ent_hashes_lock);
        if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp)) {
          hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
          k = hent->suffix;
        } else {
          hent = NULL;
          k = 0;
        }
        CRYPTO_STATIC_MUTEX_unlock_read(&g_ent_hashes_lock);
      } else {
        k = 0;
        hent = NULL;
      }
      for (;;) {
        BIO_snprintf(b->data, b->max, "%s/%08lx.%s%d", ent->dir, h, postfix,
                     k);
#ifndef OPENSSL_NO_POSIX_IO
#if defined(_WIN32) && !defined(stat)
#define stat _stat
#endif
        {
          struct stat st;
          if (stat(b->data, &st) < 0) {
            break;
          }
        }
#endif
        // found one.
        if (type == X509_LU_X509) {
          if ((X509_load_cert_file(xl, b->data, ent->dir_type)) == 0) {
            break;
          }
        } else if (type == X509_LU_CRL) {
          if ((X509_load_crl_file(xl, b->data, ent->dir_type)) == 0) {
            break;
          }
        }
        // else case will caught higher up
        k++;
      }

      // we have added it to the cache so now pull it out again
      CRYPTO_MUTEX_lock_write(&xl->store_ctx->objs_lock);
      tmp = NULL;
      sk_X509_OBJECT_sort(xl->store_ctx->objs);
      if (sk_X509_OBJECT_find(xl->store_ctx->objs, &idx, &stmp)) {
        tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, idx);
      }
      CRYPTO_MUTEX_unlock_write(&xl->store_ctx->objs_lock);

      // If a CRL, update the last file suffix added for this

      if (type == X509_LU_CRL) {
        CRYPTO_STATIC_MUTEX_lock_write(&g_ent_hashes_lock);
        // Look for entry again in case another thread added an entry
        // first.
        if (!hent) {
          htmp.hash = h;
          sk_BY_DIR_HASH_sort(ent->hashes);
          if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp)) {
            hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
          }
        }
        if (!hent) {
          hent = OPENSSL_malloc(sizeof(BY_DIR_HASH));
          if (hent == NULL) {
            CRYPTO_STATIC_MUTEX_unlock_write(&g_ent_hashes_lock);
            ok = 0;
            goto finish;
          }
          hent->hash = h;
          hent->suffix = k;
          if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) {
            CRYPTO_STATIC_MUTEX_unlock_write(&g_ent_hashes_lock);
            OPENSSL_free(hent);
            ok = 0;
            goto finish;
          }
          sk_BY_DIR_HASH_sort(ent->hashes);
        } else if (hent->suffix < k) {
          hent->suffix = k;
        }

        CRYPTO_STATIC_MUTEX_unlock_write(&g_ent_hashes_lock);
      }

      if (tmp != NULL) {
        ok = 1;
        ret->type = tmp->type;
        OPENSSL_memcpy(&ret->data, &tmp->data, sizeof(ret->data));

        // Clear any errors that might have been raised processing empty
        // or malformed files.
        ERR_clear_error();

        // If we were going to up the reference count, we would need
        // to do it on a perl 'type' basis
        goto finish;
      }
    }
  }
finish:
  BUF_MEM_free(b);
  return ok;
}

#endif  // OPENSSL_TRUSTY
