/* 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/lhash.h>
#include <openssl/mem.h>
#include <openssl/thread.h>
#include <openssl/x509.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;

DECLARE_STACK_OF(BY_DIR_HASH)
DECLARE_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);
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, dir_ctrl, 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, add_cert_dir, 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, add_cert_dir, 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;
				}
			strncpy(ent->dir,ss,len);
			ent->dir[len] = '\0';
			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, get_cert_by_subject, X509_R_WRONG_LOOKUP_TYPE);
		goto finish;
		}

	if ((b=BUF_MEM_new()) == NULL)
		{
		OPENSSL_PUT_ERROR(X509, get_cert_by_subject, 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, get_cert_by_subject, 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(&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
#ifdef _WIN32
#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;
			if (sk_X509_OBJECT_find(xl->store_ctx->objs, &idx, &stmp)) {
				tmp=sk_X509_OBJECT_value(xl->store_ctx->objs,idx);
			}
			CRYPTO_MUTEX_unlock(&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;
					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(&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(&g_ent_hashes_lock);
						OPENSSL_free(hent);
						ok = 0;
						goto finish;
						}
					}
				else if (hent->suffix < k)
					hent->suffix = k;

				CRYPTO_STATIC_MUTEX_unlock(&g_ent_hashes_lock);
				}

			if (tmp != NULL)
				{
				ok=1;
				ret->type=tmp->type;
				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);
	}
