(linenum→info "unix/slp.c:2238")

openssl/0.9.8g/ssl/ssl_cert.c

    1: /*! \file ssl/ssl_cert.c */
    2: /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
    3:  * All rights reserved.
    4:  *
    5:  * This package is an SSL implementation written
    6:  * by Eric Young (eay@cryptsoft.com).
    7:  * The implementation was written so as to conform with Netscapes SSL.
    8:  * 
    9:  * This library is free for commercial and non-commercial use as long as
   10:  * the following conditions are aheared to.  The following conditions
   11:  * apply to all code found in this distribution, be it the RC4, RSA,
   12:  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
   13:  * included with this distribution is covered by the same copyright terms
   14:  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
   15:  * 
   16:  * Copyright remains Eric Young's, and as such any Copyright notices in
   17:  * the code are not to be removed.
   18:  * If this package is used in a product, Eric Young should be given attribution
   19:  * as the author of the parts of the library used.
   20:  * This can be in the form of a textual message at program startup or
   21:  * in documentation (online or textual) provided with the package.
   22:  * 
   23:  * Redistribution and use in source and binary forms, with or without
   24:  * modification, are permitted provided that the following conditions
   25:  * are met:
   26:  * 1. Redistributions of source code must retain the copyright
   27:  *    notice, this list of conditions and the following disclaimer.
   28:  * 2. Redistributions in binary form must reproduce the above copyright
   29:  *    notice, this list of conditions and the following disclaimer in the
   30:  *    documentation and/or other materials provided with the distribution.
   31:  * 3. All advertising materials mentioning features or use of this software
   32:  *    must display the following acknowledgement:
   33:  *    "This product includes cryptographic software written by
   34:  *     Eric Young (eay@cryptsoft.com)"
   35:  *    The word 'cryptographic' can be left out if the rouines from the library
   36:  *    being used are not cryptographic related :-).
   37:  * 4. If you include any Windows specific code (or a derivative thereof) from 
   38:  *    the apps directory (application code) you must include an acknowledgement:
   39:  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
   40:  * 
   41:  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
   42:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   43:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   44:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   45:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   46:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   47:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   48:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   49:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   50:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   51:  * SUCH DAMAGE.
   52:  * 
   53:  * The licence and distribution terms for any publically available version or
   54:  * derivative of this code cannot be changed.  i.e. this code cannot simply be
   55:  * copied and put under another distribution licence
   56:  * [including the GNU Public Licence.]
   57:  */
   58: /* ====================================================================
   59:  * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
   60:  *
   61:  * Redistribution and use in source and binary forms, with or without
   62:  * modification, are permitted provided that the following conditions
   63:  * are met:
   64:  *
   65:  * 1. Redistributions of source code must retain the above copyright
   66:  *    notice, this list of conditions and the following disclaimer. 
   67:  *
   68:  * 2. Redistributions in binary form must reproduce the above copyright
   69:  *    notice, this list of conditions and the following disclaimer in
   70:  *    the documentation and/or other materials provided with the
   71:  *    distribution.
   72:  *
   73:  * 3. All advertising materials mentioning features or use of this
   74:  *    software must display the following acknowledgment:
   75:  *    "This product includes software developed by the OpenSSL Project
   76:  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
   77:  *
   78:  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
   79:  *    endorse or promote products derived from this software without
   80:  *    prior written permission. For written permission, please contact
   81:  *    openssl-core@openssl.org.
   82:  *
   83:  * 5. Products derived from this software may not be called "OpenSSL"
   84:  *    nor may "OpenSSL" appear in their names without prior written
   85:  *    permission of the OpenSSL Project.
   86:  *
   87:  * 6. Redistributions of any form whatsoever must retain the following
   88:  *    acknowledgment:
   89:  *    "This product includes software developed by the OpenSSL Project
   90:  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
   91:  *
   92:  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
   93:  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   94:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   95:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
   96:  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   97:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   98:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   99:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  100:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  101:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  102:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  103:  * OF THE POSSIBILITY OF SUCH DAMAGE.
  104:  * ====================================================================
  105:  *
  106:  * This product includes cryptographic software written by Eric Young
  107:  * (eay@cryptsoft.com).  This product includes software written by Tim
  108:  * Hudson (tjh@cryptsoft.com).
  109:  *
  110:  */
  111: /* ====================================================================
  112:  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
  113:  * ECC cipher suite support in OpenSSL originally developed by 
  114:  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
  115:  */
  116: 
  117: #include <stdio.h>
  118: 
  119: #include "e_os.h"
  120: #ifndef NO_SYS_TYPES_H
  121: # include <sys/types.h>
  122: #endif
  123: 
  124: #include "o_dir.h"
  125: #include <openssl/objects.h>
  126: #include <openssl/bio.h>
  127: #include <openssl/pem.h>
  128: #include <openssl/x509v3.h>
  129: #ifndef OPENSSL_NO_DH
  130: #include <openssl/dh.h>
  131: #endif
  132: #include <openssl/bn.h>
  133: #include "ssl_locl.h"
  134: 
  135: int SSL_get_ex_data_X509_STORE_CTX_idx(void)
  136:         {
  137:         static volatile int ssl_x509_store_ctx_idx= -1;
  138:         int got_write_lock = 0;
  139: 
  140:         CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
  141: 
  142:         if (ssl_x509_store_ctx_idx < 0)
  143:                 {
  144:                 CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
  145:                 CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
  146:                 got_write_lock = 1;
  147:                 
  148:                 if (ssl_x509_store_ctx_idx < 0)
  149:                         {
  150:                         ssl_x509_store_ctx_idx=X509_STORE_CTX_get_ex_new_index(
  151:                                 0,"SSL for verify callback",NULL,NULL,NULL);
  152:                         }
  153:                 }
  154: 
  155:         if (got_write_lock)
  156:                 CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
  157:         else
  158:                 CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
  159:         
  160:         return ssl_x509_store_ctx_idx;
  161:         }
  162: 
  163: CERT *ssl_cert_new(void)
  164:         {
  165:         CERT *ret;
  166: 
  167:         ret=(CERT *)OPENSSL_malloc(sizeof(CERT));
  168:         if (ret == NULL)
  169:                 {
  170:                 SSLerr(SSL_F_SSL_CERT_NEW,ERR_R_MALLOC_FAILURE);
  171:                 return(NULL);
  172:                 }
  173:         memset(ret,0,sizeof(CERT));
  174: 
  175:         ret->key= &(ret->pkeys[SSL_PKEY_RSA_ENC]);
  176:         ret->references=1;
  177: 
  178:         return(ret);
  179:         }
  180: 
  181: CERT *ssl_cert_dup(CERT *cert)
  182:         {
  183:         CERT *ret;
  184:         int i;
  185: 
  186:         ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
  187:         if (ret == NULL)
  188:                 {
  189:                 SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
  190:                 return(NULL);
  191:                 }
  192: 
  193:         memset(ret, 0, sizeof(CERT));
  194: 
  195:         ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]];
  196:         /* or ret->key = ret->pkeys + (cert->key - cert->pkeys),
  197:          * if you find that more readable */
  198: 
  199:         ret->valid = cert->valid;
  200:         ret->mask = cert->mask;
  201:         ret->export_mask = cert->export_mask;
  202: 
  203: #ifndef OPENSSL_NO_RSA
  204:         if (cert->rsa_tmp != NULL)
  205:                 {
  206:                 RSA_up_ref(cert->rsa_tmp);
  207:                 ret->rsa_tmp = cert->rsa_tmp;
  208:                 }
  209:         ret->rsa_tmp_cb = cert->rsa_tmp_cb;
  210: #endif
  211: 
  212: #ifndef OPENSSL_NO_DH
  213:         if (cert->dh_tmp != NULL)
  214:                 {
  215:                 ret->dh_tmp = DHparams_dup(cert->dh_tmp);
  216:                 if (ret->dh_tmp == NULL)
  217:                         {
  218:                         SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_DH_LIB);
  219:                         goto err;
  220:                         }
  221:                 if (cert->dh_tmp->priv_key)
  222:                         {
  223:                         BIGNUM *b = BN_dup(cert->dh_tmp->priv_key);
  224:                         if (!b)
  225:                                 {
  226:                                 SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
  227:                                 goto err;
  228:                                 }
  229:                         ret->dh_tmp->priv_key = b;
  230:                         }
  231:                 if (cert->dh_tmp->pub_key)
  232:                         {
  233:                         BIGNUM *b = BN_dup(cert->dh_tmp->pub_key);
  234:                         if (!b)
  235:                                 {
  236:                                 SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
  237:                                 goto err;
  238:                                 }
  239:                         ret->dh_tmp->pub_key = b;
  240:                         }
  241:                 }
  242:         ret->dh_tmp_cb = cert->dh_tmp_cb;
  243: #endif
  244: 
  245: #ifndef OPENSSL_NO_ECDH
  246:         if (cert->ecdh_tmp)
  247:                 {
  248:                 ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp);
  249:                 if (ret->ecdh_tmp == NULL)
  250:                         {
  251:                         SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_EC_LIB);
  252:                         goto err;
  253:                         }
  254:                 }
  255:         ret->ecdh_tmp_cb = cert->ecdh_tmp_cb;
  256: #endif
  257: 
  258:         for (i = 0; i < SSL_PKEY_NUM; i++)
  259:                 {
  260:                 if (cert->pkeys[i].x509 != NULL)
  261:                         {
  262:                         ret->pkeys[i].x509 = cert->pkeys[i].x509;
  263:                         CRYPTO_add(&ret->pkeys[i].x509->references, 1,
  264:                                 CRYPTO_LOCK_X509);
  265:                         }
  266:                 
  267:                 if (cert->pkeys[i].privatekey != NULL)
  268:                         {
  269:                         ret->pkeys[i].privatekey = cert->pkeys[i].privatekey;
  270:                         CRYPTO_add(&ret->pkeys[i].privatekey->references, 1,
  271:                                 CRYPTO_LOCK_EVP_PKEY);
  272: 
  273:                         switch(i) 
  274:                                 {
  275:                                 /* If there was anything special to do for
  276:                                  * certain types of keys, we'd do it here.
  277:                                  * (Nothing at the moment, I think.) */
  278: 
  279:                         case SSL_PKEY_RSA_ENC:
  280:                         case SSL_PKEY_RSA_SIGN:
  281:                                 /* We have an RSA key. */
  282:                                 break;
  283:                                 
  284:                         case SSL_PKEY_DSA_SIGN:
  285:                                 /* We have a DSA key. */
  286:                                 break;
  287:                                 
  288:                         case SSL_PKEY_DH_RSA:
  289:                         case SSL_PKEY_DH_DSA:
  290:                                 /* We have a DH key. */
  291:                                 break;
  292: 
  293:                         case SSL_PKEY_ECC:
  294:                                 /* We have an ECC key */
  295:                                 break;
  296: 
  297:                         default:
  298:                                 /* Can't happen. */
  299:                                 SSLerr(SSL_F_SSL_CERT_DUP, SSL_R_LIBRARY_BUG);
  300:                                 }
  301:                         }
  302:                 }
  303:         
  304:         /* ret->extra_certs *should* exist, but currently the own certificate
  305:          * chain is held inside SSL_CTX */
  306: 
  307:         ret->references=1;
  308: 
  309:         return(ret);
  310:         
  311: #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH)
  312: err:
  313: #endif
  314: #ifndef OPENSSL_NO_RSA
  315:         if (ret->rsa_tmp != NULL)
  316:                 RSA_free(ret->rsa_tmp);
  317: #endif
  318: #ifndef OPENSSL_NO_DH
  319:         if (ret->dh_tmp != NULL)
  320:                 DH_free(ret->dh_tmp);
  321: #endif
  322: #ifndef OPENSSL_NO_ECDH
  323:         if (ret->ecdh_tmp != NULL)
  324:                 EC_KEY_free(ret->ecdh_tmp);
  325: #endif
  326: 
  327:         for (i = 0; i < SSL_PKEY_NUM; i++)
  328:                 {
  329:                 if (ret->pkeys[i].x509 != NULL)
  330:                         X509_free(ret->pkeys[i].x509);
  331:                 if (ret->pkeys[i].privatekey != NULL)
  332:                         EVP_PKEY_free(ret->pkeys[i].privatekey);
  333:                 }
  334: 
  335:         return NULL;
  336:         }
  337: 
  338: 
  339: void ssl_cert_free(CERT *c)
  340:         {
  341:         int i;
  342: 
  343:         if(c == NULL)
  344:             return;
  345: 
  346:         i=CRYPTO_add(&c->references,-1,CRYPTO_LOCK_SSL_CERT);
  347: #ifdef REF_PRINT
  348:         REF_PRINT("CERT",c);
  349: #endif
  350:         if (i > 0) return;
  351: #ifdef REF_CHECK
  352:         if (i < 0)
  353:                 {
  354:                 fprintf(stderr,"ssl_cert_free, bad reference count\n");
  355:                 abort(); /* ok */
  356:                 }
  357: #endif
  358: 
  359: #ifndef OPENSSL_NO_RSA
  360:         if (c->rsa_tmp) RSA_free(c->rsa_tmp);
  361: #endif
  362: #ifndef OPENSSL_NO_DH
  363:         if (c->dh_tmp) DH_free(c->dh_tmp);
  364: #endif
  365: #ifndef OPENSSL_NO_ECDH
  366:         if (c->ecdh_tmp) EC_KEY_free(c->ecdh_tmp);
  367: #endif
  368: 
  369:         for (i=0; i<SSL_PKEY_NUM; i++)
  370:                 {
  371:                 if (c->pkeys[i].x509 != NULL)
  372:                         X509_free(c->pkeys[i].x509);
  373:                 if (c->pkeys[i].privatekey != NULL)
  374:                         EVP_PKEY_free(c->pkeys[i].privatekey);
  375: #if 0
  376:                 if (c->pkeys[i].publickey != NULL)
  377:                         EVP_PKEY_free(c->pkeys[i].publickey);
  378: #endif
  379:                 }
  380:         OPENSSL_free(c);
  381:         }
  382: 
  383: int ssl_cert_inst(CERT **o)
  384:         {
  385:         /* Create a CERT if there isn't already one
  386:          * (which cannot really happen, as it is initially created in
  387:          * SSL_CTX_new; but the earlier code usually allows for that one
  388:          * being non-existant, so we follow that behaviour, as it might
  389:          * turn out that there actually is a reason for it -- but I'm
  390:          * not sure that *all* of the existing code could cope with
  391:          * s->cert being NULL, otherwise we could do without the
  392:          * initialization in SSL_CTX_new).
  393:          */
  394:         
  395:         if (o == NULL) 
  396:                 {
  397:                 SSLerr(SSL_F_SSL_CERT_INST, ERR_R_PASSED_NULL_PARAMETER);
  398:                 return(0);
  399:                 }
  400:         if (*o == NULL)
  401:                 {
  402:                 if ((*o = ssl_cert_new()) == NULL)
  403:                         {
  404:                         SSLerr(SSL_F_SSL_CERT_INST, ERR_R_MALLOC_FAILURE);
  405:                         return(0);
  406:                         }
  407:                 }
  408:         return(1);
  409:         }
  410: 
  411: 
  412: SESS_CERT *ssl_sess_cert_new(void)
  413:         {
  414:         SESS_CERT *ret;
  415: 
  416:         ret = OPENSSL_malloc(sizeof *ret);
  417:         if (ret == NULL)
  418:                 {
  419:                 SSLerr(SSL_F_SSL_SESS_CERT_NEW, ERR_R_MALLOC_FAILURE);
  420:                 return NULL;
  421:                 }
  422: 
  423:         memset(ret, 0 ,sizeof *ret);
  424:         ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA_ENC]);
  425:         ret->references = 1;
  426: 
  427:         return ret;
  428:         }
  429: 
  430: void ssl_sess_cert_free(SESS_CERT *sc)
  431:         {
  432:         int i;
  433: 
  434:         if (sc == NULL)
  435:                 return;
  436: 
  437:         i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT);
  438: #ifdef REF_PRINT
  439:         REF_PRINT("SESS_CERT", sc);
  440: #endif
  441:         if (i > 0)
  442:                 return;
  443: #ifdef REF_CHECK
  444:         if (i < 0)
  445:                 {
  446:                 fprintf(stderr,"ssl_sess_cert_free, bad reference count\n");
  447:                 abort(); /* ok */
  448:                 }
  449: #endif
  450: 
  451:         /* i == 0 */
  452:         if (sc->cert_chain != NULL)
  453:                 sk_X509_pop_free(sc->cert_chain, X509_free);
  454:         for (i = 0; i < SSL_PKEY_NUM; i++)
  455:                 {
  456:                 if (sc->peer_pkeys[i].x509 != NULL)
  457:                         X509_free(sc->peer_pkeys[i].x509);
  458: #if 0 /* We don't have the peer's private key.  These lines are just
  459:            * here as a reminder that we're still using a not-quite-appropriate
  460:            * data structure. */
  461:                 if (sc->peer_pkeys[i].privatekey != NULL)
  462:                         EVP_PKEY_free(sc->peer_pkeys[i].privatekey);
  463: #endif
  464:                 }
  465: 
  466: #ifndef OPENSSL_NO_RSA
  467:         if (sc->peer_rsa_tmp != NULL)
  468:                 RSA_free(sc->peer_rsa_tmp);
  469: #endif
  470: #ifndef OPENSSL_NO_DH
  471:         if (sc->peer_dh_tmp != NULL)
  472:                 DH_free(sc->peer_dh_tmp);
  473: #endif
  474: #ifndef OPENSSL_NO_ECDH
  475:         if (sc->peer_ecdh_tmp != NULL)
  476:                 EC_KEY_free(sc->peer_ecdh_tmp);
  477: #endif
  478: 
  479:         OPENSSL_free(sc);
  480:         }
  481: 
  482: int ssl_set_peer_cert_type(SESS_CERT *sc,int type)
  483:         {
  484:         sc->peer_cert_type = type;
  485:         return(1);
  486:         }
  487: 
  488: int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk)
  489:         {
  490:         X509 *x;
  491:         int i;
  492:         X509_STORE_CTX ctx;
  493: 
  494:         if ((sk == NULL) || (sk_X509_num(sk) == 0))
  495:                 return(0);
  496: 
  497:         x=sk_X509_value(sk,0);
  498:         if(!X509_STORE_CTX_init(&ctx,s->ctx->cert_store,x,sk))
  499:                 {
  500:                 SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN,ERR_R_X509_LIB);
  501:                 return(0);
  502:                 }
  503:         if (s->param)
  504:                 X509_VERIFY_PARAM_inherit(X509_STORE_CTX_get0_param(&ctx),
  505:                                                 s->param);
  506: #if 0
  507:         if (SSL_get_verify_depth(s) >= 0)
  508:                 X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s));
  509: #endif
  510:         X509_STORE_CTX_set_ex_data(&ctx,SSL_get_ex_data_X509_STORE_CTX_idx(),s);
  511: 
  512:         /* We need to inherit the verify parameters. These can be determined by
  513:          * the context: if its a server it will verify SSL client certificates
  514:          * or vice versa.
  515:          */
  516: 
  517:         X509_STORE_CTX_set_default(&ctx,
  518:                                 s->server ? "ssl_client" : "ssl_server");
  519: 
  520:         if (s->verify_callback)
  521:                 X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback);
  522: 
  523:         if (s->ctx->app_verify_callback != NULL)
  524: #if 1 /* new with OpenSSL 0.9.7 */
  525:                 i=s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg); 
  526: #else
  527:                 i=s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */
  528: #endif
  529:         else
  530:                 {
  531: #ifndef OPENSSL_NO_X509_VERIFY
  532:                 i=X509_verify_cert(&ctx);
  533: #else
  534:                 i=0;
  535:                 ctx.error=X509_V_ERR_APPLICATION_VERIFICATION;
  536:                 SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN,SSL_R_NO_VERIFY_CALLBACK);
  537: #endif
  538:                 }
  539: 
  540:         s->verify_result=ctx.error;
  541:         X509_STORE_CTX_cleanup(&ctx);
  542: 
  543:         return(i);
  544:         }
  545: 
  546: static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list,STACK_OF(X509_NAME) *name_list)
  547:         {
  548:         if (*ca_list != NULL)
  549:                 sk_X509_NAME_pop_free(*ca_list,X509_NAME_free);
  550: 
  551:         *ca_list=name_list;
  552:         }
  553: 
  554: STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk)
  555:         {
  556:         int i;
  557:         STACK_OF(X509_NAME) *ret;
  558:         X509_NAME *name;
  559: 
  560:         ret=sk_X509_NAME_new_null();
  561:         for (i=0; i<sk_X509_NAME_num(sk); i++)
  562:                 {
  563:                 name=X509_NAME_dup(sk_X509_NAME_value(sk,i));
  564:                 if ((name == NULL) || !sk_X509_NAME_push(ret,name))
  565:                         {
  566:                         sk_X509_NAME_pop_free(ret,X509_NAME_free);
  567:                         return(NULL);
  568:                         }
  569:                 }
  570:         return(ret);