/* 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"

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
