/* crypto/x509/by_dir.c */
/* 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>
#if !defined(OPENSSL_SYS_STARBOARD)
#include <string.h>
#endif  // !defined(OPENSSL_SYS_STARBOARD)

#include "e_os.h"

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

#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"

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 */
    NULL,                       /* get_by_issuer_serial */
    NULL,                       /* get_by_fingerprint */
    NULL,                       /* get_by_alias */
};

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;
    BY_DIR *ld;
    char *dir = NULL;

    ld = (BY_DIR *)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 = (char *)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 **a, const BY_DIR_HASH **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->dir)
        OPENSSL_free(ent->dir);
    if (ent->hashes)
        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;

    a = (BY_DIR *)lu->method_data;
    if (a->dirs != NULL)
        sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free);
    if (a->buffer != NULL)
        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) {
                    OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
                    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;
            }
            BUF_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)
{
    BY_DIR *ctx;
    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;
    }

    ctx = (BY_DIR *)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)) {
                OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
                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 (;;) {
                char c = '/';
#ifdef OPENSSL_SYS_VMS
                c = ent->dir[strlen(ent->dir) - 1];
                if (c != ':' && c != '>' && c != ']') {
                    /*
                     * If no separator is present, we assume the directory
                     * specifier is a logical name, and add a colon.  We
                     * really should use better VMS routines for merging
                     * things like this, but this will do for now... --
                     * Richard Levitte
                     */
                    c = ':';
                } else {
                    c = '\0';
                }
#endif
                if (c == '\0') {
                    /*
                     * This is special.  When c == '\0', no directory
                     * separator should be added.
                     */
                    BIO_snprintf(b->data, b->max,
                                 "%s%08lx.%s%d", ent->dir, h, postfix, k);
                } else {
                    BIO_snprintf(b->data, b->max,
                                 "%s%c%08lx.%s%d", ent->dir, c, h,
                                 postfix, k);
                }
#ifndef OPENSSL_NO_POSIX_IO
#if defined(_WIN32) && !defined(__LB_XB1__) && !defined(__LB_XB360__)
#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));
                /*
                 * If we were going to up the reference count, we would need
                 * to do it on a perl 'type' basis
                 */
                /*
                 * CRYPTO_add(&tmp->data.x509->references,1,
                 * CRYPTO_LOCK_X509);
                 */
                goto finish;
            }
        }
    }
 finish:
    if (b != NULL)
        BUF_MEM_free(b);
    return (ok);
}

#endif  // OPENSSL_TRUSTY
