16f9291ceSJung-uk Kim /* 26f9291ceSJung-uk Kim * ! \file ssl/ssl_cert.c 36f9291ceSJung-uk Kim */ 474664626SKris Kennaway /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 574664626SKris Kennaway * All rights reserved. 674664626SKris Kennaway * 774664626SKris Kennaway * This package is an SSL implementation written 874664626SKris Kennaway * by Eric Young (eay@cryptsoft.com). 974664626SKris Kennaway * The implementation was written so as to conform with Netscapes SSL. 1074664626SKris Kennaway * 1174664626SKris Kennaway * This library is free for commercial and non-commercial use as long as 1274664626SKris Kennaway * the following conditions are aheared to. The following conditions 1374664626SKris Kennaway * apply to all code found in this distribution, be it the RC4, RSA, 1474664626SKris Kennaway * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1574664626SKris Kennaway * included with this distribution is covered by the same copyright terms 1674664626SKris Kennaway * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1774664626SKris Kennaway * 1874664626SKris Kennaway * Copyright remains Eric Young's, and as such any Copyright notices in 1974664626SKris Kennaway * the code are not to be removed. 2074664626SKris Kennaway * If this package is used in a product, Eric Young should be given attribution 2174664626SKris Kennaway * as the author of the parts of the library used. 2274664626SKris Kennaway * This can be in the form of a textual message at program startup or 2374664626SKris Kennaway * in documentation (online or textual) provided with the package. 2474664626SKris Kennaway * 2574664626SKris Kennaway * Redistribution and use in source and binary forms, with or without 2674664626SKris Kennaway * modification, are permitted provided that the following conditions 2774664626SKris Kennaway * are met: 2874664626SKris Kennaway * 1. Redistributions of source code must retain the copyright 2974664626SKris Kennaway * notice, this list of conditions and the following disclaimer. 3074664626SKris Kennaway * 2. Redistributions in binary form must reproduce the above copyright 3174664626SKris Kennaway * notice, this list of conditions and the following disclaimer in the 3274664626SKris Kennaway * documentation and/or other materials provided with the distribution. 3374664626SKris Kennaway * 3. All advertising materials mentioning features or use of this software 3474664626SKris Kennaway * must display the following acknowledgement: 3574664626SKris Kennaway * "This product includes cryptographic software written by 3674664626SKris Kennaway * Eric Young (eay@cryptsoft.com)" 3774664626SKris Kennaway * The word 'cryptographic' can be left out if the rouines from the library 3874664626SKris Kennaway * being used are not cryptographic related :-). 3974664626SKris Kennaway * 4. If you include any Windows specific code (or a derivative thereof) from 4074664626SKris Kennaway * the apps directory (application code) you must include an acknowledgement: 4174664626SKris Kennaway * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4274664626SKris Kennaway * 4374664626SKris Kennaway * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4474664626SKris Kennaway * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4574664626SKris Kennaway * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4674664626SKris Kennaway * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4774664626SKris Kennaway * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4874664626SKris Kennaway * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4974664626SKris Kennaway * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 5074664626SKris Kennaway * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 5174664626SKris Kennaway * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5274664626SKris Kennaway * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5374664626SKris Kennaway * SUCH DAMAGE. 5474664626SKris Kennaway * 5574664626SKris Kennaway * The licence and distribution terms for any publically available version or 5674664626SKris Kennaway * derivative of this code cannot be changed. i.e. this code cannot simply be 5774664626SKris Kennaway * copied and put under another distribution licence 5874664626SKris Kennaway * [including the GNU Public Licence.] 5974664626SKris Kennaway */ 6074664626SKris Kennaway /* ==================================================================== 611f13597dSJung-uk Kim * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. 6274664626SKris Kennaway * 6374664626SKris Kennaway * Redistribution and use in source and binary forms, with or without 6474664626SKris Kennaway * modification, are permitted provided that the following conditions 6574664626SKris Kennaway * are met: 6674664626SKris Kennaway * 6774664626SKris Kennaway * 1. Redistributions of source code must retain the above copyright 6874664626SKris Kennaway * notice, this list of conditions and the following disclaimer. 6974664626SKris Kennaway * 7074664626SKris Kennaway * 2. Redistributions in binary form must reproduce the above copyright 7174664626SKris Kennaway * notice, this list of conditions and the following disclaimer in 7274664626SKris Kennaway * the documentation and/or other materials provided with the 7374664626SKris Kennaway * distribution. 7474664626SKris Kennaway * 7574664626SKris Kennaway * 3. All advertising materials mentioning features or use of this 7674664626SKris Kennaway * software must display the following acknowledgment: 7774664626SKris Kennaway * "This product includes software developed by the OpenSSL Project 78ed5d4f9aSSimon L. B. Nielsen * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 7974664626SKris Kennaway * 8074664626SKris Kennaway * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 8174664626SKris Kennaway * endorse or promote products derived from this software without 8274664626SKris Kennaway * prior written permission. For written permission, please contact 83ed5d4f9aSSimon L. B. Nielsen * openssl-core@openssl.org. 8474664626SKris Kennaway * 8574664626SKris Kennaway * 5. Products derived from this software may not be called "OpenSSL" 8674664626SKris Kennaway * nor may "OpenSSL" appear in their names without prior written 8774664626SKris Kennaway * permission of the OpenSSL Project. 8874664626SKris Kennaway * 8974664626SKris Kennaway * 6. Redistributions of any form whatsoever must retain the following 9074664626SKris Kennaway * acknowledgment: 9174664626SKris Kennaway * "This product includes software developed by the OpenSSL Project 92ed5d4f9aSSimon L. B. Nielsen * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 9374664626SKris Kennaway * 9474664626SKris Kennaway * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 9574664626SKris Kennaway * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 9674664626SKris Kennaway * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 9774664626SKris Kennaway * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 9874664626SKris Kennaway * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 9974664626SKris Kennaway * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 10074664626SKris Kennaway * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 10174664626SKris Kennaway * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 10274664626SKris Kennaway * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 10374664626SKris Kennaway * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 10474664626SKris Kennaway * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 10574664626SKris Kennaway * OF THE POSSIBILITY OF SUCH DAMAGE. 10674664626SKris Kennaway * ==================================================================== 107ed5d4f9aSSimon L. B. Nielsen * 108ed5d4f9aSSimon L. B. Nielsen * This product includes cryptographic software written by Eric Young 109ed5d4f9aSSimon L. B. Nielsen * (eay@cryptsoft.com). This product includes software written by Tim 110ed5d4f9aSSimon L. B. Nielsen * Hudson (tjh@cryptsoft.com). 111ed5d4f9aSSimon L. B. Nielsen * 11274664626SKris Kennaway */ 1133b4e3dcbSSimon L. B. Nielsen /* ==================================================================== 1143b4e3dcbSSimon L. B. Nielsen * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 1153b4e3dcbSSimon L. B. Nielsen * ECC cipher suite support in OpenSSL originally developed by 1163b4e3dcbSSimon L. B. Nielsen * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. 1173b4e3dcbSSimon L. B. Nielsen */ 11874664626SKris Kennaway 11974664626SKris Kennaway #include <stdio.h> 120f579bf8eSKris Kennaway 1215c87c606SMark Murray #include "e_os.h" 122f579bf8eSKris Kennaway #ifndef NO_SYS_TYPES_H 12374664626SKris Kennaway # include <sys/types.h> 124f579bf8eSKris Kennaway #endif 125f579bf8eSKris Kennaway 1263b4e3dcbSSimon L. B. Nielsen #include "o_dir.h" 12774664626SKris Kennaway #include <openssl/objects.h> 12874664626SKris Kennaway #include <openssl/bio.h> 12974664626SKris Kennaway #include <openssl/pem.h> 130f579bf8eSKris Kennaway #include <openssl/x509v3.h> 1313b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_DH 1323b4e3dcbSSimon L. B. Nielsen # include <openssl/dh.h> 1333b4e3dcbSSimon L. B. Nielsen #endif 1343b4e3dcbSSimon L. B. Nielsen #include <openssl/bn.h> 13574664626SKris Kennaway #include "ssl_locl.h" 13674664626SKris Kennaway 13774664626SKris Kennaway int SSL_get_ex_data_X509_STORE_CTX_idx(void) 13874664626SKris Kennaway { 1395c87c606SMark Murray static volatile int ssl_x509_store_ctx_idx = -1; 140ed5d4f9aSSimon L. B. Nielsen int got_write_lock = 0; 141ed5d4f9aSSimon L. B. Nielsen 1427bded2dbSJung-uk Kim if (((size_t)&ssl_x509_store_ctx_idx & 1437bded2dbSJung-uk Kim (sizeof(ssl_x509_store_ctx_idx) - 1)) 1447bded2dbSJung-uk Kim == 0) { /* check alignment, practically always true */ 1457bded2dbSJung-uk Kim int ret; 1467bded2dbSJung-uk Kim 1477bded2dbSJung-uk Kim if ((ret = ssl_x509_store_ctx_idx) < 0) { 1487bded2dbSJung-uk Kim CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 1497bded2dbSJung-uk Kim if ((ret = ssl_x509_store_ctx_idx) < 0) { 1507bded2dbSJung-uk Kim ret = ssl_x509_store_ctx_idx = 1517bded2dbSJung-uk Kim X509_STORE_CTX_get_ex_new_index(0, 1527bded2dbSJung-uk Kim "SSL for verify callback", 1537bded2dbSJung-uk Kim NULL, NULL, NULL); 1547bded2dbSJung-uk Kim } 1557bded2dbSJung-uk Kim CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); 1567bded2dbSJung-uk Kim } 1577bded2dbSJung-uk Kim 1587bded2dbSJung-uk Kim return ret; 1597bded2dbSJung-uk Kim } else { /* commonly eliminated */ 1607bded2dbSJung-uk Kim 161ed5d4f9aSSimon L. B. Nielsen CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); 1625c87c606SMark Murray 1636f9291ceSJung-uk Kim if (ssl_x509_store_ctx_idx < 0) { 164ed5d4f9aSSimon L. B. Nielsen CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); 1655c87c606SMark Murray CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 166ed5d4f9aSSimon L. B. Nielsen got_write_lock = 1; 16774664626SKris Kennaway 1686f9291ceSJung-uk Kim if (ssl_x509_store_ctx_idx < 0) { 1696f9291ceSJung-uk Kim ssl_x509_store_ctx_idx = 1707bded2dbSJung-uk Kim X509_STORE_CTX_get_ex_new_index(0, 1717bded2dbSJung-uk Kim "SSL for verify callback", 1726f9291ceSJung-uk Kim NULL, NULL, NULL); 17374664626SKris Kennaway } 1745c87c606SMark Murray } 175ed5d4f9aSSimon L. B. Nielsen 176ed5d4f9aSSimon L. B. Nielsen if (got_write_lock) 177ed5d4f9aSSimon L. B. Nielsen CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); 178ed5d4f9aSSimon L. B. Nielsen else 179ed5d4f9aSSimon L. B. Nielsen CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); 180ed5d4f9aSSimon L. B. Nielsen 1815c87c606SMark Murray return ssl_x509_store_ctx_idx; 18274664626SKris Kennaway } 1837bded2dbSJung-uk Kim } 18474664626SKris Kennaway 1857bded2dbSJung-uk Kim void ssl_cert_set_default_md(CERT *cert) 1861f13597dSJung-uk Kim { 1871f13597dSJung-uk Kim /* Set digest values to defaults */ 1881f13597dSJung-uk Kim #ifndef OPENSSL_NO_DSA 18909286989SJung-uk Kim cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1(); 1901f13597dSJung-uk Kim #endif 1911f13597dSJung-uk Kim #ifndef OPENSSL_NO_RSA 1921f13597dSJung-uk Kim cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); 1931f13597dSJung-uk Kim cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); 1941f13597dSJung-uk Kim #endif 1951f13597dSJung-uk Kim #ifndef OPENSSL_NO_ECDSA 19609286989SJung-uk Kim cert->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); 1971f13597dSJung-uk Kim #endif 1981f13597dSJung-uk Kim } 1991f13597dSJung-uk Kim 20074664626SKris Kennaway CERT *ssl_cert_new(void) 20174664626SKris Kennaway { 20274664626SKris Kennaway CERT *ret; 20374664626SKris Kennaway 204ddd58736SKris Kennaway ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); 2056f9291ceSJung-uk Kim if (ret == NULL) { 20674664626SKris Kennaway SSLerr(SSL_F_SSL_CERT_NEW, ERR_R_MALLOC_FAILURE); 20774664626SKris Kennaway return (NULL); 20874664626SKris Kennaway } 20974664626SKris Kennaway memset(ret, 0, sizeof(CERT)); 21074664626SKris Kennaway 21174664626SKris Kennaway ret->key = &(ret->pkeys[SSL_PKEY_RSA_ENC]); 21274664626SKris Kennaway ret->references = 1; 2131f13597dSJung-uk Kim ssl_cert_set_default_md(ret); 21474664626SKris Kennaway return (ret); 21574664626SKris Kennaway } 21674664626SKris Kennaway 21774664626SKris Kennaway CERT *ssl_cert_dup(CERT *cert) 21874664626SKris Kennaway { 21974664626SKris Kennaway CERT *ret; 22074664626SKris Kennaway int i; 22174664626SKris Kennaway 222ddd58736SKris Kennaway ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); 2236f9291ceSJung-uk Kim if (ret == NULL) { 22474664626SKris Kennaway SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); 22574664626SKris Kennaway return (NULL); 22674664626SKris Kennaway } 22774664626SKris Kennaway 22874664626SKris Kennaway memset(ret, 0, sizeof(CERT)); 22974664626SKris Kennaway 23080815a77SJung-uk Kim ret->references = 1; 23174664626SKris Kennaway ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]]; 2326f9291ceSJung-uk Kim /* 2336f9291ceSJung-uk Kim * or ret->key = ret->pkeys + (cert->key - cert->pkeys), if you find that 2346f9291ceSJung-uk Kim * more readable 2356f9291ceSJung-uk Kim */ 23674664626SKris Kennaway 23774664626SKris Kennaway ret->valid = cert->valid; 2381f13597dSJung-uk Kim ret->mask_k = cert->mask_k; 2391f13597dSJung-uk Kim ret->mask_a = cert->mask_a; 2401f13597dSJung-uk Kim ret->export_mask_k = cert->export_mask_k; 2411f13597dSJung-uk Kim ret->export_mask_a = cert->export_mask_a; 24274664626SKris Kennaway 2435c87c606SMark Murray #ifndef OPENSSL_NO_RSA 2446f9291ceSJung-uk Kim if (cert->rsa_tmp != NULL) { 2455c87c606SMark Murray RSA_up_ref(cert->rsa_tmp); 24674664626SKris Kennaway ret->rsa_tmp = cert->rsa_tmp; 24774664626SKris Kennaway } 24874664626SKris Kennaway ret->rsa_tmp_cb = cert->rsa_tmp_cb; 24974664626SKris Kennaway #endif 25074664626SKris Kennaway 2515c87c606SMark Murray #ifndef OPENSSL_NO_DH 2526f9291ceSJung-uk Kim if (cert->dh_tmp != NULL) { 25374664626SKris Kennaway ret->dh_tmp = DHparams_dup(cert->dh_tmp); 2546f9291ceSJung-uk Kim if (ret->dh_tmp == NULL) { 255f579bf8eSKris Kennaway SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_DH_LIB); 25674664626SKris Kennaway goto err; 25774664626SKris Kennaway } 2586f9291ceSJung-uk Kim if (cert->dh_tmp->priv_key) { 259f579bf8eSKris Kennaway BIGNUM *b = BN_dup(cert->dh_tmp->priv_key); 2606f9291ceSJung-uk Kim if (!b) { 261f579bf8eSKris Kennaway SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); 262f579bf8eSKris Kennaway goto err; 263f579bf8eSKris Kennaway } 264f579bf8eSKris Kennaway ret->dh_tmp->priv_key = b; 265f579bf8eSKris Kennaway } 2666f9291ceSJung-uk Kim if (cert->dh_tmp->pub_key) { 267f579bf8eSKris Kennaway BIGNUM *b = BN_dup(cert->dh_tmp->pub_key); 2686f9291ceSJung-uk Kim if (!b) { 269f579bf8eSKris Kennaway SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); 270f579bf8eSKris Kennaway goto err; 271f579bf8eSKris Kennaway } 272f579bf8eSKris Kennaway ret->dh_tmp->pub_key = b; 273f579bf8eSKris Kennaway } 27474664626SKris Kennaway } 27574664626SKris Kennaway ret->dh_tmp_cb = cert->dh_tmp_cb; 27674664626SKris Kennaway #endif 27774664626SKris Kennaway 2783b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_ECDH 2796f9291ceSJung-uk Kim if (cert->ecdh_tmp) { 2803b4e3dcbSSimon L. B. Nielsen ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp); 2816f9291ceSJung-uk Kim if (ret->ecdh_tmp == NULL) { 2823b4e3dcbSSimon L. B. Nielsen SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_EC_LIB); 2833b4e3dcbSSimon L. B. Nielsen goto err; 2843b4e3dcbSSimon L. B. Nielsen } 2853b4e3dcbSSimon L. B. Nielsen } 2863b4e3dcbSSimon L. B. Nielsen ret->ecdh_tmp_cb = cert->ecdh_tmp_cb; 2877bded2dbSJung-uk Kim ret->ecdh_tmp_auto = cert->ecdh_tmp_auto; 2883b4e3dcbSSimon L. B. Nielsen #endif 2893b4e3dcbSSimon L. B. Nielsen 2906f9291ceSJung-uk Kim for (i = 0; i < SSL_PKEY_NUM; i++) { 2917bded2dbSJung-uk Kim CERT_PKEY *cpk = cert->pkeys + i; 2927bded2dbSJung-uk Kim CERT_PKEY *rpk = ret->pkeys + i; 2937bded2dbSJung-uk Kim if (cpk->x509 != NULL) { 2947bded2dbSJung-uk Kim rpk->x509 = cpk->x509; 2957bded2dbSJung-uk Kim CRYPTO_add(&rpk->x509->references, 1, CRYPTO_LOCK_X509); 29674664626SKris Kennaway } 29774664626SKris Kennaway 2987bded2dbSJung-uk Kim if (cpk->privatekey != NULL) { 2997bded2dbSJung-uk Kim rpk->privatekey = cpk->privatekey; 3007bded2dbSJung-uk Kim CRYPTO_add(&cpk->privatekey->references, 1, CRYPTO_LOCK_EVP_PKEY); 30174664626SKris Kennaway } 30274664626SKris Kennaway 3037bded2dbSJung-uk Kim if (cpk->chain) { 3047bded2dbSJung-uk Kim rpk->chain = X509_chain_up_ref(cpk->chain); 3057bded2dbSJung-uk Kim if (!rpk->chain) { 3067bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); 3077bded2dbSJung-uk Kim goto err; 3087bded2dbSJung-uk Kim } 3097bded2dbSJung-uk Kim } 3107bded2dbSJung-uk Kim rpk->valid_flags = 0; 3117bded2dbSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT 3127bded2dbSJung-uk Kim if (cert->pkeys[i].serverinfo != NULL) { 3137bded2dbSJung-uk Kim /* Just copy everything. */ 3147bded2dbSJung-uk Kim ret->pkeys[i].serverinfo = 3157bded2dbSJung-uk Kim OPENSSL_malloc(cert->pkeys[i].serverinfo_length); 3167bded2dbSJung-uk Kim if (ret->pkeys[i].serverinfo == NULL) { 3177bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); 318*6cf8931aSJung-uk Kim goto err; 3197bded2dbSJung-uk Kim } 3207bded2dbSJung-uk Kim ret->pkeys[i].serverinfo_length = 3217bded2dbSJung-uk Kim cert->pkeys[i].serverinfo_length; 3227bded2dbSJung-uk Kim memcpy(ret->pkeys[i].serverinfo, 3237bded2dbSJung-uk Kim cert->pkeys[i].serverinfo, 3247bded2dbSJung-uk Kim cert->pkeys[i].serverinfo_length); 3257bded2dbSJung-uk Kim } 3267bded2dbSJung-uk Kim #endif 3277bded2dbSJung-uk Kim } 32874664626SKris Kennaway 3296f9291ceSJung-uk Kim /* 3306f9291ceSJung-uk Kim * Set digests to defaults. NB: we don't copy existing values as they 3311f13597dSJung-uk Kim * will be set during handshake. 3321f13597dSJung-uk Kim */ 3331f13597dSJung-uk Kim ssl_cert_set_default_md(ret); 3347bded2dbSJung-uk Kim /* Peer sigalgs set to NULL as we get these from handshake too */ 3357bded2dbSJung-uk Kim ret->peer_sigalgs = NULL; 3367bded2dbSJung-uk Kim ret->peer_sigalgslen = 0; 3377bded2dbSJung-uk Kim /* Configured sigalgs however we copy across */ 3387bded2dbSJung-uk Kim 3397bded2dbSJung-uk Kim if (cert->conf_sigalgs) { 3407bded2dbSJung-uk Kim ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen); 3417bded2dbSJung-uk Kim if (!ret->conf_sigalgs) 3427bded2dbSJung-uk Kim goto err; 3437bded2dbSJung-uk Kim memcpy(ret->conf_sigalgs, cert->conf_sigalgs, cert->conf_sigalgslen); 3447bded2dbSJung-uk Kim ret->conf_sigalgslen = cert->conf_sigalgslen; 3457bded2dbSJung-uk Kim } else 3467bded2dbSJung-uk Kim ret->conf_sigalgs = NULL; 3477bded2dbSJung-uk Kim 3487bded2dbSJung-uk Kim if (cert->client_sigalgs) { 3497bded2dbSJung-uk Kim ret->client_sigalgs = OPENSSL_malloc(cert->client_sigalgslen); 3507bded2dbSJung-uk Kim if (!ret->client_sigalgs) 3517bded2dbSJung-uk Kim goto err; 3527bded2dbSJung-uk Kim memcpy(ret->client_sigalgs, cert->client_sigalgs, 3537bded2dbSJung-uk Kim cert->client_sigalgslen); 3547bded2dbSJung-uk Kim ret->client_sigalgslen = cert->client_sigalgslen; 3557bded2dbSJung-uk Kim } else 3567bded2dbSJung-uk Kim ret->client_sigalgs = NULL; 3577bded2dbSJung-uk Kim /* Shared sigalgs also NULL */ 3587bded2dbSJung-uk Kim ret->shared_sigalgs = NULL; 3597bded2dbSJung-uk Kim /* Copy any custom client certificate types */ 3607bded2dbSJung-uk Kim if (cert->ctypes) { 3617bded2dbSJung-uk Kim ret->ctypes = OPENSSL_malloc(cert->ctype_num); 3627bded2dbSJung-uk Kim if (!ret->ctypes) 3637bded2dbSJung-uk Kim goto err; 3647bded2dbSJung-uk Kim memcpy(ret->ctypes, cert->ctypes, cert->ctype_num); 3657bded2dbSJung-uk Kim ret->ctype_num = cert->ctype_num; 3667bded2dbSJung-uk Kim } 3677bded2dbSJung-uk Kim 3687bded2dbSJung-uk Kim ret->cert_flags = cert->cert_flags; 3697bded2dbSJung-uk Kim 3707bded2dbSJung-uk Kim ret->cert_cb = cert->cert_cb; 3717bded2dbSJung-uk Kim ret->cert_cb_arg = cert->cert_cb_arg; 3727bded2dbSJung-uk Kim 3737bded2dbSJung-uk Kim if (cert->verify_store) { 3747bded2dbSJung-uk Kim CRYPTO_add(&cert->verify_store->references, 1, 3757bded2dbSJung-uk Kim CRYPTO_LOCK_X509_STORE); 3767bded2dbSJung-uk Kim ret->verify_store = cert->verify_store; 3777bded2dbSJung-uk Kim } 3787bded2dbSJung-uk Kim 3797bded2dbSJung-uk Kim if (cert->chain_store) { 3807bded2dbSJung-uk Kim CRYPTO_add(&cert->chain_store->references, 1, CRYPTO_LOCK_X509_STORE); 3817bded2dbSJung-uk Kim ret->chain_store = cert->chain_store; 3827bded2dbSJung-uk Kim } 3837bded2dbSJung-uk Kim 3847bded2dbSJung-uk Kim ret->ciphers_raw = NULL; 3857bded2dbSJung-uk Kim 3867bded2dbSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT 3877bded2dbSJung-uk Kim if (!custom_exts_copy(&ret->cli_ext, &cert->cli_ext)) 3887bded2dbSJung-uk Kim goto err; 3897bded2dbSJung-uk Kim if (!custom_exts_copy(&ret->srv_ext, &cert->srv_ext)) 3907bded2dbSJung-uk Kim goto err; 3917bded2dbSJung-uk Kim #endif 39274664626SKris Kennaway 39374664626SKris Kennaway return (ret); 39474664626SKris Kennaway 39574664626SKris Kennaway err: 3965c87c606SMark Murray #ifndef OPENSSL_NO_RSA 39774664626SKris Kennaway if (ret->rsa_tmp != NULL) 39874664626SKris Kennaway RSA_free(ret->rsa_tmp); 39974664626SKris Kennaway #endif 4005c87c606SMark Murray #ifndef OPENSSL_NO_DH 40174664626SKris Kennaway if (ret->dh_tmp != NULL) 40274664626SKris Kennaway DH_free(ret->dh_tmp); 40374664626SKris Kennaway #endif 4043b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_ECDH 4053b4e3dcbSSimon L. B. Nielsen if (ret->ecdh_tmp != NULL) 4063b4e3dcbSSimon L. B. Nielsen EC_KEY_free(ret->ecdh_tmp); 4073b4e3dcbSSimon L. B. Nielsen #endif 40874664626SKris Kennaway 4097bded2dbSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT 4107bded2dbSJung-uk Kim custom_exts_free(&ret->cli_ext); 4117bded2dbSJung-uk Kim custom_exts_free(&ret->srv_ext); 4127bded2dbSJung-uk Kim #endif 4137bded2dbSJung-uk Kim 4147bded2dbSJung-uk Kim ssl_cert_clear_certs(ret); 41574664626SKris Kennaway 41674664626SKris Kennaway return NULL; 41774664626SKris Kennaway } 41874664626SKris Kennaway 4197bded2dbSJung-uk Kim /* Free up and clear all certificates and chains */ 4207bded2dbSJung-uk Kim 4217bded2dbSJung-uk Kim void ssl_cert_clear_certs(CERT *c) 4227bded2dbSJung-uk Kim { 4237bded2dbSJung-uk Kim int i; 4247bded2dbSJung-uk Kim if (c == NULL) 4257bded2dbSJung-uk Kim return; 4267bded2dbSJung-uk Kim for (i = 0; i < SSL_PKEY_NUM; i++) { 4277bded2dbSJung-uk Kim CERT_PKEY *cpk = c->pkeys + i; 4287bded2dbSJung-uk Kim if (cpk->x509) { 4297bded2dbSJung-uk Kim X509_free(cpk->x509); 4307bded2dbSJung-uk Kim cpk->x509 = NULL; 4317bded2dbSJung-uk Kim } 4327bded2dbSJung-uk Kim if (cpk->privatekey) { 4337bded2dbSJung-uk Kim EVP_PKEY_free(cpk->privatekey); 4347bded2dbSJung-uk Kim cpk->privatekey = NULL; 4357bded2dbSJung-uk Kim } 4367bded2dbSJung-uk Kim if (cpk->chain) { 4377bded2dbSJung-uk Kim sk_X509_pop_free(cpk->chain, X509_free); 4387bded2dbSJung-uk Kim cpk->chain = NULL; 4397bded2dbSJung-uk Kim } 4407bded2dbSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT 4417bded2dbSJung-uk Kim if (cpk->serverinfo) { 4427bded2dbSJung-uk Kim OPENSSL_free(cpk->serverinfo); 4437bded2dbSJung-uk Kim cpk->serverinfo = NULL; 4447bded2dbSJung-uk Kim cpk->serverinfo_length = 0; 4457bded2dbSJung-uk Kim } 4467bded2dbSJung-uk Kim #endif 4477bded2dbSJung-uk Kim /* Clear all flags apart from explicit sign */ 4487bded2dbSJung-uk Kim cpk->valid_flags &= CERT_PKEY_EXPLICIT_SIGN; 4497bded2dbSJung-uk Kim } 4507bded2dbSJung-uk Kim } 4517bded2dbSJung-uk Kim 45274664626SKris Kennaway void ssl_cert_free(CERT *c) 45374664626SKris Kennaway { 45474664626SKris Kennaway int i; 45574664626SKris Kennaway 45674664626SKris Kennaway if (c == NULL) 45774664626SKris Kennaway return; 45874664626SKris Kennaway 45974664626SKris Kennaway i = CRYPTO_add(&c->references, -1, CRYPTO_LOCK_SSL_CERT); 46074664626SKris Kennaway #ifdef REF_PRINT 46174664626SKris Kennaway REF_PRINT("CERT", c); 46274664626SKris Kennaway #endif 4636f9291ceSJung-uk Kim if (i > 0) 4646f9291ceSJung-uk Kim return; 46574664626SKris Kennaway #ifdef REF_CHECK 4666f9291ceSJung-uk Kim if (i < 0) { 46774664626SKris Kennaway fprintf(stderr, "ssl_cert_free, bad reference count\n"); 46874664626SKris Kennaway abort(); /* ok */ 46974664626SKris Kennaway } 47074664626SKris Kennaway #endif 47174664626SKris Kennaway 4725c87c606SMark Murray #ifndef OPENSSL_NO_RSA 4736f9291ceSJung-uk Kim if (c->rsa_tmp) 4746f9291ceSJung-uk Kim RSA_free(c->rsa_tmp); 47574664626SKris Kennaway #endif 4765c87c606SMark Murray #ifndef OPENSSL_NO_DH 4776f9291ceSJung-uk Kim if (c->dh_tmp) 4786f9291ceSJung-uk Kim DH_free(c->dh_tmp); 47974664626SKris Kennaway #endif 4803b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_ECDH 4816f9291ceSJung-uk Kim if (c->ecdh_tmp) 4826f9291ceSJung-uk Kim EC_KEY_free(c->ecdh_tmp); 4833b4e3dcbSSimon L. B. Nielsen #endif 48474664626SKris Kennaway 4857bded2dbSJung-uk Kim ssl_cert_clear_certs(c); 4867bded2dbSJung-uk Kim if (c->peer_sigalgs) 4877bded2dbSJung-uk Kim OPENSSL_free(c->peer_sigalgs); 4887bded2dbSJung-uk Kim if (c->conf_sigalgs) 4897bded2dbSJung-uk Kim OPENSSL_free(c->conf_sigalgs); 4907bded2dbSJung-uk Kim if (c->client_sigalgs) 4917bded2dbSJung-uk Kim OPENSSL_free(c->client_sigalgs); 4927bded2dbSJung-uk Kim if (c->shared_sigalgs) 4937bded2dbSJung-uk Kim OPENSSL_free(c->shared_sigalgs); 4947bded2dbSJung-uk Kim if (c->ctypes) 4957bded2dbSJung-uk Kim OPENSSL_free(c->ctypes); 4967bded2dbSJung-uk Kim if (c->verify_store) 4977bded2dbSJung-uk Kim X509_STORE_free(c->verify_store); 4987bded2dbSJung-uk Kim if (c->chain_store) 4997bded2dbSJung-uk Kim X509_STORE_free(c->chain_store); 5007bded2dbSJung-uk Kim if (c->ciphers_raw) 5017bded2dbSJung-uk Kim OPENSSL_free(c->ciphers_raw); 5027bded2dbSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT 5037bded2dbSJung-uk Kim custom_exts_free(&c->cli_ext); 5047bded2dbSJung-uk Kim custom_exts_free(&c->srv_ext); 505b8721c16SJung-uk Kim if (c->alpn_proposed) 506b8721c16SJung-uk Kim OPENSSL_free(c->alpn_proposed); 50774664626SKris Kennaway #endif 508ddd58736SKris Kennaway OPENSSL_free(c); 50974664626SKris Kennaway } 51074664626SKris Kennaway 51174664626SKris Kennaway int ssl_cert_inst(CERT **o) 51274664626SKris Kennaway { 5136f9291ceSJung-uk Kim /* 5146f9291ceSJung-uk Kim * Create a CERT if there isn't already one (which cannot really happen, 5156f9291ceSJung-uk Kim * as it is initially created in SSL_CTX_new; but the earlier code 5166f9291ceSJung-uk Kim * usually allows for that one being non-existant, so we follow that 5176f9291ceSJung-uk Kim * behaviour, as it might turn out that there actually is a reason for it 5186f9291ceSJung-uk Kim * -- but I'm not sure that *all* of the existing code could cope with 5196f9291ceSJung-uk Kim * s->cert being NULL, otherwise we could do without the initialization 5206f9291ceSJung-uk Kim * in SSL_CTX_new). 52174664626SKris Kennaway */ 52274664626SKris Kennaway 5236f9291ceSJung-uk Kim if (o == NULL) { 52474664626SKris Kennaway SSLerr(SSL_F_SSL_CERT_INST, ERR_R_PASSED_NULL_PARAMETER); 52574664626SKris Kennaway return (0); 52674664626SKris Kennaway } 5276f9291ceSJung-uk Kim if (*o == NULL) { 5286f9291ceSJung-uk Kim if ((*o = ssl_cert_new()) == NULL) { 52974664626SKris Kennaway SSLerr(SSL_F_SSL_CERT_INST, ERR_R_MALLOC_FAILURE); 53074664626SKris Kennaway return (0); 53174664626SKris Kennaway } 53274664626SKris Kennaway } 53374664626SKris Kennaway return (1); 53474664626SKris Kennaway } 53574664626SKris Kennaway 5367bded2dbSJung-uk Kim int ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain) 5377bded2dbSJung-uk Kim { 5387bded2dbSJung-uk Kim CERT_PKEY *cpk = c->key; 5397bded2dbSJung-uk Kim if (!cpk) 5407bded2dbSJung-uk Kim return 0; 5417bded2dbSJung-uk Kim if (cpk->chain) 5427bded2dbSJung-uk Kim sk_X509_pop_free(cpk->chain, X509_free); 5437bded2dbSJung-uk Kim cpk->chain = chain; 5447bded2dbSJung-uk Kim return 1; 5457bded2dbSJung-uk Kim } 5467bded2dbSJung-uk Kim 5477bded2dbSJung-uk Kim int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain) 5487bded2dbSJung-uk Kim { 5497bded2dbSJung-uk Kim STACK_OF(X509) *dchain; 5507bded2dbSJung-uk Kim if (!chain) 5517bded2dbSJung-uk Kim return ssl_cert_set0_chain(c, NULL); 5527bded2dbSJung-uk Kim dchain = X509_chain_up_ref(chain); 5537bded2dbSJung-uk Kim if (!dchain) 5547bded2dbSJung-uk Kim return 0; 5557bded2dbSJung-uk Kim if (!ssl_cert_set0_chain(c, dchain)) { 5567bded2dbSJung-uk Kim sk_X509_pop_free(dchain, X509_free); 5577bded2dbSJung-uk Kim return 0; 5587bded2dbSJung-uk Kim } 5597bded2dbSJung-uk Kim return 1; 5607bded2dbSJung-uk Kim } 5617bded2dbSJung-uk Kim 5627bded2dbSJung-uk Kim int ssl_cert_add0_chain_cert(CERT *c, X509 *x) 5637bded2dbSJung-uk Kim { 5647bded2dbSJung-uk Kim CERT_PKEY *cpk = c->key; 5657bded2dbSJung-uk Kim if (!cpk) 5667bded2dbSJung-uk Kim return 0; 5677bded2dbSJung-uk Kim if (!cpk->chain) 5687bded2dbSJung-uk Kim cpk->chain = sk_X509_new_null(); 5697bded2dbSJung-uk Kim if (!cpk->chain || !sk_X509_push(cpk->chain, x)) 5707bded2dbSJung-uk Kim return 0; 5717bded2dbSJung-uk Kim return 1; 5727bded2dbSJung-uk Kim } 5737bded2dbSJung-uk Kim 5747bded2dbSJung-uk Kim int ssl_cert_add1_chain_cert(CERT *c, X509 *x) 5757bded2dbSJung-uk Kim { 5767bded2dbSJung-uk Kim if (!ssl_cert_add0_chain_cert(c, x)) 5777bded2dbSJung-uk Kim return 0; 5787bded2dbSJung-uk Kim CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); 5797bded2dbSJung-uk Kim return 1; 5807bded2dbSJung-uk Kim } 5817bded2dbSJung-uk Kim 5827bded2dbSJung-uk Kim int ssl_cert_select_current(CERT *c, X509 *x) 5837bded2dbSJung-uk Kim { 5847bded2dbSJung-uk Kim int i; 5857bded2dbSJung-uk Kim if (x == NULL) 5867bded2dbSJung-uk Kim return 0; 5877bded2dbSJung-uk Kim for (i = 0; i < SSL_PKEY_NUM; i++) { 5887bded2dbSJung-uk Kim CERT_PKEY *cpk = c->pkeys + i; 5897bded2dbSJung-uk Kim if (cpk->x509 == x && cpk->privatekey) { 5907bded2dbSJung-uk Kim c->key = cpk; 5917bded2dbSJung-uk Kim return 1; 5927bded2dbSJung-uk Kim } 5937bded2dbSJung-uk Kim } 5947bded2dbSJung-uk Kim 5957bded2dbSJung-uk Kim for (i = 0; i < SSL_PKEY_NUM; i++) { 5967bded2dbSJung-uk Kim CERT_PKEY *cpk = c->pkeys + i; 5977bded2dbSJung-uk Kim if (cpk->privatekey && cpk->x509 && !X509_cmp(cpk->x509, x)) { 5987bded2dbSJung-uk Kim c->key = cpk; 5997bded2dbSJung-uk Kim return 1; 6007bded2dbSJung-uk Kim } 6017bded2dbSJung-uk Kim } 6027bded2dbSJung-uk Kim return 0; 6037bded2dbSJung-uk Kim } 6047bded2dbSJung-uk Kim 6057bded2dbSJung-uk Kim int ssl_cert_set_current(CERT *c, long op) 6067bded2dbSJung-uk Kim { 6077bded2dbSJung-uk Kim int i, idx; 6087bded2dbSJung-uk Kim if (!c) 6097bded2dbSJung-uk Kim return 0; 6107bded2dbSJung-uk Kim if (op == SSL_CERT_SET_FIRST) 6117bded2dbSJung-uk Kim idx = 0; 6127bded2dbSJung-uk Kim else if (op == SSL_CERT_SET_NEXT) { 6137bded2dbSJung-uk Kim idx = (int)(c->key - c->pkeys + 1); 6147bded2dbSJung-uk Kim if (idx >= SSL_PKEY_NUM) 6157bded2dbSJung-uk Kim return 0; 6167bded2dbSJung-uk Kim } else 6177bded2dbSJung-uk Kim return 0; 6187bded2dbSJung-uk Kim for (i = idx; i < SSL_PKEY_NUM; i++) { 6197bded2dbSJung-uk Kim CERT_PKEY *cpk = c->pkeys + i; 6207bded2dbSJung-uk Kim if (cpk->x509 && cpk->privatekey) { 6217bded2dbSJung-uk Kim c->key = cpk; 6227bded2dbSJung-uk Kim return 1; 6237bded2dbSJung-uk Kim } 6247bded2dbSJung-uk Kim } 6257bded2dbSJung-uk Kim return 0; 6267bded2dbSJung-uk Kim } 6277bded2dbSJung-uk Kim 6287bded2dbSJung-uk Kim void ssl_cert_set_cert_cb(CERT *c, int (*cb) (SSL *ssl, void *arg), void *arg) 6297bded2dbSJung-uk Kim { 6307bded2dbSJung-uk Kim c->cert_cb = cb; 6317bded2dbSJung-uk Kim c->cert_cb_arg = arg; 6327bded2dbSJung-uk Kim } 6337bded2dbSJung-uk Kim 63474664626SKris Kennaway SESS_CERT *ssl_sess_cert_new(void) 63574664626SKris Kennaway { 63674664626SKris Kennaway SESS_CERT *ret; 63774664626SKris Kennaway 638ddd58736SKris Kennaway ret = OPENSSL_malloc(sizeof *ret); 6396f9291ceSJung-uk Kim if (ret == NULL) { 64074664626SKris Kennaway SSLerr(SSL_F_SSL_SESS_CERT_NEW, ERR_R_MALLOC_FAILURE); 64174664626SKris Kennaway return NULL; 64274664626SKris Kennaway } 64374664626SKris Kennaway 64474664626SKris Kennaway memset(ret, 0, sizeof *ret); 64574664626SKris Kennaway ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA_ENC]); 64674664626SKris Kennaway ret->references = 1; 64774664626SKris Kennaway 64874664626SKris Kennaway return ret; 64974664626SKris Kennaway } 65074664626SKris Kennaway 65174664626SKris Kennaway void ssl_sess_cert_free(SESS_CERT *sc) 65274664626SKris Kennaway { 65374664626SKris Kennaway int i; 65474664626SKris Kennaway 65574664626SKris Kennaway if (sc == NULL) 65674664626SKris Kennaway return; 65774664626SKris Kennaway 65874664626SKris Kennaway i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT); 65974664626SKris Kennaway #ifdef REF_PRINT 66074664626SKris Kennaway REF_PRINT("SESS_CERT", sc); 66174664626SKris Kennaway #endif 66274664626SKris Kennaway if (i > 0) 66374664626SKris Kennaway return; 66474664626SKris Kennaway #ifdef REF_CHECK 6656f9291ceSJung-uk Kim if (i < 0) { 66674664626SKris Kennaway fprintf(stderr, "ssl_sess_cert_free, bad reference count\n"); 66774664626SKris Kennaway abort(); /* ok */ 66874664626SKris Kennaway } 66974664626SKris Kennaway #endif 67074664626SKris Kennaway 67174664626SKris Kennaway /* i == 0 */ 67274664626SKris Kennaway if (sc->cert_chain != NULL) 67374664626SKris Kennaway sk_X509_pop_free(sc->cert_chain, X509_free); 6746f9291ceSJung-uk Kim for (i = 0; i < SSL_PKEY_NUM; i++) { 67574664626SKris Kennaway if (sc->peer_pkeys[i].x509 != NULL) 67674664626SKris Kennaway X509_free(sc->peer_pkeys[i].x509); 6776f9291ceSJung-uk Kim #if 0 /* We don't have the peer's private key. 6786f9291ceSJung-uk Kim * These lines are just * here as a reminder 6796f9291ceSJung-uk Kim * that we're still using a 6806f9291ceSJung-uk Kim * not-quite-appropriate * data structure. */ 68174664626SKris Kennaway if (sc->peer_pkeys[i].privatekey != NULL) 68274664626SKris Kennaway EVP_PKEY_free(sc->peer_pkeys[i].privatekey); 68374664626SKris Kennaway #endif 68474664626SKris Kennaway } 68574664626SKris Kennaway 6865c87c606SMark Murray #ifndef OPENSSL_NO_RSA 68774664626SKris Kennaway if (sc->peer_rsa_tmp != NULL) 68874664626SKris Kennaway RSA_free(sc->peer_rsa_tmp); 68974664626SKris Kennaway #endif 6905c87c606SMark Murray #ifndef OPENSSL_NO_DH 69174664626SKris Kennaway if (sc->peer_dh_tmp != NULL) 69274664626SKris Kennaway DH_free(sc->peer_dh_tmp); 69374664626SKris Kennaway #endif 6943b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_ECDH 6953b4e3dcbSSimon L. B. Nielsen if (sc->peer_ecdh_tmp != NULL) 6963b4e3dcbSSimon L. B. Nielsen EC_KEY_free(sc->peer_ecdh_tmp); 6973b4e3dcbSSimon L. B. Nielsen #endif 69874664626SKris Kennaway 699ddd58736SKris Kennaway OPENSSL_free(sc); 70074664626SKris Kennaway } 70174664626SKris Kennaway 70274664626SKris Kennaway int ssl_set_peer_cert_type(SESS_CERT *sc, int type) 70374664626SKris Kennaway { 70474664626SKris Kennaway sc->peer_cert_type = type; 70574664626SKris Kennaway return (1); 70674664626SKris Kennaway } 70774664626SKris Kennaway 70874664626SKris Kennaway int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) 70974664626SKris Kennaway { 71074664626SKris Kennaway X509 *x; 71174664626SKris Kennaway int i; 7127bded2dbSJung-uk Kim X509_STORE *verify_store; 71374664626SKris Kennaway X509_STORE_CTX ctx; 71474664626SKris Kennaway 7157bded2dbSJung-uk Kim if (s->cert->verify_store) 7167bded2dbSJung-uk Kim verify_store = s->cert->verify_store; 7177bded2dbSJung-uk Kim else 7187bded2dbSJung-uk Kim verify_store = s->ctx->cert_store; 7197bded2dbSJung-uk Kim 72074664626SKris Kennaway if ((sk == NULL) || (sk_X509_num(sk) == 0)) 72174664626SKris Kennaway return (0); 72274664626SKris Kennaway 72374664626SKris Kennaway x = sk_X509_value(sk, 0); 7247bded2dbSJung-uk Kim if (!X509_STORE_CTX_init(&ctx, verify_store, x, sk)) { 7255c87c606SMark Murray SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_X509_LIB); 7265c87c606SMark Murray return (0); 7275c87c606SMark Murray } 7287bded2dbSJung-uk Kim /* Set suite B flags if needed */ 7297bded2dbSJung-uk Kim X509_STORE_CTX_set_flags(&ctx, tls1_suiteb(s)); 7303b4e3dcbSSimon L. B. Nielsen #if 0 73174664626SKris Kennaway if (SSL_get_verify_depth(s) >= 0) 73274664626SKris Kennaway X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s)); 7333b4e3dcbSSimon L. B. Nielsen #endif 734f579bf8eSKris Kennaway X509_STORE_CTX_set_ex_data(&ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s); 7355c87c606SMark Murray 7366f9291ceSJung-uk Kim /* 7376f9291ceSJung-uk Kim * We need to inherit the verify parameters. These can be determined by 7386f9291ceSJung-uk Kim * the context: if its a server it will verify SSL client certificates or 7396f9291ceSJung-uk Kim * vice versa. 740f579bf8eSKris Kennaway */ 741f579bf8eSKris Kennaway 7426f9291ceSJung-uk Kim X509_STORE_CTX_set_default(&ctx, s->server ? "ssl_client" : "ssl_server"); 7436f9291ceSJung-uk Kim /* 7446f9291ceSJung-uk Kim * Anything non-default in "param" should overwrite anything in the ctx. 7456a599222SSimon L. B. Nielsen */ 7466a599222SSimon L. B. Nielsen X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param); 74774664626SKris Kennaway 748a21b1b38SKris Kennaway if (s->verify_callback) 749a21b1b38SKris Kennaway X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback); 750a21b1b38SKris Kennaway 75174664626SKris Kennaway if (s->ctx->app_verify_callback != NULL) 7525c87c606SMark Murray #if 1 /* new with OpenSSL 0.9.7 */ 7535c87c606SMark Murray i = s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg); 7545c87c606SMark Murray #else 75574664626SKris Kennaway i = s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */ 7565c87c606SMark Murray #endif 7576f9291ceSJung-uk Kim else { 7585c87c606SMark Murray #ifndef OPENSSL_NO_X509_VERIFY 75974664626SKris Kennaway i = X509_verify_cert(&ctx); 76074664626SKris Kennaway #else 76174664626SKris Kennaway i = 0; 76274664626SKris Kennaway ctx.error = X509_V_ERR_APPLICATION_VERIFICATION; 76374664626SKris Kennaway SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, SSL_R_NO_VERIFY_CALLBACK); 76474664626SKris Kennaway #endif 76574664626SKris Kennaway } 76674664626SKris Kennaway 76774664626SKris Kennaway s->verify_result = ctx.error; 76874664626SKris Kennaway X509_STORE_CTX_cleanup(&ctx); 76974664626SKris Kennaway 77074664626SKris Kennaway return (i); 77174664626SKris Kennaway } 77274664626SKris Kennaway 7736f9291ceSJung-uk Kim static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list, 7746f9291ceSJung-uk Kim STACK_OF(X509_NAME) *name_list) 77574664626SKris Kennaway { 77674664626SKris Kennaway if (*ca_list != NULL) 77774664626SKris Kennaway sk_X509_NAME_pop_free(*ca_list, X509_NAME_free); 77874664626SKris Kennaway 779ced566fdSJacques Vidrine *ca_list = name_list; 78074664626SKris Kennaway } 78174664626SKris Kennaway 78274664626SKris Kennaway STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk) 78374664626SKris Kennaway { 78474664626SKris Kennaway int i; 78574664626SKris Kennaway STACK_OF(X509_NAME) *ret; 78674664626SKris Kennaway X509_NAME *name; 78774664626SKris Kennaway 78874664626SKris Kennaway ret = sk_X509_NAME_new_null(); 7896f9291ceSJung-uk Kim for (i = 0; i < sk_X509_NAME_num(sk); i++) { 79074664626SKris Kennaway name = X509_NAME_dup(sk_X509_NAME_value(sk, i)); 7916f9291ceSJung-uk Kim if ((name == NULL) || !sk_X509_NAME_push(ret, name)) { 79274664626SKris Kennaway sk_X509_NAME_pop_free(ret, X509_NAME_free); 79374664626SKris Kennaway return (NULL); 79474664626SKris Kennaway } 79574664626SKris Kennaway } 79674664626SKris Kennaway return (ret); 79774664626SKris Kennaway } 79874664626SKris Kennaway 799ced566fdSJacques Vidrine void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list) 80074664626SKris Kennaway { 801ced566fdSJacques Vidrine set_client_CA_list(&(s->client_CA), name_list); 80274664626SKris Kennaway } 80374664626SKris Kennaway 804ced566fdSJacques Vidrine void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) 80574664626SKris Kennaway { 806ced566fdSJacques Vidrine set_client_CA_list(&(ctx->client_CA), name_list); 80774664626SKris Kennaway } 80874664626SKris Kennaway 8093b4e3dcbSSimon L. B. Nielsen STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) 81074664626SKris Kennaway { 81174664626SKris Kennaway return (ctx->client_CA); 81274664626SKris Kennaway } 81374664626SKris Kennaway 8143b4e3dcbSSimon L. B. Nielsen STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s) 81574664626SKris Kennaway { 8166f9291ceSJung-uk Kim if (s->type == SSL_ST_CONNECT) { /* we are in the client */ 8176f9291ceSJung-uk Kim if (((s->version >> 8) == SSL3_VERSION_MAJOR) && (s->s3 != NULL)) 81874664626SKris Kennaway return (s->s3->tmp.ca_names); 81974664626SKris Kennaway else 82074664626SKris Kennaway return (NULL); 8216f9291ceSJung-uk Kim } else { 82274664626SKris Kennaway if (s->client_CA != NULL) 82374664626SKris Kennaway return (s->client_CA); 82474664626SKris Kennaway else 82574664626SKris Kennaway return (s->ctx->client_CA); 82674664626SKris Kennaway } 82774664626SKris Kennaway } 82874664626SKris Kennaway 82974664626SKris Kennaway static int add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x) 83074664626SKris Kennaway { 83174664626SKris Kennaway X509_NAME *name; 83274664626SKris Kennaway 8336f9291ceSJung-uk Kim if (x == NULL) 8346f9291ceSJung-uk Kim return (0); 83574664626SKris Kennaway if ((*sk == NULL) && ((*sk = sk_X509_NAME_new_null()) == NULL)) 83674664626SKris Kennaway return (0); 83774664626SKris Kennaway 83874664626SKris Kennaway if ((name = X509_NAME_dup(X509_get_subject_name(x))) == NULL) 83974664626SKris Kennaway return (0); 84074664626SKris Kennaway 8416f9291ceSJung-uk Kim if (!sk_X509_NAME_push(*sk, name)) { 84274664626SKris Kennaway X509_NAME_free(name); 84374664626SKris Kennaway return (0); 84474664626SKris Kennaway } 84574664626SKris Kennaway return (1); 84674664626SKris Kennaway } 84774664626SKris Kennaway 84874664626SKris Kennaway int SSL_add_client_CA(SSL *ssl, X509 *x) 84974664626SKris Kennaway { 85074664626SKris Kennaway return (add_client_CA(&(ssl->client_CA), x)); 85174664626SKris Kennaway } 85274664626SKris Kennaway 85374664626SKris Kennaway int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) 85474664626SKris Kennaway { 85574664626SKris Kennaway return (add_client_CA(&(ctx->client_CA), x)); 85674664626SKris Kennaway } 85774664626SKris Kennaway 858ddd58736SKris Kennaway static int xname_cmp(const X509_NAME *const *a, const X509_NAME *const *b) 85974664626SKris Kennaway { 86074664626SKris Kennaway return (X509_NAME_cmp(*a, *b)); 86174664626SKris Kennaway } 86274664626SKris Kennaway 8635c87c606SMark Murray #ifndef OPENSSL_NO_STDIO 8646f9291ceSJung-uk Kim /** 86574664626SKris Kennaway * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed; 86674664626SKris Kennaway * it doesn't really have anything to do with clients (except that a common use 86774664626SKris Kennaway * for a stack of CAs is to send it to the client). Actually, it doesn't have 86874664626SKris Kennaway * much to do with CAs, either, since it will load any old cert. 86974664626SKris Kennaway * \param file the file containing one or more certs. 87074664626SKris Kennaway * \return a ::STACK containing the certs. 87174664626SKris Kennaway */ 87274664626SKris Kennaway STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) 87374664626SKris Kennaway { 87474664626SKris Kennaway BIO *in; 87574664626SKris Kennaway X509 *x = NULL; 87674664626SKris Kennaway X509_NAME *xn = NULL; 8773b4e3dcbSSimon L. B. Nielsen STACK_OF(X509_NAME) *ret = NULL, *sk; 87874664626SKris Kennaway 879f579bf8eSKris Kennaway sk = sk_X509_NAME_new(xname_cmp); 88074664626SKris Kennaway 88174664626SKris Kennaway in = BIO_new(BIO_s_file_internal()); 88274664626SKris Kennaway 8836f9291ceSJung-uk Kim if ((sk == NULL) || (in == NULL)) { 88474664626SKris Kennaway SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE); 88574664626SKris Kennaway goto err; 88674664626SKris Kennaway } 88774664626SKris Kennaway 88874664626SKris Kennaway if (!BIO_read_filename(in, file)) 88974664626SKris Kennaway goto err; 89074664626SKris Kennaway 8916f9291ceSJung-uk Kim for (;;) { 89274664626SKris Kennaway if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) 89374664626SKris Kennaway break; 8946f9291ceSJung-uk Kim if (ret == NULL) { 8953b4e3dcbSSimon L. B. Nielsen ret = sk_X509_NAME_new_null(); 8966f9291ceSJung-uk Kim if (ret == NULL) { 8973b4e3dcbSSimon L. B. Nielsen SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE); 8983b4e3dcbSSimon L. B. Nielsen goto err; 8993b4e3dcbSSimon L. B. Nielsen } 9003b4e3dcbSSimon L. B. Nielsen } 9016f9291ceSJung-uk Kim if ((xn = X509_get_subject_name(x)) == NULL) 9026f9291ceSJung-uk Kim goto err; 90374664626SKris Kennaway /* check for duplicates */ 90474664626SKris Kennaway xn = X509_NAME_dup(xn); 9056f9291ceSJung-uk Kim if (xn == NULL) 9066f9291ceSJung-uk Kim goto err; 90774664626SKris Kennaway if (sk_X509_NAME_find(sk, xn) >= 0) 90874664626SKris Kennaway X509_NAME_free(xn); 9096f9291ceSJung-uk Kim else { 91074664626SKris Kennaway sk_X509_NAME_push(sk, xn); 91174664626SKris Kennaway sk_X509_NAME_push(ret, xn); 91274664626SKris Kennaway } 91374664626SKris Kennaway } 91474664626SKris Kennaway 9156f9291ceSJung-uk Kim if (0) { 91674664626SKris Kennaway err: 9176f9291ceSJung-uk Kim if (ret != NULL) 9186f9291ceSJung-uk Kim sk_X509_NAME_pop_free(ret, X509_NAME_free); 91974664626SKris Kennaway ret = NULL; 92074664626SKris Kennaway } 9216f9291ceSJung-uk Kim if (sk != NULL) 9226f9291ceSJung-uk Kim sk_X509_NAME_free(sk); 9236f9291ceSJung-uk Kim if (in != NULL) 9246f9291ceSJung-uk Kim BIO_free(in); 9256f9291ceSJung-uk Kim if (x != NULL) 9266f9291ceSJung-uk Kim X509_free(x); 9273b4e3dcbSSimon L. B. Nielsen if (ret != NULL) 9283b4e3dcbSSimon L. B. Nielsen ERR_clear_error(); 92974664626SKris Kennaway return (ret); 93074664626SKris Kennaway } 93174664626SKris Kennaway #endif 93274664626SKris Kennaway 9336f9291ceSJung-uk Kim /** 93474664626SKris Kennaway * Add a file of certs to a stack. 93574664626SKris Kennaway * \param stack the stack to add to. 93674664626SKris Kennaway * \param file the file to add from. All certs in this file that are not 93774664626SKris Kennaway * already in the stack will be added. 93874664626SKris Kennaway * \return 1 for success, 0 for failure. Note that in the case of failure some 93974664626SKris Kennaway * certs may have been added to \c stack. 94074664626SKris Kennaway */ 94174664626SKris Kennaway 94274664626SKris Kennaway int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, 94374664626SKris Kennaway const char *file) 94474664626SKris Kennaway { 94574664626SKris Kennaway BIO *in; 94674664626SKris Kennaway X509 *x = NULL; 94774664626SKris Kennaway X509_NAME *xn = NULL; 94874664626SKris Kennaway int ret = 1; 949ddd58736SKris Kennaway int (*oldcmp) (const X509_NAME *const *a, const X509_NAME *const *b); 95074664626SKris Kennaway 951f579bf8eSKris Kennaway oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp); 95274664626SKris Kennaway 95374664626SKris Kennaway in = BIO_new(BIO_s_file_internal()); 95474664626SKris Kennaway 9556f9291ceSJung-uk Kim if (in == NULL) { 9566f9291ceSJung-uk Kim SSLerr(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK, 9576f9291ceSJung-uk Kim ERR_R_MALLOC_FAILURE); 95874664626SKris Kennaway goto err; 95974664626SKris Kennaway } 96074664626SKris Kennaway 96174664626SKris Kennaway if (!BIO_read_filename(in, file)) 96274664626SKris Kennaway goto err; 96374664626SKris Kennaway 9646f9291ceSJung-uk Kim for (;;) { 96574664626SKris Kennaway if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) 96674664626SKris Kennaway break; 9676f9291ceSJung-uk Kim if ((xn = X509_get_subject_name(x)) == NULL) 9686f9291ceSJung-uk Kim goto err; 96974664626SKris Kennaway xn = X509_NAME_dup(xn); 9706f9291ceSJung-uk Kim if (xn == NULL) 9716f9291ceSJung-uk Kim goto err; 97274664626SKris Kennaway if (sk_X509_NAME_find(stack, xn) >= 0) 97374664626SKris Kennaway X509_NAME_free(xn); 97474664626SKris Kennaway else 97574664626SKris Kennaway sk_X509_NAME_push(stack, xn); 97674664626SKris Kennaway } 97774664626SKris Kennaway 978a3ddd25aSSimon L. B. Nielsen ERR_clear_error(); 979a3ddd25aSSimon L. B. Nielsen 9806f9291ceSJung-uk Kim if (0) { 98174664626SKris Kennaway err: 98274664626SKris Kennaway ret = 0; 98374664626SKris Kennaway } 98474664626SKris Kennaway if (in != NULL) 98574664626SKris Kennaway BIO_free(in); 98674664626SKris Kennaway if (x != NULL) 98774664626SKris Kennaway X509_free(x); 98874664626SKris Kennaway 989db522d3aSSimon L. B. Nielsen (void)sk_X509_NAME_set_cmp_func(stack, oldcmp); 99074664626SKris Kennaway 99174664626SKris Kennaway return ret; 99274664626SKris Kennaway } 99374664626SKris Kennaway 9946f9291ceSJung-uk Kim /** 99574664626SKris Kennaway * Add a directory of certs to a stack. 99674664626SKris Kennaway * \param stack the stack to append to. 99774664626SKris Kennaway * \param dir the directory to append from. All files in this directory will be 99874664626SKris Kennaway * examined as potential certs. Any that are acceptable to 99974664626SKris Kennaway * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will be 100074664626SKris Kennaway * included. 100174664626SKris Kennaway * \return 1 for success, 0 for failure. Note that in the case of failure some 100274664626SKris Kennaway * certs may have been added to \c stack. 100374664626SKris Kennaway */ 100474664626SKris Kennaway 100574664626SKris Kennaway int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, 100674664626SKris Kennaway const char *dir) 100774664626SKris Kennaway { 10083b4e3dcbSSimon L. B. Nielsen OPENSSL_DIR_CTX *d = NULL; 10093b4e3dcbSSimon L. B. Nielsen const char *filename; 101074664626SKris Kennaway int ret = 0; 101174664626SKris Kennaway 101274664626SKris Kennaway CRYPTO_w_lock(CRYPTO_LOCK_READDIR); 101374664626SKris Kennaway 101474664626SKris Kennaway /* Note that a side effect is that the CAs will be sorted by name */ 101574664626SKris Kennaway 10166f9291ceSJung-uk Kim while ((filename = OPENSSL_DIR_read(&d, dir))) { 101774664626SKris Kennaway char buf[1024]; 1018ddd58736SKris Kennaway int r; 101974664626SKris Kennaway 10206f9291ceSJung-uk Kim if (strlen(dir) + strlen(filename) + 2 > sizeof buf) { 10216f9291ceSJung-uk Kim SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, 10226f9291ceSJung-uk Kim SSL_R_PATH_TOO_LONG); 102374664626SKris Kennaway goto err; 102474664626SKris Kennaway } 10253b4e3dcbSSimon L. B. Nielsen #ifdef OPENSSL_SYS_VMS 10263b4e3dcbSSimon L. B. Nielsen r = BIO_snprintf(buf, sizeof buf, "%s%s", dir, filename); 10273b4e3dcbSSimon L. B. Nielsen #else 10283b4e3dcbSSimon L. B. Nielsen r = BIO_snprintf(buf, sizeof buf, "%s/%s", dir, filename); 10293b4e3dcbSSimon L. B. Nielsen #endif 10303b4e3dcbSSimon L. B. Nielsen if (r <= 0 || r >= (int)sizeof(buf)) 1031ddd58736SKris Kennaway goto err; 103274664626SKris Kennaway if (!SSL_add_file_cert_subjects_to_stack(stack, buf)) 103374664626SKris Kennaway goto err; 103474664626SKris Kennaway } 103574664626SKris Kennaway 10366f9291ceSJung-uk Kim if (errno) { 10375c87c606SMark Murray SYSerr(SYS_F_OPENDIR, get_last_sys_error()); 10383b4e3dcbSSimon L. B. Nielsen ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')"); 10395c87c606SMark Murray SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB); 10405c87c606SMark Murray goto err; 10415c87c606SMark Murray } 10425c87c606SMark Murray 10435c87c606SMark Murray ret = 1; 10445c87c606SMark Murray 10455c87c606SMark Murray err: 10466f9291ceSJung-uk Kim if (d) 10476f9291ceSJung-uk Kim OPENSSL_DIR_end(&d); 10485c87c606SMark Murray CRYPTO_w_unlock(CRYPTO_LOCK_READDIR); 10495c87c606SMark Murray return ret; 10505c87c606SMark Murray } 10517bded2dbSJung-uk Kim 10527bded2dbSJung-uk Kim /* Add a certificate to a BUF_MEM structure */ 10537bded2dbSJung-uk Kim 10547bded2dbSJung-uk Kim static int ssl_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x) 10557bded2dbSJung-uk Kim { 10567bded2dbSJung-uk Kim int n; 10577bded2dbSJung-uk Kim unsigned char *p; 10587bded2dbSJung-uk Kim 10597bded2dbSJung-uk Kim n = i2d_X509(x, NULL); 1060b8721c16SJung-uk Kim if (n < 0 || !BUF_MEM_grow_clean(buf, (int)(n + (*l) + 3))) { 10617bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_ADD_CERT_TO_BUF, ERR_R_BUF_LIB); 10627bded2dbSJung-uk Kim return 0; 10637bded2dbSJung-uk Kim } 10647bded2dbSJung-uk Kim p = (unsigned char *)&(buf->data[*l]); 10657bded2dbSJung-uk Kim l2n3(n, p); 1066b8721c16SJung-uk Kim n = i2d_X509(x, &p); 1067b8721c16SJung-uk Kim if (n < 0) { 1068b8721c16SJung-uk Kim /* Shouldn't happen */ 1069b8721c16SJung-uk Kim SSLerr(SSL_F_SSL_ADD_CERT_TO_BUF, ERR_R_BUF_LIB); 1070b8721c16SJung-uk Kim return 0; 1071b8721c16SJung-uk Kim } 10727bded2dbSJung-uk Kim *l += n + 3; 10737bded2dbSJung-uk Kim 10747bded2dbSJung-uk Kim return 1; 10757bded2dbSJung-uk Kim } 10767bded2dbSJung-uk Kim 10777bded2dbSJung-uk Kim /* Add certificate chain to internal SSL BUF_MEM strcuture */ 10787bded2dbSJung-uk Kim int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l) 10797bded2dbSJung-uk Kim { 10807bded2dbSJung-uk Kim BUF_MEM *buf = s->init_buf; 10817bded2dbSJung-uk Kim int no_chain; 10827bded2dbSJung-uk Kim int i; 10837bded2dbSJung-uk Kim 10847bded2dbSJung-uk Kim X509 *x; 10857bded2dbSJung-uk Kim STACK_OF(X509) *extra_certs; 10867bded2dbSJung-uk Kim X509_STORE *chain_store; 10877bded2dbSJung-uk Kim 10887bded2dbSJung-uk Kim if (cpk) 10897bded2dbSJung-uk Kim x = cpk->x509; 10907bded2dbSJung-uk Kim else 10917bded2dbSJung-uk Kim x = NULL; 10927bded2dbSJung-uk Kim 10937bded2dbSJung-uk Kim if (s->cert->chain_store) 10947bded2dbSJung-uk Kim chain_store = s->cert->chain_store; 10957bded2dbSJung-uk Kim else 10967bded2dbSJung-uk Kim chain_store = s->ctx->cert_store; 10977bded2dbSJung-uk Kim 10987bded2dbSJung-uk Kim /* 10997bded2dbSJung-uk Kim * If we have a certificate specific chain use it, else use parent ctx. 11007bded2dbSJung-uk Kim */ 11017bded2dbSJung-uk Kim if (cpk && cpk->chain) 11027bded2dbSJung-uk Kim extra_certs = cpk->chain; 11037bded2dbSJung-uk Kim else 11047bded2dbSJung-uk Kim extra_certs = s->ctx->extra_certs; 11057bded2dbSJung-uk Kim 11067bded2dbSJung-uk Kim if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || extra_certs) 11077bded2dbSJung-uk Kim no_chain = 1; 11087bded2dbSJung-uk Kim else 11097bded2dbSJung-uk Kim no_chain = 0; 11107bded2dbSJung-uk Kim 11117bded2dbSJung-uk Kim /* TLSv1 sends a chain with nothing in it, instead of an alert */ 11127bded2dbSJung-uk Kim if (!BUF_MEM_grow_clean(buf, 10)) { 11137bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, ERR_R_BUF_LIB); 11147bded2dbSJung-uk Kim return 0; 11157bded2dbSJung-uk Kim } 11167bded2dbSJung-uk Kim if (x != NULL) { 11177bded2dbSJung-uk Kim if (no_chain) { 11187bded2dbSJung-uk Kim if (!ssl_add_cert_to_buf(buf, l, x)) 11197bded2dbSJung-uk Kim return 0; 11207bded2dbSJung-uk Kim } else { 11217bded2dbSJung-uk Kim X509_STORE_CTX xs_ctx; 11227bded2dbSJung-uk Kim 11237bded2dbSJung-uk Kim if (!X509_STORE_CTX_init(&xs_ctx, chain_store, x, NULL)) { 11247bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, ERR_R_X509_LIB); 11257bded2dbSJung-uk Kim return (0); 11267bded2dbSJung-uk Kim } 11277bded2dbSJung-uk Kim X509_verify_cert(&xs_ctx); 11287bded2dbSJung-uk Kim /* Don't leave errors in the queue */ 11297bded2dbSJung-uk Kim ERR_clear_error(); 11307bded2dbSJung-uk Kim for (i = 0; i < sk_X509_num(xs_ctx.chain); i++) { 11317bded2dbSJung-uk Kim x = sk_X509_value(xs_ctx.chain, i); 11327bded2dbSJung-uk Kim 11337bded2dbSJung-uk Kim if (!ssl_add_cert_to_buf(buf, l, x)) { 11347bded2dbSJung-uk Kim X509_STORE_CTX_cleanup(&xs_ctx); 11357bded2dbSJung-uk Kim return 0; 11367bded2dbSJung-uk Kim } 11377bded2dbSJung-uk Kim } 11387bded2dbSJung-uk Kim X509_STORE_CTX_cleanup(&xs_ctx); 11397bded2dbSJung-uk Kim } 11407bded2dbSJung-uk Kim } 11417bded2dbSJung-uk Kim for (i = 0; i < sk_X509_num(extra_certs); i++) { 11427bded2dbSJung-uk Kim x = sk_X509_value(extra_certs, i); 11437bded2dbSJung-uk Kim if (!ssl_add_cert_to_buf(buf, l, x)) 11447bded2dbSJung-uk Kim return 0; 11457bded2dbSJung-uk Kim } 11467bded2dbSJung-uk Kim 11477bded2dbSJung-uk Kim return 1; 11487bded2dbSJung-uk Kim } 11497bded2dbSJung-uk Kim 11507bded2dbSJung-uk Kim /* Build a certificate chain for current certificate */ 11517bded2dbSJung-uk Kim int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags) 11527bded2dbSJung-uk Kim { 11537bded2dbSJung-uk Kim CERT_PKEY *cpk = c->key; 11547bded2dbSJung-uk Kim X509_STORE_CTX xs_ctx; 11557bded2dbSJung-uk Kim STACK_OF(X509) *chain = NULL, *untrusted = NULL; 11567bded2dbSJung-uk Kim X509 *x; 11577bded2dbSJung-uk Kim int i, rv = 0; 11587bded2dbSJung-uk Kim unsigned long error; 11597bded2dbSJung-uk Kim 11607bded2dbSJung-uk Kim if (!cpk->x509) { 11617bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, SSL_R_NO_CERTIFICATE_SET); 11627bded2dbSJung-uk Kim goto err; 11637bded2dbSJung-uk Kim } 11647bded2dbSJung-uk Kim /* Rearranging and check the chain: add everything to a store */ 11657bded2dbSJung-uk Kim if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) { 11667bded2dbSJung-uk Kim chain_store = X509_STORE_new(); 11677bded2dbSJung-uk Kim if (!chain_store) 11687bded2dbSJung-uk Kim goto err; 11697bded2dbSJung-uk Kim for (i = 0; i < sk_X509_num(cpk->chain); i++) { 11707bded2dbSJung-uk Kim x = sk_X509_value(cpk->chain, i); 11717bded2dbSJung-uk Kim if (!X509_STORE_add_cert(chain_store, x)) { 11727bded2dbSJung-uk Kim error = ERR_peek_last_error(); 11737bded2dbSJung-uk Kim if (ERR_GET_LIB(error) != ERR_LIB_X509 || 11747bded2dbSJung-uk Kim ERR_GET_REASON(error) != 11757bded2dbSJung-uk Kim X509_R_CERT_ALREADY_IN_HASH_TABLE) 11767bded2dbSJung-uk Kim goto err; 11777bded2dbSJung-uk Kim ERR_clear_error(); 11787bded2dbSJung-uk Kim } 11797bded2dbSJung-uk Kim } 11807bded2dbSJung-uk Kim /* Add EE cert too: it might be self signed */ 11817bded2dbSJung-uk Kim if (!X509_STORE_add_cert(chain_store, cpk->x509)) { 11827bded2dbSJung-uk Kim error = ERR_peek_last_error(); 11837bded2dbSJung-uk Kim if (ERR_GET_LIB(error) != ERR_LIB_X509 || 11847bded2dbSJung-uk Kim ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE) 11857bded2dbSJung-uk Kim goto err; 11867bded2dbSJung-uk Kim ERR_clear_error(); 11877bded2dbSJung-uk Kim } 11887bded2dbSJung-uk Kim } else { 11897bded2dbSJung-uk Kim if (c->chain_store) 11907bded2dbSJung-uk Kim chain_store = c->chain_store; 11917bded2dbSJung-uk Kim 11927bded2dbSJung-uk Kim if (flags & SSL_BUILD_CHAIN_FLAG_UNTRUSTED) 11937bded2dbSJung-uk Kim untrusted = cpk->chain; 11947bded2dbSJung-uk Kim } 11957bded2dbSJung-uk Kim 11967bded2dbSJung-uk Kim if (!X509_STORE_CTX_init(&xs_ctx, chain_store, cpk->x509, untrusted)) { 11977bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, ERR_R_X509_LIB); 11987bded2dbSJung-uk Kim goto err; 11997bded2dbSJung-uk Kim } 12007bded2dbSJung-uk Kim /* Set suite B flags if needed */ 12017bded2dbSJung-uk Kim X509_STORE_CTX_set_flags(&xs_ctx, 12027bded2dbSJung-uk Kim c->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS); 12037bded2dbSJung-uk Kim 12047bded2dbSJung-uk Kim i = X509_verify_cert(&xs_ctx); 12057bded2dbSJung-uk Kim if (i <= 0 && flags & SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR) { 12067bded2dbSJung-uk Kim if (flags & SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR) 12077bded2dbSJung-uk Kim ERR_clear_error(); 12087bded2dbSJung-uk Kim i = 1; 12097bded2dbSJung-uk Kim rv = 2; 12107bded2dbSJung-uk Kim } 12117bded2dbSJung-uk Kim if (i > 0) 12127bded2dbSJung-uk Kim chain = X509_STORE_CTX_get1_chain(&xs_ctx); 12137bded2dbSJung-uk Kim if (i <= 0) { 12147bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, SSL_R_CERTIFICATE_VERIFY_FAILED); 12157bded2dbSJung-uk Kim i = X509_STORE_CTX_get_error(&xs_ctx); 12167bded2dbSJung-uk Kim ERR_add_error_data(2, "Verify error:", 12177bded2dbSJung-uk Kim X509_verify_cert_error_string(i)); 12187bded2dbSJung-uk Kim 12197bded2dbSJung-uk Kim X509_STORE_CTX_cleanup(&xs_ctx); 12207bded2dbSJung-uk Kim goto err; 12217bded2dbSJung-uk Kim } 12227bded2dbSJung-uk Kim X509_STORE_CTX_cleanup(&xs_ctx); 12237bded2dbSJung-uk Kim if (cpk->chain) 12247bded2dbSJung-uk Kim sk_X509_pop_free(cpk->chain, X509_free); 12257bded2dbSJung-uk Kim /* Remove EE certificate from chain */ 12267bded2dbSJung-uk Kim x = sk_X509_shift(chain); 12277bded2dbSJung-uk Kim X509_free(x); 12287bded2dbSJung-uk Kim if (flags & SSL_BUILD_CHAIN_FLAG_NO_ROOT) { 12297bded2dbSJung-uk Kim if (sk_X509_num(chain) > 0) { 12307bded2dbSJung-uk Kim /* See if last cert is self signed */ 12317bded2dbSJung-uk Kim x = sk_X509_value(chain, sk_X509_num(chain) - 1); 12327bded2dbSJung-uk Kim X509_check_purpose(x, -1, 0); 12337bded2dbSJung-uk Kim if (x->ex_flags & EXFLAG_SS) { 12347bded2dbSJung-uk Kim x = sk_X509_pop(chain); 12357bded2dbSJung-uk Kim X509_free(x); 12367bded2dbSJung-uk Kim } 12377bded2dbSJung-uk Kim } 12387bded2dbSJung-uk Kim } 12397bded2dbSJung-uk Kim cpk->chain = chain; 12407bded2dbSJung-uk Kim if (rv == 0) 12417bded2dbSJung-uk Kim rv = 1; 12427bded2dbSJung-uk Kim err: 12437bded2dbSJung-uk Kim if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) 12447bded2dbSJung-uk Kim X509_STORE_free(chain_store); 12457bded2dbSJung-uk Kim 12467bded2dbSJung-uk Kim return rv; 12477bded2dbSJung-uk Kim } 12487bded2dbSJung-uk Kim 12497bded2dbSJung-uk Kim int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref) 12507bded2dbSJung-uk Kim { 12517bded2dbSJung-uk Kim X509_STORE **pstore; 12527bded2dbSJung-uk Kim if (chain) 12537bded2dbSJung-uk Kim pstore = &c->chain_store; 12547bded2dbSJung-uk Kim else 12557bded2dbSJung-uk Kim pstore = &c->verify_store; 12567bded2dbSJung-uk Kim if (*pstore) 12577bded2dbSJung-uk Kim X509_STORE_free(*pstore); 12587bded2dbSJung-uk Kim *pstore = store; 12597bded2dbSJung-uk Kim if (ref && store) 12607bded2dbSJung-uk Kim CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE); 12617bded2dbSJung-uk Kim return 1; 12627bded2dbSJung-uk Kim } 1263