1*f5b1c8a1SJohn Marino /* $OpenBSD: ssl_cert.c,v 1.51 2015/09/11 17:37:47 jsing Exp $ */ 2*f5b1c8a1SJohn Marino /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3*f5b1c8a1SJohn Marino * All rights reserved. 4*f5b1c8a1SJohn Marino * 5*f5b1c8a1SJohn Marino * This package is an SSL implementation written 6*f5b1c8a1SJohn Marino * by Eric Young (eay@cryptsoft.com). 7*f5b1c8a1SJohn Marino * The implementation was written so as to conform with Netscapes SSL. 8*f5b1c8a1SJohn Marino * 9*f5b1c8a1SJohn Marino * This library is free for commercial and non-commercial use as long as 10*f5b1c8a1SJohn Marino * the following conditions are aheared to. The following conditions 11*f5b1c8a1SJohn Marino * apply to all code found in this distribution, be it the RC4, RSA, 12*f5b1c8a1SJohn Marino * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13*f5b1c8a1SJohn Marino * included with this distribution is covered by the same copyright terms 14*f5b1c8a1SJohn Marino * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15*f5b1c8a1SJohn Marino * 16*f5b1c8a1SJohn Marino * Copyright remains Eric Young's, and as such any Copyright notices in 17*f5b1c8a1SJohn Marino * the code are not to be removed. 18*f5b1c8a1SJohn Marino * If this package is used in a product, Eric Young should be given attribution 19*f5b1c8a1SJohn Marino * as the author of the parts of the library used. 20*f5b1c8a1SJohn Marino * This can be in the form of a textual message at program startup or 21*f5b1c8a1SJohn Marino * in documentation (online or textual) provided with the package. 22*f5b1c8a1SJohn Marino * 23*f5b1c8a1SJohn Marino * Redistribution and use in source and binary forms, with or without 24*f5b1c8a1SJohn Marino * modification, are permitted provided that the following conditions 25*f5b1c8a1SJohn Marino * are met: 26*f5b1c8a1SJohn Marino * 1. Redistributions of source code must retain the copyright 27*f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer. 28*f5b1c8a1SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright 29*f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer in the 30*f5b1c8a1SJohn Marino * documentation and/or other materials provided with the distribution. 31*f5b1c8a1SJohn Marino * 3. All advertising materials mentioning features or use of this software 32*f5b1c8a1SJohn Marino * must display the following acknowledgement: 33*f5b1c8a1SJohn Marino * "This product includes cryptographic software written by 34*f5b1c8a1SJohn Marino * Eric Young (eay@cryptsoft.com)" 35*f5b1c8a1SJohn Marino * The word 'cryptographic' can be left out if the rouines from the library 36*f5b1c8a1SJohn Marino * being used are not cryptographic related :-). 37*f5b1c8a1SJohn Marino * 4. If you include any Windows specific code (or a derivative thereof) from 38*f5b1c8a1SJohn Marino * the apps directory (application code) you must include an acknowledgement: 39*f5b1c8a1SJohn Marino * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40*f5b1c8a1SJohn Marino * 41*f5b1c8a1SJohn Marino * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42*f5b1c8a1SJohn Marino * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43*f5b1c8a1SJohn Marino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44*f5b1c8a1SJohn Marino * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45*f5b1c8a1SJohn Marino * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46*f5b1c8a1SJohn Marino * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47*f5b1c8a1SJohn Marino * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48*f5b1c8a1SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49*f5b1c8a1SJohn Marino * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50*f5b1c8a1SJohn Marino * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51*f5b1c8a1SJohn Marino * SUCH DAMAGE. 52*f5b1c8a1SJohn Marino * 53*f5b1c8a1SJohn Marino * The licence and distribution terms for any publically available version or 54*f5b1c8a1SJohn Marino * derivative of this code cannot be changed. i.e. this code cannot simply be 55*f5b1c8a1SJohn Marino * copied and put under another distribution licence 56*f5b1c8a1SJohn Marino * [including the GNU Public Licence.] 57*f5b1c8a1SJohn Marino */ 58*f5b1c8a1SJohn Marino /* ==================================================================== 59*f5b1c8a1SJohn Marino * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. 60*f5b1c8a1SJohn Marino * 61*f5b1c8a1SJohn Marino * Redistribution and use in source and binary forms, with or without 62*f5b1c8a1SJohn Marino * modification, are permitted provided that the following conditions 63*f5b1c8a1SJohn Marino * are met: 64*f5b1c8a1SJohn Marino * 65*f5b1c8a1SJohn Marino * 1. Redistributions of source code must retain the above copyright 66*f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer. 67*f5b1c8a1SJohn Marino * 68*f5b1c8a1SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright 69*f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer in 70*f5b1c8a1SJohn Marino * the documentation and/or other materials provided with the 71*f5b1c8a1SJohn Marino * distribution. 72*f5b1c8a1SJohn Marino * 73*f5b1c8a1SJohn Marino * 3. All advertising materials mentioning features or use of this 74*f5b1c8a1SJohn Marino * software must display the following acknowledgment: 75*f5b1c8a1SJohn Marino * "This product includes software developed by the OpenSSL Project 76*f5b1c8a1SJohn Marino * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 77*f5b1c8a1SJohn Marino * 78*f5b1c8a1SJohn Marino * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 79*f5b1c8a1SJohn Marino * endorse or promote products derived from this software without 80*f5b1c8a1SJohn Marino * prior written permission. For written permission, please contact 81*f5b1c8a1SJohn Marino * openssl-core@openssl.org. 82*f5b1c8a1SJohn Marino * 83*f5b1c8a1SJohn Marino * 5. Products derived from this software may not be called "OpenSSL" 84*f5b1c8a1SJohn Marino * nor may "OpenSSL" appear in their names without prior written 85*f5b1c8a1SJohn Marino * permission of the OpenSSL Project. 86*f5b1c8a1SJohn Marino * 87*f5b1c8a1SJohn Marino * 6. Redistributions of any form whatsoever must retain the following 88*f5b1c8a1SJohn Marino * acknowledgment: 89*f5b1c8a1SJohn Marino * "This product includes software developed by the OpenSSL Project 90*f5b1c8a1SJohn Marino * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 91*f5b1c8a1SJohn Marino * 92*f5b1c8a1SJohn Marino * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 93*f5b1c8a1SJohn Marino * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 94*f5b1c8a1SJohn Marino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 95*f5b1c8a1SJohn Marino * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 96*f5b1c8a1SJohn Marino * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 97*f5b1c8a1SJohn Marino * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 98*f5b1c8a1SJohn Marino * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 99*f5b1c8a1SJohn Marino * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 100*f5b1c8a1SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 101*f5b1c8a1SJohn Marino * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 102*f5b1c8a1SJohn Marino * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 103*f5b1c8a1SJohn Marino * OF THE POSSIBILITY OF SUCH DAMAGE. 104*f5b1c8a1SJohn Marino * ==================================================================== 105*f5b1c8a1SJohn Marino * 106*f5b1c8a1SJohn Marino * This product includes cryptographic software written by Eric Young 107*f5b1c8a1SJohn Marino * (eay@cryptsoft.com). This product includes software written by Tim 108*f5b1c8a1SJohn Marino * Hudson (tjh@cryptsoft.com). 109*f5b1c8a1SJohn Marino * 110*f5b1c8a1SJohn Marino */ 111*f5b1c8a1SJohn Marino /* ==================================================================== 112*f5b1c8a1SJohn Marino * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 113*f5b1c8a1SJohn Marino * ECC cipher suite support in OpenSSL originally developed by 114*f5b1c8a1SJohn Marino * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. 115*f5b1c8a1SJohn Marino */ 116*f5b1c8a1SJohn Marino 117*f5b1c8a1SJohn Marino #include <sys/types.h> 118*f5b1c8a1SJohn Marino 119*f5b1c8a1SJohn Marino #include <dirent.h> 120*f5b1c8a1SJohn Marino #include <stdio.h> 121*f5b1c8a1SJohn Marino #include <unistd.h> 122*f5b1c8a1SJohn Marino 123*f5b1c8a1SJohn Marino #include <openssl/bio.h> 124*f5b1c8a1SJohn Marino #include <openssl/bn.h> 125*f5b1c8a1SJohn Marino #include <openssl/dh.h> 126*f5b1c8a1SJohn Marino #include <openssl/objects.h> 127*f5b1c8a1SJohn Marino #include <openssl/opensslconf.h> 128*f5b1c8a1SJohn Marino #include <openssl/pem.h> 129*f5b1c8a1SJohn Marino #include <openssl/x509v3.h> 130*f5b1c8a1SJohn Marino 131*f5b1c8a1SJohn Marino #include "ssl_locl.h" 132*f5b1c8a1SJohn Marino 133*f5b1c8a1SJohn Marino int 134*f5b1c8a1SJohn Marino SSL_get_ex_data_X509_STORE_CTX_idx(void) 135*f5b1c8a1SJohn Marino { 136*f5b1c8a1SJohn Marino static volatile int ssl_x509_store_ctx_idx = -1; 137*f5b1c8a1SJohn Marino int got_write_lock = 0; 138*f5b1c8a1SJohn Marino 139*f5b1c8a1SJohn Marino CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); 140*f5b1c8a1SJohn Marino 141*f5b1c8a1SJohn Marino if (ssl_x509_store_ctx_idx < 0) { 142*f5b1c8a1SJohn Marino CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); 143*f5b1c8a1SJohn Marino CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 144*f5b1c8a1SJohn Marino got_write_lock = 1; 145*f5b1c8a1SJohn Marino 146*f5b1c8a1SJohn Marino if (ssl_x509_store_ctx_idx < 0) { 147*f5b1c8a1SJohn Marino ssl_x509_store_ctx_idx = 148*f5b1c8a1SJohn Marino X509_STORE_CTX_get_ex_new_index( 149*f5b1c8a1SJohn Marino 0, "SSL for verify callback", NULL, NULL, NULL); 150*f5b1c8a1SJohn Marino } 151*f5b1c8a1SJohn Marino } 152*f5b1c8a1SJohn Marino 153*f5b1c8a1SJohn Marino if (got_write_lock) 154*f5b1c8a1SJohn Marino CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); 155*f5b1c8a1SJohn Marino else 156*f5b1c8a1SJohn Marino CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); 157*f5b1c8a1SJohn Marino 158*f5b1c8a1SJohn Marino return ssl_x509_store_ctx_idx; 159*f5b1c8a1SJohn Marino } 160*f5b1c8a1SJohn Marino 161*f5b1c8a1SJohn Marino static void 162*f5b1c8a1SJohn Marino ssl_cert_set_default_md(CERT *cert) 163*f5b1c8a1SJohn Marino { 164*f5b1c8a1SJohn Marino /* Set digest values to defaults */ 165*f5b1c8a1SJohn Marino cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1(); 166*f5b1c8a1SJohn Marino cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); 167*f5b1c8a1SJohn Marino cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); 168*f5b1c8a1SJohn Marino cert->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); 169*f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_GOST 170*f5b1c8a1SJohn Marino cert->pkeys[SSL_PKEY_GOST01].digest = EVP_gostr341194(); 171*f5b1c8a1SJohn Marino #endif 172*f5b1c8a1SJohn Marino } 173*f5b1c8a1SJohn Marino 174*f5b1c8a1SJohn Marino CERT * 175*f5b1c8a1SJohn Marino ssl_cert_new(void) 176*f5b1c8a1SJohn Marino { 177*f5b1c8a1SJohn Marino CERT *ret; 178*f5b1c8a1SJohn Marino 179*f5b1c8a1SJohn Marino ret = calloc(1, sizeof(CERT)); 180*f5b1c8a1SJohn Marino if (ret == NULL) { 181*f5b1c8a1SJohn Marino SSLerr(SSL_F_SSL_CERT_NEW, ERR_R_MALLOC_FAILURE); 182*f5b1c8a1SJohn Marino return (NULL); 183*f5b1c8a1SJohn Marino } 184*f5b1c8a1SJohn Marino ret->key = &(ret->pkeys[SSL_PKEY_RSA_ENC]); 185*f5b1c8a1SJohn Marino ret->references = 1; 186*f5b1c8a1SJohn Marino ssl_cert_set_default_md(ret); 187*f5b1c8a1SJohn Marino return (ret); 188*f5b1c8a1SJohn Marino } 189*f5b1c8a1SJohn Marino 190*f5b1c8a1SJohn Marino CERT * 191*f5b1c8a1SJohn Marino ssl_cert_dup(CERT *cert) 192*f5b1c8a1SJohn Marino { 193*f5b1c8a1SJohn Marino CERT *ret; 194*f5b1c8a1SJohn Marino int i; 195*f5b1c8a1SJohn Marino 196*f5b1c8a1SJohn Marino ret = calloc(1, sizeof(CERT)); 197*f5b1c8a1SJohn Marino if (ret == NULL) { 198*f5b1c8a1SJohn Marino SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); 199*f5b1c8a1SJohn Marino return (NULL); 200*f5b1c8a1SJohn Marino } 201*f5b1c8a1SJohn Marino 202*f5b1c8a1SJohn Marino /* 203*f5b1c8a1SJohn Marino * same as ret->key = ret->pkeys + (cert->key - cert->pkeys), 204*f5b1c8a1SJohn Marino * if you find that more readable 205*f5b1c8a1SJohn Marino */ 206*f5b1c8a1SJohn Marino ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]]; 207*f5b1c8a1SJohn Marino 208*f5b1c8a1SJohn Marino ret->valid = cert->valid; 209*f5b1c8a1SJohn Marino ret->mask_k = cert->mask_k; 210*f5b1c8a1SJohn Marino ret->mask_a = cert->mask_a; 211*f5b1c8a1SJohn Marino 212*f5b1c8a1SJohn Marino if (cert->dh_tmp != NULL) { 213*f5b1c8a1SJohn Marino ret->dh_tmp = DHparams_dup(cert->dh_tmp); 214*f5b1c8a1SJohn Marino if (ret->dh_tmp == NULL) { 215*f5b1c8a1SJohn Marino SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_DH_LIB); 216*f5b1c8a1SJohn Marino goto err; 217*f5b1c8a1SJohn Marino } 218*f5b1c8a1SJohn Marino if (cert->dh_tmp->priv_key) { 219*f5b1c8a1SJohn Marino BIGNUM *b = BN_dup(cert->dh_tmp->priv_key); 220*f5b1c8a1SJohn Marino if (!b) { 221*f5b1c8a1SJohn Marino SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); 222*f5b1c8a1SJohn Marino goto err; 223*f5b1c8a1SJohn Marino } 224*f5b1c8a1SJohn Marino ret->dh_tmp->priv_key = b; 225*f5b1c8a1SJohn Marino } 226*f5b1c8a1SJohn Marino if (cert->dh_tmp->pub_key) { 227*f5b1c8a1SJohn Marino BIGNUM *b = BN_dup(cert->dh_tmp->pub_key); 228*f5b1c8a1SJohn Marino if (!b) { 229*f5b1c8a1SJohn Marino SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); 230*f5b1c8a1SJohn Marino goto err; 231*f5b1c8a1SJohn Marino } 232*f5b1c8a1SJohn Marino ret->dh_tmp->pub_key = b; 233*f5b1c8a1SJohn Marino } 234*f5b1c8a1SJohn Marino } 235*f5b1c8a1SJohn Marino ret->dh_tmp_cb = cert->dh_tmp_cb; 236*f5b1c8a1SJohn Marino ret->dh_tmp_auto = cert->dh_tmp_auto; 237*f5b1c8a1SJohn Marino 238*f5b1c8a1SJohn Marino if (cert->ecdh_tmp) { 239*f5b1c8a1SJohn Marino ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp); 240*f5b1c8a1SJohn Marino if (ret->ecdh_tmp == NULL) { 241*f5b1c8a1SJohn Marino SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_EC_LIB); 242*f5b1c8a1SJohn Marino goto err; 243*f5b1c8a1SJohn Marino } 244*f5b1c8a1SJohn Marino } 245*f5b1c8a1SJohn Marino ret->ecdh_tmp_cb = cert->ecdh_tmp_cb; 246*f5b1c8a1SJohn Marino ret->ecdh_tmp_auto = cert->ecdh_tmp_auto; 247*f5b1c8a1SJohn Marino 248*f5b1c8a1SJohn Marino for (i = 0; i < SSL_PKEY_NUM; i++) { 249*f5b1c8a1SJohn Marino if (cert->pkeys[i].x509 != NULL) { 250*f5b1c8a1SJohn Marino ret->pkeys[i].x509 = cert->pkeys[i].x509; 251*f5b1c8a1SJohn Marino CRYPTO_add(&ret->pkeys[i].x509->references, 1, 252*f5b1c8a1SJohn Marino CRYPTO_LOCK_X509); 253*f5b1c8a1SJohn Marino } 254*f5b1c8a1SJohn Marino 255*f5b1c8a1SJohn Marino if (cert->pkeys[i].privatekey != NULL) { 256*f5b1c8a1SJohn Marino ret->pkeys[i].privatekey = cert->pkeys[i].privatekey; 257*f5b1c8a1SJohn Marino CRYPTO_add(&ret->pkeys[i].privatekey->references, 1, 258*f5b1c8a1SJohn Marino CRYPTO_LOCK_EVP_PKEY); 259*f5b1c8a1SJohn Marino 260*f5b1c8a1SJohn Marino switch (i) { 261*f5b1c8a1SJohn Marino /* 262*f5b1c8a1SJohn Marino * If there was anything special to do for 263*f5b1c8a1SJohn Marino * certain types of keys, we'd do it here. 264*f5b1c8a1SJohn Marino * (Nothing at the moment, I think.) 265*f5b1c8a1SJohn Marino */ 266*f5b1c8a1SJohn Marino 267*f5b1c8a1SJohn Marino case SSL_PKEY_RSA_ENC: 268*f5b1c8a1SJohn Marino case SSL_PKEY_RSA_SIGN: 269*f5b1c8a1SJohn Marino /* We have an RSA key. */ 270*f5b1c8a1SJohn Marino break; 271*f5b1c8a1SJohn Marino 272*f5b1c8a1SJohn Marino case SSL_PKEY_DSA_SIGN: 273*f5b1c8a1SJohn Marino /* We have a DSA key. */ 274*f5b1c8a1SJohn Marino break; 275*f5b1c8a1SJohn Marino 276*f5b1c8a1SJohn Marino case SSL_PKEY_DH_RSA: 277*f5b1c8a1SJohn Marino case SSL_PKEY_DH_DSA: 278*f5b1c8a1SJohn Marino /* We have a DH key. */ 279*f5b1c8a1SJohn Marino break; 280*f5b1c8a1SJohn Marino 281*f5b1c8a1SJohn Marino case SSL_PKEY_ECC: 282*f5b1c8a1SJohn Marino /* We have an ECC key */ 283*f5b1c8a1SJohn Marino break; 284*f5b1c8a1SJohn Marino 285*f5b1c8a1SJohn Marino default: 286*f5b1c8a1SJohn Marino /* Can't happen. */ 287*f5b1c8a1SJohn Marino SSLerr(SSL_F_SSL_CERT_DUP, SSL_R_LIBRARY_BUG); 288*f5b1c8a1SJohn Marino } 289*f5b1c8a1SJohn Marino } 290*f5b1c8a1SJohn Marino } 291*f5b1c8a1SJohn Marino 292*f5b1c8a1SJohn Marino /* 293*f5b1c8a1SJohn Marino * ret->extra_certs *should* exist, but currently the own certificate 294*f5b1c8a1SJohn Marino * chain is held inside SSL_CTX 295*f5b1c8a1SJohn Marino */ 296*f5b1c8a1SJohn Marino 297*f5b1c8a1SJohn Marino ret->references = 1; 298*f5b1c8a1SJohn Marino /* 299*f5b1c8a1SJohn Marino * Set digests to defaults. NB: we don't copy existing values 300*f5b1c8a1SJohn Marino * as they will be set during handshake. 301*f5b1c8a1SJohn Marino */ 302*f5b1c8a1SJohn Marino ssl_cert_set_default_md(ret); 303*f5b1c8a1SJohn Marino 304*f5b1c8a1SJohn Marino return (ret); 305*f5b1c8a1SJohn Marino 306*f5b1c8a1SJohn Marino err: 307*f5b1c8a1SJohn Marino DH_free(ret->dh_tmp); 308*f5b1c8a1SJohn Marino EC_KEY_free(ret->ecdh_tmp); 309*f5b1c8a1SJohn Marino 310*f5b1c8a1SJohn Marino for (i = 0; i < SSL_PKEY_NUM; i++) { 311*f5b1c8a1SJohn Marino X509_free(ret->pkeys[i].x509); 312*f5b1c8a1SJohn Marino EVP_PKEY_free(ret->pkeys[i].privatekey); 313*f5b1c8a1SJohn Marino } 314*f5b1c8a1SJohn Marino free (ret); 315*f5b1c8a1SJohn Marino return NULL; 316*f5b1c8a1SJohn Marino } 317*f5b1c8a1SJohn Marino 318*f5b1c8a1SJohn Marino 319*f5b1c8a1SJohn Marino void 320*f5b1c8a1SJohn Marino ssl_cert_free(CERT *c) 321*f5b1c8a1SJohn Marino { 322*f5b1c8a1SJohn Marino int i; 323*f5b1c8a1SJohn Marino 324*f5b1c8a1SJohn Marino if (c == NULL) 325*f5b1c8a1SJohn Marino return; 326*f5b1c8a1SJohn Marino 327*f5b1c8a1SJohn Marino i = CRYPTO_add(&c->references, -1, CRYPTO_LOCK_SSL_CERT); 328*f5b1c8a1SJohn Marino if (i > 0) 329*f5b1c8a1SJohn Marino return; 330*f5b1c8a1SJohn Marino 331*f5b1c8a1SJohn Marino DH_free(c->dh_tmp); 332*f5b1c8a1SJohn Marino EC_KEY_free(c->ecdh_tmp); 333*f5b1c8a1SJohn Marino 334*f5b1c8a1SJohn Marino for (i = 0; i < SSL_PKEY_NUM; i++) { 335*f5b1c8a1SJohn Marino X509_free(c->pkeys[i].x509); 336*f5b1c8a1SJohn Marino EVP_PKEY_free(c->pkeys[i].privatekey); 337*f5b1c8a1SJohn Marino } 338*f5b1c8a1SJohn Marino 339*f5b1c8a1SJohn Marino free(c); 340*f5b1c8a1SJohn Marino } 341*f5b1c8a1SJohn Marino 342*f5b1c8a1SJohn Marino int 343*f5b1c8a1SJohn Marino ssl_cert_inst(CERT **o) 344*f5b1c8a1SJohn Marino { 345*f5b1c8a1SJohn Marino /* 346*f5b1c8a1SJohn Marino * Create a CERT if there isn't already one 347*f5b1c8a1SJohn Marino * (which cannot really happen, as it is initially created in 348*f5b1c8a1SJohn Marino * SSL_CTX_new; but the earlier code usually allows for that one 349*f5b1c8a1SJohn Marino * being non-existant, so we follow that behaviour, as it might 350*f5b1c8a1SJohn Marino * turn out that there actually is a reason for it -- but I'm 351*f5b1c8a1SJohn Marino * not sure that *all* of the existing code could cope with 352*f5b1c8a1SJohn Marino * s->cert being NULL, otherwise we could do without the 353*f5b1c8a1SJohn Marino * initialization in SSL_CTX_new). 354*f5b1c8a1SJohn Marino */ 355*f5b1c8a1SJohn Marino 356*f5b1c8a1SJohn Marino if (o == NULL) { 357*f5b1c8a1SJohn Marino SSLerr(SSL_F_SSL_CERT_INST, ERR_R_PASSED_NULL_PARAMETER); 358*f5b1c8a1SJohn Marino return (0); 359*f5b1c8a1SJohn Marino } 360*f5b1c8a1SJohn Marino if (*o == NULL) { 361*f5b1c8a1SJohn Marino if ((*o = ssl_cert_new()) == NULL) { 362*f5b1c8a1SJohn Marino SSLerr(SSL_F_SSL_CERT_INST, ERR_R_MALLOC_FAILURE); 363*f5b1c8a1SJohn Marino return (0); 364*f5b1c8a1SJohn Marino } 365*f5b1c8a1SJohn Marino } 366*f5b1c8a1SJohn Marino return (1); 367*f5b1c8a1SJohn Marino } 368*f5b1c8a1SJohn Marino 369*f5b1c8a1SJohn Marino 370*f5b1c8a1SJohn Marino SESS_CERT * 371*f5b1c8a1SJohn Marino ssl_sess_cert_new(void) 372*f5b1c8a1SJohn Marino { 373*f5b1c8a1SJohn Marino SESS_CERT *ret; 374*f5b1c8a1SJohn Marino 375*f5b1c8a1SJohn Marino ret = calloc(1, sizeof *ret); 376*f5b1c8a1SJohn Marino if (ret == NULL) { 377*f5b1c8a1SJohn Marino SSLerr(SSL_F_SSL_SESS_CERT_NEW, ERR_R_MALLOC_FAILURE); 378*f5b1c8a1SJohn Marino return NULL; 379*f5b1c8a1SJohn Marino } 380*f5b1c8a1SJohn Marino ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA_ENC]); 381*f5b1c8a1SJohn Marino ret->references = 1; 382*f5b1c8a1SJohn Marino 383*f5b1c8a1SJohn Marino return ret; 384*f5b1c8a1SJohn Marino } 385*f5b1c8a1SJohn Marino 386*f5b1c8a1SJohn Marino void 387*f5b1c8a1SJohn Marino ssl_sess_cert_free(SESS_CERT *sc) 388*f5b1c8a1SJohn Marino { 389*f5b1c8a1SJohn Marino int i; 390*f5b1c8a1SJohn Marino 391*f5b1c8a1SJohn Marino if (sc == NULL) 392*f5b1c8a1SJohn Marino return; 393*f5b1c8a1SJohn Marino 394*f5b1c8a1SJohn Marino i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT); 395*f5b1c8a1SJohn Marino if (i > 0) 396*f5b1c8a1SJohn Marino return; 397*f5b1c8a1SJohn Marino 398*f5b1c8a1SJohn Marino /* i == 0 */ 399*f5b1c8a1SJohn Marino if (sc->cert_chain != NULL) 400*f5b1c8a1SJohn Marino sk_X509_pop_free(sc->cert_chain, X509_free); 401*f5b1c8a1SJohn Marino for (i = 0; i < SSL_PKEY_NUM; i++) 402*f5b1c8a1SJohn Marino X509_free(sc->peer_pkeys[i].x509); 403*f5b1c8a1SJohn Marino 404*f5b1c8a1SJohn Marino DH_free(sc->peer_dh_tmp); 405*f5b1c8a1SJohn Marino EC_KEY_free(sc->peer_ecdh_tmp); 406*f5b1c8a1SJohn Marino 407*f5b1c8a1SJohn Marino free(sc); 408*f5b1c8a1SJohn Marino } 409*f5b1c8a1SJohn Marino 410*f5b1c8a1SJohn Marino int 411*f5b1c8a1SJohn Marino ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) 412*f5b1c8a1SJohn Marino { 413*f5b1c8a1SJohn Marino X509_STORE_CTX ctx; 414*f5b1c8a1SJohn Marino X509 *x; 415*f5b1c8a1SJohn Marino int ret; 416*f5b1c8a1SJohn Marino 417*f5b1c8a1SJohn Marino if ((sk == NULL) || (sk_X509_num(sk) == 0)) 418*f5b1c8a1SJohn Marino return (0); 419*f5b1c8a1SJohn Marino 420*f5b1c8a1SJohn Marino x = sk_X509_value(sk, 0); 421*f5b1c8a1SJohn Marino if (!X509_STORE_CTX_init(&ctx, s->ctx->cert_store, x, sk)) { 422*f5b1c8a1SJohn Marino SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_X509_LIB); 423*f5b1c8a1SJohn Marino return (0); 424*f5b1c8a1SJohn Marino } 425*f5b1c8a1SJohn Marino X509_STORE_CTX_set_ex_data(&ctx, 426*f5b1c8a1SJohn Marino SSL_get_ex_data_X509_STORE_CTX_idx(), s); 427*f5b1c8a1SJohn Marino 428*f5b1c8a1SJohn Marino /* 429*f5b1c8a1SJohn Marino * We need to inherit the verify parameters. These can be 430*f5b1c8a1SJohn Marino * determined by the context: if its a server it will verify 431*f5b1c8a1SJohn Marino * SSL client certificates or vice versa. 432*f5b1c8a1SJohn Marino */ 433*f5b1c8a1SJohn Marino X509_STORE_CTX_set_default(&ctx, 434*f5b1c8a1SJohn Marino s->server ? "ssl_client" : "ssl_server"); 435*f5b1c8a1SJohn Marino 436*f5b1c8a1SJohn Marino /* 437*f5b1c8a1SJohn Marino * Anything non-default in "param" should overwrite anything 438*f5b1c8a1SJohn Marino * in the ctx. 439*f5b1c8a1SJohn Marino */ 440*f5b1c8a1SJohn Marino X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param); 441*f5b1c8a1SJohn Marino 442*f5b1c8a1SJohn Marino if (s->verify_callback) 443*f5b1c8a1SJohn Marino X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback); 444*f5b1c8a1SJohn Marino 445*f5b1c8a1SJohn Marino if (s->ctx->app_verify_callback != NULL) 446*f5b1c8a1SJohn Marino ret = s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg); 447*f5b1c8a1SJohn Marino else 448*f5b1c8a1SJohn Marino ret = X509_verify_cert(&ctx); 449*f5b1c8a1SJohn Marino 450*f5b1c8a1SJohn Marino s->verify_result = ctx.error; 451*f5b1c8a1SJohn Marino X509_STORE_CTX_cleanup(&ctx); 452*f5b1c8a1SJohn Marino 453*f5b1c8a1SJohn Marino return (ret); 454*f5b1c8a1SJohn Marino } 455*f5b1c8a1SJohn Marino 456*f5b1c8a1SJohn Marino static void 457*f5b1c8a1SJohn Marino set_client_CA_list(STACK_OF(X509_NAME) **ca_list, 458*f5b1c8a1SJohn Marino STACK_OF(X509_NAME) *name_list) 459*f5b1c8a1SJohn Marino { 460*f5b1c8a1SJohn Marino if (*ca_list != NULL) 461*f5b1c8a1SJohn Marino sk_X509_NAME_pop_free(*ca_list, X509_NAME_free); 462*f5b1c8a1SJohn Marino 463*f5b1c8a1SJohn Marino *ca_list = name_list; 464*f5b1c8a1SJohn Marino } 465*f5b1c8a1SJohn Marino 466*f5b1c8a1SJohn Marino STACK_OF(X509_NAME) * 467*f5b1c8a1SJohn Marino SSL_dup_CA_list(STACK_OF(X509_NAME) *sk) 468*f5b1c8a1SJohn Marino { 469*f5b1c8a1SJohn Marino int i; 470*f5b1c8a1SJohn Marino STACK_OF(X509_NAME) *ret; 471*f5b1c8a1SJohn Marino X509_NAME *name; 472*f5b1c8a1SJohn Marino 473*f5b1c8a1SJohn Marino ret = sk_X509_NAME_new_null(); 474*f5b1c8a1SJohn Marino for (i = 0; i < sk_X509_NAME_num(sk); i++) { 475*f5b1c8a1SJohn Marino name = X509_NAME_dup(sk_X509_NAME_value(sk, i)); 476*f5b1c8a1SJohn Marino if ((name == NULL) || !sk_X509_NAME_push(ret, name)) { 477*f5b1c8a1SJohn Marino sk_X509_NAME_pop_free(ret, X509_NAME_free); 478*f5b1c8a1SJohn Marino return (NULL); 479*f5b1c8a1SJohn Marino } 480*f5b1c8a1SJohn Marino } 481*f5b1c8a1SJohn Marino return (ret); 482*f5b1c8a1SJohn Marino } 483*f5b1c8a1SJohn Marino 484*f5b1c8a1SJohn Marino void 485*f5b1c8a1SJohn Marino SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list) 486*f5b1c8a1SJohn Marino { 487*f5b1c8a1SJohn Marino set_client_CA_list(&(s->client_CA), name_list); 488*f5b1c8a1SJohn Marino } 489*f5b1c8a1SJohn Marino 490*f5b1c8a1SJohn Marino void 491*f5b1c8a1SJohn Marino SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) 492*f5b1c8a1SJohn Marino { 493*f5b1c8a1SJohn Marino set_client_CA_list(&(ctx->client_CA), name_list); 494*f5b1c8a1SJohn Marino } 495*f5b1c8a1SJohn Marino 496*f5b1c8a1SJohn Marino STACK_OF(X509_NAME) * 497*f5b1c8a1SJohn Marino SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) 498*f5b1c8a1SJohn Marino { 499*f5b1c8a1SJohn Marino return (ctx->client_CA); 500*f5b1c8a1SJohn Marino } 501*f5b1c8a1SJohn Marino 502*f5b1c8a1SJohn Marino STACK_OF(X509_NAME) * 503*f5b1c8a1SJohn Marino SSL_get_client_CA_list(const SSL *s) 504*f5b1c8a1SJohn Marino { 505*f5b1c8a1SJohn Marino if (s->type == SSL_ST_CONNECT) { 506*f5b1c8a1SJohn Marino /* We are in the client. */ 507*f5b1c8a1SJohn Marino if (((s->version >> 8) == SSL3_VERSION_MAJOR) && 508*f5b1c8a1SJohn Marino (s->s3 != NULL)) 509*f5b1c8a1SJohn Marino return (s->s3->tmp.ca_names); 510*f5b1c8a1SJohn Marino else 511*f5b1c8a1SJohn Marino return (NULL); 512*f5b1c8a1SJohn Marino } else { 513*f5b1c8a1SJohn Marino if (s->client_CA != NULL) 514*f5b1c8a1SJohn Marino return (s->client_CA); 515*f5b1c8a1SJohn Marino else 516*f5b1c8a1SJohn Marino return (s->ctx->client_CA); 517*f5b1c8a1SJohn Marino } 518*f5b1c8a1SJohn Marino } 519*f5b1c8a1SJohn Marino 520*f5b1c8a1SJohn Marino static int 521*f5b1c8a1SJohn Marino add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x) 522*f5b1c8a1SJohn Marino { 523*f5b1c8a1SJohn Marino X509_NAME *name; 524*f5b1c8a1SJohn Marino 525*f5b1c8a1SJohn Marino if (x == NULL) 526*f5b1c8a1SJohn Marino return (0); 527*f5b1c8a1SJohn Marino if ((*sk == NULL) && ((*sk = sk_X509_NAME_new_null()) == NULL)) 528*f5b1c8a1SJohn Marino return (0); 529*f5b1c8a1SJohn Marino 530*f5b1c8a1SJohn Marino if ((name = X509_NAME_dup(X509_get_subject_name(x))) == NULL) 531*f5b1c8a1SJohn Marino return (0); 532*f5b1c8a1SJohn Marino 533*f5b1c8a1SJohn Marino if (!sk_X509_NAME_push(*sk, name)) { 534*f5b1c8a1SJohn Marino X509_NAME_free(name); 535*f5b1c8a1SJohn Marino return (0); 536*f5b1c8a1SJohn Marino } 537*f5b1c8a1SJohn Marino return (1); 538*f5b1c8a1SJohn Marino } 539*f5b1c8a1SJohn Marino 540*f5b1c8a1SJohn Marino int 541*f5b1c8a1SJohn Marino SSL_add_client_CA(SSL *ssl, X509 *x) 542*f5b1c8a1SJohn Marino { 543*f5b1c8a1SJohn Marino return (add_client_CA(&(ssl->client_CA), x)); 544*f5b1c8a1SJohn Marino } 545*f5b1c8a1SJohn Marino 546*f5b1c8a1SJohn Marino int 547*f5b1c8a1SJohn Marino SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) 548*f5b1c8a1SJohn Marino { 549*f5b1c8a1SJohn Marino return (add_client_CA(&(ctx->client_CA), x)); 550*f5b1c8a1SJohn Marino } 551*f5b1c8a1SJohn Marino 552*f5b1c8a1SJohn Marino static int 553*f5b1c8a1SJohn Marino xname_cmp(const X509_NAME * const *a, const X509_NAME * const *b) 554*f5b1c8a1SJohn Marino { 555*f5b1c8a1SJohn Marino return (X509_NAME_cmp(*a, *b)); 556*f5b1c8a1SJohn Marino } 557*f5b1c8a1SJohn Marino 558*f5b1c8a1SJohn Marino /*! 559*f5b1c8a1SJohn Marino * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed; 560*f5b1c8a1SJohn Marino * it doesn't really have anything to do with clients (except that a common use 561*f5b1c8a1SJohn Marino * for a stack of CAs is to send it to the client). Actually, it doesn't have 562*f5b1c8a1SJohn Marino * much to do with CAs, either, since it will load any old cert. 563*f5b1c8a1SJohn Marino * \param file the file containing one or more certs. 564*f5b1c8a1SJohn Marino * \return a ::STACK containing the certs. 565*f5b1c8a1SJohn Marino */ 566*f5b1c8a1SJohn Marino STACK_OF(X509_NAME) * 567*f5b1c8a1SJohn Marino SSL_load_client_CA_file(const char *file) 568*f5b1c8a1SJohn Marino { 569*f5b1c8a1SJohn Marino BIO *in; 570*f5b1c8a1SJohn Marino X509 *x = NULL; 571*f5b1c8a1SJohn Marino X509_NAME *xn = NULL; 572*f5b1c8a1SJohn Marino STACK_OF(X509_NAME) *ret = NULL, *sk; 573*f5b1c8a1SJohn Marino 574*f5b1c8a1SJohn Marino sk = sk_X509_NAME_new(xname_cmp); 575*f5b1c8a1SJohn Marino 576*f5b1c8a1SJohn Marino in = BIO_new(BIO_s_file_internal()); 577*f5b1c8a1SJohn Marino 578*f5b1c8a1SJohn Marino if ((sk == NULL) || (in == NULL)) { 579*f5b1c8a1SJohn Marino SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE); 580*f5b1c8a1SJohn Marino goto err; 581*f5b1c8a1SJohn Marino } 582*f5b1c8a1SJohn Marino 583*f5b1c8a1SJohn Marino if (!BIO_read_filename(in, file)) 584*f5b1c8a1SJohn Marino goto err; 585*f5b1c8a1SJohn Marino 586*f5b1c8a1SJohn Marino for (;;) { 587*f5b1c8a1SJohn Marino if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) 588*f5b1c8a1SJohn Marino break; 589*f5b1c8a1SJohn Marino if (ret == NULL) { 590*f5b1c8a1SJohn Marino ret = sk_X509_NAME_new_null(); 591*f5b1c8a1SJohn Marino if (ret == NULL) { 592*f5b1c8a1SJohn Marino SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, 593*f5b1c8a1SJohn Marino ERR_R_MALLOC_FAILURE); 594*f5b1c8a1SJohn Marino goto err; 595*f5b1c8a1SJohn Marino } 596*f5b1c8a1SJohn Marino } 597*f5b1c8a1SJohn Marino if ((xn = X509_get_subject_name(x)) == NULL) goto err; 598*f5b1c8a1SJohn Marino /* check for duplicates */ 599*f5b1c8a1SJohn Marino xn = X509_NAME_dup(xn); 600*f5b1c8a1SJohn Marino if (xn == NULL) 601*f5b1c8a1SJohn Marino goto err; 602*f5b1c8a1SJohn Marino if (sk_X509_NAME_find(sk, xn) >= 0) 603*f5b1c8a1SJohn Marino X509_NAME_free(xn); 604*f5b1c8a1SJohn Marino else { 605*f5b1c8a1SJohn Marino sk_X509_NAME_push(sk, xn); 606*f5b1c8a1SJohn Marino sk_X509_NAME_push(ret, xn); 607*f5b1c8a1SJohn Marino } 608*f5b1c8a1SJohn Marino } 609*f5b1c8a1SJohn Marino 610*f5b1c8a1SJohn Marino if (0) { 611*f5b1c8a1SJohn Marino err: 612*f5b1c8a1SJohn Marino if (ret != NULL) 613*f5b1c8a1SJohn Marino sk_X509_NAME_pop_free(ret, X509_NAME_free); 614*f5b1c8a1SJohn Marino ret = NULL; 615*f5b1c8a1SJohn Marino } 616*f5b1c8a1SJohn Marino if (sk != NULL) 617*f5b1c8a1SJohn Marino sk_X509_NAME_free(sk); 618*f5b1c8a1SJohn Marino BIO_free(in); 619*f5b1c8a1SJohn Marino X509_free(x); 620*f5b1c8a1SJohn Marino if (ret != NULL) 621*f5b1c8a1SJohn Marino ERR_clear_error(); 622*f5b1c8a1SJohn Marino return (ret); 623*f5b1c8a1SJohn Marino } 624*f5b1c8a1SJohn Marino 625*f5b1c8a1SJohn Marino /*! 626*f5b1c8a1SJohn Marino * Add a file of certs to a stack. 627*f5b1c8a1SJohn Marino * \param stack the stack to add to. 628*f5b1c8a1SJohn Marino * \param file the file to add from. All certs in this file that are not 629*f5b1c8a1SJohn Marino * already in the stack will be added. 630*f5b1c8a1SJohn Marino * \return 1 for success, 0 for failure. Note that in the case of failure some 631*f5b1c8a1SJohn Marino * certs may have been added to \c stack. 632*f5b1c8a1SJohn Marino */ 633*f5b1c8a1SJohn Marino 634*f5b1c8a1SJohn Marino int 635*f5b1c8a1SJohn Marino SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, 636*f5b1c8a1SJohn Marino const char *file) 637*f5b1c8a1SJohn Marino { 638*f5b1c8a1SJohn Marino BIO *in; 639*f5b1c8a1SJohn Marino X509 *x = NULL; 640*f5b1c8a1SJohn Marino X509_NAME *xn = NULL; 641*f5b1c8a1SJohn Marino int ret = 1; 642*f5b1c8a1SJohn Marino int (*oldcmp)(const X509_NAME * const *a, const X509_NAME * const *b); 643*f5b1c8a1SJohn Marino 644*f5b1c8a1SJohn Marino oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp); 645*f5b1c8a1SJohn Marino 646*f5b1c8a1SJohn Marino in = BIO_new(BIO_s_file_internal()); 647*f5b1c8a1SJohn Marino 648*f5b1c8a1SJohn Marino if (in == NULL) { 649*f5b1c8a1SJohn Marino SSLerr(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK, 650*f5b1c8a1SJohn Marino ERR_R_MALLOC_FAILURE); 651*f5b1c8a1SJohn Marino goto err; 652*f5b1c8a1SJohn Marino } 653*f5b1c8a1SJohn Marino 654*f5b1c8a1SJohn Marino if (!BIO_read_filename(in, file)) 655*f5b1c8a1SJohn Marino goto err; 656*f5b1c8a1SJohn Marino 657*f5b1c8a1SJohn Marino for (;;) { 658*f5b1c8a1SJohn Marino if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) 659*f5b1c8a1SJohn Marino break; 660*f5b1c8a1SJohn Marino if ((xn = X509_get_subject_name(x)) == NULL) goto err; 661*f5b1c8a1SJohn Marino xn = X509_NAME_dup(xn); 662*f5b1c8a1SJohn Marino if (xn == NULL) 663*f5b1c8a1SJohn Marino goto err; 664*f5b1c8a1SJohn Marino if (sk_X509_NAME_find(stack, xn) >= 0) 665*f5b1c8a1SJohn Marino X509_NAME_free(xn); 666*f5b1c8a1SJohn Marino else 667*f5b1c8a1SJohn Marino sk_X509_NAME_push(stack, xn); 668*f5b1c8a1SJohn Marino } 669*f5b1c8a1SJohn Marino 670*f5b1c8a1SJohn Marino ERR_clear_error(); 671*f5b1c8a1SJohn Marino 672*f5b1c8a1SJohn Marino if (0) { 673*f5b1c8a1SJohn Marino err: 674*f5b1c8a1SJohn Marino ret = 0; 675*f5b1c8a1SJohn Marino } 676*f5b1c8a1SJohn Marino BIO_free(in); 677*f5b1c8a1SJohn Marino X509_free(x); 678*f5b1c8a1SJohn Marino 679*f5b1c8a1SJohn Marino (void)sk_X509_NAME_set_cmp_func(stack, oldcmp); 680*f5b1c8a1SJohn Marino 681*f5b1c8a1SJohn Marino return ret; 682*f5b1c8a1SJohn Marino } 683*f5b1c8a1SJohn Marino 684*f5b1c8a1SJohn Marino /*! 685*f5b1c8a1SJohn Marino * Add a directory of certs to a stack. 686*f5b1c8a1SJohn Marino * \param stack the stack to append to. 687*f5b1c8a1SJohn Marino * \param dir the directory to append from. All files in this directory will be 688*f5b1c8a1SJohn Marino * examined as potential certs. Any that are acceptable to 689*f5b1c8a1SJohn Marino * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will 690*f5b1c8a1SJohn Marino * be included. 691*f5b1c8a1SJohn Marino * \return 1 for success, 0 for failure. Note that in the case of failure some 692*f5b1c8a1SJohn Marino * certs may have been added to \c stack. 693*f5b1c8a1SJohn Marino */ 694*f5b1c8a1SJohn Marino 695*f5b1c8a1SJohn Marino int 696*f5b1c8a1SJohn Marino SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, const char *dir) 697*f5b1c8a1SJohn Marino { 698*f5b1c8a1SJohn Marino DIR *dirp = NULL; 699*f5b1c8a1SJohn Marino char *path = NULL; 700*f5b1c8a1SJohn Marino int ret = 0; 701*f5b1c8a1SJohn Marino 702*f5b1c8a1SJohn Marino dirp = opendir(dir); 703*f5b1c8a1SJohn Marino if (dirp) { 704*f5b1c8a1SJohn Marino struct dirent *dp; 705*f5b1c8a1SJohn Marino while ((dp = readdir(dirp)) != NULL) { 706*f5b1c8a1SJohn Marino if (asprintf(&path, "%s/%s", dir, dp->d_name) != -1) { 707*f5b1c8a1SJohn Marino ret = SSL_add_file_cert_subjects_to_stack( 708*f5b1c8a1SJohn Marino stack, path); 709*f5b1c8a1SJohn Marino free(path); 710*f5b1c8a1SJohn Marino } 711*f5b1c8a1SJohn Marino if (!ret) 712*f5b1c8a1SJohn Marino break; 713*f5b1c8a1SJohn Marino } 714*f5b1c8a1SJohn Marino (void) closedir(dirp); 715*f5b1c8a1SJohn Marino } 716*f5b1c8a1SJohn Marino if (!ret) { 717*f5b1c8a1SJohn Marino SYSerr(SYS_F_OPENDIR, errno); 718*f5b1c8a1SJohn Marino ERR_asprintf_error_data("opendir ('%s')", dir); 719*f5b1c8a1SJohn Marino SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB); 720*f5b1c8a1SJohn Marino } 721*f5b1c8a1SJohn Marino return ret; 722*f5b1c8a1SJohn Marino } 723