1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* crypto/x509/by_dir.c */
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * All rights reserved.
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This package is an SSL implementation written
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * by Eric Young (eay@cryptsoft.com).
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The implementation was written so as to conform with Netscapes SSL.
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This library is free for commercial and non-commercial use as long as
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the following conditions are aheared to.  The following conditions
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * apply to all code found in this distribution, be it the RC4, RSA,
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * included with this distribution is covered by the same copyright terms
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright remains Eric Young's, and as such any Copyright notices in
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the code are not to be removed.
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * If this package is used in a product, Eric Young should be given attribution
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * as the author of the parts of the library used.
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This can be in the form of a textual message at program startup or
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * in documentation (online or textual) provided with the package.
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the copyright
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    documentation and/or other materials provided with the distribution.
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this software
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    must display the following acknowledgement:
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes cryptographic software written by
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *     Eric Young (eay@cryptsoft.com)"
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    The word 'cryptographic' can be left out if the rouines from the library
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    being used are not cryptographic related :-).
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. If you include any Windows specific code (or a derivative thereof) from
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the apps directory (application code) you must include an acknowledgement:
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SUCH DAMAGE.
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The licence and distribution terms for any publically available version or
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * derivative of this code cannot be changed.  i.e. this code cannot simply be
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * copied and put under another distribution licence
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * [including the GNU Public Licence.]
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdio.h>
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <time.h>
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <errno.h>
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "cryptlib.h"
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef NO_SYS_TYPES_H
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# include <sys/types.h>
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
68221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifndef OPENSSL_NO_POSIX_IO
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# include <sys/stat.h>
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/lhash.h>
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/x509.h>
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
75221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
76221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromtypedef struct lookup_dir_hashes_st
77221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
78221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	unsigned long hash;
79221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int suffix;
80221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	} BY_DIR_HASH;
81221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
82221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromtypedef struct lookup_dir_entry_st
83221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
84221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	char *dir;
85221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int dir_type;
86221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	STACK_OF(BY_DIR_HASH) *hashes;
87221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	} BY_DIR_ENTRY;
88e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef struct lookup_dir_st
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BUF_MEM *buffer;
92221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	STACK_OF(BY_DIR_ENTRY) *dirs;
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} BY_DIR;
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
95221304ee937bc0910948a8be1320cb8cc4eb6d36Brian CarlstromDECLARE_STACK_OF(BY_DIR_HASH)
96221304ee937bc0910948a8be1320cb8cc4eb6d36Brian CarlstromDECLARE_STACK_OF(BY_DIR_ENTRY)
97221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char **ret);
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int new_dir(X509_LOOKUP *lu);
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void free_dir(X509_LOOKUP *lu);
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int add_cert_dir(BY_DIR *ctx,const char *dir,int type);
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int get_cert_by_subject(X509_LOOKUP *xl,int type,X509_NAME *name,
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509_OBJECT *ret);
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectX509_LOOKUP_METHOD x509_dir_lookup=
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	"Load certs from files in a directory",
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	new_dir,		/* new */
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	free_dir,		/* free */
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL, 			/* init */
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,			/* shutdown */
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dir_ctrl,		/* ctrl */
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	get_cert_by_subject,	/* get_by_subject */
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,			/* get_by_issuer_serial */
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,			/* get_by_fingerprint */
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,			/* get_by_alias */
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	};
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectX509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void)
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(&x509_dir_lookup);
122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	     char **retp)
126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret=0;
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BY_DIR *ld;
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char *dir = NULL;
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ld=(BY_DIR *)ctx->method_data;
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	switch (cmd)
134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case X509_L_ADD_DIR:
136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (argl == X509_FILETYPE_DEFAULT)
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
138221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			dir=(char *)getenv(X509_get_default_cert_dir_env());
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (dir)
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ret=add_cert_dir(ld,dir,X509_FILETYPE_PEM);
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ret=add_cert_dir(ld,X509_get_default_cert_dir(),
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					X509_FILETYPE_PEM);
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!ret)
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				X509err(X509_F_DIR_CTRL,X509_R_LOADING_CERT_DIR);
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=add_cert_dir(ld,argp,(int)argl);
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(ret);
154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int new_dir(X509_LOOKUP *lu)
157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BY_DIR *a;
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((a=(BY_DIR *)OPENSSL_malloc(sizeof(BY_DIR))) == NULL)
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(0);
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((a->buffer=BUF_MEM_new()) == NULL)
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		OPENSSL_free(a);
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(0);
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	a->dirs=NULL;
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	lu->method_data=(char *)a;
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(1);
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
172221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void by_dir_hash_free(BY_DIR_HASH *hash)
173221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
174221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	OPENSSL_free(hash);
175221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
176221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
177221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int by_dir_hash_cmp(const BY_DIR_HASH * const *a,
178221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			const BY_DIR_HASH * const *b)
179221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
180221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if ((*a)->hash > (*b)->hash)
181221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 1;
182221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if ((*a)->hash < (*b)->hash)
183221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -1;
184221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 0;
185221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
186221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
187221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void by_dir_entry_free(BY_DIR_ENTRY *ent)
188221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
189221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ent->dir)
190221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		OPENSSL_free(ent->dir);
191221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ent->hashes)
192221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free);
193221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	OPENSSL_free(ent);
194221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
195221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void free_dir(X509_LOOKUP *lu)
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BY_DIR *a;
199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	a=(BY_DIR *)lu->method_data;
201221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (a->dirs != NULL)
202221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free);
203221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (a->buffer != NULL)
204221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		BUF_MEM_free(a->buffer);
205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	OPENSSL_free(a);
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int j,len;
211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const char *s,*ss,*p;
212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (dir == NULL || !*dir)
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    {
215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    X509err(X509_F_ADD_CERT_DIR,X509_R_INVALID_DIRECTORY);
216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    return 0;
217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    }
218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	s=dir;
220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	p=s;
2217f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root	do
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((*p == LIST_SEPARATOR_CHAR) || (*p == '\0'))
224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
225221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			BY_DIR_ENTRY *ent;
226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ss=s;
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s=p+1;
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			len=(int)(p-ss);
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (len == 0) continue;
230221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			for (j=0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++)
231221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
232221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j);
233221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				if (strlen(ent->dir) == (size_t)len &&
234221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				    strncmp(ent->dir,ss,(unsigned int)len) == 0)
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					break;
236221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
237221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (j < sk_BY_DIR_ENTRY_num(ctx->dirs))
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				continue;
239221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (ctx->dirs == NULL)
240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
241221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				ctx->dirs = sk_BY_DIR_ENTRY_new_null();
242221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				if (!ctx->dirs)
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					{
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					X509err(X509_F_ADD_CERT_DIR,ERR_R_MALLOC_FAILURE);
245221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					return 0;
246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					}
247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
248221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			ent = OPENSSL_malloc(sizeof(BY_DIR_ENTRY));
249221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (!ent)
250221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				return 0;
251221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			ent->dir_type = type;
252221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp);
253221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			ent->dir = OPENSSL_malloc((unsigned int)len+1);
254221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (!ent->dir || !ent->hashes)
255221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
256221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				by_dir_entry_free(ent);
257221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				return 0;
258221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
259221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			strncpy(ent->dir,ss,(unsigned int)len);
260221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			ent->dir[len] = '\0';
261221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent))
262221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
263221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				by_dir_entry_free(ent);
264221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				return 0;
265221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
2677f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root		} while (*p++ != '\0');
268221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 1;
269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	     X509_OBJECT *ret)
273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BY_DIR *ctx;
275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	union	{
276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		struct	{
277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			X509 st_x509;
278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			X509_CINF st_x509_cinf;
279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			} x509;
280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		struct	{
281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			X509_CRL st_crl;
282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			X509_CRL_INFO st_crl_info;
283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			} crl;
284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} data;
285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ok=0;
286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i,j,k;
287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned long h;
288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BUF_MEM *b=NULL;
289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509_OBJECT stmp,*tmp;
290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const char *postfix="";
291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (name == NULL) return(0);
293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	stmp.type=type;
295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (type == X509_LU_X509)
296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		data.x509.st_x509.cert_info= &data.x509.st_x509_cinf;
298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		data.x509.st_x509_cinf.subject=name;
299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		stmp.data.x509= &data.x509.st_x509;
300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		postfix="";
301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else if (type == X509_LU_CRL)
303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		data.crl.st_crl.crl= &data.crl.st_crl_info;
305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		data.crl.st_crl_info.issuer=name;
306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		stmp.data.crl= &data.crl.st_crl;
307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		postfix="r";
308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		X509err(X509_F_GET_CERT_BY_SUBJECT,X509_R_WRONG_LOOKUP_TYPE);
312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto finish;
313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((b=BUF_MEM_new()) == NULL)
316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		X509err(X509_F_GET_CERT_BY_SUBJECT,ERR_R_BUF_LIB);
318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto finish;
319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx=(BY_DIR *)xl->method_data;
322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	h=X509_NAME_hash(name);
324221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	for (i=0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++)
325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
326221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		BY_DIR_ENTRY *ent;
327221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		int idx;
328221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		BY_DIR_HASH htmp, *hent;
329221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i);
330221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		j=strlen(ent->dir)+1+8+6+1+1;
331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!BUF_MEM_grow(b,j))
332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			X509err(X509_F_GET_CERT_BY_SUBJECT,ERR_R_MALLOC_FAILURE);
334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto finish;
335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
336221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (type == X509_LU_CRL && ent->hashes)
337221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
338221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			htmp.hash = h;
339221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE);
340221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp);
341221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (idx >= 0)
342221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
343221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
344221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				k = hent->suffix;
345221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
346221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			else
347221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
348221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				hent = NULL;
349221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				k=0;
350221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
351221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE);
352221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
353221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else
354221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
355221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			k = 0;
356221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			hent = NULL;
357221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		for (;;)
359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			char c = '/';
361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef OPENSSL_SYS_VMS
362221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			c = ent->dir[strlen(ent->dir)-1];
363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (c != ':' && c != '>' && c != ']')
364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				/* If no separator is present, we assume the
366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				   directory specifier is a logical name, and
367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				   add a colon.  We really should use better
368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				   VMS routines for merging things like this,
369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				   but this will do for now...
370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				   -- Richard Levitte */
371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				c = ':';
372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				c = '\0';
376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (c == '\0')
379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				/* This is special.  When c == '\0', no
381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				   directory separator should be added. */
382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				BIO_snprintf(b->data,b->max,
383221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					"%s%08lx.%s%d",ent->dir,h,
384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					postfix,k);
385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				BIO_snprintf(b->data,b->max,
389221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					"%s%c%08lx.%s%d",ent->dir,c,h,
390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					postfix,k);
391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
392221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifndef OPENSSL_NO_POSIX_IO
393221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifdef _WIN32
394221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#define stat _stat
395221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
396221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
397221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			struct stat st;
398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (stat(b->data,&st) < 0)
399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				break;
400221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
401221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
402656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* found one. */
403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (type == X509_LU_X509)
404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
405656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if ((X509_load_cert_file(xl,b->data,
406221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					ent->dir_type)) == 0)
407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					break;
408656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
409656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else if (type == X509_LU_CRL)
410656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
411656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if ((X509_load_crl_file(xl,b->data,
412221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					ent->dir_type)) == 0)
413656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					break;
414656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
415656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* else case will caught higher up */
416221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			k++;
417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* we have added it to the cache so now pull
420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * it out again */
42198d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom		CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		j = sk_X509_OBJECT_find(xl->store_ctx->objs,&stmp);
423656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(j != -1) tmp=sk_X509_OBJECT_value(xl->store_ctx->objs,j);
424656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else tmp = NULL;
42598d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom		CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
426656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
427221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
428221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		/* If a CRL, update the last file suffix added for this */
429221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
430221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (type == X509_LU_CRL)
431221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
432221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
433221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			/* Look for entry again in case another thread added
434221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			 * an entry first.
435221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			 */
436221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (!hent)
437221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
438221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				htmp.hash = h;
439221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp);
440221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				if (idx >= 0)
441221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					hent =
442221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					 sk_BY_DIR_HASH_value(ent->hashes, idx);
443221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
444221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (!hent)
445221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
446221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				hent = OPENSSL_malloc(sizeof(BY_DIR_HASH));
447221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				hent->hash = h;
448221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				hent->suffix = k;
449221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				if (!sk_BY_DIR_HASH_push(ent->hashes, hent))
450221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					{
451221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
452221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					OPENSSL_free(hent);
453221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					ok = 0;
454221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					goto finish;
455221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					}
456221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
457221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			else if (hent->suffix < k)
458221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				hent->suffix = k;
459221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
460221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
461221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
462221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
463221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
464656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (tmp != NULL)
465656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
466656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ok=1;
467656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret->type=tmp->type;
468656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			memcpy(&ret->data,&tmp->data,sizeof(ret->data));
469656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* If we were going to up the reference count,
470656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * we would need to do it on a perl 'type'
471656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * basis */
472656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/*		CRYPTO_add(&tmp->data.x509->references,1,
473656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				CRYPTO_LOCK_X509);*/
474656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto finish;
475656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
476656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
477656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectfinish:
478656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b != NULL) BUF_MEM_free(b);
479656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(ok);
480656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
481