x509_lu.c revision 109998
118334Speter/* crypto/x509/x509_lu.c */ 252518Sobrien/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 318334Speter * All rights reserved. 418334Speter * 518334Speter * This package is an SSL implementation written 618334Speter * by Eric Young (eay@cryptsoft.com). 718334Speter * The implementation was written so as to conform with Netscapes SSL. 818334Speter * 918334Speter * This library is free for commercial and non-commercial use as long as 1018334Speter * the following conditions are aheared to. The following conditions 1118334Speter * apply to all code found in this distribution, be it the RC4, RSA, 1218334Speter * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1318334Speter * included with this distribution is covered by the same copyright terms 1418334Speter * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1518334Speter * 1618334Speter * Copyright remains Eric Young's, and as such any Copyright notices in 1718334Speter * the code are not to be removed. 1818334Speter * If this package is used in a product, Eric Young should be given attribution 1918334Speter * as the author of the parts of the library used. 2018334Speter * This can be in the form of a textual message at program startup or 2152518Sobrien * in documentation (online or textual) provided with the package. 2218334Speter * 2352518Sobrien * Redistribution and use in source and binary forms, with or without 2418334Speter * modification, are permitted provided that the following conditions 2518334Speter * are met: 2618334Speter * 1. Redistributions of source code must retain the copyright 2718334Speter * notice, this list of conditions and the following disclaimer. 2818334Speter * 2. Redistributions in binary form must reproduce the above copyright 2918334Speter * notice, this list of conditions and the following disclaimer in the 3018334Speter * documentation and/or other materials provided with the distribution. 3118334Speter * 3. All advertising materials mentioning features or use of this software 3218334Speter * must display the following acknowledgement: 3318334Speter * "This product includes cryptographic software written by 3418334Speter * Eric Young (eay@cryptsoft.com)" 3518334Speter * The word 'cryptographic' can be left out if the rouines from the library 3618334Speter * being used are not cryptographic related :-). 3718334Speter * 4. If you include any Windows specific code (or a derivative thereof) from 3818334Speter * the apps directory (application code) you must include an acknowledgement: 3918334Speter * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4018334Speter * 4118334Speter * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4218334Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4318334Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4452268Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4518334Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4618334Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4718334Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4852268Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4918334Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5018334Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5118334Speter * SUCH DAMAGE. 5218334Speter * 5318334Speter * The licence and distribution terms for any publically available version or 5418334Speter * derivative of this code cannot be changed. i.e. this code cannot simply be 5518334Speter * copied and put under another distribution licence 5618334Speter * [including the GNU Public Licence.] 5718334Speter */ 5818334Speter 5918334Speter#include <stdio.h> 6052268Sobrien#include "cryptlib.h" 6152518Sobrien#include <openssl/lhash.h> 6218334Speter#include <openssl/x509.h> 6352268Sobrien#include <openssl/x509v3.h> 6452268Sobrien 6552268SobrienX509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method) 6652268Sobrien { 6752518Sobrien X509_LOOKUP *ret; 6852518Sobrien 6952518Sobrien ret=(X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP)); 7052518Sobrien if (ret == NULL) return NULL; 7118334Speter 7218334Speter ret->init=0; 7318334Speter ret->skip=0; 7452268Sobrien ret->method=method; 7518334Speter ret->method_data=NULL; 7618334Speter ret->store_ctx=NULL; 7718334Speter if ((method->new_item != NULL) && !method->new_item(ret)) 7818334Speter { 7918334Speter OPENSSL_free(ret); 8018334Speter return NULL; 8118334Speter } 8218334Speter return ret; 8318334Speter } 8418334Speter 8518334Spetervoid X509_LOOKUP_free(X509_LOOKUP *ctx) 8618334Speter { 8718334Speter if (ctx == NULL) return; 8818334Speter if ( (ctx->method != NULL) && 8918334Speter (ctx->method->free != NULL)) 9018334Speter ctx->method->free(ctx); 9118334Speter OPENSSL_free(ctx); 9218334Speter } 9318334Speter 9418334Speterint X509_LOOKUP_init(X509_LOOKUP *ctx) 9518334Speter { 9618334Speter if (ctx->method == NULL) return 0; 9718334Speter if (ctx->method->init != NULL) 9818334Speter return ctx->method->init(ctx); 9918334Speter else 10018334Speter return 1; 10118334Speter } 10218334Speter 10318334Speterint X509_LOOKUP_shutdown(X509_LOOKUP *ctx) 10418334Speter { 10518334Speter if (ctx->method == NULL) return 0; 10618334Speter if (ctx->method->shutdown != NULL) 10718334Speter return ctx->method->shutdown(ctx); 10818334Speter else 10918334Speter return 1; 11018334Speter } 11118334Speter 11218334Speterint X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, 11318334Speter char **ret) 11418334Speter { 11518334Speter if (ctx->method == NULL) return -1; 11618334Speter if (ctx->method->ctrl != NULL) 11718334Speter return ctx->method->ctrl(ctx,cmd,argc,argl,ret); 11818334Speter else 11918334Speter return 1; 12018334Speter } 12118334Speter 12218334Speterint X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, 12318334Speter X509_OBJECT *ret) 12418334Speter { 12518334Speter if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL)) 12618334Speter return X509_LU_FAIL; 12718334Speter if (ctx->skip) return 0; 12818334Speter return ctx->method->get_by_subject(ctx,type,name,ret); 12918334Speter } 13018334Speter 13118334Speterint X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name, 13218334Speter ASN1_INTEGER *serial, X509_OBJECT *ret) 13318334Speter { 13418334Speter if ((ctx->method == NULL) || 13518334Speter (ctx->method->get_by_issuer_serial == NULL)) 13618334Speter return X509_LU_FAIL; 13752518Sobrien return ctx->method->get_by_issuer_serial(ctx,type,name,serial,ret); 13852268Sobrien } 13952518Sobrien 14052268Sobrienint X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, 14152518Sobrien unsigned char *bytes, int len, X509_OBJECT *ret) 14252518Sobrien { 14352518Sobrien if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL)) 14452518Sobrien return X509_LU_FAIL; 14552268Sobrien return ctx->method->get_by_fingerprint(ctx,type,bytes,len,ret); 14652518Sobrien } 14718334Speter 14852518Sobrienint X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len, 14952518Sobrien X509_OBJECT *ret) 15052518Sobrien { 15118334Speter if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL)) 15252518Sobrien return X509_LU_FAIL; 15352518Sobrien return ctx->method->get_by_alias(ctx,type,str,len,ret); 15452518Sobrien } 15552518Sobrien 15652518Sobrien 15752518Sobrienstatic int x509_object_cmp(const X509_OBJECT * const *a, const X509_OBJECT * const *b) 15852518Sobrien { 15952518Sobrien int ret; 16052518Sobrien 16152518Sobrien ret=((*a)->type - (*b)->type); 16252518Sobrien if (ret) return ret; 16352518Sobrien switch ((*a)->type) 16452268Sobrien { 16552268Sobrien case X509_LU_X509: 16652268Sobrien ret=X509_subject_name_cmp((*a)->data.x509,(*b)->data.x509); 16752268Sobrien break; 16852268Sobrien case X509_LU_CRL: 16918334Speter ret=X509_CRL_cmp((*a)->data.crl,(*b)->data.crl); 17018334Speter break; 17118334Speter default: 17218334Speter /* abort(); */ 17318334Speter return 0; 17418334Speter } 17518334Speter return ret; 17618334Speter } 17718334Speter 17818334SpeterX509_STORE *X509_STORE_new(void) 17918334Speter { 18018334Speter X509_STORE *ret; 18118334Speter 18218334Speter if ((ret=(X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL) 18318334Speter return NULL; 18418334Speter ret->objs = sk_X509_OBJECT_new(x509_object_cmp); 18518334Speter ret->cache=1; 18618334Speter ret->get_cert_methods=sk_X509_LOOKUP_new_null(); 18718334Speter ret->verify=0; 18818334Speter ret->verify_cb=0; 18918334Speter 19018334Speter ret->purpose = 0; 19118334Speter ret->trust = 0; 19218334Speter 19318334Speter ret->flags = 0; 19418334Speter 19552268Sobrien ret->get_issuer = 0; 19618334Speter ret->check_issued = 0; 19718334Speter ret->check_revocation = 0; 19818334Speter ret->get_crl = 0; 19918334Speter ret->check_crl = 0; 20018334Speter ret->cert_crl = 0; 20118334Speter ret->cleanup = 0; 20218334Speter 20318334Speter CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data); 20418334Speter ret->references=1; 20518334Speter ret->depth=0; 20618334Speter return ret; 20718334Speter } 20818334Speter 20918334Speterstatic void cleanup(X509_OBJECT *a) 21018334Speter { 21118334Speter if (a->type == X509_LU_X509) 21218334Speter { 21318334Speter X509_free(a->data.x509); 21418334Speter } 21518334Speter else if (a->type == X509_LU_CRL) 21618334Speter { 21718334Speter X509_CRL_free(a->data.crl); 21818334Speter } 21918334Speter else 22018334Speter { 22118334Speter /* abort(); */ 22218334Speter } 22352268Sobrien 22452268Sobrien OPENSSL_free(a); 22552268Sobrien } 22652268Sobrien 22718334Spetervoid X509_STORE_free(X509_STORE *vfy) 22818334Speter { 22918334Speter int i; 23018334Speter STACK_OF(X509_LOOKUP) *sk; 23118334Speter X509_LOOKUP *lu; 23218334Speter 23318334Speter if (vfy == NULL) 23418334Speter return; 23518334Speter 23618334Speter sk=vfy->get_cert_methods; 23718334Speter for (i=0; i<sk_X509_LOOKUP_num(sk); i++) 23818334Speter { 23918334Speter lu=sk_X509_LOOKUP_value(sk,i); 24052268Sobrien X509_LOOKUP_shutdown(lu); 24152268Sobrien X509_LOOKUP_free(lu); 24252268Sobrien } 24352518Sobrien sk_X509_LOOKUP_free(sk); 24452518Sobrien sk_X509_OBJECT_pop_free(vfy->objs, cleanup); 24552518Sobrien 24652518Sobrien CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data); 24752518Sobrien OPENSSL_free(vfy); 24852518Sobrien } 24952518Sobrien 25018334SpeterX509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m) 25118334Speter { 25218334Speter int i; 25318334Speter STACK_OF(X509_LOOKUP) *sk; 25418334Speter X509_LOOKUP *lu; 25518334Speter 25618334Speter sk=v->get_cert_methods; 25718334Speter for (i=0; i<sk_X509_LOOKUP_num(sk); i++) 25818334Speter { 25918334Speter lu=sk_X509_LOOKUP_value(sk,i); 26018334Speter if (m == lu->method) 26118334Speter { 26218334Speter return lu; 26352518Sobrien } 26452518Sobrien } 26552518Sobrien /* a new one */ 26618334Speter lu=X509_LOOKUP_new(m); 26718334Speter if (lu == NULL) 26852518Sobrien return NULL; 26918334Speter else 27052518Sobrien { 27152518Sobrien lu->store_ctx=v; 27252518Sobrien if (sk_X509_LOOKUP_push(v->get_cert_methods,lu)) 27352518Sobrien return lu; 27452518Sobrien else 27518334Speter { 27618334Speter X509_LOOKUP_free(lu); 27718334Speter return NULL; 27818334Speter } 27918334Speter } 28018334Speter } 28118334Speter 28218334Speterint X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name, 28318334Speter X509_OBJECT *ret) 28418334Speter { 28518334Speter X509_STORE *ctx=vs->ctx; 28618334Speter X509_LOOKUP *lu; 28718334Speter X509_OBJECT stmp,*tmp; 28818334Speter int i,j; 28918334Speter 29018334Speter tmp=X509_OBJECT_retrieve_by_subject(ctx->objs,type,name); 29118334Speter 29218334Speter if (tmp == NULL) 29318334Speter { 29418334Speter for (i=vs->current_method; i<sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) 29518334Speter { 29618334Speter lu=sk_X509_LOOKUP_value(ctx->get_cert_methods,i); 29718334Speter j=X509_LOOKUP_by_subject(lu,type,name,&stmp); 29818334Speter if (j < 0) 29918334Speter { 30018334Speter vs->current_method=j; 30118334Speter return j; 30218334Speter } 30318334Speter else if (j) 30418334Speter { 30518334Speter tmp= &stmp; 30618334Speter break; 30718334Speter } 30818334Speter } 30918334Speter vs->current_method=0; 31018334Speter if (tmp == NULL) 31118334Speter return 0; 31218334Speter } 31318334Speter 31418334Speter/* if (ret->data.ptr != NULL) 31518334Speter X509_OBJECT_free_contents(ret); */ 31618334Speter 31718334Speter ret->type=tmp->type; 31818334Speter ret->data.ptr=tmp->data.ptr; 31918334Speter 32018334Speter X509_OBJECT_up_ref_count(ret); 32152268Sobrien 32218334Speter return 1; 32318334Speter } 32418334Speter 32518334Speterint X509_STORE_add_cert(X509_STORE *ctx, X509 *x) 32618334Speter { 32718334Speter X509_OBJECT *obj; 32818334Speter int ret=1; 32918334Speter 33018334Speter if (x == NULL) return 0; 33118334Speter obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); 33218334Speter if (obj == NULL) 33318334Speter { 33418334Speter X509err(X509_F_X509_STORE_ADD_CERT,ERR_R_MALLOC_FAILURE); 33518334Speter return 0; 33618334Speter } 33718334Speter obj->type=X509_LU_X509; 33818334Speter obj->data.x509=x; 33918334Speter 34018334Speter CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); 34118334Speter 34218334Speter X509_OBJECT_up_ref_count(obj); 34318334Speter 34418334Speter 34518334Speter if (X509_OBJECT_retrieve_match(ctx->objs, obj)) 34618334Speter { 34718334Speter X509_OBJECT_free_contents(obj); 34818334Speter OPENSSL_free(obj); 34952268Sobrien X509err(X509_F_X509_STORE_ADD_CERT,X509_R_CERT_ALREADY_IN_HASH_TABLE); 35052268Sobrien ret=0; 35152268Sobrien } 35218334Speter else sk_X509_OBJECT_push(ctx->objs, obj); 35318334Speter 35418334Speter CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); 35552268Sobrien 35652268Sobrien return ret; 35752268Sobrien } 35818334Speter 35918334Speterint X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x) 36018334Speter { 36118334Speter X509_OBJECT *obj; 36218334Speter int ret=1; 36318334Speter 36418334Speter if (x == NULL) return 0; 36518334Speter obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); 36652268Sobrien if (obj == NULL) 36752268Sobrien { 36818334Speter X509err(X509_F_X509_STORE_ADD_CRL,ERR_R_MALLOC_FAILURE); 36918334Speter return 0; 37018334Speter } 37118334Speter obj->type=X509_LU_CRL; 37218334Speter obj->data.crl=x; 37318334Speter 37418334Speter CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); 37518334Speter 37618334Speter X509_OBJECT_up_ref_count(obj); 37718334Speter 37818334Speter if (X509_OBJECT_retrieve_match(ctx->objs, obj)) 37918334Speter { 38018334Speter X509_OBJECT_free_contents(obj); 38118334Speter OPENSSL_free(obj); 38218334Speter X509err(X509_F_X509_STORE_ADD_CRL,X509_R_CERT_ALREADY_IN_HASH_TABLE); 38318334Speter ret=0; 38418334Speter } 38518334Speter else sk_X509_OBJECT_push(ctx->objs, obj); 38618334Speter 38718334Speter CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); 38818334Speter 38918334Speter return ret; 39018334Speter } 39118334Speter 39218334Spetervoid X509_OBJECT_up_ref_count(X509_OBJECT *a) 39318334Speter { 39418334Speter switch (a->type) 39518334Speter { 39618334Speter case X509_LU_X509: 39718334Speter CRYPTO_add(&a->data.x509->references,1,CRYPTO_LOCK_X509); 39852268Sobrien break; 39918334Speter case X509_LU_CRL: 40018334Speter CRYPTO_add(&a->data.crl->references,1,CRYPTO_LOCK_X509_CRL); 40118334Speter break; 40218334Speter } 40352518Sobrien } 40452518Sobrien 40518334Spetervoid X509_OBJECT_free_contents(X509_OBJECT *a) 40652268Sobrien { 40752518Sobrien switch (a->type) 40852518Sobrien { 40952518Sobrien case X509_LU_X509: 41052518Sobrien X509_free(a->data.x509); 41152518Sobrien break; 41252518Sobrien case X509_LU_CRL: 41352518Sobrien X509_CRL_free(a->data.crl); 41452518Sobrien break; 41552518Sobrien } 41652518Sobrien } 41752518Sobrien 41818334Speterint X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, 41918334Speter X509_NAME *name) 42018334Speter { 42118334Speter X509_OBJECT stmp; 42218334Speter X509 x509_s; 42318334Speter X509_CINF cinf_s; 42418334Speter X509_CRL crl_s; 42518334Speter X509_CRL_INFO crl_info_s; 42618334Speter 42718334Speter stmp.type=type; 42818334Speter switch (type) 42918334Speter { 43052268Sobrien case X509_LU_X509: 43118334Speter stmp.data.x509= &x509_s; 43218334Speter x509_s.cert_info= &cinf_s; 43352268Sobrien cinf_s.subject=name; 43418334Speter break; 43518334Speter case X509_LU_CRL: 43618334Speter stmp.data.crl= &crl_s; 43718334Speter crl_s.crl= &crl_info_s; 43818334Speter crl_info_s.issuer=name; 43918334Speter break; 44018334Speter default: 44118334Speter /* abort(); */ 44218334Speter return -1; 44318334Speter } 44452268Sobrien 44518334Speter return sk_X509_OBJECT_find(h,&stmp); 44652268Sobrien } 44718334Speter 44852268SobrienX509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type, 44952268Sobrien X509_NAME *name) 45052268Sobrien{ 45152268Sobrien int idx; 45252268Sobrien idx = X509_OBJECT_idx_by_subject(h, type, name); 45352268Sobrien if (idx==-1) return NULL; 45418334Speter return sk_X509_OBJECT_value(h, idx); 45518334Speter} 45618334Speter 45718334SpeterX509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x) 45818334Speter{ 45918334Speter int idx, i; 46018334Speter X509_OBJECT *obj; 46118334Speter idx = sk_X509_OBJECT_find(h, x); 46218334Speter if (idx == -1) return NULL; 46318334Speter if (x->type != X509_LU_X509) return sk_X509_OBJECT_value(h, idx); 46418334Speter for (i = idx; i < sk_X509_OBJECT_num(h); i++) 46518334Speter { 46652518Sobrien obj = sk_X509_OBJECT_value(h, i); 46752518Sobrien if (x509_object_cmp((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x)) 46852518Sobrien return NULL; 46952518Sobrien if ((x->type != X509_LU_X509) || !X509_cmp(obj->data.x509, x->data.x509)) 47052518Sobrien return obj; 47152518Sobrien } 47252518Sobrien return NULL; 47318334Speter} 47418334Speter 47552268Sobrien 47652268Sobrien/* Try to get issuer certificate from store. Due to limitations 47752518Sobrien * of the API this can only retrieve a single certificate matching 47852518Sobrien * a given subject name. However it will fill the cache with all 47918334Speter * matching certificates, so we can examine the cache for all 48018334Speter * matches. 48118334Speter * 48252518Sobrien * Return values are: 48352518Sobrien * 1 lookup successful. 48452518Sobrien * 0 certificate not found. 48552518Sobrien * -1 some other error. 48618334Speter */ 48718334Speter 48818334Speter 48952518Sobrienint X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) 49018334Speter{ 49118334Speter X509_NAME *xn; 49218334Speter X509_OBJECT obj, *pobj; 49318334Speter int i, ok, idx; 49418334Speter xn=X509_get_issuer_name(x); 49518334Speter ok=X509_STORE_get_by_subject(ctx,X509_LU_X509,xn,&obj); 49618334Speter if (ok != X509_LU_X509) 49718334Speter { 49818334Speter if (ok == X509_LU_RETRY) 49918334Speter { 50018334Speter X509_OBJECT_free_contents(&obj); 50118334Speter X509err(X509_F_X509_VERIFY_CERT,X509_R_SHOULD_RETRY); 50252268Sobrien return -1; 50318334Speter } 50418334Speter else if (ok != X509_LU_FAIL) 50552268Sobrien { 50652268Sobrien X509_OBJECT_free_contents(&obj); 50718334Speter /* not good :-(, break anyway */ 50852268Sobrien return -1; 50918334Speter } 51018334Speter return 0; 51118334Speter } 51252268Sobrien /* If certificate matches all OK */ 51318334Speter if (ctx->check_issued(ctx, x, obj.data.x509)) 51418334Speter { 51552268Sobrien *issuer = obj.data.x509; 51652518Sobrien return 1; 51752518Sobrien } 51852518Sobrien X509_OBJECT_free_contents(&obj); 51952518Sobrien /* Else find index of first matching cert */ 52052518Sobrien idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn); 52152518Sobrien /* This shouldn't normally happen since we already have one match */ 52252518Sobrien if (idx == -1) return 0; 52352518Sobrien 52452518Sobrien /* Look through all matching certificates for a suitable issuer */ 52552518Sobrien for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) 52652518Sobrien { 52718334Speter pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i); 52818334Speter /* See if we've ran out of matches */ 52918334Speter if (pobj->type != X509_LU_X509) return 0; 53018334Speter if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509))) return 0; 53118334Speter if (ctx->check_issued(ctx, x, pobj->data.x509)) 53218334Speter { 53318334Speter *issuer = pobj->data.x509; 53418334Speter X509_OBJECT_up_ref_count(pobj); 53518334Speter return 1; 53618334Speter } 53718334Speter } 53818334Speter return 0; 53952268Sobrien} 54018334Speter 54118334Spetervoid X509_STORE_set_flags(X509_STORE *ctx, long flags) 54218334Speter { 54352268Sobrien ctx->flags |= flags; 54418334Speter } 54518334Speter 54618334Speterint X509_STORE_set_purpose(X509_STORE *ctx, int purpose) 54718334Speter { 54818334Speter return X509_PURPOSE_set(&ctx->purpose, purpose); 54918334Speter } 55018334Speter 55118334Speterint X509_STORE_set_trust(X509_STORE *ctx, int trust) 55218334Speter { 55318334Speter return X509_TRUST_set(&ctx->trust, trust); 55418334Speter } 55518334Speter 55618334SpeterIMPLEMENT_STACK_OF(X509_LOOKUP) 55718334SpeterIMPLEMENT_STACK_OF(X509_OBJECT) 55818334Speter