OLD | NEW |
1 /* crypto/x509/x509_lu.c */ | 1 /* crypto/x509/x509_lu.c */ |
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 * All rights reserved. | 3 * All rights reserved. |
4 * | 4 * |
5 * This package is an SSL implementation written | 5 * This package is an SSL implementation written |
6 * by Eric Young (eay@cryptsoft.com). | 6 * by Eric Young (eay@cryptsoft.com). |
7 * The implementation was written so as to conform with Netscapes SSL. | 7 * The implementation was written so as to conform with Netscapes SSL. |
8 * | 8 * |
9 * This library is free for commercial and non-commercial use as long as | 9 * This library is free for commercial and non-commercial use as long as |
10 * the following conditions are aheared to. The following conditions | 10 * the following conditions are aheared to. The following conditions |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 | 189 |
190 if ((ret->param = X509_VERIFY_PARAM_new()) == NULL) | 190 if ((ret->param = X509_VERIFY_PARAM_new()) == NULL) |
191 return NULL; | 191 return NULL; |
192 | 192 |
193 ret->get_issuer = 0; | 193 ret->get_issuer = 0; |
194 ret->check_issued = 0; | 194 ret->check_issued = 0; |
195 ret->check_revocation = 0; | 195 ret->check_revocation = 0; |
196 ret->get_crl = 0; | 196 ret->get_crl = 0; |
197 ret->check_crl = 0; | 197 ret->check_crl = 0; |
198 ret->cert_crl = 0; | 198 ret->cert_crl = 0; |
| 199 ret->lookup_certs = 0; |
| 200 ret->lookup_crls = 0; |
199 ret->cleanup = 0; | 201 ret->cleanup = 0; |
200 | 202 |
201 if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data)) | 203 if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data)) |
202 { | 204 { |
203 sk_X509_OBJECT_free(ret->objs); | 205 sk_X509_OBJECT_free(ret->objs); |
204 OPENSSL_free(ret); | 206 OPENSSL_free(ret); |
205 return NULL; | 207 return NULL; |
206 } | 208 } |
207 | 209 |
208 ret->references=1; | 210 ret->references=1; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 { | 291 { |
290 X509_STORE *ctx=vs->ctx; | 292 X509_STORE *ctx=vs->ctx; |
291 X509_LOOKUP *lu; | 293 X509_LOOKUP *lu; |
292 X509_OBJECT stmp,*tmp; | 294 X509_OBJECT stmp,*tmp; |
293 int i,j; | 295 int i,j; |
294 | 296 |
295 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); | 297 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); |
296 tmp=X509_OBJECT_retrieve_by_subject(ctx->objs,type,name); | 298 tmp=X509_OBJECT_retrieve_by_subject(ctx->objs,type,name); |
297 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); | 299 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); |
298 | 300 |
299 » if (tmp == NULL) | 301 » if (tmp == NULL || type == X509_LU_CRL) |
300 { | 302 { |
301 for (i=vs->current_method; i<sk_X509_LOOKUP_num(ctx->get_cert_me
thods); i++) | 303 for (i=vs->current_method; i<sk_X509_LOOKUP_num(ctx->get_cert_me
thods); i++) |
302 { | 304 { |
303 lu=sk_X509_LOOKUP_value(ctx->get_cert_methods,i); | 305 lu=sk_X509_LOOKUP_value(ctx->get_cert_methods,i); |
304 j=X509_LOOKUP_by_subject(lu,type,name,&stmp); | 306 j=X509_LOOKUP_by_subject(lu,type,name,&stmp); |
305 if (j < 0) | 307 if (j < 0) |
306 { | 308 { |
307 vs->current_method=j; | 309 vs->current_method=j; |
308 return j; | 310 return j; |
309 } | 311 } |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 { | 416 { |
415 case X509_LU_X509: | 417 case X509_LU_X509: |
416 X509_free(a->data.x509); | 418 X509_free(a->data.x509); |
417 break; | 419 break; |
418 case X509_LU_CRL: | 420 case X509_LU_CRL: |
419 X509_CRL_free(a->data.crl); | 421 X509_CRL_free(a->data.crl); |
420 break; | 422 break; |
421 } | 423 } |
422 } | 424 } |
423 | 425 |
424 int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, | 426 static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type, |
425 » X509_NAME *name) | 427 » X509_NAME *name, int *pnmatch) |
426 { | 428 { |
427 X509_OBJECT stmp; | 429 X509_OBJECT stmp; |
428 X509 x509_s; | 430 X509 x509_s; |
429 X509_CINF cinf_s; | 431 X509_CINF cinf_s; |
430 X509_CRL crl_s; | 432 X509_CRL crl_s; |
431 X509_CRL_INFO crl_info_s; | 433 X509_CRL_INFO crl_info_s; |
| 434 int idx; |
432 | 435 |
433 stmp.type=type; | 436 stmp.type=type; |
434 switch (type) | 437 switch (type) |
435 { | 438 { |
436 case X509_LU_X509: | 439 case X509_LU_X509: |
437 stmp.data.x509= &x509_s; | 440 stmp.data.x509= &x509_s; |
438 x509_s.cert_info= &cinf_s; | 441 x509_s.cert_info= &cinf_s; |
439 cinf_s.subject=name; | 442 cinf_s.subject=name; |
440 break; | 443 break; |
441 case X509_LU_CRL: | 444 case X509_LU_CRL: |
442 stmp.data.crl= &crl_s; | 445 stmp.data.crl= &crl_s; |
443 crl_s.crl= &crl_info_s; | 446 crl_s.crl= &crl_info_s; |
444 crl_info_s.issuer=name; | 447 crl_info_s.issuer=name; |
445 break; | 448 break; |
446 default: | 449 default: |
447 /* abort(); */ | 450 /* abort(); */ |
448 return -1; | 451 return -1; |
449 } | 452 } |
450 | 453 |
451 » return sk_X509_OBJECT_find(h,&stmp); | 454 » idx = sk_X509_OBJECT_find(h,&stmp); |
| 455 » if (idx >= 0 && pnmatch) |
| 456 » » { |
| 457 » » int tidx; |
| 458 » » const X509_OBJECT *tobj, *pstmp; |
| 459 » » *pnmatch = 1; |
| 460 » » pstmp = &stmp; |
| 461 » » for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++) |
| 462 » » » { |
| 463 » » » tobj = sk_X509_OBJECT_value(h, tidx); |
| 464 » » » if (x509_object_cmp(&tobj, &pstmp)) |
| 465 » » » » break; |
| 466 » » » (*pnmatch)++; |
| 467 » » » } |
| 468 » » } |
| 469 » return idx; |
| 470 » } |
| 471 |
| 472 |
| 473 int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, |
| 474 » X509_NAME *name) |
| 475 » { |
| 476 » return x509_object_idx_cnt(h, type, name, NULL); |
452 } | 477 } |
453 | 478 |
454 X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type, | 479 X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type, |
455 X509_NAME *name) | 480 X509_NAME *name) |
456 { | 481 { |
457 int idx; | 482 int idx; |
458 idx = X509_OBJECT_idx_by_subject(h, type, name); | 483 idx = X509_OBJECT_idx_by_subject(h, type, name); |
459 if (idx==-1) return NULL; | 484 if (idx==-1) return NULL; |
460 return sk_X509_OBJECT_value(h, idx); | 485 return sk_X509_OBJECT_value(h, idx); |
461 } | 486 } |
462 | 487 |
| 488 STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm) |
| 489 { |
| 490 int i, idx, cnt; |
| 491 STACK_OF(X509) *sk; |
| 492 X509 *x; |
| 493 X509_OBJECT *obj; |
| 494 sk = sk_X509_new_null(); |
| 495 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); |
| 496 idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); |
| 497 if (idx < 0) |
| 498 { |
| 499 /* Nothing found in cache: do lookup to possibly add new |
| 500 * objects to cache |
| 501 */ |
| 502 X509_OBJECT xobj; |
| 503 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); |
| 504 if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) |
| 505 { |
| 506 sk_X509_free(sk); |
| 507 return NULL; |
| 508 } |
| 509 X509_OBJECT_free_contents(&xobj); |
| 510 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); |
| 511 idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_X509,nm, &cnt); |
| 512 if (idx < 0) |
| 513 { |
| 514 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); |
| 515 sk_X509_free(sk); |
| 516 return NULL; |
| 517 } |
| 518 } |
| 519 for (i = 0; i < cnt; i++, idx++) |
| 520 { |
| 521 obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); |
| 522 x = obj->data.x509; |
| 523 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); |
| 524 if (!sk_X509_push(sk, x)) |
| 525 { |
| 526 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); |
| 527 X509_free(x); |
| 528 sk_X509_pop_free(sk, X509_free); |
| 529 return NULL; |
| 530 } |
| 531 } |
| 532 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); |
| 533 return sk; |
| 534 |
| 535 } |
| 536 |
| 537 STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm) |
| 538 { |
| 539 int i, idx, cnt; |
| 540 STACK_OF(X509_CRL) *sk; |
| 541 X509_CRL *x; |
| 542 X509_OBJECT *obj, xobj; |
| 543 sk = sk_X509_CRL_new_null(); |
| 544 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); |
| 545 /* Check cache first */ |
| 546 idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt); |
| 547 |
| 548 /* Always do lookup to possibly add new CRLs to cache |
| 549 */ |
| 550 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); |
| 551 if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj)) |
| 552 { |
| 553 sk_X509_CRL_free(sk); |
| 554 return NULL; |
| 555 } |
| 556 X509_OBJECT_free_contents(&xobj); |
| 557 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); |
| 558 idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_CRL, nm, &cnt); |
| 559 if (idx < 0) |
| 560 { |
| 561 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); |
| 562 sk_X509_CRL_free(sk); |
| 563 return NULL; |
| 564 } |
| 565 |
| 566 for (i = 0; i < cnt; i++, idx++) |
| 567 { |
| 568 obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); |
| 569 x = obj->data.crl; |
| 570 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL); |
| 571 if (!sk_X509_CRL_push(sk, x)) |
| 572 { |
| 573 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); |
| 574 X509_CRL_free(x); |
| 575 sk_X509_CRL_pop_free(sk, X509_CRL_free); |
| 576 return NULL; |
| 577 } |
| 578 } |
| 579 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); |
| 580 return sk; |
| 581 } |
| 582 |
463 X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x
) | 583 X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x
) |
464 { | 584 { |
465 int idx, i; | 585 int idx, i; |
466 X509_OBJECT *obj; | 586 X509_OBJECT *obj; |
467 idx = sk_X509_OBJECT_find(h, x); | 587 idx = sk_X509_OBJECT_find(h, x); |
468 if (idx == -1) return NULL; | 588 if (idx == -1) return NULL; |
469 » if (x->type != X509_LU_X509) return sk_X509_OBJECT_value(h, idx); | 589 » if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL)) |
| 590 » » return sk_X509_OBJECT_value(h, idx); |
470 for (i = idx; i < sk_X509_OBJECT_num(h); i++) | 591 for (i = idx; i < sk_X509_OBJECT_num(h); i++) |
471 { | 592 { |
472 obj = sk_X509_OBJECT_value(h, i); | 593 obj = sk_X509_OBJECT_value(h, i); |
473 if (x509_object_cmp((const X509_OBJECT **)&obj, (const X509_OBJE
CT **)&x)) | 594 if (x509_object_cmp((const X509_OBJECT **)&obj, (const X509_OBJE
CT **)&x)) |
474 return NULL; | 595 return NULL; |
475 » » if ((x->type != X509_LU_X509) || !X509_cmp(obj->data.x509, x->da
ta.x509)) | 596 » » if (x->type == X509_LU_X509) |
| 597 » » » { |
| 598 » » » if (!X509_cmp(obj->data.x509, x->data.x509)) |
| 599 » » » » return obj; |
| 600 » » » } |
| 601 » » else if (x->type == X509_LU_CRL) |
| 602 » » » { |
| 603 » » » if (!X509_CRL_match(obj->data.crl, x->data.crl)) |
| 604 » » » » return obj; |
| 605 » » » } |
| 606 » » else |
476 return obj; | 607 return obj; |
477 } | 608 } |
478 return NULL; | 609 return NULL; |
479 } | 610 } |
480 | 611 |
481 | 612 |
482 /* Try to get issuer certificate from store. Due to limitations | 613 /* Try to get issuer certificate from store. Due to limitations |
483 * of the API this can only retrieve a single certificate matching | 614 * of the API this can only retrieve a single certificate matching |
484 * a given subject name. However it will fill the cache with all | 615 * a given subject name. However it will fill the cache with all |
485 * matching certificates, so we can examine the cache for all | 616 * matching certificates, so we can examine the cache for all |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
568 int X509_STORE_set_trust(X509_STORE *ctx, int trust) | 699 int X509_STORE_set_trust(X509_STORE *ctx, int trust) |
569 { | 700 { |
570 return X509_VERIFY_PARAM_set_trust(ctx->param, trust); | 701 return X509_VERIFY_PARAM_set_trust(ctx->param, trust); |
571 } | 702 } |
572 | 703 |
573 int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param) | 704 int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param) |
574 { | 705 { |
575 return X509_VERIFY_PARAM_set1(ctx->param, param); | 706 return X509_VERIFY_PARAM_set1(ctx->param, param); |
576 } | 707 } |
577 | 708 |
| 709 void X509_STORE_set_verify_cb(X509_STORE *ctx, |
| 710 int (*verify_cb)(int, X509_STORE_CTX *)) |
| 711 { |
| 712 ctx->verify_cb = verify_cb; |
| 713 } |
| 714 |
578 IMPLEMENT_STACK_OF(X509_LOOKUP) | 715 IMPLEMENT_STACK_OF(X509_LOOKUP) |
579 IMPLEMENT_STACK_OF(X509_OBJECT) | 716 IMPLEMENT_STACK_OF(X509_OBJECT) |
OLD | NEW |