/* 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 <string.h>
#include <sys/stat.h>
#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 */
    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) {
            dir = (char *)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);
            }
        } 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 == ':') || (*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;
            }
            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)
{
    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(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));
                /*
                 * 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
