x509_lu.c revision 296341
12432Sse/* crypto/x509/x509_lu.c */ 22432Sse/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 32432Sse * All rights reserved. 439247Sgibbs * 52432Sse * This package is an SSL implementation written 62432Sse * by Eric Young (eay@cryptsoft.com). 72432Sse * The implementation was written so as to conform with Netscapes SSL. 82432Sse * 97228Sse * This library is free for commercial and non-commercial use as long as 103533Sse * the following conditions are aheared to. The following conditions 112432Sse * apply to all code found in this distribution, be it the RC4, RSA, 122432Sse * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13139834Sscottl * included with this distribution is covered by the same copyright terms 14139825Simp * except that the holder is Tim Hudson (tjh@cryptsoft.com). 152432Sse * 162432Sse * Copyright remains Eric Young's, and as such any Copyright notices in 172432Sse * the code are not to be removed. 182432Sse * If this package is used in a product, Eric Young should be given attribution 192432Sse * as the author of the parts of the library used. 202432Sse * This can be in the form of a textual message at program startup or 212432Sse * in documentation (online or textual) provided with the package. 222432Sse * 232432Sse * Redistribution and use in source and binary forms, with or without 242432Sse * modification, are permitted provided that the following conditions 252432Sse * are met: 262432Sse * 1. Redistributions of source code must retain the copyright 272432Sse * notice, this list of conditions and the following disclaimer. 282432Sse * 2. Redistributions in binary form must reproduce the above copyright 292432Sse * notice, this list of conditions and the following disclaimer in the 302432Sse * documentation and/or other materials provided with the distribution. 312432Sse * 3. All advertising materials mentioning features or use of this software 322432Sse * must display the following acknowledgement: 332432Sse * "This product includes cryptographic software written by 342432Sse * Eric Young (eay@cryptsoft.com)" 352432Sse * The word 'cryptographic' can be left out if the rouines from the library 362432Sse * being used are not cryptographic related :-). 372432Sse * 4. If you include any Windows specific code (or a derivative thereof) from 382432Sse * the apps directory (application code) you must include an acknowledgement: 393533Sse * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 402432Sse * 412432Sse * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42116192Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43116192Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44116192Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45116192Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 469429Sse * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 477228Sse * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855206Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4920535Sse * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055206Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5120517Sse * SUCH DAMAGE. 522432Sse * 532432Sse * The licence and distribution terms for any publically available version or 542432Sse * derivative of this code cannot be changed. i.e. this code cannot simply be 552432Sse * copied and put under another distribution licence 566460Sse * [including the GNU Public Licence.] 572432Sse */ 582432Sse 592432Sse#include <stdio.h> 602432Sse#include "cryptlib.h" 612432Sse#include <openssl/lhash.h> 622432Sse#include <openssl/x509.h> 632432Sse#include <openssl/x509v3.h> 642432Sse 652432SseX509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method) 662432Sse{ 672432Sse X509_LOOKUP *ret; 682432Sse 692432Sse ret = (X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP)); 702432Sse if (ret == NULL) 712432Sse return NULL; 7227684Sse 732432Sse ret->init = 0; 7427684Sse ret->skip = 0; 752432Sse ret->method = method; 762432Sse ret->method_data = NULL; 7727684Sse ret->store_ctx = NULL; 782432Sse if ((method->new_item != NULL) && !method->new_item(ret)) { 7927684Sse OPENSSL_free(ret); 8027684Sse return NULL; 8127684Sse } 8227684Sse return ret; 8327684Sse} 8427684Sse 8527684Ssevoid X509_LOOKUP_free(X509_LOOKUP *ctx) 8627684Sse{ 8727684Sse if (ctx == NULL) 8827684Sse return; 8927684Sse if ((ctx->method != NULL) && (ctx->method->free != NULL)) 9027684Sse (*ctx->method->free) (ctx); 9127684Sse OPENSSL_free(ctx); 9227684Sse} 932432Sse 9427684Sseint X509_LOOKUP_init(X509_LOOKUP *ctx) 9527684Sse{ 9627684Sse if (ctx->method == NULL) 9727684Sse return 0; 9827684Sse if (ctx->method->init != NULL) 9927684Sse return ctx->method->init(ctx); 10027684Sse else 10127684Sse return 1; 10227684Sse} 1032814Sse 1042814Sseint X509_LOOKUP_shutdown(X509_LOOKUP *ctx) 1052814Sse{ 1062814Sse if (ctx->method == NULL) 1072814Sse return 0; 1083939Sse if (ctx->method->shutdown != NULL) 1092814Sse return ctx->method->shutdown(ctx); 1102814Sse else 1112432Sse return 1; 1122432Sse} 1132432Sse 1142432Sseint X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, 1152432Sse char **ret) 1162432Sse{ 1172432Sse if (ctx->method == NULL) 1182432Sse return -1; 1192432Sse if (ctx->method->ctrl != NULL) 1202432Sse return ctx->method->ctrl(ctx, cmd, argc, argl, ret); 1212432Sse else 1222432Sse return 1; 1232432Sse} 1242432Sse 12510605Sseint X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, 1262432Sse X509_OBJECT *ret) 1272432Sse{ 1282432Sse if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL)) 1292432Sse return X509_LU_FAIL; 1302432Sse if (ctx->skip) 1312432Sse return 0; 1322432Sse return ctx->method->get_by_subject(ctx, type, name, ret); 1332432Sse} 13414556Sse 13513481Sseint X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name, 13614556Sse ASN1_INTEGER *serial, X509_OBJECT *ret) 1372432Sse{ 1382432Sse if ((ctx->method == NULL) || (ctx->method->get_by_issuer_serial == NULL)) 1392432Sse return X509_LU_FAIL; 1402432Sse return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret); 14110605Sse} 1422432Sse 1432432Sseint X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, 14439247Sgibbs unsigned char *bytes, int len, 1452432Sse X509_OBJECT *ret) 1462432Sse{ 1472432Sse if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL)) 1482432Sse return X509_LU_FAIL; 1492432Sse return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret); 1502432Sse} 1512432Sse 1522432Sseint X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len, 1532432Sse X509_OBJECT *ret) 15415543Sphk{ 1552432Sse if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL)) 1562432Sse return X509_LU_FAIL; 15715543Sphk return ctx->method->get_by_alias(ctx, type, str, len, ret); 1586526Sse} 1596526Sse 1606526Ssestatic int x509_object_cmp(const X509_OBJECT *const *a, 1616526Sse const X509_OBJECT *const *b) 1626526Sse{ 1636526Sse int ret; 1647228Sse 1652432Sse ret = ((*a)->type - (*b)->type); 1662432Sse if (ret) 1672432Sse return ret; 1682432Sse switch ((*a)->type) { 1692432Sse case X509_LU_X509: 1702432Sse ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509); 1712432Sse break; 1722432Sse case X509_LU_CRL: 1732432Sse ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl); 1742432Sse break; 17555206Speter default: 1762432Sse /* abort(); */ 1772432Sse return 0; 1782432Sse } 179129878Sphk return ret; 18012820Sphk} 181168752Sscottl 182168752SscottlX509_STORE *X509_STORE_new(void) 18360974Sdfr{ 18448424Speter X509_STORE *ret; 18560974Sdfr 18660974Sdfr if ((ret = (X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL) 18760974Sdfr return NULL; 1882432Sse ret->objs = sk_X509_OBJECT_new(x509_object_cmp); 18912662Sdg ret->cache = 1; 19010605Sse ret->get_cert_methods = sk_X509_LOOKUP_new_null(); 19155206Speter ret->verify = 0; 1922432Sse ret->verify_cb = 0; 193119288Simp 194119288Simp if ((ret->param = X509_VERIFY_PARAM_new()) == NULL) 195272015Srpaulo return NULL; 1962432Sse 19739247Sgibbs ret->get_issuer = 0; 19839247Sgibbs ret->check_issued = 0; 19939247Sgibbs ret->check_revocation = 0; 20039247Sgibbs ret->get_crl = 0; 20139247Sgibbs ret->check_crl = 0; 2022432Sse ret->cert_crl = 0; 20339247Sgibbs ret->lookup_certs = 0; 20439247Sgibbs ret->lookup_crls = 0; 2057228Sse ret->cleanup = 0; 2062432Sse 2072432Sse if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data)) { 2082432Sse sk_X509_OBJECT_free(ret->objs); 2092432Sse OPENSSL_free(ret); 2102432Sse return NULL; 2112432Sse } 2122432Sse 2132432Sse ret->references = 1; 2142432Sse return ret; 2152432Sse} 2162432Sse 2172432Ssestatic void cleanup(X509_OBJECT *a) 2182432Sse{ 2192432Sse if (!a) 2202432Sse return; 2212432Sse if (a->type == X509_LU_X509) { 2222814Sse X509_free(a->data.x509); 2232432Sse } else if (a->type == X509_LU_CRL) { 2242432Sse X509_CRL_free(a->data.crl); 2252814Sse } else { 2262432Sse /* abort(); */ 2273552Sse } 2283552Sse 2293552Sse OPENSSL_free(a); 2303552Sse} 23120549Sse 2326766Ssevoid X509_STORE_free(X509_STORE *vfy) 23320549Sse{ 23420549Sse int i; 2353552Sse STACK_OF(X509_LOOKUP) *sk; 23620549Sse X509_LOOKUP *lu; 2372432Sse 2382432Sse if (vfy == NULL) 2393552Sse return; 2402432Sse 2412432Sse sk = vfy->get_cert_methods; 2422432Sse for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) { 2432432Sse lu = sk_X509_LOOKUP_value(sk, i); 2442432Sse X509_LOOKUP_shutdown(lu); 2452432Sse X509_LOOKUP_free(lu); 2462432Sse } 2472432Sse sk_X509_LOOKUP_free(sk); 2482432Sse sk_X509_OBJECT_pop_free(vfy->objs, cleanup); 2492432Sse 2502432Sse CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data); 25139247Sgibbs if (vfy->param) 25239247Sgibbs X509_VERIFY_PARAM_free(vfy->param); 253170027Srwatson OPENSSL_free(vfy); 2542432Sse} 25539247Sgibbs 25639247SgibbsX509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m) 25739247Sgibbs{ 25839247Sgibbs int i; 25939247Sgibbs STACK_OF(X509_LOOKUP) *sk; 26039247Sgibbs X509_LOOKUP *lu; 26139247Sgibbs 26239247Sgibbs sk = v->get_cert_methods; 26339247Sgibbs for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) { 2647228Sse lu = sk_X509_LOOKUP_value(sk, i); 2652432Sse if (m == lu->method) { 2662432Sse return lu; 2672432Sse } 2682432Sse } 2692432Sse /* a new one */ 2702432Sse lu = X509_LOOKUP_new(m); 2712432Sse if (lu == NULL) 272272121Sjhb return NULL; 273272121Sjhb else { 274272121Sjhb lu->store_ctx = v; 2756401Sse if (sk_X509_LOOKUP_push(v->get_cert_methods, lu)) 276272121Sjhb return lu; 277272121Sjhb else { 278272121Sjhb X509_LOOKUP_free(lu); 279272121Sjhb return NULL; 2806401Sse } 281272121Sjhb } 282272121Sjhb} 283272121Sjhb 2846401Sseint X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name, 28560974Sdfr X509_OBJECT *ret) 28660974Sdfr{ 287272121Sjhb X509_STORE *ctx = vs->ctx; 28827744Sse X509_LOOKUP *lu; 28960974Sdfr X509_OBJECT stmp, *tmp; 29060974Sdfr int i, j; 29160974Sdfr 29260974Sdfr CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); 29360974Sdfr tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name); 29460974Sdfr CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); 295272121Sjhb 29639532Sken if (tmp == NULL || type == X509_LU_CRL) { 29739532Sken for (i = vs->current_method; 29839532Sken i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) { 29939532Sken lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i); 30039532Sken j = X509_LOOKUP_by_subject(lu, type, name, &stmp); 30139532Sken if (j < 0) { 30239532Sken vs->current_method = j; 30339532Sken return j; 30427684Sse } else if (j) { 30527684Sse tmp = &stmp; 30627684Sse break; 30727684Sse } 30827684Sse } 30927684Sse vs->current_method = 0; 31027684Sse if (tmp == NULL) 31127684Sse return 0; 31227684Sse } 31327684Sse 31427684Sse/*- if (ret->data.ptr != NULL) 3152432Sse X509_OBJECT_free_contents(ret); */ 3162432Sse 3172432Sse ret->type = tmp->type; 3182432Sse ret->data.ptr = tmp->data.ptr; 3192432Sse 3202432Sse X509_OBJECT_up_ref_count(ret); 3212432Sse 32210567Sse return 1; 32310567Sse} 32410567Sse 32510567Sseint X509_STORE_add_cert(X509_STORE *ctx, X509 *x) 3262432Sse{ 32710567Sse X509_OBJECT *obj; 32810567Sse int ret = 1; 3297228Sse 33010567Sse if (x == NULL) 33110567Sse return 0; 33210567Sse obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); 33310567Sse if (obj == NULL) { 33439247Sgibbs X509err(X509_F_X509_STORE_ADD_CERT, ERR_R_MALLOC_FAILURE); 3352432Sse return 0; 3362814Sse } 3372814Sse obj->type = X509_LU_X509; 3382432Sse obj->data.x509 = x; 3392432Sse 3406705Sse CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); 3412432Sse 3422432Sse X509_OBJECT_up_ref_count(obj); 3432432Sse 3442432Sse if (X509_OBJECT_retrieve_match(ctx->objs, obj)) { 3452814Sse X509_OBJECT_free_contents(obj); 3462814Sse OPENSSL_free(obj); 3472814Sse X509err(X509_F_X509_STORE_ADD_CERT, 3482814Sse X509_R_CERT_ALREADY_IN_HASH_TABLE); 3492814Sse ret = 0; 3502814Sse } else 3512814Sse sk_X509_OBJECT_push(ctx->objs, obj); 3522814Sse 3532814Sse CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); 3542814Sse 3552814Sse return ret; 3562814Sse} 3572814Sse 3587228Sseint X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x) 3592814Sse{ 3602814Sse X509_OBJECT *obj; 3612814Sse int ret = 1; 36239247Sgibbs 3632814Sse if (x == NULL) 3642814Sse return 0; 3652814Sse obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); 3662432Sse if (obj == NULL) { 3672814Sse X509err(X509_F_X509_STORE_ADD_CRL, ERR_R_MALLOC_FAILURE); 3682814Sse return 0; 3692814Sse } 3702814Sse obj->type = X509_LU_CRL; 3712432Sse obj->data.crl = x; 3722432Sse 3732814Sse CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); 37439247Sgibbs 3752432Sse X509_OBJECT_up_ref_count(obj); 3762432Sse 3772432Sse if (X509_OBJECT_retrieve_match(ctx->objs, obj)) { 3782432Sse X509_OBJECT_free_contents(obj); 3792814Sse OPENSSL_free(obj); 3802814Sse X509err(X509_F_X509_STORE_ADD_CRL, X509_R_CERT_ALREADY_IN_HASH_TABLE); 3812814Sse ret = 0; 3822814Sse } else 3832814Sse sk_X509_OBJECT_push(ctx->objs, obj); 38439247Sgibbs 38539247Sgibbs CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); 3862814Sse 38739247Sgibbs return ret; 38839247Sgibbs} 3892814Sse 3902814Ssevoid X509_OBJECT_up_ref_count(X509_OBJECT *a) 3912814Sse{ 3922814Sse switch (a->type) { 3932814Sse case X509_LU_X509: 3942814Sse CRYPTO_add(&a->data.x509->references, 1, CRYPTO_LOCK_X509); 39539247Sgibbs break; 39639247Sgibbs case X509_LU_CRL: 39739247Sgibbs CRYPTO_add(&a->data.crl->references, 1, CRYPTO_LOCK_X509_CRL); 3982814Sse break; 3992814Sse } 4002814Sse} 4012814Sse 4022814Ssevoid X509_OBJECT_free_contents(X509_OBJECT *a) 4032814Sse{ 4042814Sse switch (a->type) { 4052814Sse case X509_LU_X509: 4062814Sse X509_free(a->data.x509); 4072814Sse break; 40839247Sgibbs case X509_LU_CRL: 4097228Sse X509_CRL_free(a->data.crl); 4102432Sse break; 4112432Sse } 4122432Sse} 4132432Sse 4142432Ssestatic int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type, 4152432Sse X509_NAME *name, int *pnmatch) 4162432Sse{ 41739247Sgibbs X509_OBJECT stmp; 4187228Sse X509 x509_s; 4192432Sse X509_CINF cinf_s; 4202432Sse X509_CRL crl_s; 4212432Sse X509_CRL_INFO crl_info_s; 4222432Sse int idx; 4232432Sse 4242432Sse stmp.type = type; 4252432Sse switch (type) { 4262432Sse case X509_LU_X509: 4272432Sse stmp.data.x509 = &x509_s; 42839247Sgibbs x509_s.cert_info = &cinf_s; 4292432Sse cinf_s.subject = name; 4302432Sse break; 4312432Sse case X509_LU_CRL: 4322432Sse stmp.data.crl = &crl_s; 4332432Sse crl_s.crl = &crl_info_s; 4342432Sse crl_info_s.issuer = name; 43539247Sgibbs break; 4362432Sse default: 4372432Sse /* abort(); */ 43828960Sse return -1; 43928960Sse } 4402432Sse 4412432Sse idx = sk_X509_OBJECT_find(h, &stmp); 4422432Sse if (idx >= 0 && pnmatch) { 4432432Sse int tidx; 4442432Sse const X509_OBJECT *tobj, *pstmp; 4452432Sse *pnmatch = 1; 4462432Sse pstmp = &stmp; 4472432Sse for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++) { 4482432Sse tobj = sk_X509_OBJECT_value(h, tidx); 4492432Sse if (x509_object_cmp(&tobj, &pstmp)) 4502432Sse break; 4512432Sse (*pnmatch)++; 4522432Sse } 4532435Sse } 4542435Sse return idx; 4552432Sse} 4562814Sse 4572814Sseint X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, 4582432Sse X509_NAME *name) 4592432Sse{ 4602432Sse return x509_object_idx_cnt(h, type, name, NULL); 4612432Sse} 4622432Sse 4632432SseX509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, 4642432Sse int type, X509_NAME *name) 46539554Sgibbs{ 46639554Sgibbs int idx; 46739554Sgibbs idx = X509_OBJECT_idx_by_subject(h, type, name); 4682432Sse if (idx == -1) 46939554Sgibbs return NULL; 47039554Sgibbs return sk_X509_OBJECT_value(h, idx); 47139554Sgibbs} 47239554Sgibbs 47339554SgibbsSTACK_OF(X509) *X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm) 47439554Sgibbs{ 47539554Sgibbs int i, idx, cnt; 4762432Sse STACK_OF(X509) *sk; 4772432Sse X509 *x; 4782432Sse X509_OBJECT *obj; 4792432Sse sk = sk_X509_new_null(); 4802432Sse CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); 4812432Sse idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); 4822432Sse if (idx < 0) { 4832432Sse /* 4842432Sse * Nothing found in cache: do lookup to possibly add new objects to 4852432Sse * cache 4862432Sse */ 4872432Sse X509_OBJECT xobj; 4882432Sse CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); 4892432Sse if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) { 4902432Sse sk_X509_free(sk); 4912432Sse return NULL; 4922432Sse } 4932432Sse X509_OBJECT_free_contents(&xobj); 4947228Sse CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); 4952432Sse idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); 4962432Sse if (idx < 0) { 4977228Sse CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); 4982432Sse sk_X509_free(sk); 4992432Sse return NULL; 5002432Sse } 5012432Sse } 50239247Sgibbs for (i = 0; i < cnt; i++, idx++) { 50339247Sgibbs obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); 50439247Sgibbs x = obj->data.x509; 50539247Sgibbs CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); 50639247Sgibbs if (!sk_X509_push(sk, x)) { 50739247Sgibbs CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); 50839247Sgibbs X509_free(x); 50939247Sgibbs sk_X509_pop_free(sk, X509_free); 51039247Sgibbs return NULL; 51139247Sgibbs } 51239247Sgibbs } 51339247Sgibbs CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); 51439247Sgibbs return sk; 51539247Sgibbs 51639247Sgibbs} 51739247Sgibbs 51839247SgibbsSTACK_OF(X509_CRL) *X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm) 51939247Sgibbs{ 52039247Sgibbs int i, idx, cnt; 52139247Sgibbs STACK_OF(X509_CRL) *sk; 52239247Sgibbs X509_CRL *x; 52339247Sgibbs X509_OBJECT *obj, xobj; 52439247Sgibbs sk = sk_X509_CRL_new_null(); 52539247Sgibbs CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); 52639247Sgibbs /* Check cache first */ 52739247Sgibbs idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt); 5282432Sse 5292432Sse /* 5302432Sse * Always do lookup to possibly add new CRLs to cache 5317228Sse */ 5322432Sse CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); 5332432Sse if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj)) { 5342432Sse sk_X509_CRL_free(sk); 5357228Sse return NULL; 5362432Sse } 5372432Sse X509_OBJECT_free_contents(&xobj); 5382432Sse CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); 5392432Sse idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt); 5402432Sse if (idx < 0) { 5412432Sse CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); 5422814Sse sk_X509_CRL_free(sk); 5432814Sse return NULL; 5442432Sse } 5452432Sse 5462432Sse for (i = 0; i < cnt; i++, idx++) { 5472432Sse obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); 5482814Sse x = obj->data.crl; 5492814Sse CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL); 5502814Sse if (!sk_X509_CRL_push(sk, x)) { 5512432Sse CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); 5522432Sse X509_CRL_free(x); 5532814Sse sk_X509_CRL_pop_free(sk, X509_CRL_free); 5542432Sse return NULL; 5552432Sse } 5562432Sse } 5572432Sse CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); 5582432Sse return sk; 5592432Sse} 5602432Sse 5612432SseX509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, 5622432Sse X509_OBJECT *x) 5632432Sse{ 5642432Sse int idx, i; 5652432Sse X509_OBJECT *obj; 5662432Sse idx = sk_X509_OBJECT_find(h, x); 5672432Sse if (idx == -1) 5682432Sse return NULL; 5692432Sse if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL)) 57039247Sgibbs return sk_X509_OBJECT_value(h, idx); 5712432Sse for (i = idx; i < sk_X509_OBJECT_num(h); i++) { 5722432Sse obj = sk_X509_OBJECT_value(h, i); 5732432Sse if (x509_object_cmp 5747228Sse ((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x)) 5752432Sse return NULL; 57639247Sgibbs if (x->type == X509_LU_X509) { 5772432Sse if (!X509_cmp(obj->data.x509, x->data.x509)) 5782432Sse return obj; 57939247Sgibbs } else if (x->type == X509_LU_CRL) { 5802432Sse if (!X509_CRL_match(obj->data.crl, x->data.crl)) 5812432Sse return obj; 58239247Sgibbs } else 58327684Sse return obj; 58427684Sse } 58527684Sse return NULL; 58627684Sse} 58739247Sgibbs 58827684Sse/*- 58927684Sse * Try to get issuer certificate from store. Due to limitations 5902432Sse * of the API this can only retrieve a single certificate matching 5912432Sse * a given subject name. However it will fill the cache with all 5922432Sse * matching certificates, so we can examine the cache for all 5932432Sse * matches. 5942432Sse * 5952432Sse * Return values are: 5962432Sse * 1 lookup successful. 5972432Sse * 0 certificate not found. 5982432Sse * -1 some other error. 5992432Sse */ 6002432Sseint X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) 60139247Sgibbs{ 6022432Sse X509_NAME *xn; 6032432Sse X509_OBJECT obj, *pobj; 6042432Sse int i, ok, idx, ret; 6052432Sse xn = X509_get_issuer_name(x); 6062432Sse ok = X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj); 6072432Sse if (ok != X509_LU_X509) { 6082432Sse if (ok == X509_LU_RETRY) { 6097228Sse X509_OBJECT_free_contents(&obj); 6102432Sse X509err(X509_F_X509_STORE_CTX_GET1_ISSUER, X509_R_SHOULD_RETRY); 6112432Sse return -1; 6127228Sse } else if (ok != X509_LU_FAIL) { 6132432Sse X509_OBJECT_free_contents(&obj); 6142432Sse /* not good :-(, break anyway */ 6152432Sse return -1; 6162432Sse } 6172432Sse return 0; 6182432Sse } 6192432Sse /* If certificate matches all OK */ 6202432Sse if (ctx->check_issued(ctx, x, obj.data.x509)) { 6212432Sse *issuer = obj.data.x509; 6222432Sse return 1; 62310567Sse } 6242432Sse X509_OBJECT_free_contents(&obj); 6252432Sse 6262432Sse /* Else find index of first cert accepted by 'check_issued' */ 6272432Sse ret = 0; 6282432Sse CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); 6292432Sse idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn); 6302432Sse if (idx != -1) { /* should be true as we've had at least one 6312432Sse * match */ 6322432Sse /* Look through all matching certs for suitable issuer */ 6332432Sse for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) { 6342432Sse pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i); 6352432Sse /* See if we've run past the matches */ 6362432Sse if (pobj->type != X509_LU_X509) 6372432Sse break; 6382432Sse if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509))) 6392432Sse break; 6402432Sse if (ctx->check_issued(ctx, x, pobj->data.x509)) { 64139247Sgibbs *issuer = pobj->data.x509; 6422432Sse X509_OBJECT_up_ref_count(pobj); 6432432Sse ret = 1; 64439247Sgibbs break; 6452432Sse } 6462432Sse } 64739247Sgibbs } 6482432Sse CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); 6492432Sse return ret; 65039247Sgibbs} 6512432Sse 6522432Sseint X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags) 65339247Sgibbs{ 6542432Sse return X509_VERIFY_PARAM_set_flags(ctx->param, flags); 6552432Sse} 6562432Sse 6572432Sseint X509_STORE_set_depth(X509_STORE *ctx, int depth) 6582432Sse{ 65939247Sgibbs X509_VERIFY_PARAM_set_depth(ctx->param, depth); 6602432Sse return 1; 6612432Sse} 6622432Sse 6632432Sseint X509_STORE_set_purpose(X509_STORE *ctx, int purpose) 6642432Sse{ 6657228Sse return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose); 6662432Sse} 6672432Sse 6682432Sseint X509_STORE_set_trust(X509_STORE *ctx, int trust) 6692432Sse{ 6702432Sse return X509_VERIFY_PARAM_set_trust(ctx->param, trust); 6712432Sse} 67239247Sgibbs 6732432Sseint X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param) 6742432Sse{ 6752432Sse return X509_VERIFY_PARAM_set1(ctx->param, param); 6762432Sse} 6772432Sse 6782432Ssevoid X509_STORE_set_verify_cb(X509_STORE *ctx, 6792432Sse int (*verify_cb) (int, X509_STORE_CTX *)) 6802432Sse{ 6812432Sse ctx->verify_cb = verify_cb; 6822432Sse} 68339247Sgibbs 6842432SseIMPLEMENT_STACK_OF(X509_LOOKUP) 6852432Sse 6862432SseIMPLEMENT_STACK_OF(X509_OBJECT) 6872432Sse