/* 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 <stdio.h>
#include <time.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>

#include "cryptlib.h"
#include "lhash.h"
#include "x509.h"

typedef struct lookup_dir_st
	{
	BUF_MEM *buffer;
	int num_dirs;
	char **dirs;
	int *dirs_type;
	int num_dirs_alloced;
	} BY_DIR;

#ifndef NOPROTO
static int dir_ctrl(X509_LOOKUP *ctx,int cmd,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,char *dir,int type);
static int get_cert_by_subject(X509_LOOKUP *xl,int type,X509_NAME *name,
	X509_OBJECT *ret);
#else
static int dir_ctrl();
static int new_dir();
static void free_dir();
static int add_cert_dir();
static int get_cert_by_subject();
#endif

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()
	{
	return(&x509_dir_lookup);
	}

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

	ld=(BY_DIR *)ctx->method_data;

	switch (cmd)
		{
	case X509_L_ADD_DIR:
		if (argl == X509_FILETYPE_DEFAULT)
			{
			ret=add_cert_dir(ld,X509_get_default_cert_dir(),
				X509_FILETYPE_PEM);
			if (!ret)
				{
				X509err(X509_F_DIR_CTRL,X509_R_LOADING_CERT_DIR);
				}
			else
				{
				dir=(char *)Getenv(X509_get_default_cert_dir_env());
				ret=add_cert_dir(ld,dir,X509_FILETYPE_PEM);
				}
			}
		else
			ret=add_cert_dir(ld,argp,(int)argl);
		break;
		}
	return(ret);
	}

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

	if ((a=(BY_DIR *)Malloc(sizeof(BY_DIR))) == NULL)
		return(0);
	if ((a->buffer=BUF_MEM_new()) == NULL)
		{
		Free(a);
		return(0);
		}
	a->num_dirs=0;
	a->dirs=NULL;
	a->dirs_type=NULL;
	a->num_dirs_alloced=0;
	lu->method_data=(char *)a;
	return(1);
	}

static void free_dir(lu)
X509_LOOKUP *lu;
	{
	BY_DIR *a;
	int i;

	a=(BY_DIR *)lu->method_data;
	for (i=0; i<a->num_dirs; i++)
		if (a->dirs[i] != NULL) Free(a->dirs[i]);
	if (a->dirs != NULL) Free(a->dirs);
	if (a->dirs_type != NULL) Free(a->dirs_type);
	if (a->buffer != NULL) BUF_MEM_free(a->buffer);
	Free(a);
	}

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

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

	s=dir;
	p=s;
	for (;;)
		{
		if ((*p == LIST_SEPARATOR_CHAR) || (*p == '\0'))
			{
			ss=s;
			s=p+1;
			len=(int)(p-ss);
			if (len == 0) continue;
			for (j=0; j<ctx->num_dirs; j++)
				if (strncmp(ctx->dirs[j],ss,(unsigned int)len) == 0)
					continue;
			if (ctx->num_dirs_alloced < (ctx->num_dirs+1))
				{
				ctx->num_dirs_alloced+=10;
				pp=(char **)Malloc(ctx->num_dirs_alloced*
					sizeof(char *));
				ip=(int *)Malloc(ctx->num_dirs_alloced*
					sizeof(int));
				if ((pp == NULL) || (ip == NULL))
					{
					X509err(X509_F_ADD_CERT_DIR,ERR_R_MALLOC_FAILURE);
					return(0);
					}
				memcpy(pp,ctx->dirs,(ctx->num_dirs_alloced-10)*
					sizeof(char *));
				memcpy(ip,ctx->dirs_type,(ctx->num_dirs_alloced-10)*
					sizeof(int));
				if (ctx->dirs != NULL)
					Free((char *)ctx->dirs);
				if (ctx->dirs_type != NULL)
					Free((char *)ctx->dirs_type);
				ctx->dirs=pp;
				ctx->dirs_type=ip;
				}
			ctx->dirs_type[ctx->num_dirs]=type;
			ctx->dirs[ctx->num_dirs]=(char *)Malloc((unsigned int)len+1);
			if (ctx->dirs[ctx->num_dirs] == NULL) return(0);
			strncpy(ctx->dirs[ctx->num_dirs],ss,(unsigned int)len);
			ctx->dirs[ctx->num_dirs][len]='\0';
			ctx->num_dirs++;
			}
		if (*p == '\0') break;
		p++;
		}
	return(1);
	}

static int get_cert_by_subject(xl,type,name,ret)
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;
	int i,j,k;
	unsigned long h;
	BUF_MEM *b=NULL;
	struct stat st;
	X509_OBJECT stmp,*tmp;
	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
		{
		X509err(X509_F_GET_CERT_BY_SUBJECT,X509_R_WRONG_LOOKUP_TYPE);
		goto finish;
		}

	if ((b=BUF_MEM_new()) == NULL)
		{
		X509err(X509_F_GET_CERT_BY_SUBJECT,ERR_R_BUF_LIB);
		goto finish;
		}
	
	ctx=(BY_DIR *)xl->method_data;

	h=X509_NAME_hash(name);
	for (i=0; i<ctx->num_dirs; i++)
		{
		j=strlen(ctx->dirs[i])+1+8+6+1+1;
		if (!BUF_MEM_grow(b,j))
			{
			X509err(X509_F_GET_CERT_BY_SUBJECT,ERR_R_MALLOC_FAILURE);
			goto finish;
			}
		k=0;
		for (;;)
			{
			sprintf(b->data,"%s/%08lx.%s%d",ctx->dirs[i],h,
				postfix,k);
			k++;
			if (stat(b->data,&st) < 0)
				break;
			/* found one. */
			if (type == X509_LU_X509)
				{
				if ((X509_load_cert_file(xl,b->data,
					ctx->dirs_type[i])) == 0)
					break;
				}
			else if (type == X509_LU_CRL)
				{
				if ((X509_load_crl_file(xl,b->data,
					ctx->dirs_type[i])) == 0)
					break;
				}
			/* else case will caught higher up */
			}

		/* we have added it to the cache so now pull
		 * it out again */
		CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE);
		tmp=(X509_OBJECT *)lh_retrieve(xl->store_ctx->certs,
			(char *)&stmp);
		CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE);

		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);
	}

