]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/x509/x509_lu.c
Import of old SSLeay release: SSLeay 0.8.1b
[thirdparty/openssl.git] / crypto / x509 / x509_lu.c
1 /* crypto/x509/x509_lu.c */
2 /* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
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
64 X509_LOOKUP *X509_LOOKUP_new(method)
65 X509_LOOKUP_METHOD *method;
66 {
67 X509_LOOKUP *ret;
68
69 ret=(X509_LOOKUP *)Malloc(sizeof(X509_LOOKUP));
70 if (ret == NULL) return(NULL);
71
72 ret->init=0;
73 ret->skip=0;
74 ret->method=method;
75 ret->method_data=NULL;
76 ret->store_ctx=NULL;
77 if ((method->new_item != NULL) && !method->new_item(ret))
78 {
79 Free(ret);
80 return(NULL);
81 }
82 return(ret);
83 }
84
85 void X509_LOOKUP_free(ctx)
86 X509_LOOKUP *ctx;
87 {
88 if (ctx == NULL) return;
89 if ( (ctx->method != NULL) &&
90 (ctx->method->free != NULL))
91 ctx->method->free(ctx);
92 Free(ctx);
93 }
94
95 int X509_LOOKUP_init(ctx)
96 X509_LOOKUP *ctx;
97 {
98 if (ctx->method == NULL) return(0);
99 if (ctx->method->init != NULL)
100 return(ctx->method->init(ctx));
101 else
102 return(1);
103 }
104
105 int X509_LOOKUP_shutdown(ctx)
106 X509_LOOKUP *ctx;
107 {
108 if (ctx->method == NULL) return(0);
109 if (ctx->method->init != NULL)
110 return(ctx->method->shutdown(ctx));
111 else
112 return(1);
113 }
114
115 int X509_LOOKUP_ctrl(ctx,cmd,argc,argl,ret)
116 X509_LOOKUP *ctx;
117 int cmd;
118 char *argc;
119 long argl;
120 char **ret;
121 {
122 if (ctx->method == NULL) return(-1);
123 if (ctx->method->ctrl != NULL)
124 return(ctx->method->ctrl(ctx,cmd,argc,argl,ret));
125 else
126 return(1);
127 }
128
129 int X509_LOOKUP_by_subject(ctx,type,name,ret)
130 X509_LOOKUP *ctx;
131 int type;
132 X509_NAME *name;
133 X509_OBJECT *ret;
134 {
135 if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL))
136 return(X509_LU_FAIL);
137 if (ctx->skip) return(0);
138 return(ctx->method->get_by_subject(ctx,type,name,ret));
139 }
140
141 int X509_LOOKUP_by_issuer_serial(ctx,type,name,serial,ret)
142 X509_LOOKUP *ctx;
143 int type;
144 X509_NAME *name;
145 ASN1_INTEGER *serial;
146 X509_OBJECT *ret;
147 {
148 if ((ctx->method == NULL) ||
149 (ctx->method->get_by_issuer_serial == NULL))
150 return(X509_LU_FAIL);
151 return(ctx->method->get_by_issuer_serial(ctx,type,name,serial,ret));
152 }
153
154 int X509_LOOKUP_by_fingerprint(ctx,type,bytes,len,ret)
155 X509_LOOKUP *ctx;
156 int type;
157 unsigned char *bytes;
158 int len;
159 X509_OBJECT *ret;
160 {
161 if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL))
162 return(X509_LU_FAIL);
163 return(ctx->method->get_by_fingerprint(ctx,type,bytes,len,ret));
164 }
165
166 int X509_LOOKUP_by_alias(ctx,type,str,len,ret)
167 X509_LOOKUP *ctx;
168 int type;
169 char *str;
170 int len;
171 X509_OBJECT *ret;
172 {
173 if ((ctx->method == NULL) || (ctx->method->get_by_alias))
174 return(X509_LU_FAIL);
175 return(ctx->method->get_by_alias(ctx,str,len,ret));
176 }
177
178 static unsigned long x509_object_hash(a)
179 X509_OBJECT *a;
180 {
181 unsigned long h;
182
183 switch (a->type)
184 {
185 case X509_LU_X509:
186 h=X509_NAME_hash(a->data.x509->cert_info->subject);
187 break;
188 case X509_LU_CRL:
189 h=X509_NAME_hash(a->data.crl->crl->issuer);
190 break;
191 default:
192 abort();
193 }
194 return(h);
195 }
196
197 static int x509_object_cmp(a,b)
198 X509_OBJECT *a,*b;
199 {
200 int ret;
201
202 ret=(a->type - b->type);
203 if (ret) return(ret);
204 switch (a->type)
205 {
206 case X509_LU_X509:
207 ret=X509_subject_name_cmp(a->data.x509,b->data.x509);
208 break;
209 case X509_LU_CRL:
210 ret=X509_CRL_cmp(a->data.crl,b->data.crl);
211 break;
212 default:
213 abort();
214 }
215 return(ret);
216 }
217
218 X509_STORE *X509_STORE_new()
219 {
220 X509_STORE *ret;
221
222 if ((ret=(X509_STORE *)Malloc(sizeof(X509_STORE))) == NULL)
223 return(NULL);
224 ret->certs=lh_new(x509_object_hash,x509_object_cmp);
225 ret->cache=1;
226 ret->get_cert_methods=sk_new_null();
227 ret->verify=NULL;
228 ret->verify_cb=NULL;
229 ret->app_data=NULL;
230 ret->references=1;
231 return(ret);
232 }
233
234 static void cleanup(a)
235 X509_OBJECT *a;
236 {
237 if (a->type == X509_LU_X509)
238 {
239 X509_free(a->data.x509);
240 }
241 else if (a->type == X509_LU_CRL)
242 {
243 X509_CRL_free(a->data.crl);
244 }
245 else
246 abort();
247
248 Free(a);
249 }
250
251 void X509_STORE_free(vfy)
252 X509_STORE *vfy;
253 {
254 int i;
255 STACK *sk;
256 X509_LOOKUP *lu;
257
258 sk=vfy->get_cert_methods;
259 for (i=0; i<sk_num(sk); i++)
260 {
261 lu=(X509_LOOKUP *)sk_value(sk,i);
262 X509_LOOKUP_shutdown(lu);
263 X509_LOOKUP_free(lu);
264 }
265 sk_free(sk);
266
267 lh_doall(vfy->certs,cleanup);
268 lh_free(vfy->certs);
269 Free(vfy);
270 }
271
272 X509_LOOKUP *X509_STORE_add_lookup(v,m)
273 X509_STORE *v;
274 X509_LOOKUP_METHOD *m;
275 {
276 int i;
277 STACK *sk;
278 X509_LOOKUP *lu;
279
280 sk=v->get_cert_methods;
281 for (i=0; i<sk_num(sk); i++)
282 {
283 lu=(X509_LOOKUP *)sk_value(sk,i);
284 if (m == lu->method)
285 {
286 return(lu);
287 }
288 }
289 /* a new one */
290 lu=X509_LOOKUP_new(m);
291 if (lu == NULL)
292 return(NULL);
293 else
294 {
295 lu->store_ctx=v;
296 if (sk_push(v->get_cert_methods,(char *)lu))
297 return(lu);
298 else
299 {
300 X509_LOOKUP_free(lu);
301 return(NULL);
302 }
303 }
304 }
305
306 int X509_STORE_get_by_subject(vs,type,name,ret)
307 X509_STORE_CTX *vs;
308 int type;
309 X509_NAME *name;
310 X509_OBJECT *ret;
311 {
312 X509_STORE *ctx=vs->ctx;
313 X509_LOOKUP *lu;
314 X509_OBJECT stmp,*tmp;
315 int i,j;
316
317 tmp=X509_OBJECT_retrive_by_subject(ctx->certs,type,name);
318
319 if (tmp == NULL)
320 {
321 for (i=vs->current_method; i<sk_num(ctx->get_cert_methods); i++)
322 {
323 lu=(X509_LOOKUP *)sk_value(ctx->get_cert_methods,i);
324 j=X509_LOOKUP_by_subject(lu,type,name,&stmp);
325 if (j < 0)
326 {
327 vs->current_method=j;
328 return(j);
329 }
330 else if (j)
331 {
332 tmp= &stmp;
333 break;
334 }
335 }
336 vs->current_method=0;
337 if (tmp == NULL)
338 return(0);
339 }
340
341 /* if (ret->data.ptr != NULL)
342 X509_OBJECT_free_contents(ret); */
343
344 ret->type=tmp->type;
345 ret->data.ptr=tmp->data.ptr;
346
347 X509_OBJECT_up_ref_count(ret);
348
349 return(1);
350 }
351
352 void X509_OBJECT_up_ref_count(a)
353 X509_OBJECT *a;
354 {
355 switch (a->type)
356 {
357 case X509_LU_X509:
358 CRYPTO_add(&a->data.x509->references,1,CRYPTO_LOCK_X509);
359 break;
360 case X509_LU_CRL:
361 CRYPTO_add(&a->data.crl->references,1,CRYPTO_LOCK_X509_CRL);
362 break;
363 }
364 }
365
366 void X509_OBJECT_free_contents(a)
367 X509_OBJECT *a;
368 {
369 switch (a->type)
370 {
371 case X509_LU_X509:
372 X509_free(a->data.x509);
373 break;
374 case X509_LU_CRL:
375 X509_CRL_free(a->data.crl);
376 break;
377 }
378 }
379
380 X509_OBJECT *X509_OBJECT_retrive_by_subject(h,type,name)
381 LHASH *h;
382 int type;
383 X509_NAME *name;
384 {
385 X509_OBJECT stmp,*tmp;
386 X509 x509_s;
387 X509_CINF cinf_s;
388 X509_CRL crl_s;
389 X509_CRL_INFO crl_info_s;
390
391 stmp.type=type;
392 switch (type)
393 {
394 case X509_LU_X509:
395 stmp.data.x509= &x509_s;
396 x509_s.cert_info= &cinf_s;
397 cinf_s.subject=name;
398 break;
399 case X509_LU_CRL:
400 stmp.data.crl= &crl_s;
401 crl_s.crl= &crl_info_s;
402 crl_info_s.issuer=name;
403 break;
404 default:
405 abort();
406 }
407
408 tmp=(X509_OBJECT *)lh_retrieve(h,(char *)&stmp);
409 return(tmp);
410 }
411
412 void X509_STORE_CTX_init(ctx,store,x509,chain)
413 X509_STORE_CTX *ctx;
414 X509_STORE *store;
415 X509 *x509;
416 STACK *chain;
417 {
418 ctx->ctx=store;
419 ctx->current_method=0;
420 ctx->cert=x509;
421 ctx->untrusted=chain;
422 ctx->last_untrusted=0;
423 ctx->valid=0;
424 ctx->chain=NULL;
425 ctx->depth=10;
426 ctx->error=0;
427 ctx->current_cert=NULL;
428 }
429
430 void X509_STORE_CTX_cleanup(ctx)
431 X509_STORE_CTX *ctx;
432 {
433 if (ctx->chain != NULL)
434 {
435 sk_pop_free(ctx->chain,X509_free);
436 ctx->chain=NULL;
437 }
438 }
439