]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/x509/x509_lu.c
Import of old SSLeay release: SSLeay 0.9.0b
[thirdparty/openssl.git] / crypto / x509 / x509_lu.c
CommitLineData
d02b48c6 1/* crypto/x509/x509_lu.c */
58964a49 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
d02b48c6
RE
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include "cryptlib.h"
61#include "lhash.h"
62#include "x509.h"
63
58964a49
RE
64static STACK *x509_store_meth=NULL;
65static STACK *x509_store_ctx_meth=NULL;
66
d02b48c6
RE
67X509_LOOKUP *X509_LOOKUP_new(method)
68X509_LOOKUP_METHOD *method;
69 {
70 X509_LOOKUP *ret;
71
72 ret=(X509_LOOKUP *)Malloc(sizeof(X509_LOOKUP));
73 if (ret == NULL) return(NULL);
74
75 ret->init=0;
76 ret->skip=0;
77 ret->method=method;
78 ret->method_data=NULL;
79 ret->store_ctx=NULL;
80 if ((method->new_item != NULL) && !method->new_item(ret))
81 {
82 Free(ret);
83 return(NULL);
84 }
85 return(ret);
86 }
87
88void X509_LOOKUP_free(ctx)
89X509_LOOKUP *ctx;
90 {
91 if (ctx == NULL) return;
92 if ( (ctx->method != NULL) &&
93 (ctx->method->free != NULL))
94 ctx->method->free(ctx);
95 Free(ctx);
96 }
97
98int X509_LOOKUP_init(ctx)
99X509_LOOKUP *ctx;
100 {
101 if (ctx->method == NULL) return(0);
102 if (ctx->method->init != NULL)
103 return(ctx->method->init(ctx));
104 else
105 return(1);
106 }
107
108int X509_LOOKUP_shutdown(ctx)
109X509_LOOKUP *ctx;
110 {
111 if (ctx->method == NULL) return(0);
112 if (ctx->method->init != NULL)
113 return(ctx->method->shutdown(ctx));
114 else
115 return(1);
116 }
117
118int X509_LOOKUP_ctrl(ctx,cmd,argc,argl,ret)
119X509_LOOKUP *ctx;
120int cmd;
121char *argc;
122long argl;
123char **ret;
124 {
125 if (ctx->method == NULL) return(-1);
126 if (ctx->method->ctrl != NULL)
127 return(ctx->method->ctrl(ctx,cmd,argc,argl,ret));
128 else
129 return(1);
130 }
131
132int X509_LOOKUP_by_subject(ctx,type,name,ret)
133X509_LOOKUP *ctx;
134int type;
135X509_NAME *name;
136X509_OBJECT *ret;
137 {
138 if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL))
139 return(X509_LU_FAIL);
140 if (ctx->skip) return(0);
141 return(ctx->method->get_by_subject(ctx,type,name,ret));
142 }
143
144int X509_LOOKUP_by_issuer_serial(ctx,type,name,serial,ret)
145X509_LOOKUP *ctx;
146int type;
147X509_NAME *name;
148ASN1_INTEGER *serial;
149X509_OBJECT *ret;
150 {
151 if ((ctx->method == NULL) ||
152 (ctx->method->get_by_issuer_serial == NULL))
153 return(X509_LU_FAIL);
154 return(ctx->method->get_by_issuer_serial(ctx,type,name,serial,ret));
155 }
156
157int X509_LOOKUP_by_fingerprint(ctx,type,bytes,len,ret)
158X509_LOOKUP *ctx;
159int type;
160unsigned char *bytes;
161int len;
162X509_OBJECT *ret;
163 {
164 if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL))
165 return(X509_LU_FAIL);
166 return(ctx->method->get_by_fingerprint(ctx,type,bytes,len,ret));
167 }
168
169int X509_LOOKUP_by_alias(ctx,type,str,len,ret)
170X509_LOOKUP *ctx;
171int type;
172char *str;
173int len;
174X509_OBJECT *ret;
175 {
58964a49 176 if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL))
d02b48c6
RE
177 return(X509_LU_FAIL);
178 return(ctx->method->get_by_alias(ctx,str,len,ret));
179 }
180
181static unsigned long x509_object_hash(a)
182X509_OBJECT *a;
183 {
184 unsigned long h;
185
186 switch (a->type)
187 {
188 case X509_LU_X509:
189 h=X509_NAME_hash(a->data.x509->cert_info->subject);
190 break;
191 case X509_LU_CRL:
192 h=X509_NAME_hash(a->data.crl->crl->issuer);
193 break;
194 default:
195 abort();
196 }
197 return(h);
198 }
199
200static int x509_object_cmp(a,b)
201X509_OBJECT *a,*b;
202 {
203 int ret;
204
205 ret=(a->type - b->type);
206 if (ret) return(ret);
207 switch (a->type)
208 {
209 case X509_LU_X509:
210 ret=X509_subject_name_cmp(a->data.x509,b->data.x509);
211 break;
212 case X509_LU_CRL:
213 ret=X509_CRL_cmp(a->data.crl,b->data.crl);
214 break;
215 default:
216 abort();
217 }
218 return(ret);
219 }
220
221X509_STORE *X509_STORE_new()
222 {
223 X509_STORE *ret;
224
225 if ((ret=(X509_STORE *)Malloc(sizeof(X509_STORE))) == NULL)
226 return(NULL);
227 ret->certs=lh_new(x509_object_hash,x509_object_cmp);
228 ret->cache=1;
229 ret->get_cert_methods=sk_new_null();
230 ret->verify=NULL;
231 ret->verify_cb=NULL;
58964a49 232 memset(&ret->ex_data,0,sizeof(CRYPTO_EX_DATA));
d02b48c6
RE
233 ret->references=1;
234 return(ret);
235 }
236
237static void cleanup(a)
238X509_OBJECT *a;
239 {
240 if (a->type == X509_LU_X509)
241 {
242 X509_free(a->data.x509);
243 }
244 else if (a->type == X509_LU_CRL)
245 {
246 X509_CRL_free(a->data.crl);
247 }
248 else
249 abort();
250
251 Free(a);
252 }
253
254void X509_STORE_free(vfy)
255X509_STORE *vfy;
256 {
257 int i;
258 STACK *sk;
259 X509_LOOKUP *lu;
260
261 sk=vfy->get_cert_methods;
262 for (i=0; i<sk_num(sk); i++)
263 {
264 lu=(X509_LOOKUP *)sk_value(sk,i);
265 X509_LOOKUP_shutdown(lu);
266 X509_LOOKUP_free(lu);
267 }
268 sk_free(sk);
269
58964a49 270 CRYPTO_free_ex_data(x509_store_meth,(char *)vfy,&vfy->ex_data);
d02b48c6
RE
271 lh_doall(vfy->certs,cleanup);
272 lh_free(vfy->certs);
273 Free(vfy);
274 }
275
276X509_LOOKUP *X509_STORE_add_lookup(v,m)
277X509_STORE *v;
278X509_LOOKUP_METHOD *m;
279 {
280 int i;
281 STACK *sk;
282 X509_LOOKUP *lu;
283
284 sk=v->get_cert_methods;
285 for (i=0; i<sk_num(sk); i++)
286 {
287 lu=(X509_LOOKUP *)sk_value(sk,i);
288 if (m == lu->method)
289 {
290 return(lu);
291 }
292 }
293 /* a new one */
294 lu=X509_LOOKUP_new(m);
295 if (lu == NULL)
296 return(NULL);
297 else
298 {
299 lu->store_ctx=v;
300 if (sk_push(v->get_cert_methods,(char *)lu))
301 return(lu);
302 else
303 {
304 X509_LOOKUP_free(lu);
305 return(NULL);
306 }
307 }
308 }
309
310int X509_STORE_get_by_subject(vs,type,name,ret)
311X509_STORE_CTX *vs;
312int type;
313X509_NAME *name;
314X509_OBJECT *ret;
315 {
316 X509_STORE *ctx=vs->ctx;
317 X509_LOOKUP *lu;
318 X509_OBJECT stmp,*tmp;
319 int i,j;
320
321 tmp=X509_OBJECT_retrive_by_subject(ctx->certs,type,name);
322
323 if (tmp == NULL)
324 {
325 for (i=vs->current_method; i<sk_num(ctx->get_cert_methods); i++)
326 {
327 lu=(X509_LOOKUP *)sk_value(ctx->get_cert_methods,i);
328 j=X509_LOOKUP_by_subject(lu,type,name,&stmp);
329 if (j < 0)
330 {
331 vs->current_method=j;
332 return(j);
333 }
334 else if (j)
335 {
336 tmp= &stmp;
337 break;
338 }
339 }
340 vs->current_method=0;
341 if (tmp == NULL)
342 return(0);
343 }
344
345/* if (ret->data.ptr != NULL)
346 X509_OBJECT_free_contents(ret); */
347
348 ret->type=tmp->type;
349 ret->data.ptr=tmp->data.ptr;
350
351 X509_OBJECT_up_ref_count(ret);
352
353 return(1);
354 }
355
356void X509_OBJECT_up_ref_count(a)
357X509_OBJECT *a;
358 {
359 switch (a->type)
360 {
361 case X509_LU_X509:
362 CRYPTO_add(&a->data.x509->references,1,CRYPTO_LOCK_X509);
363 break;
364 case X509_LU_CRL:
365 CRYPTO_add(&a->data.crl->references,1,CRYPTO_LOCK_X509_CRL);
366 break;
367 }
368 }
369
370void X509_OBJECT_free_contents(a)
371X509_OBJECT *a;
372 {
373 switch (a->type)
374 {
375 case X509_LU_X509:
376 X509_free(a->data.x509);
377 break;
378 case X509_LU_CRL:
379 X509_CRL_free(a->data.crl);
380 break;
381 }
382 }
383
384X509_OBJECT *X509_OBJECT_retrive_by_subject(h,type,name)
385LHASH *h;
386int type;
387X509_NAME *name;
388 {
389 X509_OBJECT stmp,*tmp;
390 X509 x509_s;
391 X509_CINF cinf_s;
392 X509_CRL crl_s;
393 X509_CRL_INFO crl_info_s;
394
395 stmp.type=type;
396 switch (type)
397 {
398 case X509_LU_X509:
399 stmp.data.x509= &x509_s;
400 x509_s.cert_info= &cinf_s;
401 cinf_s.subject=name;
402 break;
403 case X509_LU_CRL:
404 stmp.data.crl= &crl_s;
405 crl_s.crl= &crl_info_s;
406 crl_info_s.issuer=name;
407 break;
408 default:
409 abort();
410 }
411
412 tmp=(X509_OBJECT *)lh_retrieve(h,(char *)&stmp);
413 return(tmp);
414 }
415
416void X509_STORE_CTX_init(ctx,store,x509,chain)
417X509_STORE_CTX *ctx;
418X509_STORE *store;
419X509 *x509;
420STACK *chain;
421 {
422 ctx->ctx=store;
423 ctx->current_method=0;
424 ctx->cert=x509;
425 ctx->untrusted=chain;
426 ctx->last_untrusted=0;
427 ctx->valid=0;
428 ctx->chain=NULL;
429 ctx->depth=10;
430 ctx->error=0;
431 ctx->current_cert=NULL;
58964a49 432 memset(&(ctx->ex_data),0,sizeof(CRYPTO_EX_DATA));
d02b48c6
RE
433 }
434
435void X509_STORE_CTX_cleanup(ctx)
436X509_STORE_CTX *ctx;
437 {
438 if (ctx->chain != NULL)
439 {
440 sk_pop_free(ctx->chain,X509_free);
441 ctx->chain=NULL;
442 }
58964a49
RE
443 CRYPTO_free_ex_data(x509_store_ctx_meth,(char *)ctx,&(ctx->ex_data));
444 memset(&ctx->ex_data,0,sizeof(CRYPTO_EX_DATA));
d02b48c6
RE
445 }
446