1296465Sdelphij/* 2296465Sdelphij * ! \file ssl/ssl_cert.c 3296465Sdelphij */ 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. 10296465Sdelphij * 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). 17296465Sdelphij * 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. 24296465Sdelphij * 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 :-). 39296465Sdelphij * 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)" 42296465Sdelphij * 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. 54296465Sdelphij * 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/* ==================================================================== 61162911Ssimon * Copyright (c) 1998-2006 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 68296465Sdelphij * 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. 115296465Sdelphij * 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 132296465Sdelphij# 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) 138296465Sdelphij{ 139296465Sdelphij static volatile int ssl_x509_store_ctx_idx = -1; 140296465Sdelphij int got_write_lock = 0; 14155714Skris 142296465Sdelphij CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); 143162911Ssimon 144296465Sdelphij if (ssl_x509_store_ctx_idx < 0) { 145296465Sdelphij CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); 146296465Sdelphij CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 147296465Sdelphij got_write_lock = 1; 148162911Ssimon 149296465Sdelphij if (ssl_x509_store_ctx_idx < 0) { 150296465Sdelphij ssl_x509_store_ctx_idx = 151296465Sdelphij X509_STORE_CTX_get_ex_new_index(0, "SSL for verify callback", 152296465Sdelphij NULL, NULL, NULL); 153296465Sdelphij } 154296465Sdelphij } 15555714Skris 156296465Sdelphij if (got_write_lock) 157296465Sdelphij CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); 158296465Sdelphij else 159296465Sdelphij CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); 160296465Sdelphij 161296465Sdelphij return ssl_x509_store_ctx_idx; 162296465Sdelphij} 163296465Sdelphij 16455714SkrisCERT *ssl_cert_new(void) 165296465Sdelphij{ 166296465Sdelphij CERT *ret; 16755714Skris 168296465Sdelphij ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); 169296465Sdelphij if (ret == NULL) { 170296465Sdelphij SSLerr(SSL_F_SSL_CERT_NEW, ERR_R_MALLOC_FAILURE); 171296465Sdelphij return (NULL); 172296465Sdelphij } 173296465Sdelphij memset(ret, 0, sizeof(CERT)); 17455714Skris 175296465Sdelphij ret->key = &(ret->pkeys[SSL_PKEY_RSA_ENC]); 176296465Sdelphij ret->references = 1; 17755714Skris 178296465Sdelphij return (ret); 179296465Sdelphij} 18055714Skris 18155714SkrisCERT *ssl_cert_dup(CERT *cert) 182296465Sdelphij{ 183296465Sdelphij CERT *ret; 184296465Sdelphij int i; 18555714Skris 186296465Sdelphij ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); 187296465Sdelphij if (ret == NULL) { 188296465Sdelphij SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); 189296465Sdelphij return (NULL); 190296465Sdelphij } 19155714Skris 192296465Sdelphij memset(ret, 0, sizeof(CERT)); 19355714Skris 194296465Sdelphij ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]]; 195296465Sdelphij /* 196296465Sdelphij * or ret->key = ret->pkeys + (cert->key - cert->pkeys), if you find that 197296465Sdelphij * more readable 198296465Sdelphij */ 19955714Skris 200296465Sdelphij ret->valid = cert->valid; 201296465Sdelphij ret->mask = cert->mask; 202296465Sdelphij ret->export_mask = cert->export_mask; 20355714Skris 204109998Smarkm#ifndef OPENSSL_NO_RSA 205296465Sdelphij if (cert->rsa_tmp != NULL) { 206296465Sdelphij RSA_up_ref(cert->rsa_tmp); 207296465Sdelphij ret->rsa_tmp = cert->rsa_tmp; 208296465Sdelphij } 209296465Sdelphij ret->rsa_tmp_cb = cert->rsa_tmp_cb; 21055714Skris#endif 21155714Skris 212109998Smarkm#ifndef OPENSSL_NO_DH 213296465Sdelphij if (cert->dh_tmp != NULL) { 214296465Sdelphij ret->dh_tmp = DHparams_dup(cert->dh_tmp); 215296465Sdelphij if (ret->dh_tmp == NULL) { 216296465Sdelphij SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_DH_LIB); 217296465Sdelphij goto err; 218296465Sdelphij } 219296465Sdelphij if (cert->dh_tmp->priv_key) { 220296465Sdelphij BIGNUM *b = BN_dup(cert->dh_tmp->priv_key); 221296465Sdelphij if (!b) { 222296465Sdelphij SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); 223296465Sdelphij goto err; 224296465Sdelphij } 225296465Sdelphij ret->dh_tmp->priv_key = b; 226296465Sdelphij } 227296465Sdelphij if (cert->dh_tmp->pub_key) { 228296465Sdelphij BIGNUM *b = BN_dup(cert->dh_tmp->pub_key); 229296465Sdelphij if (!b) { 230296465Sdelphij SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); 231296465Sdelphij goto err; 232296465Sdelphij } 233296465Sdelphij ret->dh_tmp->pub_key = b; 234296465Sdelphij } 235296465Sdelphij } 236296465Sdelphij ret->dh_tmp_cb = cert->dh_tmp_cb; 23755714Skris#endif 23855714Skris 239160814Ssimon#ifndef OPENSSL_NO_ECDH 240296465Sdelphij if (cert->ecdh_tmp) { 241296465Sdelphij ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp); 242296465Sdelphij if (ret->ecdh_tmp == NULL) { 243296465Sdelphij SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_EC_LIB); 244296465Sdelphij goto err; 245296465Sdelphij } 246296465Sdelphij } 247296465Sdelphij ret->ecdh_tmp_cb = cert->ecdh_tmp_cb; 248160814Ssimon#endif 249160814Ssimon 250296465Sdelphij for (i = 0; i < SSL_PKEY_NUM; i++) { 251296465Sdelphij if (cert->pkeys[i].x509 != NULL) { 252296465Sdelphij ret->pkeys[i].x509 = cert->pkeys[i].x509; 253296465Sdelphij CRYPTO_add(&ret->pkeys[i].x509->references, 1, CRYPTO_LOCK_X509); 254296465Sdelphij } 25555714Skris 256296465Sdelphij if (cert->pkeys[i].privatekey != NULL) { 257296465Sdelphij ret->pkeys[i].privatekey = cert->pkeys[i].privatekey; 258296465Sdelphij CRYPTO_add(&ret->pkeys[i].privatekey->references, 1, 259296465Sdelphij CRYPTO_LOCK_EVP_PKEY); 26055714Skris 261296465Sdelphij switch (i) { 262296465Sdelphij /* 263296465Sdelphij * If there was anything special to do for certain types of 264296465Sdelphij * keys, we'd do it here. (Nothing at the moment, I think.) 265296465Sdelphij */ 266160814Ssimon 267296465Sdelphij case SSL_PKEY_RSA_ENC: 268296465Sdelphij case SSL_PKEY_RSA_SIGN: 269296465Sdelphij /* We have an RSA key. */ 270296465Sdelphij break; 271160814Ssimon 272296465Sdelphij case SSL_PKEY_DSA_SIGN: 273296465Sdelphij /* We have a DSA key. */ 274296465Sdelphij break; 27555714Skris 276296465Sdelphij case SSL_PKEY_DH_RSA: 277296465Sdelphij case SSL_PKEY_DH_DSA: 278296465Sdelphij /* We have a DH key. */ 279296465Sdelphij break; 28055714Skris 281296465Sdelphij case SSL_PKEY_ECC: 282296465Sdelphij /* We have an ECC key */ 283296465Sdelphij break; 284296465Sdelphij 285296465Sdelphij default: 286296465Sdelphij /* Can't happen. */ 287296465Sdelphij SSLerr(SSL_F_SSL_CERT_DUP, SSL_R_LIBRARY_BUG); 288296465Sdelphij } 289296465Sdelphij } 290296465Sdelphij } 291296465Sdelphij 292296465Sdelphij /* 293296465Sdelphij * ret->extra_certs *should* exist, but currently the own certificate 294296465Sdelphij * chain is held inside SSL_CTX 295296465Sdelphij */ 296296465Sdelphij 297296465Sdelphij ret->references = 1; 298296465Sdelphij 299296465Sdelphij return (ret); 300296465Sdelphij 301160814Ssimon#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH) 302296465Sdelphij err: 30376866Skris#endif 304109998Smarkm#ifndef OPENSSL_NO_RSA 305296465Sdelphij if (ret->rsa_tmp != NULL) 306296465Sdelphij RSA_free(ret->rsa_tmp); 30755714Skris#endif 308109998Smarkm#ifndef OPENSSL_NO_DH 309296465Sdelphij if (ret->dh_tmp != NULL) 310296465Sdelphij DH_free(ret->dh_tmp); 31155714Skris#endif 312160814Ssimon#ifndef OPENSSL_NO_ECDH 313296465Sdelphij if (ret->ecdh_tmp != NULL) 314296465Sdelphij EC_KEY_free(ret->ecdh_tmp); 315160814Ssimon#endif 31655714Skris 317296465Sdelphij for (i = 0; i < SSL_PKEY_NUM; i++) { 318296465Sdelphij if (ret->pkeys[i].x509 != NULL) 319296465Sdelphij X509_free(ret->pkeys[i].x509); 320296465Sdelphij if (ret->pkeys[i].privatekey != NULL) 321296465Sdelphij EVP_PKEY_free(ret->pkeys[i].privatekey); 322296465Sdelphij } 32355714Skris 324296465Sdelphij return NULL; 325296465Sdelphij} 32655714Skris 32755714Skrisvoid ssl_cert_free(CERT *c) 328296465Sdelphij{ 329296465Sdelphij int i; 33055714Skris 331296465Sdelphij if (c == NULL) 332296465Sdelphij return; 33355714Skris 334296465Sdelphij i = CRYPTO_add(&c->references, -1, CRYPTO_LOCK_SSL_CERT); 33555714Skris#ifdef REF_PRINT 336296465Sdelphij REF_PRINT("CERT", c); 33755714Skris#endif 338296465Sdelphij if (i > 0) 339296465Sdelphij return; 34055714Skris#ifdef REF_CHECK 341296465Sdelphij if (i < 0) { 342296465Sdelphij fprintf(stderr, "ssl_cert_free, bad reference count\n"); 343296465Sdelphij abort(); /* ok */ 344296465Sdelphij } 34555714Skris#endif 34655714Skris 347109998Smarkm#ifndef OPENSSL_NO_RSA 348296465Sdelphij if (c->rsa_tmp) 349296465Sdelphij RSA_free(c->rsa_tmp); 35055714Skris#endif 351109998Smarkm#ifndef OPENSSL_NO_DH 352296465Sdelphij if (c->dh_tmp) 353296465Sdelphij DH_free(c->dh_tmp); 35455714Skris#endif 355160814Ssimon#ifndef OPENSSL_NO_ECDH 356296465Sdelphij if (c->ecdh_tmp) 357296465Sdelphij EC_KEY_free(c->ecdh_tmp); 358160814Ssimon#endif 35955714Skris 360296465Sdelphij for (i = 0; i < SSL_PKEY_NUM; i++) { 361296465Sdelphij if (c->pkeys[i].x509 != NULL) 362296465Sdelphij X509_free(c->pkeys[i].x509); 363296465Sdelphij if (c->pkeys[i].privatekey != NULL) 364296465Sdelphij EVP_PKEY_free(c->pkeys[i].privatekey); 36555714Skris#if 0 366296465Sdelphij if (c->pkeys[i].publickey != NULL) 367296465Sdelphij EVP_PKEY_free(c->pkeys[i].publickey); 36855714Skris#endif 369296465Sdelphij } 370296465Sdelphij OPENSSL_free(c); 371296465Sdelphij} 37255714Skris 37355714Skrisint ssl_cert_inst(CERT **o) 374296465Sdelphij{ 375296465Sdelphij /* 376296465Sdelphij * Create a CERT if there isn't already one (which cannot really happen, 377296465Sdelphij * as it is initially created in SSL_CTX_new; but the earlier code 378296465Sdelphij * usually allows for that one being non-existant, so we follow that 379296465Sdelphij * behaviour, as it might turn out that there actually is a reason for it 380296465Sdelphij * -- but I'm not sure that *all* of the existing code could cope with 381296465Sdelphij * s->cert being NULL, otherwise we could do without the initialization 382296465Sdelphij * in SSL_CTX_new). 383296465Sdelphij */ 38455714Skris 385296465Sdelphij if (o == NULL) { 386296465Sdelphij SSLerr(SSL_F_SSL_CERT_INST, ERR_R_PASSED_NULL_PARAMETER); 387296465Sdelphij return (0); 388296465Sdelphij } 389296465Sdelphij if (*o == NULL) { 390296465Sdelphij if ((*o = ssl_cert_new()) == NULL) { 391296465Sdelphij SSLerr(SSL_F_SSL_CERT_INST, ERR_R_MALLOC_FAILURE); 392296465Sdelphij return (0); 393296465Sdelphij } 394296465Sdelphij } 395296465Sdelphij return (1); 396296465Sdelphij} 39755714Skris 39855714SkrisSESS_CERT *ssl_sess_cert_new(void) 399296465Sdelphij{ 400296465Sdelphij SESS_CERT *ret; 40155714Skris 402296465Sdelphij ret = OPENSSL_malloc(sizeof *ret); 403296465Sdelphij if (ret == NULL) { 404296465Sdelphij SSLerr(SSL_F_SSL_SESS_CERT_NEW, ERR_R_MALLOC_FAILURE); 405296465Sdelphij return NULL; 406296465Sdelphij } 40755714Skris 408296465Sdelphij memset(ret, 0, sizeof *ret); 409296465Sdelphij ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA_ENC]); 410296465Sdelphij ret->references = 1; 41155714Skris 412296465Sdelphij return ret; 413296465Sdelphij} 41455714Skris 41555714Skrisvoid ssl_sess_cert_free(SESS_CERT *sc) 416296465Sdelphij{ 417296465Sdelphij int i; 41855714Skris 419296465Sdelphij if (sc == NULL) 420296465Sdelphij return; 42155714Skris 422296465Sdelphij i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT); 42355714Skris#ifdef REF_PRINT 424296465Sdelphij REF_PRINT("SESS_CERT", sc); 42555714Skris#endif 426296465Sdelphij if (i > 0) 427296465Sdelphij return; 42855714Skris#ifdef REF_CHECK 429296465Sdelphij if (i < 0) { 430296465Sdelphij fprintf(stderr, "ssl_sess_cert_free, bad reference count\n"); 431296465Sdelphij abort(); /* ok */ 432296465Sdelphij } 43355714Skris#endif 43455714Skris 435296465Sdelphij /* i == 0 */ 436296465Sdelphij if (sc->cert_chain != NULL) 437296465Sdelphij sk_X509_pop_free(sc->cert_chain, X509_free); 438296465Sdelphij for (i = 0; i < SSL_PKEY_NUM; i++) { 439296465Sdelphij if (sc->peer_pkeys[i].x509 != NULL) 440296465Sdelphij X509_free(sc->peer_pkeys[i].x509); 441296465Sdelphij#if 0 /* We don't have the peer's private key. 442296465Sdelphij * These lines are just * here as a reminder 443296465Sdelphij * that we're still using a 444296465Sdelphij * not-quite-appropriate * data structure. */ 445296465Sdelphij if (sc->peer_pkeys[i].privatekey != NULL) 446296465Sdelphij EVP_PKEY_free(sc->peer_pkeys[i].privatekey); 44755714Skris#endif 448296465Sdelphij } 44955714Skris 450109998Smarkm#ifndef OPENSSL_NO_RSA 451296465Sdelphij if (sc->peer_rsa_tmp != NULL) 452296465Sdelphij RSA_free(sc->peer_rsa_tmp); 45355714Skris#endif 454109998Smarkm#ifndef OPENSSL_NO_DH 455296465Sdelphij if (sc->peer_dh_tmp != NULL) 456296465Sdelphij DH_free(sc->peer_dh_tmp); 45755714Skris#endif 458160814Ssimon#ifndef OPENSSL_NO_ECDH 459296465Sdelphij if (sc->peer_ecdh_tmp != NULL) 460296465Sdelphij EC_KEY_free(sc->peer_ecdh_tmp); 461160814Ssimon#endif 46255714Skris 463296465Sdelphij OPENSSL_free(sc); 464296465Sdelphij} 46555714Skris 466296465Sdelphijint ssl_set_peer_cert_type(SESS_CERT *sc, int type) 467296465Sdelphij{ 468296465Sdelphij sc->peer_cert_type = type; 469296465Sdelphij return (1); 470296465Sdelphij} 47155714Skris 472296465Sdelphijint ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) 473296465Sdelphij{ 474296465Sdelphij X509 *x; 475296465Sdelphij int i; 476296465Sdelphij X509_STORE_CTX ctx; 47755714Skris 478296465Sdelphij if ((sk == NULL) || (sk_X509_num(sk) == 0)) 479296465Sdelphij return (0); 48055714Skris 481296465Sdelphij x = sk_X509_value(sk, 0); 482296465Sdelphij if (!X509_STORE_CTX_init(&ctx, s->ctx->cert_store, x, sk)) { 483296465Sdelphij SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_X509_LIB); 484296465Sdelphij return (0); 485296465Sdelphij } 486160814Ssimon#if 0 487296465Sdelphij if (SSL_get_verify_depth(s) >= 0) 488296465Sdelphij X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s)); 489160814Ssimon#endif 490296465Sdelphij X509_STORE_CTX_set_ex_data(&ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s); 491109998Smarkm 492296465Sdelphij /* 493296465Sdelphij * We need to inherit the verify parameters. These can be determined by 494296465Sdelphij * the context: if its a server it will verify SSL client certificates or 495296465Sdelphij * vice versa. 496296465Sdelphij */ 49755714Skris 498296465Sdelphij X509_STORE_CTX_set_default(&ctx, s->server ? "ssl_client" : "ssl_server"); 499296465Sdelphij /* 500296465Sdelphij * Anything non-default in "param" should overwrite anything in the ctx. 501296465Sdelphij */ 502296465Sdelphij X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param); 50359191Skris 504296465Sdelphij if (s->verify_callback) 505296465Sdelphij X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback); 50689837Skris 507296465Sdelphij if (s->ctx->app_verify_callback != NULL) 508296465Sdelphij#if 1 /* new with OpenSSL 0.9.7 */ 509296465Sdelphij i = s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg); 510109998Smarkm#else 511296465Sdelphij i = s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */ 512109998Smarkm#endif 513296465Sdelphij else { 514109998Smarkm#ifndef OPENSSL_NO_X509_VERIFY 515296465Sdelphij i = X509_verify_cert(&ctx); 51655714Skris#else 517296465Sdelphij i = 0; 518296465Sdelphij ctx.error = X509_V_ERR_APPLICATION_VERIFICATION; 519296465Sdelphij SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, SSL_R_NO_VERIFY_CALLBACK); 52055714Skris#endif 521296465Sdelphij } 52255714Skris 523296465Sdelphij s->verify_result = ctx.error; 524296465Sdelphij X509_STORE_CTX_cleanup(&ctx); 52555714Skris 526296465Sdelphij return (i); 527296465Sdelphij} 52855714Skris 529296465Sdelphijstatic void set_client_CA_list(STACK_OF(X509_NAME) **ca_list, 530296465Sdelphij STACK_OF(X509_NAME) *name_list) 531296465Sdelphij{ 532296465Sdelphij if (*ca_list != NULL) 533296465Sdelphij sk_X509_NAME_pop_free(*ca_list, X509_NAME_free); 53455714Skris 535296465Sdelphij *ca_list = name_list; 536296465Sdelphij} 53755714Skris 53855714SkrisSTACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk) 539296465Sdelphij{ 540296465Sdelphij int i; 541296465Sdelphij STACK_OF(X509_NAME) *ret; 542296465Sdelphij X509_NAME *name; 54355714Skris 544296465Sdelphij ret = sk_X509_NAME_new_null(); 545296465Sdelphij for (i = 0; i < sk_X509_NAME_num(sk); i++) { 546296465Sdelphij name = X509_NAME_dup(sk_X509_NAME_value(sk, i)); 547296465Sdelphij if ((name == NULL) || !sk_X509_NAME_push(ret, name)) { 548296465Sdelphij sk_X509_NAME_pop_free(ret, X509_NAME_free); 549296465Sdelphij return (NULL); 550296465Sdelphij } 551296465Sdelphij } 552296465Sdelphij return (ret); 553296465Sdelphij} 55455714Skris 555296465Sdelphijvoid SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list) 556296465Sdelphij{ 557296465Sdelphij set_client_CA_list(&(s->client_CA), name_list); 558296465Sdelphij} 55955714Skris 560296465Sdelphijvoid SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) 561296465Sdelphij{ 562296465Sdelphij set_client_CA_list(&(ctx->client_CA), name_list); 563296465Sdelphij} 56455714Skris 565160814SsimonSTACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) 566296465Sdelphij{ 567296465Sdelphij return (ctx->client_CA); 568296465Sdelphij} 56955714Skris 570160814SsimonSTACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s) 571296465Sdelphij{ 572296465Sdelphij if (s->type == SSL_ST_CONNECT) { /* we are in the client */ 573296465Sdelphij if (((s->version >> 8) == SSL3_VERSION_MAJOR) && (s->s3 != NULL)) 574296465Sdelphij return (s->s3->tmp.ca_names); 575296465Sdelphij else 576296465Sdelphij return (NULL); 577296465Sdelphij } else { 578296465Sdelphij if (s->client_CA != NULL) 579296465Sdelphij return (s->client_CA); 580296465Sdelphij else 581296465Sdelphij return (s->ctx->client_CA); 582296465Sdelphij } 583296465Sdelphij} 58455714Skris 585296465Sdelphijstatic int add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x) 586296465Sdelphij{ 587296465Sdelphij X509_NAME *name; 58855714Skris 589296465Sdelphij if (x == NULL) 590296465Sdelphij return (0); 591296465Sdelphij if ((*sk == NULL) && ((*sk = sk_X509_NAME_new_null()) == NULL)) 592296465Sdelphij return (0); 59355714Skris 594296465Sdelphij if ((name = X509_NAME_dup(X509_get_subject_name(x))) == NULL) 595296465Sdelphij return (0); 59655714Skris 597296465Sdelphij if (!sk_X509_NAME_push(*sk, name)) { 598296465Sdelphij X509_NAME_free(name); 599296465Sdelphij return (0); 600296465Sdelphij } 601296465Sdelphij return (1); 602296465Sdelphij} 60355714Skris 604296465Sdelphijint SSL_add_client_CA(SSL *ssl, X509 *x) 605296465Sdelphij{ 606296465Sdelphij return (add_client_CA(&(ssl->client_CA), x)); 607296465Sdelphij} 60855714Skris 609296465Sdelphijint SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) 610296465Sdelphij{ 611296465Sdelphij return (add_client_CA(&(ctx->client_CA), x)); 612296465Sdelphij} 61355714Skris 614296465Sdelphijstatic int xname_cmp(const X509_NAME *const *a, const X509_NAME *const *b) 615296465Sdelphij{ 616296465Sdelphij return (X509_NAME_cmp(*a, *b)); 617296465Sdelphij} 618296465Sdelphij 619109998Smarkm#ifndef OPENSSL_NO_STDIO 620296465Sdelphij/** 62155714Skris * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed; 62255714Skris * it doesn't really have anything to do with clients (except that a common use 62355714Skris * for a stack of CAs is to send it to the client). Actually, it doesn't have 62455714Skris * much to do with CAs, either, since it will load any old cert. 62555714Skris * \param file the file containing one or more certs. 62655714Skris * \return a ::STACK containing the certs. 62755714Skris */ 62855714SkrisSTACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) 629296465Sdelphij{ 630296465Sdelphij BIO *in; 631296465Sdelphij X509 *x = NULL; 632296465Sdelphij X509_NAME *xn = NULL; 633296465Sdelphij STACK_OF(X509_NAME) *ret = NULL, *sk; 63455714Skris 635296465Sdelphij sk = sk_X509_NAME_new(xname_cmp); 63655714Skris 637296465Sdelphij in = BIO_new(BIO_s_file_internal()); 63855714Skris 639296465Sdelphij if ((sk == NULL) || (in == NULL)) { 640296465Sdelphij SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE); 641296465Sdelphij goto err; 642296465Sdelphij } 64355714Skris 644296465Sdelphij if (!BIO_read_filename(in, file)) 645296465Sdelphij goto err; 64655714Skris 647296465Sdelphij for (;;) { 648296465Sdelphij if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) 649296465Sdelphij break; 650296465Sdelphij if (ret == NULL) { 651296465Sdelphij ret = sk_X509_NAME_new_null(); 652296465Sdelphij if (ret == NULL) { 653296465Sdelphij SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE); 654296465Sdelphij goto err; 655296465Sdelphij } 656296465Sdelphij } 657296465Sdelphij if ((xn = X509_get_subject_name(x)) == NULL) 658296465Sdelphij goto err; 659296465Sdelphij /* check for duplicates */ 660296465Sdelphij xn = X509_NAME_dup(xn); 661296465Sdelphij if (xn == NULL) 662296465Sdelphij goto err; 663296465Sdelphij if (sk_X509_NAME_find(sk, xn) >= 0) 664296465Sdelphij X509_NAME_free(xn); 665296465Sdelphij else { 666296465Sdelphij sk_X509_NAME_push(sk, xn); 667296465Sdelphij sk_X509_NAME_push(ret, xn); 668296465Sdelphij } 669296465Sdelphij } 670296465Sdelphij 671296465Sdelphij if (0) { 672296465Sdelphij err: 673296465Sdelphij if (ret != NULL) 674296465Sdelphij sk_X509_NAME_pop_free(ret, X509_NAME_free); 675296465Sdelphij ret = NULL; 676296465Sdelphij } 677296465Sdelphij if (sk != NULL) 678296465Sdelphij sk_X509_NAME_free(sk); 679296465Sdelphij if (in != NULL) 680296465Sdelphij BIO_free(in); 681296465Sdelphij if (x != NULL) 682296465Sdelphij X509_free(x); 683296465Sdelphij if (ret != NULL) 684296465Sdelphij ERR_clear_error(); 685296465Sdelphij return (ret); 686296465Sdelphij} 68755714Skris#endif 68855714Skris 689296465Sdelphij/** 69055714Skris * Add a file of certs to a stack. 69155714Skris * \param stack the stack to add to. 69255714Skris * \param file the file to add from. All certs in this file that are not 69355714Skris * already in the stack will be added. 69455714Skris * \return 1 for success, 0 for failure. Note that in the case of failure some 69555714Skris * certs may have been added to \c stack. 69655714Skris */ 69755714Skris 69855714Skrisint SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, 699296465Sdelphij const char *file) 700296465Sdelphij{ 701296465Sdelphij BIO *in; 702296465Sdelphij X509 *x = NULL; 703296465Sdelphij X509_NAME *xn = NULL; 704296465Sdelphij int ret = 1; 705296465Sdelphij int (*oldcmp) (const X509_NAME *const *a, const X509_NAME *const *b); 70655714Skris 707296465Sdelphij oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp); 708215697Ssimon 709296465Sdelphij in = BIO_new(BIO_s_file_internal()); 71055714Skris 711296465Sdelphij if (in == NULL) { 712296465Sdelphij SSLerr(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK, 713296465Sdelphij ERR_R_MALLOC_FAILURE); 714296465Sdelphij goto err; 715296465Sdelphij } 71655714Skris 717296465Sdelphij if (!BIO_read_filename(in, file)) 718296465Sdelphij goto err; 719296465Sdelphij 720296465Sdelphij for (;;) { 721296465Sdelphij if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) 722296465Sdelphij break; 723296465Sdelphij if ((xn = X509_get_subject_name(x)) == NULL) 724296465Sdelphij goto err; 725296465Sdelphij xn = X509_NAME_dup(xn); 726296465Sdelphij if (xn == NULL) 727296465Sdelphij goto err; 728296465Sdelphij if (sk_X509_NAME_find(stack, xn) >= 0) 729296465Sdelphij X509_NAME_free(xn); 730296465Sdelphij else 731296465Sdelphij sk_X509_NAME_push(stack, xn); 732296465Sdelphij } 733296465Sdelphij 734296465Sdelphij ERR_clear_error(); 735296465Sdelphij 736296465Sdelphij if (0) { 737296465Sdelphij err: 738296465Sdelphij ret = 0; 739296465Sdelphij } 740296465Sdelphij if (in != NULL) 741296465Sdelphij BIO_free(in); 742296465Sdelphij if (x != NULL) 743296465Sdelphij X509_free(x); 744296465Sdelphij 745296465Sdelphij (void)sk_X509_NAME_set_cmp_func(stack, oldcmp); 746296465Sdelphij 747296465Sdelphij return ret; 748296465Sdelphij} 749296465Sdelphij 750296465Sdelphij/** 75155714Skris * Add a directory of certs to a stack. 75255714Skris * \param stack the stack to append to. 75355714Skris * \param dir the directory to append from. All files in this directory will be 75455714Skris * examined as potential certs. Any that are acceptable to 75555714Skris * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will be 75655714Skris * included. 75755714Skris * \return 1 for success, 0 for failure. Note that in the case of failure some 75855714Skris * certs may have been added to \c stack. 75955714Skris */ 76055714Skris 76155714Skrisint SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, 762296465Sdelphij const char *dir) 763296465Sdelphij{ 764296465Sdelphij OPENSSL_DIR_CTX *d = NULL; 765296465Sdelphij const char *filename; 766296465Sdelphij int ret = 0; 76755714Skris 768296465Sdelphij CRYPTO_w_lock(CRYPTO_LOCK_READDIR); 76955714Skris 770296465Sdelphij /* Note that a side effect is that the CAs will be sorted by name */ 771160814Ssimon 772296465Sdelphij while ((filename = OPENSSL_DIR_read(&d, dir))) { 773296465Sdelphij char buf[1024]; 774296465Sdelphij int r; 775160814Ssimon 776296465Sdelphij if (strlen(dir) + strlen(filename) + 2 > sizeof buf) { 777296465Sdelphij SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, 778296465Sdelphij SSL_R_PATH_TOO_LONG); 779296465Sdelphij goto err; 780296465Sdelphij } 781160814Ssimon#ifdef OPENSSL_SYS_VMS 782296465Sdelphij r = BIO_snprintf(buf, sizeof buf, "%s%s", dir, filename); 783160814Ssimon#else 784296465Sdelphij r = BIO_snprintf(buf, sizeof buf, "%s/%s", dir, filename); 785160814Ssimon#endif 786296465Sdelphij if (r <= 0 || r >= (int)sizeof(buf)) 787296465Sdelphij goto err; 788296465Sdelphij if (!SSL_add_file_cert_subjects_to_stack(stack, buf)) 789296465Sdelphij goto err; 790296465Sdelphij } 79155714Skris 792296465Sdelphij if (errno) { 793296465Sdelphij SYSerr(SYS_F_OPENDIR, get_last_sys_error()); 794296465Sdelphij ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')"); 795296465Sdelphij SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB); 796296465Sdelphij goto err; 797296465Sdelphij } 798142425Snectar 799296465Sdelphij ret = 1; 800109998Smarkm 801296465Sdelphij err: 802296465Sdelphij if (d) 803296465Sdelphij OPENSSL_DIR_end(&d); 804296465Sdelphij CRYPTO_w_unlock(CRYPTO_LOCK_READDIR); 805296465Sdelphij return ret; 806296465Sdelphij} 807