1*6f9291ceSJung-uk Kim /* 2*6f9291ceSJung-uk Kim * ! \file ssl/ssl_cert.c 3*6f9291ceSJung-uk Kim */ 474664626SKris Kennaway /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 574664626SKris Kennaway * All rights reserved. 674664626SKris Kennaway * 774664626SKris Kennaway * This package is an SSL implementation written 874664626SKris Kennaway * by Eric Young (eay@cryptsoft.com). 974664626SKris Kennaway * The implementation was written so as to conform with Netscapes SSL. 1074664626SKris Kennaway * 1174664626SKris Kennaway * This library is free for commercial and non-commercial use as long as 1274664626SKris Kennaway * the following conditions are aheared to. The following conditions 1374664626SKris Kennaway * apply to all code found in this distribution, be it the RC4, RSA, 1474664626SKris Kennaway * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1574664626SKris Kennaway * included with this distribution is covered by the same copyright terms 1674664626SKris Kennaway * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1774664626SKris Kennaway * 1874664626SKris Kennaway * Copyright remains Eric Young's, and as such any Copyright notices in 1974664626SKris Kennaway * the code are not to be removed. 2074664626SKris Kennaway * If this package is used in a product, Eric Young should be given attribution 2174664626SKris Kennaway * as the author of the parts of the library used. 2274664626SKris Kennaway * This can be in the form of a textual message at program startup or 2374664626SKris Kennaway * in documentation (online or textual) provided with the package. 2474664626SKris Kennaway * 2574664626SKris Kennaway * Redistribution and use in source and binary forms, with or without 2674664626SKris Kennaway * modification, are permitted provided that the following conditions 2774664626SKris Kennaway * are met: 2874664626SKris Kennaway * 1. Redistributions of source code must retain the copyright 2974664626SKris Kennaway * notice, this list of conditions and the following disclaimer. 3074664626SKris Kennaway * 2. Redistributions in binary form must reproduce the above copyright 3174664626SKris Kennaway * notice, this list of conditions and the following disclaimer in the 3274664626SKris Kennaway * documentation and/or other materials provided with the distribution. 3374664626SKris Kennaway * 3. All advertising materials mentioning features or use of this software 3474664626SKris Kennaway * must display the following acknowledgement: 3574664626SKris Kennaway * "This product includes cryptographic software written by 3674664626SKris Kennaway * Eric Young (eay@cryptsoft.com)" 3774664626SKris Kennaway * The word 'cryptographic' can be left out if the rouines from the library 3874664626SKris Kennaway * being used are not cryptographic related :-). 3974664626SKris Kennaway * 4. If you include any Windows specific code (or a derivative thereof) from 4074664626SKris Kennaway * the apps directory (application code) you must include an acknowledgement: 4174664626SKris Kennaway * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4274664626SKris Kennaway * 4374664626SKris Kennaway * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4474664626SKris Kennaway * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4574664626SKris Kennaway * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4674664626SKris Kennaway * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4774664626SKris Kennaway * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4874664626SKris Kennaway * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4974664626SKris Kennaway * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 5074664626SKris Kennaway * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 5174664626SKris Kennaway * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5274664626SKris Kennaway * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5374664626SKris Kennaway * SUCH DAMAGE. 5474664626SKris Kennaway * 5574664626SKris Kennaway * The licence and distribution terms for any publically available version or 5674664626SKris Kennaway * derivative of this code cannot be changed. i.e. this code cannot simply be 5774664626SKris Kennaway * copied and put under another distribution licence 5874664626SKris Kennaway * [including the GNU Public Licence.] 5974664626SKris Kennaway */ 6074664626SKris Kennaway /* ==================================================================== 611f13597dSJung-uk Kim * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. 6274664626SKris Kennaway * 6374664626SKris Kennaway * Redistribution and use in source and binary forms, with or without 6474664626SKris Kennaway * modification, are permitted provided that the following conditions 6574664626SKris Kennaway * are met: 6674664626SKris Kennaway * 6774664626SKris Kennaway * 1. Redistributions of source code must retain the above copyright 6874664626SKris Kennaway * notice, this list of conditions and the following disclaimer. 6974664626SKris Kennaway * 7074664626SKris Kennaway * 2. Redistributions in binary form must reproduce the above copyright 7174664626SKris Kennaway * notice, this list of conditions and the following disclaimer in 7274664626SKris Kennaway * the documentation and/or other materials provided with the 7374664626SKris Kennaway * distribution. 7474664626SKris Kennaway * 7574664626SKris Kennaway * 3. All advertising materials mentioning features or use of this 7674664626SKris Kennaway * software must display the following acknowledgment: 7774664626SKris Kennaway * "This product includes software developed by the OpenSSL Project 78ed5d4f9aSSimon L. B. Nielsen * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 7974664626SKris Kennaway * 8074664626SKris Kennaway * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 8174664626SKris Kennaway * endorse or promote products derived from this software without 8274664626SKris Kennaway * prior written permission. For written permission, please contact 83ed5d4f9aSSimon L. B. Nielsen * openssl-core@openssl.org. 8474664626SKris Kennaway * 8574664626SKris Kennaway * 5. Products derived from this software may not be called "OpenSSL" 8674664626SKris Kennaway * nor may "OpenSSL" appear in their names without prior written 8774664626SKris Kennaway * permission of the OpenSSL Project. 8874664626SKris Kennaway * 8974664626SKris Kennaway * 6. Redistributions of any form whatsoever must retain the following 9074664626SKris Kennaway * acknowledgment: 9174664626SKris Kennaway * "This product includes software developed by the OpenSSL Project 92ed5d4f9aSSimon L. B. Nielsen * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 9374664626SKris Kennaway * 9474664626SKris Kennaway * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 9574664626SKris Kennaway * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 9674664626SKris Kennaway * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 9774664626SKris Kennaway * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 9874664626SKris Kennaway * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 9974664626SKris Kennaway * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 10074664626SKris Kennaway * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 10174664626SKris Kennaway * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 10274664626SKris Kennaway * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 10374664626SKris Kennaway * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 10474664626SKris Kennaway * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 10574664626SKris Kennaway * OF THE POSSIBILITY OF SUCH DAMAGE. 10674664626SKris Kennaway * ==================================================================== 107ed5d4f9aSSimon L. B. Nielsen * 108ed5d4f9aSSimon L. B. Nielsen * This product includes cryptographic software written by Eric Young 109ed5d4f9aSSimon L. B. Nielsen * (eay@cryptsoft.com). This product includes software written by Tim 110ed5d4f9aSSimon L. B. Nielsen * Hudson (tjh@cryptsoft.com). 111ed5d4f9aSSimon L. B. Nielsen * 11274664626SKris Kennaway */ 1133b4e3dcbSSimon L. B. Nielsen /* ==================================================================== 1143b4e3dcbSSimon L. B. Nielsen * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 1153b4e3dcbSSimon L. B. Nielsen * ECC cipher suite support in OpenSSL originally developed by 1163b4e3dcbSSimon L. B. Nielsen * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. 1173b4e3dcbSSimon L. B. Nielsen */ 11874664626SKris Kennaway 11974664626SKris Kennaway #include <stdio.h> 120f579bf8eSKris Kennaway 1215c87c606SMark Murray #include "e_os.h" 122f579bf8eSKris Kennaway #ifndef NO_SYS_TYPES_H 12374664626SKris Kennaway # include <sys/types.h> 124f579bf8eSKris Kennaway #endif 125f579bf8eSKris Kennaway 1263b4e3dcbSSimon L. B. Nielsen #include "o_dir.h" 12774664626SKris Kennaway #include <openssl/objects.h> 12874664626SKris Kennaway #include <openssl/bio.h> 12974664626SKris Kennaway #include <openssl/pem.h> 130f579bf8eSKris Kennaway #include <openssl/x509v3.h> 1313b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_DH 1323b4e3dcbSSimon L. B. Nielsen # include <openssl/dh.h> 1333b4e3dcbSSimon L. B. Nielsen #endif 1343b4e3dcbSSimon L. B. Nielsen #include <openssl/bn.h> 13574664626SKris Kennaway #include "ssl_locl.h" 13674664626SKris Kennaway 13774664626SKris Kennaway int SSL_get_ex_data_X509_STORE_CTX_idx(void) 13874664626SKris Kennaway { 1395c87c606SMark Murray static volatile int ssl_x509_store_ctx_idx = -1; 140ed5d4f9aSSimon L. B. Nielsen int got_write_lock = 0; 141ed5d4f9aSSimon L. B. Nielsen 142ed5d4f9aSSimon L. B. Nielsen CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); 1435c87c606SMark Murray 144*6f9291ceSJung-uk Kim if (ssl_x509_store_ctx_idx < 0) { 145ed5d4f9aSSimon L. B. Nielsen CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); 1465c87c606SMark Murray CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 147ed5d4f9aSSimon L. B. Nielsen got_write_lock = 1; 14874664626SKris Kennaway 149*6f9291ceSJung-uk Kim if (ssl_x509_store_ctx_idx < 0) { 150*6f9291ceSJung-uk Kim ssl_x509_store_ctx_idx = 151*6f9291ceSJung-uk Kim X509_STORE_CTX_get_ex_new_index(0, "SSL for verify callback", 152*6f9291ceSJung-uk Kim NULL, NULL, NULL); 15374664626SKris Kennaway } 1545c87c606SMark Murray } 155ed5d4f9aSSimon L. B. Nielsen 156ed5d4f9aSSimon L. B. Nielsen if (got_write_lock) 157ed5d4f9aSSimon L. B. Nielsen CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); 158ed5d4f9aSSimon L. B. Nielsen else 159ed5d4f9aSSimon L. B. Nielsen CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); 160ed5d4f9aSSimon L. B. Nielsen 1615c87c606SMark Murray return ssl_x509_store_ctx_idx; 16274664626SKris Kennaway } 16374664626SKris Kennaway 1641f13597dSJung-uk Kim static void ssl_cert_set_default_md(CERT *cert) 1651f13597dSJung-uk Kim { 1661f13597dSJung-uk Kim /* Set digest values to defaults */ 1671f13597dSJung-uk Kim #ifndef OPENSSL_NO_DSA 16809286989SJung-uk Kim cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1(); 1691f13597dSJung-uk Kim #endif 1701f13597dSJung-uk Kim #ifndef OPENSSL_NO_RSA 1711f13597dSJung-uk Kim cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); 1721f13597dSJung-uk Kim cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); 1731f13597dSJung-uk Kim #endif 1741f13597dSJung-uk Kim #ifndef OPENSSL_NO_ECDSA 17509286989SJung-uk Kim cert->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); 1761f13597dSJung-uk Kim #endif 1771f13597dSJung-uk Kim } 1781f13597dSJung-uk Kim 17974664626SKris Kennaway CERT *ssl_cert_new(void) 18074664626SKris Kennaway { 18174664626SKris Kennaway CERT *ret; 18274664626SKris Kennaway 183ddd58736SKris Kennaway ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); 184*6f9291ceSJung-uk Kim if (ret == NULL) { 18574664626SKris Kennaway SSLerr(SSL_F_SSL_CERT_NEW, ERR_R_MALLOC_FAILURE); 18674664626SKris Kennaway return (NULL); 18774664626SKris Kennaway } 18874664626SKris Kennaway memset(ret, 0, sizeof(CERT)); 18974664626SKris Kennaway 19074664626SKris Kennaway ret->key = &(ret->pkeys[SSL_PKEY_RSA_ENC]); 19174664626SKris Kennaway ret->references = 1; 1921f13597dSJung-uk Kim ssl_cert_set_default_md(ret); 19374664626SKris Kennaway return (ret); 19474664626SKris Kennaway } 19574664626SKris Kennaway 19674664626SKris Kennaway CERT *ssl_cert_dup(CERT *cert) 19774664626SKris Kennaway { 19874664626SKris Kennaway CERT *ret; 19974664626SKris Kennaway int i; 20074664626SKris Kennaway 201ddd58736SKris Kennaway ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); 202*6f9291ceSJung-uk Kim if (ret == NULL) { 20374664626SKris Kennaway SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); 20474664626SKris Kennaway return (NULL); 20574664626SKris Kennaway } 20674664626SKris Kennaway 20774664626SKris Kennaway memset(ret, 0, sizeof(CERT)); 20874664626SKris Kennaway 20974664626SKris Kennaway ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]]; 210*6f9291ceSJung-uk Kim /* 211*6f9291ceSJung-uk Kim * or ret->key = ret->pkeys + (cert->key - cert->pkeys), if you find that 212*6f9291ceSJung-uk Kim * more readable 213*6f9291ceSJung-uk Kim */ 21474664626SKris Kennaway 21574664626SKris Kennaway ret->valid = cert->valid; 2161f13597dSJung-uk Kim ret->mask_k = cert->mask_k; 2171f13597dSJung-uk Kim ret->mask_a = cert->mask_a; 2181f13597dSJung-uk Kim ret->export_mask_k = cert->export_mask_k; 2191f13597dSJung-uk Kim ret->export_mask_a = cert->export_mask_a; 22074664626SKris Kennaway 2215c87c606SMark Murray #ifndef OPENSSL_NO_RSA 222*6f9291ceSJung-uk Kim if (cert->rsa_tmp != NULL) { 2235c87c606SMark Murray RSA_up_ref(cert->rsa_tmp); 22474664626SKris Kennaway ret->rsa_tmp = cert->rsa_tmp; 22574664626SKris Kennaway } 22674664626SKris Kennaway ret->rsa_tmp_cb = cert->rsa_tmp_cb; 22774664626SKris Kennaway #endif 22874664626SKris Kennaway 2295c87c606SMark Murray #ifndef OPENSSL_NO_DH 230*6f9291ceSJung-uk Kim if (cert->dh_tmp != NULL) { 23174664626SKris Kennaway ret->dh_tmp = DHparams_dup(cert->dh_tmp); 232*6f9291ceSJung-uk Kim if (ret->dh_tmp == NULL) { 233f579bf8eSKris Kennaway SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_DH_LIB); 23474664626SKris Kennaway goto err; 23574664626SKris Kennaway } 236*6f9291ceSJung-uk Kim if (cert->dh_tmp->priv_key) { 237f579bf8eSKris Kennaway BIGNUM *b = BN_dup(cert->dh_tmp->priv_key); 238*6f9291ceSJung-uk Kim if (!b) { 239f579bf8eSKris Kennaway SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); 240f579bf8eSKris Kennaway goto err; 241f579bf8eSKris Kennaway } 242f579bf8eSKris Kennaway ret->dh_tmp->priv_key = b; 243f579bf8eSKris Kennaway } 244*6f9291ceSJung-uk Kim if (cert->dh_tmp->pub_key) { 245f579bf8eSKris Kennaway BIGNUM *b = BN_dup(cert->dh_tmp->pub_key); 246*6f9291ceSJung-uk Kim if (!b) { 247f579bf8eSKris Kennaway SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); 248f579bf8eSKris Kennaway goto err; 249f579bf8eSKris Kennaway } 250f579bf8eSKris Kennaway ret->dh_tmp->pub_key = b; 251f579bf8eSKris Kennaway } 25274664626SKris Kennaway } 25374664626SKris Kennaway ret->dh_tmp_cb = cert->dh_tmp_cb; 25474664626SKris Kennaway #endif 25574664626SKris Kennaway 2563b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_ECDH 257*6f9291ceSJung-uk Kim if (cert->ecdh_tmp) { 2583b4e3dcbSSimon L. B. Nielsen ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp); 259*6f9291ceSJung-uk Kim if (ret->ecdh_tmp == NULL) { 2603b4e3dcbSSimon L. B. Nielsen SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_EC_LIB); 2613b4e3dcbSSimon L. B. Nielsen goto err; 2623b4e3dcbSSimon L. B. Nielsen } 2633b4e3dcbSSimon L. B. Nielsen } 2643b4e3dcbSSimon L. B. Nielsen ret->ecdh_tmp_cb = cert->ecdh_tmp_cb; 2653b4e3dcbSSimon L. B. Nielsen #endif 2663b4e3dcbSSimon L. B. Nielsen 267*6f9291ceSJung-uk Kim for (i = 0; i < SSL_PKEY_NUM; i++) { 268*6f9291ceSJung-uk Kim if (cert->pkeys[i].x509 != NULL) { 26974664626SKris Kennaway ret->pkeys[i].x509 = cert->pkeys[i].x509; 270*6f9291ceSJung-uk Kim CRYPTO_add(&ret->pkeys[i].x509->references, 1, CRYPTO_LOCK_X509); 27174664626SKris Kennaway } 27274664626SKris Kennaway 273*6f9291ceSJung-uk Kim if (cert->pkeys[i].privatekey != NULL) { 27474664626SKris Kennaway ret->pkeys[i].privatekey = cert->pkeys[i].privatekey; 27574664626SKris Kennaway CRYPTO_add(&ret->pkeys[i].privatekey->references, 1, 27674664626SKris Kennaway CRYPTO_LOCK_EVP_PKEY); 27774664626SKris Kennaway } 27874664626SKris Kennaway } 27974664626SKris Kennaway 280*6f9291ceSJung-uk Kim /* 281*6f9291ceSJung-uk Kim * ret->extra_certs *should* exist, but currently the own certificate 282*6f9291ceSJung-uk Kim * chain is held inside SSL_CTX 283*6f9291ceSJung-uk Kim */ 28474664626SKris Kennaway 28574664626SKris Kennaway ret->references = 1; 286*6f9291ceSJung-uk Kim /* 287*6f9291ceSJung-uk Kim * Set digests to defaults. NB: we don't copy existing values as they 2881f13597dSJung-uk Kim * will be set during handshake. 2891f13597dSJung-uk Kim */ 2901f13597dSJung-uk Kim ssl_cert_set_default_md(ret); 29174664626SKris Kennaway 29274664626SKris Kennaway return (ret); 29374664626SKris Kennaway 2943b4e3dcbSSimon L. B. Nielsen #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH) 29574664626SKris Kennaway err: 2965740a5e3SKris Kennaway #endif 2975c87c606SMark Murray #ifndef OPENSSL_NO_RSA 29874664626SKris Kennaway if (ret->rsa_tmp != NULL) 29974664626SKris Kennaway RSA_free(ret->rsa_tmp); 30074664626SKris Kennaway #endif 3015c87c606SMark Murray #ifndef OPENSSL_NO_DH 30274664626SKris Kennaway if (ret->dh_tmp != NULL) 30374664626SKris Kennaway DH_free(ret->dh_tmp); 30474664626SKris Kennaway #endif 3053b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_ECDH 3063b4e3dcbSSimon L. B. Nielsen if (ret->ecdh_tmp != NULL) 3073b4e3dcbSSimon L. B. Nielsen EC_KEY_free(ret->ecdh_tmp); 3083b4e3dcbSSimon L. B. Nielsen #endif 30974664626SKris Kennaway 310*6f9291ceSJung-uk Kim for (i = 0; i < SSL_PKEY_NUM; i++) { 31174664626SKris Kennaway if (ret->pkeys[i].x509 != NULL) 31274664626SKris Kennaway X509_free(ret->pkeys[i].x509); 31374664626SKris Kennaway if (ret->pkeys[i].privatekey != NULL) 31474664626SKris Kennaway EVP_PKEY_free(ret->pkeys[i].privatekey); 31574664626SKris Kennaway } 31674664626SKris Kennaway 31774664626SKris Kennaway return NULL; 31874664626SKris Kennaway } 31974664626SKris Kennaway 32074664626SKris Kennaway void ssl_cert_free(CERT *c) 32174664626SKris Kennaway { 32274664626SKris Kennaway int i; 32374664626SKris Kennaway 32474664626SKris Kennaway if (c == NULL) 32574664626SKris Kennaway return; 32674664626SKris Kennaway 32774664626SKris Kennaway i = CRYPTO_add(&c->references, -1, CRYPTO_LOCK_SSL_CERT); 32874664626SKris Kennaway #ifdef REF_PRINT 32974664626SKris Kennaway REF_PRINT("CERT", c); 33074664626SKris Kennaway #endif 331*6f9291ceSJung-uk Kim if (i > 0) 332*6f9291ceSJung-uk Kim return; 33374664626SKris Kennaway #ifdef REF_CHECK 334*6f9291ceSJung-uk Kim if (i < 0) { 33574664626SKris Kennaway fprintf(stderr, "ssl_cert_free, bad reference count\n"); 33674664626SKris Kennaway abort(); /* ok */ 33774664626SKris Kennaway } 33874664626SKris Kennaway #endif 33974664626SKris Kennaway 3405c87c606SMark Murray #ifndef OPENSSL_NO_RSA 341*6f9291ceSJung-uk Kim if (c->rsa_tmp) 342*6f9291ceSJung-uk Kim RSA_free(c->rsa_tmp); 34374664626SKris Kennaway #endif 3445c87c606SMark Murray #ifndef OPENSSL_NO_DH 345*6f9291ceSJung-uk Kim if (c->dh_tmp) 346*6f9291ceSJung-uk Kim DH_free(c->dh_tmp); 34774664626SKris Kennaway #endif 3483b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_ECDH 349*6f9291ceSJung-uk Kim if (c->ecdh_tmp) 350*6f9291ceSJung-uk Kim EC_KEY_free(c->ecdh_tmp); 3513b4e3dcbSSimon L. B. Nielsen #endif 35274664626SKris Kennaway 353*6f9291ceSJung-uk Kim for (i = 0; i < SSL_PKEY_NUM; i++) { 35474664626SKris Kennaway if (c->pkeys[i].x509 != NULL) 35574664626SKris Kennaway X509_free(c->pkeys[i].x509); 35674664626SKris Kennaway if (c->pkeys[i].privatekey != NULL) 35774664626SKris Kennaway EVP_PKEY_free(c->pkeys[i].privatekey); 35874664626SKris Kennaway #if 0 35974664626SKris Kennaway if (c->pkeys[i].publickey != NULL) 36074664626SKris Kennaway EVP_PKEY_free(c->pkeys[i].publickey); 36174664626SKris Kennaway #endif 36274664626SKris Kennaway } 363ddd58736SKris Kennaway OPENSSL_free(c); 36474664626SKris Kennaway } 36574664626SKris Kennaway 36674664626SKris Kennaway int ssl_cert_inst(CERT **o) 36774664626SKris Kennaway { 368*6f9291ceSJung-uk Kim /* 369*6f9291ceSJung-uk Kim * Create a CERT if there isn't already one (which cannot really happen, 370*6f9291ceSJung-uk Kim * as it is initially created in SSL_CTX_new; but the earlier code 371*6f9291ceSJung-uk Kim * usually allows for that one being non-existant, so we follow that 372*6f9291ceSJung-uk Kim * behaviour, as it might turn out that there actually is a reason for it 373*6f9291ceSJung-uk Kim * -- but I'm not sure that *all* of the existing code could cope with 374*6f9291ceSJung-uk Kim * s->cert being NULL, otherwise we could do without the initialization 375*6f9291ceSJung-uk Kim * in SSL_CTX_new). 37674664626SKris Kennaway */ 37774664626SKris Kennaway 378*6f9291ceSJung-uk Kim if (o == NULL) { 37974664626SKris Kennaway SSLerr(SSL_F_SSL_CERT_INST, ERR_R_PASSED_NULL_PARAMETER); 38074664626SKris Kennaway return (0); 38174664626SKris Kennaway } 382*6f9291ceSJung-uk Kim if (*o == NULL) { 383*6f9291ceSJung-uk Kim if ((*o = ssl_cert_new()) == NULL) { 38474664626SKris Kennaway SSLerr(SSL_F_SSL_CERT_INST, ERR_R_MALLOC_FAILURE); 38574664626SKris Kennaway return (0); 38674664626SKris Kennaway } 38774664626SKris Kennaway } 38874664626SKris Kennaway return (1); 38974664626SKris Kennaway } 39074664626SKris Kennaway 39174664626SKris Kennaway SESS_CERT *ssl_sess_cert_new(void) 39274664626SKris Kennaway { 39374664626SKris Kennaway SESS_CERT *ret; 39474664626SKris Kennaway 395ddd58736SKris Kennaway ret = OPENSSL_malloc(sizeof *ret); 396*6f9291ceSJung-uk Kim if (ret == NULL) { 39774664626SKris Kennaway SSLerr(SSL_F_SSL_SESS_CERT_NEW, ERR_R_MALLOC_FAILURE); 39874664626SKris Kennaway return NULL; 39974664626SKris Kennaway } 40074664626SKris Kennaway 40174664626SKris Kennaway memset(ret, 0, sizeof *ret); 40274664626SKris Kennaway ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA_ENC]); 40374664626SKris Kennaway ret->references = 1; 40474664626SKris Kennaway 40574664626SKris Kennaway return ret; 40674664626SKris Kennaway } 40774664626SKris Kennaway 40874664626SKris Kennaway void ssl_sess_cert_free(SESS_CERT *sc) 40974664626SKris Kennaway { 41074664626SKris Kennaway int i; 41174664626SKris Kennaway 41274664626SKris Kennaway if (sc == NULL) 41374664626SKris Kennaway return; 41474664626SKris Kennaway 41574664626SKris Kennaway i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT); 41674664626SKris Kennaway #ifdef REF_PRINT 41774664626SKris Kennaway REF_PRINT("SESS_CERT", sc); 41874664626SKris Kennaway #endif 41974664626SKris Kennaway if (i > 0) 42074664626SKris Kennaway return; 42174664626SKris Kennaway #ifdef REF_CHECK 422*6f9291ceSJung-uk Kim if (i < 0) { 42374664626SKris Kennaway fprintf(stderr, "ssl_sess_cert_free, bad reference count\n"); 42474664626SKris Kennaway abort(); /* ok */ 42574664626SKris Kennaway } 42674664626SKris Kennaway #endif 42774664626SKris Kennaway 42874664626SKris Kennaway /* i == 0 */ 42974664626SKris Kennaway if (sc->cert_chain != NULL) 43074664626SKris Kennaway sk_X509_pop_free(sc->cert_chain, X509_free); 431*6f9291ceSJung-uk Kim for (i = 0; i < SSL_PKEY_NUM; i++) { 43274664626SKris Kennaway if (sc->peer_pkeys[i].x509 != NULL) 43374664626SKris Kennaway X509_free(sc->peer_pkeys[i].x509); 434*6f9291ceSJung-uk Kim #if 0 /* We don't have the peer's private key. 435*6f9291ceSJung-uk Kim * These lines are just * here as a reminder 436*6f9291ceSJung-uk Kim * that we're still using a 437*6f9291ceSJung-uk Kim * not-quite-appropriate * data structure. */ 43874664626SKris Kennaway if (sc->peer_pkeys[i].privatekey != NULL) 43974664626SKris Kennaway EVP_PKEY_free(sc->peer_pkeys[i].privatekey); 44074664626SKris Kennaway #endif 44174664626SKris Kennaway } 44274664626SKris Kennaway 4435c87c606SMark Murray #ifndef OPENSSL_NO_RSA 44474664626SKris Kennaway if (sc->peer_rsa_tmp != NULL) 44574664626SKris Kennaway RSA_free(sc->peer_rsa_tmp); 44674664626SKris Kennaway #endif 4475c87c606SMark Murray #ifndef OPENSSL_NO_DH 44874664626SKris Kennaway if (sc->peer_dh_tmp != NULL) 44974664626SKris Kennaway DH_free(sc->peer_dh_tmp); 45074664626SKris Kennaway #endif 4513b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_ECDH 4523b4e3dcbSSimon L. B. Nielsen if (sc->peer_ecdh_tmp != NULL) 4533b4e3dcbSSimon L. B. Nielsen EC_KEY_free(sc->peer_ecdh_tmp); 4543b4e3dcbSSimon L. B. Nielsen #endif 45574664626SKris Kennaway 456ddd58736SKris Kennaway OPENSSL_free(sc); 45774664626SKris Kennaway } 45874664626SKris Kennaway 45974664626SKris Kennaway int ssl_set_peer_cert_type(SESS_CERT *sc, int type) 46074664626SKris Kennaway { 46174664626SKris Kennaway sc->peer_cert_type = type; 46274664626SKris Kennaway return (1); 46374664626SKris Kennaway } 46474664626SKris Kennaway 46574664626SKris Kennaway int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) 46674664626SKris Kennaway { 46774664626SKris Kennaway X509 *x; 46874664626SKris Kennaway int i; 46974664626SKris Kennaway X509_STORE_CTX ctx; 47074664626SKris Kennaway 47174664626SKris Kennaway if ((sk == NULL) || (sk_X509_num(sk) == 0)) 47274664626SKris Kennaway return (0); 47374664626SKris Kennaway 47474664626SKris Kennaway x = sk_X509_value(sk, 0); 475*6f9291ceSJung-uk Kim if (!X509_STORE_CTX_init(&ctx, s->ctx->cert_store, x, sk)) { 4765c87c606SMark Murray SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_X509_LIB); 4775c87c606SMark Murray return (0); 4785c87c606SMark Murray } 4793b4e3dcbSSimon L. B. Nielsen #if 0 48074664626SKris Kennaway if (SSL_get_verify_depth(s) >= 0) 48174664626SKris Kennaway X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s)); 4823b4e3dcbSSimon L. B. Nielsen #endif 483f579bf8eSKris Kennaway X509_STORE_CTX_set_ex_data(&ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s); 4845c87c606SMark Murray 485*6f9291ceSJung-uk Kim /* 486*6f9291ceSJung-uk Kim * We need to inherit the verify parameters. These can be determined by 487*6f9291ceSJung-uk Kim * the context: if its a server it will verify SSL client certificates or 488*6f9291ceSJung-uk Kim * vice versa. 489f579bf8eSKris Kennaway */ 490f579bf8eSKris Kennaway 491*6f9291ceSJung-uk Kim X509_STORE_CTX_set_default(&ctx, s->server ? "ssl_client" : "ssl_server"); 492*6f9291ceSJung-uk Kim /* 493*6f9291ceSJung-uk Kim * Anything non-default in "param" should overwrite anything in the ctx. 4946a599222SSimon L. B. Nielsen */ 4956a599222SSimon L. B. Nielsen X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param); 49674664626SKris Kennaway 497a21b1b38SKris Kennaway if (s->verify_callback) 498a21b1b38SKris Kennaway X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback); 499a21b1b38SKris Kennaway 50074664626SKris Kennaway if (s->ctx->app_verify_callback != NULL) 5015c87c606SMark Murray #if 1 /* new with OpenSSL 0.9.7 */ 5025c87c606SMark Murray i = s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg); 5035c87c606SMark Murray #else 50474664626SKris Kennaway i = s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */ 5055c87c606SMark Murray #endif 506*6f9291ceSJung-uk Kim else { 5075c87c606SMark Murray #ifndef OPENSSL_NO_X509_VERIFY 50874664626SKris Kennaway i = X509_verify_cert(&ctx); 50974664626SKris Kennaway #else 51074664626SKris Kennaway i = 0; 51174664626SKris Kennaway ctx.error = X509_V_ERR_APPLICATION_VERIFICATION; 51274664626SKris Kennaway SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, SSL_R_NO_VERIFY_CALLBACK); 51374664626SKris Kennaway #endif 51474664626SKris Kennaway } 51574664626SKris Kennaway 51674664626SKris Kennaway s->verify_result = ctx.error; 51774664626SKris Kennaway X509_STORE_CTX_cleanup(&ctx); 51874664626SKris Kennaway 51974664626SKris Kennaway return (i); 52074664626SKris Kennaway } 52174664626SKris Kennaway 522*6f9291ceSJung-uk Kim static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list, 523*6f9291ceSJung-uk Kim STACK_OF(X509_NAME) *name_list) 52474664626SKris Kennaway { 52574664626SKris Kennaway if (*ca_list != NULL) 52674664626SKris Kennaway sk_X509_NAME_pop_free(*ca_list, X509_NAME_free); 52774664626SKris Kennaway 528ced566fdSJacques Vidrine *ca_list = name_list; 52974664626SKris Kennaway } 53074664626SKris Kennaway 53174664626SKris Kennaway STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk) 53274664626SKris Kennaway { 53374664626SKris Kennaway int i; 53474664626SKris Kennaway STACK_OF(X509_NAME) *ret; 53574664626SKris Kennaway X509_NAME *name; 53674664626SKris Kennaway 53774664626SKris Kennaway ret = sk_X509_NAME_new_null(); 538*6f9291ceSJung-uk Kim for (i = 0; i < sk_X509_NAME_num(sk); i++) { 53974664626SKris Kennaway name = X509_NAME_dup(sk_X509_NAME_value(sk, i)); 540*6f9291ceSJung-uk Kim if ((name == NULL) || !sk_X509_NAME_push(ret, name)) { 54174664626SKris Kennaway sk_X509_NAME_pop_free(ret, X509_NAME_free); 54274664626SKris Kennaway return (NULL); 54374664626SKris Kennaway } 54474664626SKris Kennaway } 54574664626SKris Kennaway return (ret); 54674664626SKris Kennaway } 54774664626SKris Kennaway 548ced566fdSJacques Vidrine void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list) 54974664626SKris Kennaway { 550ced566fdSJacques Vidrine set_client_CA_list(&(s->client_CA), name_list); 55174664626SKris Kennaway } 55274664626SKris Kennaway 553ced566fdSJacques Vidrine void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) 55474664626SKris Kennaway { 555ced566fdSJacques Vidrine set_client_CA_list(&(ctx->client_CA), name_list); 55674664626SKris Kennaway } 55774664626SKris Kennaway 5583b4e3dcbSSimon L. B. Nielsen STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) 55974664626SKris Kennaway { 56074664626SKris Kennaway return (ctx->client_CA); 56174664626SKris Kennaway } 56274664626SKris Kennaway 5633b4e3dcbSSimon L. B. Nielsen STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s) 56474664626SKris Kennaway { 565*6f9291ceSJung-uk Kim if (s->type == SSL_ST_CONNECT) { /* we are in the client */ 566*6f9291ceSJung-uk Kim if (((s->version >> 8) == SSL3_VERSION_MAJOR) && (s->s3 != NULL)) 56774664626SKris Kennaway return (s->s3->tmp.ca_names); 56874664626SKris Kennaway else 56974664626SKris Kennaway return (NULL); 570*6f9291ceSJung-uk Kim } else { 57174664626SKris Kennaway if (s->client_CA != NULL) 57274664626SKris Kennaway return (s->client_CA); 57374664626SKris Kennaway else 57474664626SKris Kennaway return (s->ctx->client_CA); 57574664626SKris Kennaway } 57674664626SKris Kennaway } 57774664626SKris Kennaway 57874664626SKris Kennaway static int add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x) 57974664626SKris Kennaway { 58074664626SKris Kennaway X509_NAME *name; 58174664626SKris Kennaway 582*6f9291ceSJung-uk Kim if (x == NULL) 583*6f9291ceSJung-uk Kim return (0); 58474664626SKris Kennaway if ((*sk == NULL) && ((*sk = sk_X509_NAME_new_null()) == NULL)) 58574664626SKris Kennaway return (0); 58674664626SKris Kennaway 58774664626SKris Kennaway if ((name = X509_NAME_dup(X509_get_subject_name(x))) == NULL) 58874664626SKris Kennaway return (0); 58974664626SKris Kennaway 590*6f9291ceSJung-uk Kim if (!sk_X509_NAME_push(*sk, name)) { 59174664626SKris Kennaway X509_NAME_free(name); 59274664626SKris Kennaway return (0); 59374664626SKris Kennaway } 59474664626SKris Kennaway return (1); 59574664626SKris Kennaway } 59674664626SKris Kennaway 59774664626SKris Kennaway int SSL_add_client_CA(SSL *ssl, X509 *x) 59874664626SKris Kennaway { 59974664626SKris Kennaway return (add_client_CA(&(ssl->client_CA), x)); 60074664626SKris Kennaway } 60174664626SKris Kennaway 60274664626SKris Kennaway int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) 60374664626SKris Kennaway { 60474664626SKris Kennaway return (add_client_CA(&(ctx->client_CA), x)); 60574664626SKris Kennaway } 60674664626SKris Kennaway 607ddd58736SKris Kennaway static int xname_cmp(const X509_NAME *const *a, const X509_NAME *const *b) 60874664626SKris Kennaway { 60974664626SKris Kennaway return (X509_NAME_cmp(*a, *b)); 61074664626SKris Kennaway } 61174664626SKris Kennaway 6125c87c606SMark Murray #ifndef OPENSSL_NO_STDIO 613*6f9291ceSJung-uk Kim /** 61474664626SKris Kennaway * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed; 61574664626SKris Kennaway * it doesn't really have anything to do with clients (except that a common use 61674664626SKris Kennaway * for a stack of CAs is to send it to the client). Actually, it doesn't have 61774664626SKris Kennaway * much to do with CAs, either, since it will load any old cert. 61874664626SKris Kennaway * \param file the file containing one or more certs. 61974664626SKris Kennaway * \return a ::STACK containing the certs. 62074664626SKris Kennaway */ 62174664626SKris Kennaway STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) 62274664626SKris Kennaway { 62374664626SKris Kennaway BIO *in; 62474664626SKris Kennaway X509 *x = NULL; 62574664626SKris Kennaway X509_NAME *xn = NULL; 6263b4e3dcbSSimon L. B. Nielsen STACK_OF(X509_NAME) *ret = NULL, *sk; 62774664626SKris Kennaway 628f579bf8eSKris Kennaway sk = sk_X509_NAME_new(xname_cmp); 62974664626SKris Kennaway 63074664626SKris Kennaway in = BIO_new(BIO_s_file_internal()); 63174664626SKris Kennaway 632*6f9291ceSJung-uk Kim if ((sk == NULL) || (in == NULL)) { 63374664626SKris Kennaway SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE); 63474664626SKris Kennaway goto err; 63574664626SKris Kennaway } 63674664626SKris Kennaway 63774664626SKris Kennaway if (!BIO_read_filename(in, file)) 63874664626SKris Kennaway goto err; 63974664626SKris Kennaway 640*6f9291ceSJung-uk Kim for (;;) { 64174664626SKris Kennaway if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) 64274664626SKris Kennaway break; 643*6f9291ceSJung-uk Kim if (ret == NULL) { 6443b4e3dcbSSimon L. B. Nielsen ret = sk_X509_NAME_new_null(); 645*6f9291ceSJung-uk Kim if (ret == NULL) { 6463b4e3dcbSSimon L. B. Nielsen SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE); 6473b4e3dcbSSimon L. B. Nielsen goto err; 6483b4e3dcbSSimon L. B. Nielsen } 6493b4e3dcbSSimon L. B. Nielsen } 650*6f9291ceSJung-uk Kim if ((xn = X509_get_subject_name(x)) == NULL) 651*6f9291ceSJung-uk Kim goto err; 65274664626SKris Kennaway /* check for duplicates */ 65374664626SKris Kennaway xn = X509_NAME_dup(xn); 654*6f9291ceSJung-uk Kim if (xn == NULL) 655*6f9291ceSJung-uk Kim goto err; 65674664626SKris Kennaway if (sk_X509_NAME_find(sk, xn) >= 0) 65774664626SKris Kennaway X509_NAME_free(xn); 658*6f9291ceSJung-uk Kim else { 65974664626SKris Kennaway sk_X509_NAME_push(sk, xn); 66074664626SKris Kennaway sk_X509_NAME_push(ret, xn); 66174664626SKris Kennaway } 66274664626SKris Kennaway } 66374664626SKris Kennaway 664*6f9291ceSJung-uk Kim if (0) { 66574664626SKris Kennaway err: 666*6f9291ceSJung-uk Kim if (ret != NULL) 667*6f9291ceSJung-uk Kim sk_X509_NAME_pop_free(ret, X509_NAME_free); 66874664626SKris Kennaway ret = NULL; 66974664626SKris Kennaway } 670*6f9291ceSJung-uk Kim if (sk != NULL) 671*6f9291ceSJung-uk Kim sk_X509_NAME_free(sk); 672*6f9291ceSJung-uk Kim if (in != NULL) 673*6f9291ceSJung-uk Kim BIO_free(in); 674*6f9291ceSJung-uk Kim if (x != NULL) 675*6f9291ceSJung-uk Kim X509_free(x); 6763b4e3dcbSSimon L. B. Nielsen if (ret != NULL) 6773b4e3dcbSSimon L. B. Nielsen ERR_clear_error(); 67874664626SKris Kennaway return (ret); 67974664626SKris Kennaway } 68074664626SKris Kennaway #endif 68174664626SKris Kennaway 682*6f9291ceSJung-uk Kim /** 68374664626SKris Kennaway * Add a file of certs to a stack. 68474664626SKris Kennaway * \param stack the stack to add to. 68574664626SKris Kennaway * \param file the file to add from. All certs in this file that are not 68674664626SKris Kennaway * already in the stack will be added. 68774664626SKris Kennaway * \return 1 for success, 0 for failure. Note that in the case of failure some 68874664626SKris Kennaway * certs may have been added to \c stack. 68974664626SKris Kennaway */ 69074664626SKris Kennaway 69174664626SKris Kennaway int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, 69274664626SKris Kennaway const char *file) 69374664626SKris Kennaway { 69474664626SKris Kennaway BIO *in; 69574664626SKris Kennaway X509 *x = NULL; 69674664626SKris Kennaway X509_NAME *xn = NULL; 69774664626SKris Kennaway int ret = 1; 698ddd58736SKris Kennaway int (*oldcmp) (const X509_NAME *const *a, const X509_NAME *const *b); 69974664626SKris Kennaway 700f579bf8eSKris Kennaway oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp); 70174664626SKris Kennaway 70274664626SKris Kennaway in = BIO_new(BIO_s_file_internal()); 70374664626SKris Kennaway 704*6f9291ceSJung-uk Kim if (in == NULL) { 705*6f9291ceSJung-uk Kim SSLerr(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK, 706*6f9291ceSJung-uk Kim ERR_R_MALLOC_FAILURE); 70774664626SKris Kennaway goto err; 70874664626SKris Kennaway } 70974664626SKris Kennaway 71074664626SKris Kennaway if (!BIO_read_filename(in, file)) 71174664626SKris Kennaway goto err; 71274664626SKris Kennaway 713*6f9291ceSJung-uk Kim for (;;) { 71474664626SKris Kennaway if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) 71574664626SKris Kennaway break; 716*6f9291ceSJung-uk Kim if ((xn = X509_get_subject_name(x)) == NULL) 717*6f9291ceSJung-uk Kim goto err; 71874664626SKris Kennaway xn = X509_NAME_dup(xn); 719*6f9291ceSJung-uk Kim if (xn == NULL) 720*6f9291ceSJung-uk Kim goto err; 72174664626SKris Kennaway if (sk_X509_NAME_find(stack, xn) >= 0) 72274664626SKris Kennaway X509_NAME_free(xn); 72374664626SKris Kennaway else 72474664626SKris Kennaway sk_X509_NAME_push(stack, xn); 72574664626SKris Kennaway } 72674664626SKris Kennaway 727a3ddd25aSSimon L. B. Nielsen ERR_clear_error(); 728a3ddd25aSSimon L. B. Nielsen 729*6f9291ceSJung-uk Kim if (0) { 73074664626SKris Kennaway err: 73174664626SKris Kennaway ret = 0; 73274664626SKris Kennaway } 73374664626SKris Kennaway if (in != NULL) 73474664626SKris Kennaway BIO_free(in); 73574664626SKris Kennaway if (x != NULL) 73674664626SKris Kennaway X509_free(x); 73774664626SKris Kennaway 738db522d3aSSimon L. B. Nielsen (void)sk_X509_NAME_set_cmp_func(stack, oldcmp); 73974664626SKris Kennaway 74074664626SKris Kennaway return ret; 74174664626SKris Kennaway } 74274664626SKris Kennaway 743*6f9291ceSJung-uk Kim /** 74474664626SKris Kennaway * Add a directory of certs to a stack. 74574664626SKris Kennaway * \param stack the stack to append to. 74674664626SKris Kennaway * \param dir the directory to append from. All files in this directory will be 74774664626SKris Kennaway * examined as potential certs. Any that are acceptable to 74874664626SKris Kennaway * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will be 74974664626SKris Kennaway * included. 75074664626SKris Kennaway * \return 1 for success, 0 for failure. Note that in the case of failure some 75174664626SKris Kennaway * certs may have been added to \c stack. 75274664626SKris Kennaway */ 75374664626SKris Kennaway 75474664626SKris Kennaway int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, 75574664626SKris Kennaway const char *dir) 75674664626SKris Kennaway { 7573b4e3dcbSSimon L. B. Nielsen OPENSSL_DIR_CTX *d = NULL; 7583b4e3dcbSSimon L. B. Nielsen const char *filename; 75974664626SKris Kennaway int ret = 0; 76074664626SKris Kennaway 76174664626SKris Kennaway CRYPTO_w_lock(CRYPTO_LOCK_READDIR); 76274664626SKris Kennaway 76374664626SKris Kennaway /* Note that a side effect is that the CAs will be sorted by name */ 76474664626SKris Kennaway 765*6f9291ceSJung-uk Kim while ((filename = OPENSSL_DIR_read(&d, dir))) { 76674664626SKris Kennaway char buf[1024]; 767ddd58736SKris Kennaway int r; 76874664626SKris Kennaway 769*6f9291ceSJung-uk Kim if (strlen(dir) + strlen(filename) + 2 > sizeof buf) { 770*6f9291ceSJung-uk Kim SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, 771*6f9291ceSJung-uk Kim SSL_R_PATH_TOO_LONG); 77274664626SKris Kennaway goto err; 77374664626SKris Kennaway } 7743b4e3dcbSSimon L. B. Nielsen #ifdef OPENSSL_SYS_VMS 7753b4e3dcbSSimon L. B. Nielsen r = BIO_snprintf(buf, sizeof buf, "%s%s", dir, filename); 7763b4e3dcbSSimon L. B. Nielsen #else 7773b4e3dcbSSimon L. B. Nielsen r = BIO_snprintf(buf, sizeof buf, "%s/%s", dir, filename); 7783b4e3dcbSSimon L. B. Nielsen #endif 7793b4e3dcbSSimon L. B. Nielsen if (r <= 0 || r >= (int)sizeof(buf)) 780ddd58736SKris Kennaway goto err; 78174664626SKris Kennaway if (!SSL_add_file_cert_subjects_to_stack(stack, buf)) 78274664626SKris Kennaway goto err; 78374664626SKris Kennaway } 78474664626SKris Kennaway 785*6f9291ceSJung-uk Kim if (errno) { 7865c87c606SMark Murray SYSerr(SYS_F_OPENDIR, get_last_sys_error()); 7873b4e3dcbSSimon L. B. Nielsen ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')"); 7885c87c606SMark Murray SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB); 7895c87c606SMark Murray goto err; 7905c87c606SMark Murray } 7915c87c606SMark Murray 7925c87c606SMark Murray ret = 1; 7935c87c606SMark Murray 7945c87c606SMark Murray err: 795*6f9291ceSJung-uk Kim if (d) 796*6f9291ceSJung-uk Kim OPENSSL_DIR_end(&d); 7975c87c606SMark Murray CRYPTO_w_unlock(CRYPTO_LOCK_READDIR); 7985c87c606SMark Murray return ret; 7995c87c606SMark Murray } 800