diff options
Diffstat (limited to 'src/lib/libssl/src/crypto/x509/x509_lu.c')
-rw-r--r-- | src/lib/libssl/src/crypto/x509/x509_lu.c | 481 |
1 files changed, 296 insertions, 185 deletions
diff --git a/src/lib/libssl/src/crypto/x509/x509_lu.c b/src/lib/libssl/src/crypto/x509/x509_lu.c index 2c7e10a46e..b780dae5e2 100644 --- a/src/lib/libssl/src/crypto/x509/x509_lu.c +++ b/src/lib/libssl/src/crypto/x509/x509_lu.c | |||
@@ -58,19 +58,16 @@ | |||
58 | 58 | ||
59 | #include <stdio.h> | 59 | #include <stdio.h> |
60 | #include "cryptlib.h" | 60 | #include "cryptlib.h" |
61 | #include "lhash.h" | 61 | #include <openssl/lhash.h> |
62 | #include "x509.h" | 62 | #include <openssl/x509.h> |
63 | #include <openssl/x509v3.h> | ||
63 | 64 | ||
64 | static STACK *x509_store_meth=NULL; | 65 | X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method) |
65 | static STACK *x509_store_ctx_meth=NULL; | ||
66 | |||
67 | X509_LOOKUP *X509_LOOKUP_new(method) | ||
68 | X509_LOOKUP_METHOD *method; | ||
69 | { | 66 | { |
70 | X509_LOOKUP *ret; | 67 | X509_LOOKUP *ret; |
71 | 68 | ||
72 | ret=(X509_LOOKUP *)Malloc(sizeof(X509_LOOKUP)); | 69 | ret=(X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP)); |
73 | if (ret == NULL) return(NULL); | 70 | if (ret == NULL) return NULL; |
74 | 71 | ||
75 | ret->init=0; | 72 | ret->init=0; |
76 | ret->skip=0; | 73 | ret->skip=0; |
@@ -79,163 +76,137 @@ X509_LOOKUP_METHOD *method; | |||
79 | ret->store_ctx=NULL; | 76 | ret->store_ctx=NULL; |
80 | if ((method->new_item != NULL) && !method->new_item(ret)) | 77 | if ((method->new_item != NULL) && !method->new_item(ret)) |
81 | { | 78 | { |
82 | Free(ret); | 79 | OPENSSL_free(ret); |
83 | return(NULL); | 80 | return NULL; |
84 | } | 81 | } |
85 | return(ret); | 82 | return ret; |
86 | } | 83 | } |
87 | 84 | ||
88 | void X509_LOOKUP_free(ctx) | 85 | void X509_LOOKUP_free(X509_LOOKUP *ctx) |
89 | X509_LOOKUP *ctx; | ||
90 | { | 86 | { |
91 | if (ctx == NULL) return; | 87 | if (ctx == NULL) return; |
92 | if ( (ctx->method != NULL) && | 88 | if ( (ctx->method != NULL) && |
93 | (ctx->method->free != NULL)) | 89 | (ctx->method->free != NULL)) |
94 | ctx->method->free(ctx); | 90 | ctx->method->free(ctx); |
95 | Free(ctx); | 91 | OPENSSL_free(ctx); |
96 | } | 92 | } |
97 | 93 | ||
98 | int X509_LOOKUP_init(ctx) | 94 | int X509_LOOKUP_init(X509_LOOKUP *ctx) |
99 | X509_LOOKUP *ctx; | ||
100 | { | 95 | { |
101 | if (ctx->method == NULL) return(0); | 96 | if (ctx->method == NULL) return 0; |
102 | if (ctx->method->init != NULL) | 97 | if (ctx->method->init != NULL) |
103 | return(ctx->method->init(ctx)); | 98 | return ctx->method->init(ctx); |
104 | else | 99 | else |
105 | return(1); | 100 | return 1; |
106 | } | 101 | } |
107 | 102 | ||
108 | int X509_LOOKUP_shutdown(ctx) | 103 | int X509_LOOKUP_shutdown(X509_LOOKUP *ctx) |
109 | X509_LOOKUP *ctx; | ||
110 | { | 104 | { |
111 | if (ctx->method == NULL) return(0); | 105 | if (ctx->method == NULL) return 0; |
112 | if (ctx->method->init != NULL) | 106 | if (ctx->method->shutdown != NULL) |
113 | return(ctx->method->shutdown(ctx)); | 107 | return ctx->method->shutdown(ctx); |
114 | else | 108 | else |
115 | return(1); | 109 | return 1; |
116 | } | 110 | } |
117 | 111 | ||
118 | int X509_LOOKUP_ctrl(ctx,cmd,argc,argl,ret) | 112 | int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, |
119 | X509_LOOKUP *ctx; | 113 | char **ret) |
120 | int cmd; | ||
121 | char *argc; | ||
122 | long argl; | ||
123 | char **ret; | ||
124 | { | 114 | { |
125 | if (ctx->method == NULL) return(-1); | 115 | if (ctx->method == NULL) return -1; |
126 | if (ctx->method->ctrl != NULL) | 116 | if (ctx->method->ctrl != NULL) |
127 | return(ctx->method->ctrl(ctx,cmd,argc,argl,ret)); | 117 | return ctx->method->ctrl(ctx,cmd,argc,argl,ret); |
128 | else | 118 | else |
129 | return(1); | 119 | return 1; |
130 | } | 120 | } |
131 | 121 | ||
132 | int X509_LOOKUP_by_subject(ctx,type,name,ret) | 122 | int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, |
133 | X509_LOOKUP *ctx; | 123 | X509_OBJECT *ret) |
134 | int type; | ||
135 | X509_NAME *name; | ||
136 | X509_OBJECT *ret; | ||
137 | { | 124 | { |
138 | if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL)) | 125 | if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL)) |
139 | return(X509_LU_FAIL); | 126 | return X509_LU_FAIL; |
140 | if (ctx->skip) return(0); | 127 | if (ctx->skip) return 0; |
141 | return(ctx->method->get_by_subject(ctx,type,name,ret)); | 128 | return ctx->method->get_by_subject(ctx,type,name,ret); |
142 | } | 129 | } |
143 | 130 | ||
144 | int X509_LOOKUP_by_issuer_serial(ctx,type,name,serial,ret) | 131 | int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name, |
145 | X509_LOOKUP *ctx; | 132 | ASN1_INTEGER *serial, X509_OBJECT *ret) |
146 | int type; | ||
147 | X509_NAME *name; | ||
148 | ASN1_INTEGER *serial; | ||
149 | X509_OBJECT *ret; | ||
150 | { | 133 | { |
151 | if ((ctx->method == NULL) || | 134 | if ((ctx->method == NULL) || |
152 | (ctx->method->get_by_issuer_serial == NULL)) | 135 | (ctx->method->get_by_issuer_serial == NULL)) |
153 | return(X509_LU_FAIL); | 136 | return X509_LU_FAIL; |
154 | return(ctx->method->get_by_issuer_serial(ctx,type,name,serial,ret)); | 137 | return ctx->method->get_by_issuer_serial(ctx,type,name,serial,ret); |
155 | } | 138 | } |
156 | 139 | ||
157 | int X509_LOOKUP_by_fingerprint(ctx,type,bytes,len,ret) | 140 | int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, |
158 | X509_LOOKUP *ctx; | 141 | unsigned char *bytes, int len, X509_OBJECT *ret) |
159 | int type; | ||
160 | unsigned char *bytes; | ||
161 | int len; | ||
162 | X509_OBJECT *ret; | ||
163 | { | 142 | { |
164 | if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL)) | 143 | if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL)) |
165 | return(X509_LU_FAIL); | 144 | return X509_LU_FAIL; |
166 | return(ctx->method->get_by_fingerprint(ctx,type,bytes,len,ret)); | 145 | return ctx->method->get_by_fingerprint(ctx,type,bytes,len,ret); |
167 | } | 146 | } |
168 | 147 | ||
169 | int X509_LOOKUP_by_alias(ctx,type,str,len,ret) | 148 | int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len, |
170 | X509_LOOKUP *ctx; | 149 | X509_OBJECT *ret) |
171 | int type; | ||
172 | char *str; | ||
173 | int len; | ||
174 | X509_OBJECT *ret; | ||
175 | { | 150 | { |
176 | if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL)) | 151 | if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL)) |
177 | return(X509_LU_FAIL); | 152 | return X509_LU_FAIL; |
178 | return(ctx->method->get_by_alias(ctx,str,len,ret)); | 153 | return ctx->method->get_by_alias(ctx,type,str,len,ret); |
179 | } | 154 | } |
180 | 155 | ||
181 | static unsigned long x509_object_hash(a) | 156 | |
182 | X509_OBJECT *a; | 157 | static int x509_object_cmp(const X509_OBJECT * const *a, const X509_OBJECT * const *b) |
183 | { | 158 | { |
184 | unsigned long h; | 159 | int ret; |
185 | 160 | ||
186 | switch (a->type) | 161 | ret=((*a)->type - (*b)->type); |
187 | { | 162 | if (ret) return ret; |
188 | case X509_LU_X509: | 163 | switch ((*a)->type) |
189 | h=X509_NAME_hash(a->data.x509->cert_info->subject); | 164 | { |
190 | break; | 165 | case X509_LU_X509: |
191 | case X509_LU_CRL: | 166 | ret=X509_subject_name_cmp((*a)->data.x509,(*b)->data.x509); |
192 | h=X509_NAME_hash(a->data.crl->crl->issuer); | 167 | break; |
193 | break; | 168 | case X509_LU_CRL: |
169 | ret=X509_CRL_cmp((*a)->data.crl,(*b)->data.crl); | ||
170 | break; | ||
194 | default: | 171 | default: |
195 | abort(); | 172 | /* abort(); */ |
173 | return 0; | ||
196 | } | 174 | } |
197 | return(h); | 175 | return ret; |
198 | } | 176 | } |
199 | 177 | ||
200 | static int x509_object_cmp(a,b) | 178 | X509_STORE *X509_STORE_new(void) |
201 | X509_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 | |||
221 | X509_STORE *X509_STORE_new() | ||
222 | { | 179 | { |
223 | X509_STORE *ret; | 180 | X509_STORE *ret; |
224 | 181 | ||
225 | if ((ret=(X509_STORE *)Malloc(sizeof(X509_STORE))) == NULL) | 182 | if ((ret=(X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL) |
226 | return(NULL); | 183 | return NULL; |
227 | ret->certs=lh_new(x509_object_hash,x509_object_cmp); | 184 | ret->objs = sk_X509_OBJECT_new(x509_object_cmp); |
228 | ret->cache=1; | 185 | ret->cache=1; |
229 | ret->get_cert_methods=sk_new_null(); | 186 | ret->get_cert_methods=sk_X509_LOOKUP_new_null(); |
230 | ret->verify=NULL; | 187 | ret->verify=0; |
231 | ret->verify_cb=NULL; | 188 | ret->verify_cb=0; |
232 | memset(&ret->ex_data,0,sizeof(CRYPTO_EX_DATA)); | 189 | |
190 | ret->purpose = 0; | ||
191 | ret->trust = 0; | ||
192 | |||
193 | ret->flags = 0; | ||
194 | |||
195 | ret->get_issuer = 0; | ||
196 | ret->check_issued = 0; | ||
197 | ret->check_revocation = 0; | ||
198 | ret->get_crl = 0; | ||
199 | ret->check_crl = 0; | ||
200 | ret->cert_crl = 0; | ||
201 | ret->cleanup = 0; | ||
202 | |||
203 | CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data); | ||
233 | ret->references=1; | 204 | ret->references=1; |
234 | return(ret); | 205 | ret->depth=0; |
206 | return ret; | ||
235 | } | 207 | } |
236 | 208 | ||
237 | static void cleanup(a) | 209 | static void cleanup(X509_OBJECT *a) |
238 | X509_OBJECT *a; | ||
239 | { | 210 | { |
240 | if (a->type == X509_LU_X509) | 211 | if (a->type == X509_LU_X509) |
241 | { | 212 | { |
@@ -246,90 +217,88 @@ X509_OBJECT *a; | |||
246 | X509_CRL_free(a->data.crl); | 217 | X509_CRL_free(a->data.crl); |
247 | } | 218 | } |
248 | else | 219 | else |
249 | abort(); | 220 | { |
221 | /* abort(); */ | ||
222 | } | ||
250 | 223 | ||
251 | Free(a); | 224 | OPENSSL_free(a); |
252 | } | 225 | } |
253 | 226 | ||
254 | void X509_STORE_free(vfy) | 227 | void X509_STORE_free(X509_STORE *vfy) |
255 | X509_STORE *vfy; | ||
256 | { | 228 | { |
257 | int i; | 229 | int i; |
258 | STACK *sk; | 230 | STACK_OF(X509_LOOKUP) *sk; |
259 | X509_LOOKUP *lu; | 231 | X509_LOOKUP *lu; |
260 | 232 | ||
233 | if (vfy == NULL) | ||
234 | return; | ||
235 | |||
261 | sk=vfy->get_cert_methods; | 236 | sk=vfy->get_cert_methods; |
262 | for (i=0; i<sk_num(sk); i++) | 237 | for (i=0; i<sk_X509_LOOKUP_num(sk); i++) |
263 | { | 238 | { |
264 | lu=(X509_LOOKUP *)sk_value(sk,i); | 239 | lu=sk_X509_LOOKUP_value(sk,i); |
265 | X509_LOOKUP_shutdown(lu); | 240 | X509_LOOKUP_shutdown(lu); |
266 | X509_LOOKUP_free(lu); | 241 | X509_LOOKUP_free(lu); |
267 | } | 242 | } |
268 | sk_free(sk); | 243 | sk_X509_LOOKUP_free(sk); |
244 | sk_X509_OBJECT_pop_free(vfy->objs, cleanup); | ||
269 | 245 | ||
270 | CRYPTO_free_ex_data(x509_store_meth,(char *)vfy,&vfy->ex_data); | 246 | CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data); |
271 | lh_doall(vfy->certs,cleanup); | 247 | OPENSSL_free(vfy); |
272 | lh_free(vfy->certs); | ||
273 | Free(vfy); | ||
274 | } | 248 | } |
275 | 249 | ||
276 | X509_LOOKUP *X509_STORE_add_lookup(v,m) | 250 | X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m) |
277 | X509_STORE *v; | ||
278 | X509_LOOKUP_METHOD *m; | ||
279 | { | 251 | { |
280 | int i; | 252 | int i; |
281 | STACK *sk; | 253 | STACK_OF(X509_LOOKUP) *sk; |
282 | X509_LOOKUP *lu; | 254 | X509_LOOKUP *lu; |
283 | 255 | ||
284 | sk=v->get_cert_methods; | 256 | sk=v->get_cert_methods; |
285 | for (i=0; i<sk_num(sk); i++) | 257 | for (i=0; i<sk_X509_LOOKUP_num(sk); i++) |
286 | { | 258 | { |
287 | lu=(X509_LOOKUP *)sk_value(sk,i); | 259 | lu=sk_X509_LOOKUP_value(sk,i); |
288 | if (m == lu->method) | 260 | if (m == lu->method) |
289 | { | 261 | { |
290 | return(lu); | 262 | return lu; |
291 | } | 263 | } |
292 | } | 264 | } |
293 | /* a new one */ | 265 | /* a new one */ |
294 | lu=X509_LOOKUP_new(m); | 266 | lu=X509_LOOKUP_new(m); |
295 | if (lu == NULL) | 267 | if (lu == NULL) |
296 | return(NULL); | 268 | return NULL; |
297 | else | 269 | else |
298 | { | 270 | { |
299 | lu->store_ctx=v; | 271 | lu->store_ctx=v; |
300 | if (sk_push(v->get_cert_methods,(char *)lu)) | 272 | if (sk_X509_LOOKUP_push(v->get_cert_methods,lu)) |
301 | return(lu); | 273 | return lu; |
302 | else | 274 | else |
303 | { | 275 | { |
304 | X509_LOOKUP_free(lu); | 276 | X509_LOOKUP_free(lu); |
305 | return(NULL); | 277 | return NULL; |
306 | } | 278 | } |
307 | } | 279 | } |
308 | } | 280 | } |
309 | 281 | ||
310 | int X509_STORE_get_by_subject(vs,type,name,ret) | 282 | int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name, |
311 | X509_STORE_CTX *vs; | 283 | X509_OBJECT *ret) |
312 | int type; | ||
313 | X509_NAME *name; | ||
314 | X509_OBJECT *ret; | ||
315 | { | 284 | { |
316 | X509_STORE *ctx=vs->ctx; | 285 | X509_STORE *ctx=vs->ctx; |
317 | X509_LOOKUP *lu; | 286 | X509_LOOKUP *lu; |
318 | X509_OBJECT stmp,*tmp; | 287 | X509_OBJECT stmp,*tmp; |
319 | int i,j; | 288 | int i,j; |
320 | 289 | ||
321 | tmp=X509_OBJECT_retrive_by_subject(ctx->certs,type,name); | 290 | tmp=X509_OBJECT_retrieve_by_subject(ctx->objs,type,name); |
322 | 291 | ||
323 | if (tmp == NULL) | 292 | if (tmp == NULL) |
324 | { | 293 | { |
325 | for (i=vs->current_method; i<sk_num(ctx->get_cert_methods); i++) | 294 | for (i=vs->current_method; i<sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) |
326 | { | 295 | { |
327 | lu=(X509_LOOKUP *)sk_value(ctx->get_cert_methods,i); | 296 | lu=sk_X509_LOOKUP_value(ctx->get_cert_methods,i); |
328 | j=X509_LOOKUP_by_subject(lu,type,name,&stmp); | 297 | j=X509_LOOKUP_by_subject(lu,type,name,&stmp); |
329 | if (j < 0) | 298 | if (j < 0) |
330 | { | 299 | { |
331 | vs->current_method=j; | 300 | vs->current_method=j; |
332 | return(j); | 301 | return j; |
333 | } | 302 | } |
334 | else if (j) | 303 | else if (j) |
335 | { | 304 | { |
@@ -339,7 +308,7 @@ X509_OBJECT *ret; | |||
339 | } | 308 | } |
340 | vs->current_method=0; | 309 | vs->current_method=0; |
341 | if (tmp == NULL) | 310 | if (tmp == NULL) |
342 | return(0); | 311 | return 0; |
343 | } | 312 | } |
344 | 313 | ||
345 | /* if (ret->data.ptr != NULL) | 314 | /* if (ret->data.ptr != NULL) |
@@ -350,11 +319,77 @@ X509_OBJECT *ret; | |||
350 | 319 | ||
351 | X509_OBJECT_up_ref_count(ret); | 320 | X509_OBJECT_up_ref_count(ret); |
352 | 321 | ||
353 | return(1); | 322 | return 1; |
323 | } | ||
324 | |||
325 | int X509_STORE_add_cert(X509_STORE *ctx, X509 *x) | ||
326 | { | ||
327 | X509_OBJECT *obj; | ||
328 | int ret=1; | ||
329 | |||
330 | if (x == NULL) return 0; | ||
331 | obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); | ||
332 | if (obj == NULL) | ||
333 | { | ||
334 | X509err(X509_F_X509_STORE_ADD_CERT,ERR_R_MALLOC_FAILURE); | ||
335 | return 0; | ||
336 | } | ||
337 | obj->type=X509_LU_X509; | ||
338 | obj->data.x509=x; | ||
339 | |||
340 | CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); | ||
341 | |||
342 | X509_OBJECT_up_ref_count(obj); | ||
343 | |||
344 | |||
345 | if (X509_OBJECT_retrieve_match(ctx->objs, obj)) | ||
346 | { | ||
347 | X509_OBJECT_free_contents(obj); | ||
348 | OPENSSL_free(obj); | ||
349 | X509err(X509_F_X509_STORE_ADD_CERT,X509_R_CERT_ALREADY_IN_HASH_TABLE); | ||
350 | ret=0; | ||
351 | } | ||
352 | else sk_X509_OBJECT_push(ctx->objs, obj); | ||
353 | |||
354 | CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); | ||
355 | |||
356 | return ret; | ||
354 | } | 357 | } |
355 | 358 | ||
356 | void X509_OBJECT_up_ref_count(a) | 359 | int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x) |
357 | X509_OBJECT *a; | 360 | { |
361 | X509_OBJECT *obj; | ||
362 | int ret=1; | ||
363 | |||
364 | if (x == NULL) return 0; | ||
365 | obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); | ||
366 | if (obj == NULL) | ||
367 | { | ||
368 | X509err(X509_F_X509_STORE_ADD_CRL,ERR_R_MALLOC_FAILURE); | ||
369 | return 0; | ||
370 | } | ||
371 | obj->type=X509_LU_CRL; | ||
372 | obj->data.crl=x; | ||
373 | |||
374 | CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); | ||
375 | |||
376 | X509_OBJECT_up_ref_count(obj); | ||
377 | |||
378 | if (X509_OBJECT_retrieve_match(ctx->objs, obj)) | ||
379 | { | ||
380 | X509_OBJECT_free_contents(obj); | ||
381 | OPENSSL_free(obj); | ||
382 | X509err(X509_F_X509_STORE_ADD_CRL,X509_R_CERT_ALREADY_IN_HASH_TABLE); | ||
383 | ret=0; | ||
384 | } | ||
385 | else sk_X509_OBJECT_push(ctx->objs, obj); | ||
386 | |||
387 | CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); | ||
388 | |||
389 | return ret; | ||
390 | } | ||
391 | |||
392 | void X509_OBJECT_up_ref_count(X509_OBJECT *a) | ||
358 | { | 393 | { |
359 | switch (a->type) | 394 | switch (a->type) |
360 | { | 395 | { |
@@ -367,8 +402,7 @@ X509_OBJECT *a; | |||
367 | } | 402 | } |
368 | } | 403 | } |
369 | 404 | ||
370 | void X509_OBJECT_free_contents(a) | 405 | void X509_OBJECT_free_contents(X509_OBJECT *a) |
371 | X509_OBJECT *a; | ||
372 | { | 406 | { |
373 | switch (a->type) | 407 | switch (a->type) |
374 | { | 408 | { |
@@ -381,12 +415,10 @@ X509_OBJECT *a; | |||
381 | } | 415 | } |
382 | } | 416 | } |
383 | 417 | ||
384 | X509_OBJECT *X509_OBJECT_retrive_by_subject(h,type,name) | 418 | int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, |
385 | LHASH *h; | 419 | X509_NAME *name) |
386 | int type; | ||
387 | X509_NAME *name; | ||
388 | { | 420 | { |
389 | X509_OBJECT stmp,*tmp; | 421 | X509_OBJECT stmp; |
390 | X509 x509_s; | 422 | X509 x509_s; |
391 | X509_CINF cinf_s; | 423 | X509_CINF cinf_s; |
392 | X509_CRL crl_s; | 424 | X509_CRL crl_s; |
@@ -406,41 +438,120 @@ X509_NAME *name; | |||
406 | crl_info_s.issuer=name; | 438 | crl_info_s.issuer=name; |
407 | break; | 439 | break; |
408 | default: | 440 | default: |
409 | abort(); | 441 | /* abort(); */ |
442 | return -1; | ||
410 | } | 443 | } |
411 | 444 | ||
412 | tmp=(X509_OBJECT *)lh_retrieve(h,(char *)&stmp); | 445 | return sk_X509_OBJECT_find(h,&stmp); |
413 | return(tmp); | ||
414 | } | 446 | } |
415 | 447 | ||
416 | void X509_STORE_CTX_init(ctx,store,x509,chain) | 448 | X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type, |
417 | X509_STORE_CTX *ctx; | 449 | X509_NAME *name) |
418 | X509_STORE *store; | 450 | { |
419 | X509 *x509; | 451 | int idx; |
420 | STACK *chain; | 452 | idx = X509_OBJECT_idx_by_subject(h, type, name); |
453 | if (idx==-1) return NULL; | ||
454 | return sk_X509_OBJECT_value(h, idx); | ||
455 | } | ||
456 | |||
457 | X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x) | ||
458 | { | ||
459 | int idx, i; | ||
460 | X509_OBJECT *obj; | ||
461 | idx = sk_X509_OBJECT_find(h, x); | ||
462 | if (idx == -1) return NULL; | ||
463 | if (x->type != X509_LU_X509) return sk_X509_OBJECT_value(h, idx); | ||
464 | for (i = idx; i < sk_X509_OBJECT_num(h); i++) | ||
465 | { | ||
466 | obj = sk_X509_OBJECT_value(h, i); | ||
467 | if (x509_object_cmp((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x)) | ||
468 | return NULL; | ||
469 | if ((x->type != X509_LU_X509) || !X509_cmp(obj->data.x509, x->data.x509)) | ||
470 | return obj; | ||
471 | } | ||
472 | return NULL; | ||
473 | } | ||
474 | |||
475 | |||
476 | /* Try to get issuer certificate from store. Due to limitations | ||
477 | * of the API this can only retrieve a single certificate matching | ||
478 | * a given subject name. However it will fill the cache with all | ||
479 | * matching certificates, so we can examine the cache for all | ||
480 | * matches. | ||
481 | * | ||
482 | * Return values are: | ||
483 | * 1 lookup successful. | ||
484 | * 0 certificate not found. | ||
485 | * -1 some other error. | ||
486 | */ | ||
487 | |||
488 | |||
489 | int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) | ||
490 | { | ||
491 | X509_NAME *xn; | ||
492 | X509_OBJECT obj, *pobj; | ||
493 | int i, ok, idx; | ||
494 | xn=X509_get_issuer_name(x); | ||
495 | ok=X509_STORE_get_by_subject(ctx,X509_LU_X509,xn,&obj); | ||
496 | if (ok != X509_LU_X509) | ||
497 | { | ||
498 | if (ok == X509_LU_RETRY) | ||
499 | { | ||
500 | X509_OBJECT_free_contents(&obj); | ||
501 | X509err(X509_F_X509_VERIFY_CERT,X509_R_SHOULD_RETRY); | ||
502 | return -1; | ||
503 | } | ||
504 | else if (ok != X509_LU_FAIL) | ||
505 | { | ||
506 | X509_OBJECT_free_contents(&obj); | ||
507 | /* not good :-(, break anyway */ | ||
508 | return -1; | ||
509 | } | ||
510 | return 0; | ||
511 | } | ||
512 | /* If certificate matches all OK */ | ||
513 | if (ctx->check_issued(ctx, x, obj.data.x509)) | ||
514 | { | ||
515 | *issuer = obj.data.x509; | ||
516 | return 1; | ||
517 | } | ||
518 | X509_OBJECT_free_contents(&obj); | ||
519 | /* Else find index of first matching cert */ | ||
520 | idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn); | ||
521 | /* This shouldn't normally happen since we already have one match */ | ||
522 | if (idx == -1) return 0; | ||
523 | |||
524 | /* Look through all matching certificates for a suitable issuer */ | ||
525 | for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) | ||
526 | { | ||
527 | pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i); | ||
528 | /* See if we've ran out of matches */ | ||
529 | if (pobj->type != X509_LU_X509) return 0; | ||
530 | if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509))) return 0; | ||
531 | if (ctx->check_issued(ctx, x, pobj->data.x509)) | ||
532 | { | ||
533 | *issuer = pobj->data.x509; | ||
534 | X509_OBJECT_up_ref_count(pobj); | ||
535 | return 1; | ||
536 | } | ||
537 | } | ||
538 | return 0; | ||
539 | } | ||
540 | |||
541 | void X509_STORE_set_flags(X509_STORE *ctx, long flags) | ||
421 | { | 542 | { |
422 | ctx->ctx=store; | 543 | ctx->flags |= flags; |
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; | ||
432 | memset(&(ctx->ex_data),0,sizeof(CRYPTO_EX_DATA)); | ||
433 | } | 544 | } |
434 | 545 | ||
435 | void X509_STORE_CTX_cleanup(ctx) | 546 | int X509_STORE_set_purpose(X509_STORE *ctx, int purpose) |
436 | X509_STORE_CTX *ctx; | ||
437 | { | 547 | { |
438 | if (ctx->chain != NULL) | 548 | return X509_PURPOSE_set(&ctx->purpose, purpose); |
439 | { | 549 | } |
440 | sk_pop_free(ctx->chain,X509_free); | 550 | |
441 | ctx->chain=NULL; | 551 | int X509_STORE_set_trust(X509_STORE *ctx, int trust) |
442 | } | 552 | { |
443 | CRYPTO_free_ex_data(x509_store_ctx_meth,(char *)ctx,&(ctx->ex_data)); | 553 | return X509_TRUST_set(&ctx->trust, trust); |
444 | memset(&ctx->ex_data,0,sizeof(CRYPTO_EX_DATA)); | ||
445 | } | 554 | } |
446 | 555 | ||
556 | IMPLEMENT_STACK_OF(X509_LOOKUP) | ||
557 | IMPLEMENT_STACK_OF(X509_OBJECT) | ||