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