1280297Sjkim/* 2280297Sjkim * ! \file ssl/ssl_cert.c 3280297Sjkim */ 455714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 555714Skris * All rights reserved. 655714Skris * 755714Skris * This package is an SSL implementation written 855714Skris * by Eric Young (eay@cryptsoft.com). 955714Skris * The implementation was written so as to conform with Netscapes SSL. 10280297Sjkim * 1155714Skris * This library is free for commercial and non-commercial use as long as 1255714Skris * the following conditions are aheared to. The following conditions 1355714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1455714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1555714Skris * included with this distribution is covered by the same copyright terms 1655714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 17280297Sjkim * 1855714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1955714Skris * the code are not to be removed. 2055714Skris * If this package is used in a product, Eric Young should be given attribution 2155714Skris * as the author of the parts of the library used. 2255714Skris * This can be in the form of a textual message at program startup or 2355714Skris * in documentation (online or textual) provided with the package. 24280297Sjkim * 2555714Skris * Redistribution and use in source and binary forms, with or without 2655714Skris * modification, are permitted provided that the following conditions 2755714Skris * are met: 2855714Skris * 1. Redistributions of source code must retain the copyright 2955714Skris * notice, this list of conditions and the following disclaimer. 3055714Skris * 2. Redistributions in binary form must reproduce the above copyright 3155714Skris * notice, this list of conditions and the following disclaimer in the 3255714Skris * documentation and/or other materials provided with the distribution. 3355714Skris * 3. All advertising materials mentioning features or use of this software 3455714Skris * must display the following acknowledgement: 3555714Skris * "This product includes cryptographic software written by 3655714Skris * Eric Young (eay@cryptsoft.com)" 3755714Skris * The word 'cryptographic' can be left out if the rouines from the library 3855714Skris * being used are not cryptographic related :-). 39280297Sjkim * 4. If you include any Windows specific code (or a derivative thereof) from 4055714Skris * the apps directory (application code) you must include an acknowledgement: 4155714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 42280297Sjkim * 4355714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4455714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4555714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4655714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4755714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4855714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4955714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 5055714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 5155714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5255714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5355714Skris * SUCH DAMAGE. 54280297Sjkim * 5555714Skris * The licence and distribution terms for any publically available version or 5655714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5755714Skris * copied and put under another distribution licence 5855714Skris * [including the GNU Public Licence.] 5955714Skris */ 6055714Skris/* ==================================================================== 61238405Sjkim * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. 6255714Skris * 6355714Skris * Redistribution and use in source and binary forms, with or without 6455714Skris * modification, are permitted provided that the following conditions 6555714Skris * are met: 6655714Skris * 6755714Skris * 1. Redistributions of source code must retain the above copyright 68280297Sjkim * notice, this list of conditions and the following disclaimer. 6955714Skris * 7055714Skris * 2. Redistributions in binary form must reproduce the above copyright 7155714Skris * notice, this list of conditions and the following disclaimer in 7255714Skris * the documentation and/or other materials provided with the 7355714Skris * distribution. 7455714Skris * 7555714Skris * 3. All advertising materials mentioning features or use of this 7655714Skris * software must display the following acknowledgment: 7755714Skris * "This product includes software developed by the OpenSSL Project 78162911Ssimon * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 7955714Skris * 8055714Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 8155714Skris * endorse or promote products derived from this software without 8255714Skris * prior written permission. For written permission, please contact 83162911Ssimon * openssl-core@openssl.org. 8455714Skris * 8555714Skris * 5. Products derived from this software may not be called "OpenSSL" 8655714Skris * nor may "OpenSSL" appear in their names without prior written 8755714Skris * permission of the OpenSSL Project. 8855714Skris * 8955714Skris * 6. Redistributions of any form whatsoever must retain the following 9055714Skris * acknowledgment: 9155714Skris * "This product includes software developed by the OpenSSL Project 92162911Ssimon * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 9355714Skris * 9455714Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 9555714Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 9655714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 9755714Skris * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 9855714Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 9955714Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 10055714Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 10155714Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 10255714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 10355714Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 10455714Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 10555714Skris * OF THE POSSIBILITY OF SUCH DAMAGE. 10655714Skris * ==================================================================== 107162911Ssimon * 108162911Ssimon * This product includes cryptographic software written by Eric Young 109162911Ssimon * (eay@cryptsoft.com). This product includes software written by Tim 110162911Ssimon * Hudson (tjh@cryptsoft.com). 111162911Ssimon * 11255714Skris */ 113160814Ssimon/* ==================================================================== 114160814Ssimon * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 115280297Sjkim * ECC cipher suite support in OpenSSL originally developed by 116160814Ssimon * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. 117160814Ssimon */ 11855714Skris 11955714Skris#include <stdio.h> 12059191Skris 121109998Smarkm#include "e_os.h" 12259191Skris#ifndef NO_SYS_TYPES_H 12359191Skris# include <sys/types.h> 12459191Skris#endif 12559191Skris 126160814Ssimon#include "o_dir.h" 12755714Skris#include <openssl/objects.h> 12855714Skris#include <openssl/bio.h> 12955714Skris#include <openssl/pem.h> 13059191Skris#include <openssl/x509v3.h> 131160814Ssimon#ifndef OPENSSL_NO_DH 132280297Sjkim# include <openssl/dh.h> 133160814Ssimon#endif 134160814Ssimon#include <openssl/bn.h> 13555714Skris#include "ssl_locl.h" 13655714Skris 13755714Skrisint SSL_get_ex_data_X509_STORE_CTX_idx(void) 138280297Sjkim{ 139280297Sjkim static volatile int ssl_x509_store_ctx_idx = -1; 140280297Sjkim int got_write_lock = 0; 14155714Skris 142290207Sjkim if (((size_t)&ssl_x509_store_ctx_idx & 143290207Sjkim (sizeof(ssl_x509_store_ctx_idx) - 1)) 144290207Sjkim == 0) { /* check alignment, practically always true */ 145290207Sjkim int ret; 146162911Ssimon 147290207Sjkim if ((ret = ssl_x509_store_ctx_idx) < 0) { 148290207Sjkim CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 149290207Sjkim if ((ret = ssl_x509_store_ctx_idx) < 0) { 150290207Sjkim ret = ssl_x509_store_ctx_idx = 151290207Sjkim X509_STORE_CTX_get_ex_new_index(0, 152290207Sjkim "SSL for verify callback", 153290207Sjkim NULL, NULL, NULL); 154290207Sjkim } 155290207Sjkim CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); 156290207Sjkim } 157162911Ssimon 158290207Sjkim return ret; 159290207Sjkim } else { /* commonly eliminated */ 160290207Sjkim 161290207Sjkim CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); 162290207Sjkim 163280297Sjkim if (ssl_x509_store_ctx_idx < 0) { 164290207Sjkim CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); 165290207Sjkim CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 166290207Sjkim got_write_lock = 1; 167290207Sjkim 168290207Sjkim if (ssl_x509_store_ctx_idx < 0) { 169290207Sjkim ssl_x509_store_ctx_idx = 170290207Sjkim X509_STORE_CTX_get_ex_new_index(0, 171290207Sjkim "SSL for verify callback", 172290207Sjkim NULL, NULL, NULL); 173290207Sjkim } 174280297Sjkim } 17555714Skris 176290207Sjkim if (got_write_lock) 177290207Sjkim CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); 178290207Sjkim else 179290207Sjkim CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); 180280297Sjkim 181290207Sjkim return ssl_x509_store_ctx_idx; 182290207Sjkim } 183280297Sjkim} 184280297Sjkim 185290207Sjkimvoid ssl_cert_set_default_md(CERT *cert) 186280297Sjkim{ 187280297Sjkim /* Set digest values to defaults */ 188238405Sjkim#ifndef OPENSSL_NO_DSA 189280297Sjkim cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1(); 190238405Sjkim#endif 191238405Sjkim#ifndef OPENSSL_NO_RSA 192280297Sjkim cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); 193280297Sjkim cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); 194238405Sjkim#endif 195238405Sjkim#ifndef OPENSSL_NO_ECDSA 196280297Sjkim cert->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); 197238405Sjkim#endif 198280297Sjkim} 199238405Sjkim 20055714SkrisCERT *ssl_cert_new(void) 201280297Sjkim{ 202280297Sjkim CERT *ret; 20355714Skris 204280297Sjkim ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); 205280297Sjkim if (ret == NULL) { 206280297Sjkim SSLerr(SSL_F_SSL_CERT_NEW, ERR_R_MALLOC_FAILURE); 207280297Sjkim return (NULL); 208280297Sjkim } 209280297Sjkim memset(ret, 0, sizeof(CERT)); 21055714Skris 211280297Sjkim ret->key = &(ret->pkeys[SSL_PKEY_RSA_ENC]); 212280297Sjkim ret->references = 1; 213280297Sjkim ssl_cert_set_default_md(ret); 214280297Sjkim return (ret); 215280297Sjkim} 21655714Skris 21755714SkrisCERT *ssl_cert_dup(CERT *cert) 218280297Sjkim{ 219280297Sjkim CERT *ret; 220280297Sjkim int i; 22155714Skris 222280297Sjkim ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); 223280297Sjkim if (ret == NULL) { 224280297Sjkim SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); 225280297Sjkim return (NULL); 226280297Sjkim } 22755714Skris 228280297Sjkim memset(ret, 0, sizeof(CERT)); 22955714Skris 230291719Sjkim ret->references = 1; 231280297Sjkim ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]]; 232280297Sjkim /* 233280297Sjkim * or ret->key = ret->pkeys + (cert->key - cert->pkeys), if you find that 234280297Sjkim * more readable 235280297Sjkim */ 23655714Skris 237280297Sjkim ret->valid = cert->valid; 238280297Sjkim ret->mask_k = cert->mask_k; 239280297Sjkim ret->mask_a = cert->mask_a; 240280297Sjkim ret->export_mask_k = cert->export_mask_k; 241280297Sjkim ret->export_mask_a = cert->export_mask_a; 24255714Skris 243109998Smarkm#ifndef OPENSSL_NO_RSA 244280297Sjkim if (cert->rsa_tmp != NULL) { 245280297Sjkim RSA_up_ref(cert->rsa_tmp); 246280297Sjkim ret->rsa_tmp = cert->rsa_tmp; 247280297Sjkim } 248280297Sjkim ret->rsa_tmp_cb = cert->rsa_tmp_cb; 24955714Skris#endif 25055714Skris 251109998Smarkm#ifndef OPENSSL_NO_DH 252280297Sjkim if (cert->dh_tmp != NULL) { 253280297Sjkim ret->dh_tmp = DHparams_dup(cert->dh_tmp); 254280297Sjkim if (ret->dh_tmp == NULL) { 255280297Sjkim SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_DH_LIB); 256280297Sjkim goto err; 257280297Sjkim } 258280297Sjkim if (cert->dh_tmp->priv_key) { 259280297Sjkim BIGNUM *b = BN_dup(cert->dh_tmp->priv_key); 260280297Sjkim if (!b) { 261280297Sjkim SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); 262280297Sjkim goto err; 263280297Sjkim } 264280297Sjkim ret->dh_tmp->priv_key = b; 265280297Sjkim } 266280297Sjkim if (cert->dh_tmp->pub_key) { 267280297Sjkim BIGNUM *b = BN_dup(cert->dh_tmp->pub_key); 268280297Sjkim if (!b) { 269280297Sjkim SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); 270280297Sjkim goto err; 271280297Sjkim } 272280297Sjkim ret->dh_tmp->pub_key = b; 273280297Sjkim } 274280297Sjkim } 275280297Sjkim ret->dh_tmp_cb = cert->dh_tmp_cb; 27655714Skris#endif 27755714Skris 278160814Ssimon#ifndef OPENSSL_NO_ECDH 279280297Sjkim if (cert->ecdh_tmp) { 280280297Sjkim ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp); 281280297Sjkim if (ret->ecdh_tmp == NULL) { 282280297Sjkim SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_EC_LIB); 283280297Sjkim goto err; 284280297Sjkim } 285280297Sjkim } 286280297Sjkim ret->ecdh_tmp_cb = cert->ecdh_tmp_cb; 287290207Sjkim ret->ecdh_tmp_auto = cert->ecdh_tmp_auto; 288160814Ssimon#endif 289160814Ssimon 290280297Sjkim for (i = 0; i < SSL_PKEY_NUM; i++) { 291290207Sjkim CERT_PKEY *cpk = cert->pkeys + i; 292290207Sjkim CERT_PKEY *rpk = ret->pkeys + i; 293290207Sjkim if (cpk->x509 != NULL) { 294290207Sjkim rpk->x509 = cpk->x509; 295290207Sjkim CRYPTO_add(&rpk->x509->references, 1, CRYPTO_LOCK_X509); 296280297Sjkim } 29755714Skris 298290207Sjkim if (cpk->privatekey != NULL) { 299290207Sjkim rpk->privatekey = cpk->privatekey; 300290207Sjkim CRYPTO_add(&cpk->privatekey->references, 1, CRYPTO_LOCK_EVP_PKEY); 301280297Sjkim } 302290207Sjkim 303290207Sjkim if (cpk->chain) { 304290207Sjkim rpk->chain = X509_chain_up_ref(cpk->chain); 305290207Sjkim if (!rpk->chain) { 306290207Sjkim SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); 307290207Sjkim goto err; 308290207Sjkim } 309290207Sjkim } 310290207Sjkim rpk->valid_flags = 0; 311290207Sjkim#ifndef OPENSSL_NO_TLSEXT 312290207Sjkim if (cert->pkeys[i].serverinfo != NULL) { 313290207Sjkim /* Just copy everything. */ 314290207Sjkim ret->pkeys[i].serverinfo = 315290207Sjkim OPENSSL_malloc(cert->pkeys[i].serverinfo_length); 316290207Sjkim if (ret->pkeys[i].serverinfo == NULL) { 317290207Sjkim SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); 318312826Sjkim goto err; 319290207Sjkim } 320290207Sjkim ret->pkeys[i].serverinfo_length = 321290207Sjkim cert->pkeys[i].serverinfo_length; 322290207Sjkim memcpy(ret->pkeys[i].serverinfo, 323290207Sjkim cert->pkeys[i].serverinfo, 324290207Sjkim cert->pkeys[i].serverinfo_length); 325290207Sjkim } 326290207Sjkim#endif 327280297Sjkim } 32855714Skris 329280297Sjkim /* 330280297Sjkim * Set digests to defaults. NB: we don't copy existing values as they 331280297Sjkim * will be set during handshake. 332280297Sjkim */ 333280297Sjkim ssl_cert_set_default_md(ret); 334290207Sjkim /* Peer sigalgs set to NULL as we get these from handshake too */ 335290207Sjkim ret->peer_sigalgs = NULL; 336290207Sjkim ret->peer_sigalgslen = 0; 337290207Sjkim /* Configured sigalgs however we copy across */ 338280297Sjkim 339290207Sjkim if (cert->conf_sigalgs) { 340290207Sjkim ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen); 341290207Sjkim if (!ret->conf_sigalgs) 342290207Sjkim goto err; 343290207Sjkim memcpy(ret->conf_sigalgs, cert->conf_sigalgs, cert->conf_sigalgslen); 344290207Sjkim ret->conf_sigalgslen = cert->conf_sigalgslen; 345290207Sjkim } else 346290207Sjkim ret->conf_sigalgs = NULL; 347290207Sjkim 348290207Sjkim if (cert->client_sigalgs) { 349290207Sjkim ret->client_sigalgs = OPENSSL_malloc(cert->client_sigalgslen); 350290207Sjkim if (!ret->client_sigalgs) 351290207Sjkim goto err; 352290207Sjkim memcpy(ret->client_sigalgs, cert->client_sigalgs, 353290207Sjkim cert->client_sigalgslen); 354290207Sjkim ret->client_sigalgslen = cert->client_sigalgslen; 355290207Sjkim } else 356290207Sjkim ret->client_sigalgs = NULL; 357290207Sjkim /* Shared sigalgs also NULL */ 358290207Sjkim ret->shared_sigalgs = NULL; 359290207Sjkim /* Copy any custom client certificate types */ 360290207Sjkim if (cert->ctypes) { 361290207Sjkim ret->ctypes = OPENSSL_malloc(cert->ctype_num); 362290207Sjkim if (!ret->ctypes) 363290207Sjkim goto err; 364290207Sjkim memcpy(ret->ctypes, cert->ctypes, cert->ctype_num); 365290207Sjkim ret->ctype_num = cert->ctype_num; 366290207Sjkim } 367290207Sjkim 368290207Sjkim ret->cert_flags = cert->cert_flags; 369290207Sjkim 370290207Sjkim ret->cert_cb = cert->cert_cb; 371290207Sjkim ret->cert_cb_arg = cert->cert_cb_arg; 372290207Sjkim 373290207Sjkim if (cert->verify_store) { 374290207Sjkim CRYPTO_add(&cert->verify_store->references, 1, 375290207Sjkim CRYPTO_LOCK_X509_STORE); 376290207Sjkim ret->verify_store = cert->verify_store; 377290207Sjkim } 378290207Sjkim 379290207Sjkim if (cert->chain_store) { 380290207Sjkim CRYPTO_add(&cert->chain_store->references, 1, CRYPTO_LOCK_X509_STORE); 381290207Sjkim ret->chain_store = cert->chain_store; 382290207Sjkim } 383290207Sjkim 384290207Sjkim ret->ciphers_raw = NULL; 385290207Sjkim 386290207Sjkim#ifndef OPENSSL_NO_TLSEXT 387290207Sjkim if (!custom_exts_copy(&ret->cli_ext, &cert->cli_ext)) 388290207Sjkim goto err; 389290207Sjkim if (!custom_exts_copy(&ret->srv_ext, &cert->srv_ext)) 390290207Sjkim goto err; 391290207Sjkim#endif 392290207Sjkim 393280297Sjkim return (ret); 394280297Sjkim 395280297Sjkim err: 396109998Smarkm#ifndef OPENSSL_NO_RSA 397280297Sjkim if (ret->rsa_tmp != NULL) 398280297Sjkim RSA_free(ret->rsa_tmp); 39955714Skris#endif 400109998Smarkm#ifndef OPENSSL_NO_DH 401280297Sjkim if (ret->dh_tmp != NULL) 402280297Sjkim DH_free(ret->dh_tmp); 40355714Skris#endif 404160814Ssimon#ifndef OPENSSL_NO_ECDH 405280297Sjkim if (ret->ecdh_tmp != NULL) 406280297Sjkim EC_KEY_free(ret->ecdh_tmp); 407160814Ssimon#endif 40855714Skris 409290207Sjkim#ifndef OPENSSL_NO_TLSEXT 410290207Sjkim custom_exts_free(&ret->cli_ext); 411290207Sjkim custom_exts_free(&ret->srv_ext); 412290207Sjkim#endif 41355714Skris 414290207Sjkim ssl_cert_clear_certs(ret); 415325335Sjkim OPENSSL_free(ret); 416290207Sjkim 417280297Sjkim return NULL; 418280297Sjkim} 41955714Skris 420290207Sjkim/* Free up and clear all certificates and chains */ 421290207Sjkim 422290207Sjkimvoid ssl_cert_clear_certs(CERT *c) 423290207Sjkim{ 424290207Sjkim int i; 425290207Sjkim if (c == NULL) 426290207Sjkim return; 427290207Sjkim for (i = 0; i < SSL_PKEY_NUM; i++) { 428290207Sjkim CERT_PKEY *cpk = c->pkeys + i; 429290207Sjkim if (cpk->x509) { 430290207Sjkim X509_free(cpk->x509); 431290207Sjkim cpk->x509 = NULL; 432290207Sjkim } 433290207Sjkim if (cpk->privatekey) { 434290207Sjkim EVP_PKEY_free(cpk->privatekey); 435290207Sjkim cpk->privatekey = NULL; 436290207Sjkim } 437290207Sjkim if (cpk->chain) { 438290207Sjkim sk_X509_pop_free(cpk->chain, X509_free); 439290207Sjkim cpk->chain = NULL; 440290207Sjkim } 441290207Sjkim#ifndef OPENSSL_NO_TLSEXT 442290207Sjkim if (cpk->serverinfo) { 443290207Sjkim OPENSSL_free(cpk->serverinfo); 444290207Sjkim cpk->serverinfo = NULL; 445290207Sjkim cpk->serverinfo_length = 0; 446290207Sjkim } 447290207Sjkim#endif 448290207Sjkim /* Clear all flags apart from explicit sign */ 449290207Sjkim cpk->valid_flags &= CERT_PKEY_EXPLICIT_SIGN; 450290207Sjkim } 451290207Sjkim} 452290207Sjkim 45355714Skrisvoid ssl_cert_free(CERT *c) 454280297Sjkim{ 455280297Sjkim int i; 45655714Skris 457280297Sjkim if (c == NULL) 458280297Sjkim return; 45955714Skris 460280297Sjkim i = CRYPTO_add(&c->references, -1, CRYPTO_LOCK_SSL_CERT); 46155714Skris#ifdef REF_PRINT 462280297Sjkim REF_PRINT("CERT", c); 46355714Skris#endif 464280297Sjkim if (i > 0) 465280297Sjkim return; 46655714Skris#ifdef REF_CHECK 467280297Sjkim if (i < 0) { 468280297Sjkim fprintf(stderr, "ssl_cert_free, bad reference count\n"); 469280297Sjkim abort(); /* ok */ 470280297Sjkim } 47155714Skris#endif 47255714Skris 473109998Smarkm#ifndef OPENSSL_NO_RSA 474280297Sjkim if (c->rsa_tmp) 475280297Sjkim RSA_free(c->rsa_tmp); 47655714Skris#endif 477109998Smarkm#ifndef OPENSSL_NO_DH 478280297Sjkim if (c->dh_tmp) 479280297Sjkim DH_free(c->dh_tmp); 48055714Skris#endif 481160814Ssimon#ifndef OPENSSL_NO_ECDH 482280297Sjkim if (c->ecdh_tmp) 483280297Sjkim EC_KEY_free(c->ecdh_tmp); 484160814Ssimon#endif 48555714Skris 486290207Sjkim ssl_cert_clear_certs(c); 487290207Sjkim if (c->peer_sigalgs) 488290207Sjkim OPENSSL_free(c->peer_sigalgs); 489290207Sjkim if (c->conf_sigalgs) 490290207Sjkim OPENSSL_free(c->conf_sigalgs); 491290207Sjkim if (c->client_sigalgs) 492290207Sjkim OPENSSL_free(c->client_sigalgs); 493290207Sjkim if (c->shared_sigalgs) 494290207Sjkim OPENSSL_free(c->shared_sigalgs); 495290207Sjkim if (c->ctypes) 496290207Sjkim OPENSSL_free(c->ctypes); 497290207Sjkim if (c->verify_store) 498290207Sjkim X509_STORE_free(c->verify_store); 499290207Sjkim if (c->chain_store) 500290207Sjkim X509_STORE_free(c->chain_store); 501290207Sjkim if (c->ciphers_raw) 502290207Sjkim OPENSSL_free(c->ciphers_raw); 503290207Sjkim#ifndef OPENSSL_NO_TLSEXT 504290207Sjkim custom_exts_free(&c->cli_ext); 505290207Sjkim custom_exts_free(&c->srv_ext); 506298998Sjkim if (c->alpn_proposed) 507298998Sjkim OPENSSL_free(c->alpn_proposed); 50855714Skris#endif 509280297Sjkim OPENSSL_free(c); 510280297Sjkim} 51155714Skris 51255714Skrisint ssl_cert_inst(CERT **o) 513280297Sjkim{ 514280297Sjkim /* 515280297Sjkim * Create a CERT if there isn't already one (which cannot really happen, 516280297Sjkim * as it is initially created in SSL_CTX_new; but the earlier code 517280297Sjkim * usually allows for that one being non-existant, so we follow that 518280297Sjkim * behaviour, as it might turn out that there actually is a reason for it 519280297Sjkim * -- but I'm not sure that *all* of the existing code could cope with 520280297Sjkim * s->cert being NULL, otherwise we could do without the initialization 521280297Sjkim * in SSL_CTX_new). 522280297Sjkim */ 52355714Skris 524280297Sjkim if (o == NULL) { 525280297Sjkim SSLerr(SSL_F_SSL_CERT_INST, ERR_R_PASSED_NULL_PARAMETER); 526280297Sjkim return (0); 527280297Sjkim } 528280297Sjkim if (*o == NULL) { 529280297Sjkim if ((*o = ssl_cert_new()) == NULL) { 530280297Sjkim SSLerr(SSL_F_SSL_CERT_INST, ERR_R_MALLOC_FAILURE); 531280297Sjkim return (0); 532280297Sjkim } 533280297Sjkim } 534280297Sjkim return (1); 535280297Sjkim} 53655714Skris 537290207Sjkimint ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain) 538290207Sjkim{ 539290207Sjkim CERT_PKEY *cpk = c->key; 540290207Sjkim if (!cpk) 541290207Sjkim return 0; 542290207Sjkim if (cpk->chain) 543290207Sjkim sk_X509_pop_free(cpk->chain, X509_free); 544290207Sjkim cpk->chain = chain; 545290207Sjkim return 1; 546290207Sjkim} 547290207Sjkim 548290207Sjkimint ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain) 549290207Sjkim{ 550290207Sjkim STACK_OF(X509) *dchain; 551290207Sjkim if (!chain) 552290207Sjkim return ssl_cert_set0_chain(c, NULL); 553290207Sjkim dchain = X509_chain_up_ref(chain); 554290207Sjkim if (!dchain) 555290207Sjkim return 0; 556290207Sjkim if (!ssl_cert_set0_chain(c, dchain)) { 557290207Sjkim sk_X509_pop_free(dchain, X509_free); 558290207Sjkim return 0; 559290207Sjkim } 560290207Sjkim return 1; 561290207Sjkim} 562290207Sjkim 563290207Sjkimint ssl_cert_add0_chain_cert(CERT *c, X509 *x) 564290207Sjkim{ 565290207Sjkim CERT_PKEY *cpk = c->key; 566290207Sjkim if (!cpk) 567290207Sjkim return 0; 568290207Sjkim if (!cpk->chain) 569290207Sjkim cpk->chain = sk_X509_new_null(); 570290207Sjkim if (!cpk->chain || !sk_X509_push(cpk->chain, x)) 571290207Sjkim return 0; 572290207Sjkim return 1; 573290207Sjkim} 574290207Sjkim 575290207Sjkimint ssl_cert_add1_chain_cert(CERT *c, X509 *x) 576290207Sjkim{ 577290207Sjkim if (!ssl_cert_add0_chain_cert(c, x)) 578290207Sjkim return 0; 579290207Sjkim CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); 580290207Sjkim return 1; 581290207Sjkim} 582290207Sjkim 583290207Sjkimint ssl_cert_select_current(CERT *c, X509 *x) 584290207Sjkim{ 585290207Sjkim int i; 586290207Sjkim if (x == NULL) 587290207Sjkim return 0; 588290207Sjkim for (i = 0; i < SSL_PKEY_NUM; i++) { 589290207Sjkim CERT_PKEY *cpk = c->pkeys + i; 590290207Sjkim if (cpk->x509 == x && cpk->privatekey) { 591290207Sjkim c->key = cpk; 592290207Sjkim return 1; 593290207Sjkim } 594290207Sjkim } 595290207Sjkim 596290207Sjkim for (i = 0; i < SSL_PKEY_NUM; i++) { 597290207Sjkim CERT_PKEY *cpk = c->pkeys + i; 598290207Sjkim if (cpk->privatekey && cpk->x509 && !X509_cmp(cpk->x509, x)) { 599290207Sjkim c->key = cpk; 600290207Sjkim return 1; 601290207Sjkim } 602290207Sjkim } 603290207Sjkim return 0; 604290207Sjkim} 605290207Sjkim 606290207Sjkimint ssl_cert_set_current(CERT *c, long op) 607290207Sjkim{ 608290207Sjkim int i, idx; 609290207Sjkim if (!c) 610290207Sjkim return 0; 611290207Sjkim if (op == SSL_CERT_SET_FIRST) 612290207Sjkim idx = 0; 613290207Sjkim else if (op == SSL_CERT_SET_NEXT) { 614290207Sjkim idx = (int)(c->key - c->pkeys + 1); 615290207Sjkim if (idx >= SSL_PKEY_NUM) 616290207Sjkim return 0; 617290207Sjkim } else 618290207Sjkim return 0; 619290207Sjkim for (i = idx; i < SSL_PKEY_NUM; i++) { 620290207Sjkim CERT_PKEY *cpk = c->pkeys + i; 621290207Sjkim if (cpk->x509 && cpk->privatekey) { 622290207Sjkim c->key = cpk; 623290207Sjkim return 1; 624290207Sjkim } 625290207Sjkim } 626290207Sjkim return 0; 627290207Sjkim} 628290207Sjkim 629290207Sjkimvoid ssl_cert_set_cert_cb(CERT *c, int (*cb) (SSL *ssl, void *arg), void *arg) 630290207Sjkim{ 631290207Sjkim c->cert_cb = cb; 632290207Sjkim c->cert_cb_arg = arg; 633290207Sjkim} 634290207Sjkim 63555714SkrisSESS_CERT *ssl_sess_cert_new(void) 636280297Sjkim{ 637280297Sjkim SESS_CERT *ret; 63855714Skris 639331638Sjkim ret = OPENSSL_malloc(sizeof(*ret)); 640280297Sjkim if (ret == NULL) { 641280297Sjkim SSLerr(SSL_F_SSL_SESS_CERT_NEW, ERR_R_MALLOC_FAILURE); 642280297Sjkim return NULL; 643280297Sjkim } 64455714Skris 645331638Sjkim memset(ret, 0, sizeof(*ret)); 646280297Sjkim ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA_ENC]); 647280297Sjkim ret->references = 1; 64855714Skris 649280297Sjkim return ret; 650280297Sjkim} 65155714Skris 65255714Skrisvoid ssl_sess_cert_free(SESS_CERT *sc) 653280297Sjkim{ 654280297Sjkim int i; 65555714Skris 656280297Sjkim if (sc == NULL) 657280297Sjkim return; 65855714Skris 659280297Sjkim i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT); 66055714Skris#ifdef REF_PRINT 661280297Sjkim REF_PRINT("SESS_CERT", sc); 66255714Skris#endif 663280297Sjkim if (i > 0) 664280297Sjkim return; 66555714Skris#ifdef REF_CHECK 666280297Sjkim if (i < 0) { 667280297Sjkim fprintf(stderr, "ssl_sess_cert_free, bad reference count\n"); 668280297Sjkim abort(); /* ok */ 669280297Sjkim } 67055714Skris#endif 67155714Skris 672280297Sjkim /* i == 0 */ 673280297Sjkim if (sc->cert_chain != NULL) 674280297Sjkim sk_X509_pop_free(sc->cert_chain, X509_free); 675280297Sjkim for (i = 0; i < SSL_PKEY_NUM; i++) { 676280297Sjkim if (sc->peer_pkeys[i].x509 != NULL) 677280297Sjkim X509_free(sc->peer_pkeys[i].x509); 678280297Sjkim#if 0 /* We don't have the peer's private key. 679280297Sjkim * These lines are just * here as a reminder 680280297Sjkim * that we're still using a 681280297Sjkim * not-quite-appropriate * data structure. */ 682280297Sjkim if (sc->peer_pkeys[i].privatekey != NULL) 683280297Sjkim EVP_PKEY_free(sc->peer_pkeys[i].privatekey); 68455714Skris#endif 685280297Sjkim } 68655714Skris 687109998Smarkm#ifndef OPENSSL_NO_RSA 688280297Sjkim if (sc->peer_rsa_tmp != NULL) 689280297Sjkim RSA_free(sc->peer_rsa_tmp); 69055714Skris#endif 691109998Smarkm#ifndef OPENSSL_NO_DH 692280297Sjkim if (sc->peer_dh_tmp != NULL) 693280297Sjkim DH_free(sc->peer_dh_tmp); 69455714Skris#endif 695160814Ssimon#ifndef OPENSSL_NO_ECDH 696280297Sjkim if (sc->peer_ecdh_tmp != NULL) 697280297Sjkim EC_KEY_free(sc->peer_ecdh_tmp); 698160814Ssimon#endif 69955714Skris 700280297Sjkim OPENSSL_free(sc); 701280297Sjkim} 70255714Skris 703280297Sjkimint ssl_set_peer_cert_type(SESS_CERT *sc, int type) 704280297Sjkim{ 705280297Sjkim sc->peer_cert_type = type; 706280297Sjkim return (1); 707280297Sjkim} 70855714Skris 709280297Sjkimint ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) 710280297Sjkim{ 711280297Sjkim X509 *x; 712280297Sjkim int i; 713290207Sjkim X509_STORE *verify_store; 714280297Sjkim X509_STORE_CTX ctx; 71555714Skris 716290207Sjkim if (s->cert->verify_store) 717290207Sjkim verify_store = s->cert->verify_store; 718290207Sjkim else 719290207Sjkim verify_store = s->ctx->cert_store; 720290207Sjkim 721280297Sjkim if ((sk == NULL) || (sk_X509_num(sk) == 0)) 722280297Sjkim return (0); 72355714Skris 724280297Sjkim x = sk_X509_value(sk, 0); 725290207Sjkim if (!X509_STORE_CTX_init(&ctx, verify_store, x, sk)) { 726280297Sjkim SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_X509_LIB); 727280297Sjkim return (0); 728280297Sjkim } 729290207Sjkim /* Set suite B flags if needed */ 730290207Sjkim X509_STORE_CTX_set_flags(&ctx, tls1_suiteb(s)); 731160814Ssimon#if 0 732280297Sjkim if (SSL_get_verify_depth(s) >= 0) 733280297Sjkim X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s)); 734160814Ssimon#endif 735280297Sjkim X509_STORE_CTX_set_ex_data(&ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s); 736109998Smarkm 737280297Sjkim /* 738280297Sjkim * We need to inherit the verify parameters. These can be determined by 739280297Sjkim * the context: if its a server it will verify SSL client certificates or 740280297Sjkim * vice versa. 741280297Sjkim */ 74255714Skris 743280297Sjkim X509_STORE_CTX_set_default(&ctx, s->server ? "ssl_client" : "ssl_server"); 744280297Sjkim /* 745280297Sjkim * Anything non-default in "param" should overwrite anything in the ctx. 746280297Sjkim */ 747280297Sjkim X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param); 74859191Skris 749280297Sjkim if (s->verify_callback) 750280297Sjkim X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback); 75189837Skris 752280297Sjkim if (s->ctx->app_verify_callback != NULL) 753280297Sjkim#if 1 /* new with OpenSSL 0.9.7 */ 754280297Sjkim i = s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg); 755109998Smarkm#else 756280297Sjkim i = s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */ 757109998Smarkm#endif 758280297Sjkim else { 759109998Smarkm#ifndef OPENSSL_NO_X509_VERIFY 760280297Sjkim i = X509_verify_cert(&ctx); 76155714Skris#else 762280297Sjkim i = 0; 763280297Sjkim ctx.error = X509_V_ERR_APPLICATION_VERIFICATION; 764280297Sjkim SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, SSL_R_NO_VERIFY_CALLBACK); 76555714Skris#endif 766280297Sjkim } 76755714Skris 768280297Sjkim s->verify_result = ctx.error; 769280297Sjkim X509_STORE_CTX_cleanup(&ctx); 77055714Skris 771280297Sjkim return (i); 772280297Sjkim} 77355714Skris 774280297Sjkimstatic void set_client_CA_list(STACK_OF(X509_NAME) **ca_list, 775280297Sjkim STACK_OF(X509_NAME) *name_list) 776280297Sjkim{ 777280297Sjkim if (*ca_list != NULL) 778280297Sjkim sk_X509_NAME_pop_free(*ca_list, X509_NAME_free); 77955714Skris 780280297Sjkim *ca_list = name_list; 781280297Sjkim} 78255714Skris 78355714SkrisSTACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk) 784280297Sjkim{ 785280297Sjkim int i; 786280297Sjkim STACK_OF(X509_NAME) *ret; 787280297Sjkim X509_NAME *name; 78855714Skris 789280297Sjkim ret = sk_X509_NAME_new_null(); 790280297Sjkim for (i = 0; i < sk_X509_NAME_num(sk); i++) { 791280297Sjkim name = X509_NAME_dup(sk_X509_NAME_value(sk, i)); 792280297Sjkim if ((name == NULL) || !sk_X509_NAME_push(ret, name)) { 793280297Sjkim sk_X509_NAME_pop_free(ret, X509_NAME_free); 794280297Sjkim return (NULL); 795280297Sjkim } 796280297Sjkim } 797280297Sjkim return (ret); 798280297Sjkim} 79955714Skris 800280297Sjkimvoid SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list) 801280297Sjkim{ 802280297Sjkim set_client_CA_list(&(s->client_CA), name_list); 803280297Sjkim} 80455714Skris 805280297Sjkimvoid SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) 806280297Sjkim{ 807280297Sjkim set_client_CA_list(&(ctx->client_CA), name_list); 808280297Sjkim} 80955714Skris 810160814SsimonSTACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) 811280297Sjkim{ 812280297Sjkim return (ctx->client_CA); 813280297Sjkim} 81455714Skris 815160814SsimonSTACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s) 816280297Sjkim{ 817280297Sjkim if (s->type == SSL_ST_CONNECT) { /* we are in the client */ 818280297Sjkim if (((s->version >> 8) == SSL3_VERSION_MAJOR) && (s->s3 != NULL)) 819280297Sjkim return (s->s3->tmp.ca_names); 820280297Sjkim else 821280297Sjkim return (NULL); 822280297Sjkim } else { 823280297Sjkim if (s->client_CA != NULL) 824280297Sjkim return (s->client_CA); 825280297Sjkim else 826280297Sjkim return (s->ctx->client_CA); 827280297Sjkim } 828280297Sjkim} 82955714Skris 830280297Sjkimstatic int add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x) 831280297Sjkim{ 832280297Sjkim X509_NAME *name; 83355714Skris 834280297Sjkim if (x == NULL) 835280297Sjkim return (0); 836280297Sjkim if ((*sk == NULL) && ((*sk = sk_X509_NAME_new_null()) == NULL)) 837280297Sjkim return (0); 83855714Skris 839280297Sjkim if ((name = X509_NAME_dup(X509_get_subject_name(x))) == NULL) 840280297Sjkim return (0); 84155714Skris 842280297Sjkim if (!sk_X509_NAME_push(*sk, name)) { 843280297Sjkim X509_NAME_free(name); 844280297Sjkim return (0); 845280297Sjkim } 846280297Sjkim return (1); 847280297Sjkim} 84855714Skris 849280297Sjkimint SSL_add_client_CA(SSL *ssl, X509 *x) 850280297Sjkim{ 851280297Sjkim return (add_client_CA(&(ssl->client_CA), x)); 852280297Sjkim} 85355714Skris 854280297Sjkimint SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) 855280297Sjkim{ 856280297Sjkim return (add_client_CA(&(ctx->client_CA), x)); 857280297Sjkim} 85855714Skris 859280297Sjkimstatic int xname_cmp(const X509_NAME *const *a, const X509_NAME *const *b) 860280297Sjkim{ 861280297Sjkim return (X509_NAME_cmp(*a, *b)); 862280297Sjkim} 863280297Sjkim 864109998Smarkm#ifndef OPENSSL_NO_STDIO 865280297Sjkim/** 86655714Skris * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed; 86755714Skris * it doesn't really have anything to do with clients (except that a common use 86855714Skris * for a stack of CAs is to send it to the client). Actually, it doesn't have 86955714Skris * much to do with CAs, either, since it will load any old cert. 87055714Skris * \param file the file containing one or more certs. 87155714Skris * \return a ::STACK containing the certs. 87255714Skris */ 87355714SkrisSTACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) 874280297Sjkim{ 875280297Sjkim BIO *in; 876280297Sjkim X509 *x = NULL; 877280297Sjkim X509_NAME *xn = NULL; 878280297Sjkim STACK_OF(X509_NAME) *ret = NULL, *sk; 87955714Skris 880280297Sjkim sk = sk_X509_NAME_new(xname_cmp); 88155714Skris 882280297Sjkim in = BIO_new(BIO_s_file_internal()); 88355714Skris 884280297Sjkim if ((sk == NULL) || (in == NULL)) { 885280297Sjkim SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE); 886280297Sjkim goto err; 887280297Sjkim } 88855714Skris 889280297Sjkim if (!BIO_read_filename(in, file)) 890280297Sjkim goto err; 89155714Skris 892280297Sjkim for (;;) { 893280297Sjkim if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) 894280297Sjkim break; 895280297Sjkim if (ret == NULL) { 896280297Sjkim ret = sk_X509_NAME_new_null(); 897280297Sjkim if (ret == NULL) { 898280297Sjkim SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE); 899280297Sjkim goto err; 900280297Sjkim } 901280297Sjkim } 902280297Sjkim if ((xn = X509_get_subject_name(x)) == NULL) 903280297Sjkim goto err; 904280297Sjkim /* check for duplicates */ 905280297Sjkim xn = X509_NAME_dup(xn); 906280297Sjkim if (xn == NULL) 907280297Sjkim goto err; 908280297Sjkim if (sk_X509_NAME_find(sk, xn) >= 0) 909280297Sjkim X509_NAME_free(xn); 910280297Sjkim else { 911280297Sjkim sk_X509_NAME_push(sk, xn); 912280297Sjkim sk_X509_NAME_push(ret, xn); 913280297Sjkim } 914280297Sjkim } 915280297Sjkim 916280297Sjkim if (0) { 917280297Sjkim err: 918280297Sjkim if (ret != NULL) 919280297Sjkim sk_X509_NAME_pop_free(ret, X509_NAME_free); 920280297Sjkim ret = NULL; 921280297Sjkim } 922280297Sjkim if (sk != NULL) 923280297Sjkim sk_X509_NAME_free(sk); 924280297Sjkim if (in != NULL) 925280297Sjkim BIO_free(in); 926280297Sjkim if (x != NULL) 927280297Sjkim X509_free(x); 928280297Sjkim if (ret != NULL) 929280297Sjkim ERR_clear_error(); 930280297Sjkim return (ret); 931280297Sjkim} 93255714Skris#endif 93355714Skris 934280297Sjkim/** 93555714Skris * Add a file of certs to a stack. 93655714Skris * \param stack the stack to add to. 93755714Skris * \param file the file to add from. All certs in this file that are not 93855714Skris * already in the stack will be added. 93955714Skris * \return 1 for success, 0 for failure. Note that in the case of failure some 94055714Skris * certs may have been added to \c stack. 94155714Skris */ 94255714Skris 94355714Skrisint SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, 944280297Sjkim const char *file) 945280297Sjkim{ 946280297Sjkim BIO *in; 947280297Sjkim X509 *x = NULL; 948280297Sjkim X509_NAME *xn = NULL; 949280297Sjkim int ret = 1; 950280297Sjkim int (*oldcmp) (const X509_NAME *const *a, const X509_NAME *const *b); 95155714Skris 952280297Sjkim oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp); 953215697Ssimon 954280297Sjkim in = BIO_new(BIO_s_file_internal()); 95555714Skris 956280297Sjkim if (in == NULL) { 957280297Sjkim SSLerr(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK, 958280297Sjkim ERR_R_MALLOC_FAILURE); 959280297Sjkim goto err; 960280297Sjkim } 96155714Skris 962280297Sjkim if (!BIO_read_filename(in, file)) 963280297Sjkim goto err; 964280297Sjkim 965280297Sjkim for (;;) { 966280297Sjkim if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) 967280297Sjkim break; 968280297Sjkim if ((xn = X509_get_subject_name(x)) == NULL) 969280297Sjkim goto err; 970280297Sjkim xn = X509_NAME_dup(xn); 971280297Sjkim if (xn == NULL) 972280297Sjkim goto err; 973280297Sjkim if (sk_X509_NAME_find(stack, xn) >= 0) 974280297Sjkim X509_NAME_free(xn); 975280297Sjkim else 976280297Sjkim sk_X509_NAME_push(stack, xn); 977280297Sjkim } 978280297Sjkim 979280297Sjkim ERR_clear_error(); 980280297Sjkim 981280297Sjkim if (0) { 982280297Sjkim err: 983280297Sjkim ret = 0; 984280297Sjkim } 985280297Sjkim if (in != NULL) 986280297Sjkim BIO_free(in); 987280297Sjkim if (x != NULL) 988280297Sjkim X509_free(x); 989280297Sjkim 990280297Sjkim (void)sk_X509_NAME_set_cmp_func(stack, oldcmp); 991280297Sjkim 992280297Sjkim return ret; 993280297Sjkim} 994280297Sjkim 995280297Sjkim/** 99655714Skris * Add a directory of certs to a stack. 99755714Skris * \param stack the stack to append to. 99855714Skris * \param dir the directory to append from. All files in this directory will be 99955714Skris * examined as potential certs. Any that are acceptable to 100055714Skris * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will be 100155714Skris * included. 100255714Skris * \return 1 for success, 0 for failure. Note that in the case of failure some 100355714Skris * certs may have been added to \c stack. 100455714Skris */ 100555714Skris 100655714Skrisint SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, 1007280297Sjkim const char *dir) 1008280297Sjkim{ 1009280297Sjkim OPENSSL_DIR_CTX *d = NULL; 1010280297Sjkim const char *filename; 1011280297Sjkim int ret = 0; 101255714Skris 1013280297Sjkim CRYPTO_w_lock(CRYPTO_LOCK_READDIR); 101455714Skris 1015280297Sjkim /* Note that a side effect is that the CAs will be sorted by name */ 1016160814Ssimon 1017280297Sjkim while ((filename = OPENSSL_DIR_read(&d, dir))) { 1018280297Sjkim char buf[1024]; 1019280297Sjkim int r; 1020160814Ssimon 1021331638Sjkim if (strlen(dir) + strlen(filename) + 2 > sizeof(buf)) { 1022280297Sjkim SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, 1023280297Sjkim SSL_R_PATH_TOO_LONG); 1024280297Sjkim goto err; 1025280297Sjkim } 1026160814Ssimon#ifdef OPENSSL_SYS_VMS 1027331638Sjkim r = BIO_snprintf(buf, sizeof(buf), "%s%s", dir, filename); 1028160814Ssimon#else 1029331638Sjkim r = BIO_snprintf(buf, sizeof(buf), "%s/%s", dir, filename); 1030160814Ssimon#endif 1031280297Sjkim if (r <= 0 || r >= (int)sizeof(buf)) 1032280297Sjkim goto err; 1033280297Sjkim if (!SSL_add_file_cert_subjects_to_stack(stack, buf)) 1034280297Sjkim goto err; 1035280297Sjkim } 103655714Skris 1037280297Sjkim if (errno) { 1038280297Sjkim SYSerr(SYS_F_OPENDIR, get_last_sys_error()); 1039280297Sjkim ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')"); 1040280297Sjkim SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB); 1041280297Sjkim goto err; 1042280297Sjkim } 1043142425Snectar 1044280297Sjkim ret = 1; 1045109998Smarkm 1046280297Sjkim err: 1047280297Sjkim if (d) 1048280297Sjkim OPENSSL_DIR_end(&d); 1049280297Sjkim CRYPTO_w_unlock(CRYPTO_LOCK_READDIR); 1050280297Sjkim return ret; 1051280297Sjkim} 1052290207Sjkim 1053290207Sjkim/* Add a certificate to a BUF_MEM structure */ 1054290207Sjkim 1055290207Sjkimstatic int ssl_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x) 1056290207Sjkim{ 1057290207Sjkim int n; 1058290207Sjkim unsigned char *p; 1059290207Sjkim 1060290207Sjkim n = i2d_X509(x, NULL); 1061298998Sjkim if (n < 0 || !BUF_MEM_grow_clean(buf, (int)(n + (*l) + 3))) { 1062290207Sjkim SSLerr(SSL_F_SSL_ADD_CERT_TO_BUF, ERR_R_BUF_LIB); 1063290207Sjkim return 0; 1064290207Sjkim } 1065290207Sjkim p = (unsigned char *)&(buf->data[*l]); 1066290207Sjkim l2n3(n, p); 1067298998Sjkim n = i2d_X509(x, &p); 1068298998Sjkim if (n < 0) { 1069298998Sjkim /* Shouldn't happen */ 1070298998Sjkim SSLerr(SSL_F_SSL_ADD_CERT_TO_BUF, ERR_R_BUF_LIB); 1071298998Sjkim return 0; 1072298998Sjkim } 1073290207Sjkim *l += n + 3; 1074290207Sjkim 1075290207Sjkim return 1; 1076290207Sjkim} 1077290207Sjkim 1078290207Sjkim/* Add certificate chain to internal SSL BUF_MEM strcuture */ 1079290207Sjkimint ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l) 1080290207Sjkim{ 1081290207Sjkim BUF_MEM *buf = s->init_buf; 1082290207Sjkim int no_chain; 1083290207Sjkim int i; 1084290207Sjkim 1085290207Sjkim X509 *x; 1086290207Sjkim STACK_OF(X509) *extra_certs; 1087290207Sjkim X509_STORE *chain_store; 1088290207Sjkim 1089290207Sjkim if (cpk) 1090290207Sjkim x = cpk->x509; 1091290207Sjkim else 1092290207Sjkim x = NULL; 1093290207Sjkim 1094290207Sjkim if (s->cert->chain_store) 1095290207Sjkim chain_store = s->cert->chain_store; 1096290207Sjkim else 1097290207Sjkim chain_store = s->ctx->cert_store; 1098290207Sjkim 1099290207Sjkim /* 1100290207Sjkim * If we have a certificate specific chain use it, else use parent ctx. 1101290207Sjkim */ 1102290207Sjkim if (cpk && cpk->chain) 1103290207Sjkim extra_certs = cpk->chain; 1104290207Sjkim else 1105290207Sjkim extra_certs = s->ctx->extra_certs; 1106290207Sjkim 1107290207Sjkim if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || extra_certs) 1108290207Sjkim no_chain = 1; 1109290207Sjkim else 1110290207Sjkim no_chain = 0; 1111290207Sjkim 1112290207Sjkim /* TLSv1 sends a chain with nothing in it, instead of an alert */ 1113290207Sjkim if (!BUF_MEM_grow_clean(buf, 10)) { 1114290207Sjkim SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, ERR_R_BUF_LIB); 1115290207Sjkim return 0; 1116290207Sjkim } 1117290207Sjkim if (x != NULL) { 1118290207Sjkim if (no_chain) { 1119290207Sjkim if (!ssl_add_cert_to_buf(buf, l, x)) 1120290207Sjkim return 0; 1121290207Sjkim } else { 1122290207Sjkim X509_STORE_CTX xs_ctx; 1123290207Sjkim 1124290207Sjkim if (!X509_STORE_CTX_init(&xs_ctx, chain_store, x, NULL)) { 1125290207Sjkim SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, ERR_R_X509_LIB); 1126290207Sjkim return (0); 1127290207Sjkim } 1128290207Sjkim X509_verify_cert(&xs_ctx); 1129290207Sjkim /* Don't leave errors in the queue */ 1130290207Sjkim ERR_clear_error(); 1131290207Sjkim for (i = 0; i < sk_X509_num(xs_ctx.chain); i++) { 1132290207Sjkim x = sk_X509_value(xs_ctx.chain, i); 1133290207Sjkim 1134290207Sjkim if (!ssl_add_cert_to_buf(buf, l, x)) { 1135290207Sjkim X509_STORE_CTX_cleanup(&xs_ctx); 1136290207Sjkim return 0; 1137290207Sjkim } 1138290207Sjkim } 1139290207Sjkim X509_STORE_CTX_cleanup(&xs_ctx); 1140290207Sjkim } 1141290207Sjkim } 1142290207Sjkim for (i = 0; i < sk_X509_num(extra_certs); i++) { 1143290207Sjkim x = sk_X509_value(extra_certs, i); 1144290207Sjkim if (!ssl_add_cert_to_buf(buf, l, x)) 1145290207Sjkim return 0; 1146290207Sjkim } 1147290207Sjkim 1148290207Sjkim return 1; 1149290207Sjkim} 1150290207Sjkim 1151290207Sjkim/* Build a certificate chain for current certificate */ 1152290207Sjkimint ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags) 1153290207Sjkim{ 1154290207Sjkim CERT_PKEY *cpk = c->key; 1155290207Sjkim X509_STORE_CTX xs_ctx; 1156290207Sjkim STACK_OF(X509) *chain = NULL, *untrusted = NULL; 1157290207Sjkim X509 *x; 1158290207Sjkim int i, rv = 0; 1159290207Sjkim unsigned long error; 1160290207Sjkim 1161290207Sjkim if (!cpk->x509) { 1162290207Sjkim SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, SSL_R_NO_CERTIFICATE_SET); 1163290207Sjkim goto err; 1164290207Sjkim } 1165290207Sjkim /* Rearranging and check the chain: add everything to a store */ 1166290207Sjkim if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) { 1167290207Sjkim chain_store = X509_STORE_new(); 1168290207Sjkim if (!chain_store) 1169290207Sjkim goto err; 1170290207Sjkim for (i = 0; i < sk_X509_num(cpk->chain); i++) { 1171290207Sjkim x = sk_X509_value(cpk->chain, i); 1172290207Sjkim if (!X509_STORE_add_cert(chain_store, x)) { 1173290207Sjkim error = ERR_peek_last_error(); 1174290207Sjkim if (ERR_GET_LIB(error) != ERR_LIB_X509 || 1175290207Sjkim ERR_GET_REASON(error) != 1176290207Sjkim X509_R_CERT_ALREADY_IN_HASH_TABLE) 1177290207Sjkim goto err; 1178290207Sjkim ERR_clear_error(); 1179290207Sjkim } 1180290207Sjkim } 1181290207Sjkim /* Add EE cert too: it might be self signed */ 1182290207Sjkim if (!X509_STORE_add_cert(chain_store, cpk->x509)) { 1183290207Sjkim error = ERR_peek_last_error(); 1184290207Sjkim if (ERR_GET_LIB(error) != ERR_LIB_X509 || 1185290207Sjkim ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE) 1186290207Sjkim goto err; 1187290207Sjkim ERR_clear_error(); 1188290207Sjkim } 1189290207Sjkim } else { 1190290207Sjkim if (c->chain_store) 1191290207Sjkim chain_store = c->chain_store; 1192290207Sjkim 1193290207Sjkim if (flags & SSL_BUILD_CHAIN_FLAG_UNTRUSTED) 1194290207Sjkim untrusted = cpk->chain; 1195290207Sjkim } 1196290207Sjkim 1197290207Sjkim if (!X509_STORE_CTX_init(&xs_ctx, chain_store, cpk->x509, untrusted)) { 1198290207Sjkim SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, ERR_R_X509_LIB); 1199290207Sjkim goto err; 1200290207Sjkim } 1201290207Sjkim /* Set suite B flags if needed */ 1202290207Sjkim X509_STORE_CTX_set_flags(&xs_ctx, 1203290207Sjkim c->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS); 1204290207Sjkim 1205290207Sjkim i = X509_verify_cert(&xs_ctx); 1206290207Sjkim if (i <= 0 && flags & SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR) { 1207290207Sjkim if (flags & SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR) 1208290207Sjkim ERR_clear_error(); 1209290207Sjkim i = 1; 1210290207Sjkim rv = 2; 1211290207Sjkim } 1212290207Sjkim if (i > 0) 1213290207Sjkim chain = X509_STORE_CTX_get1_chain(&xs_ctx); 1214290207Sjkim if (i <= 0) { 1215290207Sjkim SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, SSL_R_CERTIFICATE_VERIFY_FAILED); 1216290207Sjkim i = X509_STORE_CTX_get_error(&xs_ctx); 1217290207Sjkim ERR_add_error_data(2, "Verify error:", 1218290207Sjkim X509_verify_cert_error_string(i)); 1219290207Sjkim 1220290207Sjkim X509_STORE_CTX_cleanup(&xs_ctx); 1221290207Sjkim goto err; 1222290207Sjkim } 1223290207Sjkim X509_STORE_CTX_cleanup(&xs_ctx); 1224290207Sjkim if (cpk->chain) 1225290207Sjkim sk_X509_pop_free(cpk->chain, X509_free); 1226290207Sjkim /* Remove EE certificate from chain */ 1227290207Sjkim x = sk_X509_shift(chain); 1228290207Sjkim X509_free(x); 1229290207Sjkim if (flags & SSL_BUILD_CHAIN_FLAG_NO_ROOT) { 1230290207Sjkim if (sk_X509_num(chain) > 0) { 1231290207Sjkim /* See if last cert is self signed */ 1232290207Sjkim x = sk_X509_value(chain, sk_X509_num(chain) - 1); 1233290207Sjkim X509_check_purpose(x, -1, 0); 1234290207Sjkim if (x->ex_flags & EXFLAG_SS) { 1235290207Sjkim x = sk_X509_pop(chain); 1236290207Sjkim X509_free(x); 1237290207Sjkim } 1238290207Sjkim } 1239290207Sjkim } 1240290207Sjkim cpk->chain = chain; 1241290207Sjkim if (rv == 0) 1242290207Sjkim rv = 1; 1243290207Sjkim err: 1244290207Sjkim if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) 1245290207Sjkim X509_STORE_free(chain_store); 1246290207Sjkim 1247290207Sjkim return rv; 1248290207Sjkim} 1249290207Sjkim 1250290207Sjkimint ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref) 1251290207Sjkim{ 1252290207Sjkim X509_STORE **pstore; 1253290207Sjkim if (chain) 1254290207Sjkim pstore = &c->chain_store; 1255290207Sjkim else 1256290207Sjkim pstore = &c->verify_store; 1257290207Sjkim if (*pstore) 1258290207Sjkim X509_STORE_free(*pstore); 1259290207Sjkim *pstore = store; 1260290207Sjkim if (ref && store) 1261290207Sjkim CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE); 1262290207Sjkim return 1; 1263290207Sjkim} 1264