174664626SKris Kennaway /* ssl/ssl_rsa.c */ 274664626SKris Kennaway /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 374664626SKris Kennaway * All rights reserved. 474664626SKris Kennaway * 574664626SKris Kennaway * This package is an SSL implementation written 674664626SKris Kennaway * by Eric Young (eay@cryptsoft.com). 774664626SKris Kennaway * The implementation was written so as to conform with Netscapes SSL. 874664626SKris Kennaway * 974664626SKris Kennaway * This library is free for commercial and non-commercial use as long as 1074664626SKris Kennaway * the following conditions are aheared to. The following conditions 1174664626SKris Kennaway * apply to all code found in this distribution, be it the RC4, RSA, 1274664626SKris Kennaway * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1374664626SKris Kennaway * included with this distribution is covered by the same copyright terms 1474664626SKris Kennaway * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1574664626SKris Kennaway * 1674664626SKris Kennaway * Copyright remains Eric Young's, and as such any Copyright notices in 1774664626SKris Kennaway * the code are not to be removed. 1874664626SKris Kennaway * If this package is used in a product, Eric Young should be given attribution 1974664626SKris Kennaway * as the author of the parts of the library used. 2074664626SKris Kennaway * This can be in the form of a textual message at program startup or 2174664626SKris Kennaway * in documentation (online or textual) provided with the package. 2274664626SKris Kennaway * 2374664626SKris Kennaway * Redistribution and use in source and binary forms, with or without 2474664626SKris Kennaway * modification, are permitted provided that the following conditions 2574664626SKris Kennaway * are met: 2674664626SKris Kennaway * 1. Redistributions of source code must retain the copyright 2774664626SKris Kennaway * notice, this list of conditions and the following disclaimer. 2874664626SKris Kennaway * 2. Redistributions in binary form must reproduce the above copyright 2974664626SKris Kennaway * notice, this list of conditions and the following disclaimer in the 3074664626SKris Kennaway * documentation and/or other materials provided with the distribution. 3174664626SKris Kennaway * 3. All advertising materials mentioning features or use of this software 3274664626SKris Kennaway * must display the following acknowledgement: 3374664626SKris Kennaway * "This product includes cryptographic software written by 3474664626SKris Kennaway * Eric Young (eay@cryptsoft.com)" 3574664626SKris Kennaway * The word 'cryptographic' can be left out if the rouines from the library 3674664626SKris Kennaway * being used are not cryptographic related :-). 3774664626SKris Kennaway * 4. If you include any Windows specific code (or a derivative thereof) from 3874664626SKris Kennaway * the apps directory (application code) you must include an acknowledgement: 3974664626SKris Kennaway * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4074664626SKris Kennaway * 4174664626SKris Kennaway * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4274664626SKris Kennaway * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4374664626SKris Kennaway * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4474664626SKris Kennaway * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4574664626SKris Kennaway * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4674664626SKris Kennaway * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4774664626SKris Kennaway * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4874664626SKris Kennaway * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4974664626SKris Kennaway * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5074664626SKris Kennaway * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5174664626SKris Kennaway * SUCH DAMAGE. 5274664626SKris Kennaway * 5374664626SKris Kennaway * The licence and distribution terms for any publically available version or 5474664626SKris Kennaway * derivative of this code cannot be changed. i.e. this code cannot simply be 5574664626SKris Kennaway * copied and put under another distribution licence 5674664626SKris Kennaway * [including the GNU Public Licence.] 5774664626SKris Kennaway */ 5874664626SKris Kennaway 5974664626SKris Kennaway #include <stdio.h> 605c87c606SMark Murray #include "ssl_locl.h" 6174664626SKris Kennaway #include <openssl/bio.h> 6274664626SKris Kennaway #include <openssl/objects.h> 6374664626SKris Kennaway #include <openssl/evp.h> 6474664626SKris Kennaway #include <openssl/x509.h> 6574664626SKris Kennaway #include <openssl/pem.h> 6674664626SKris Kennaway 6774664626SKris Kennaway static int ssl_set_cert(CERT *c, X509 *x509); 6874664626SKris Kennaway static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey); 6974664626SKris Kennaway int SSL_use_certificate(SSL *ssl, X509 *x) 7074664626SKris Kennaway { 71*6f9291ceSJung-uk Kim if (x == NULL) { 7274664626SKris Kennaway SSLerr(SSL_F_SSL_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); 7374664626SKris Kennaway return (0); 7474664626SKris Kennaway } 75*6f9291ceSJung-uk Kim if (!ssl_cert_inst(&ssl->cert)) { 7674664626SKris Kennaway SSLerr(SSL_F_SSL_USE_CERTIFICATE, ERR_R_MALLOC_FAILURE); 7774664626SKris Kennaway return (0); 7874664626SKris Kennaway } 7974664626SKris Kennaway return (ssl_set_cert(ssl->cert, x)); 8074664626SKris Kennaway } 8174664626SKris Kennaway 825c87c606SMark Murray #ifndef OPENSSL_NO_STDIO 8374664626SKris Kennaway int SSL_use_certificate_file(SSL *ssl, const char *file, int type) 8474664626SKris Kennaway { 8574664626SKris Kennaway int j; 8674664626SKris Kennaway BIO *in; 8774664626SKris Kennaway int ret = 0; 8874664626SKris Kennaway X509 *x = NULL; 8974664626SKris Kennaway 9074664626SKris Kennaway in = BIO_new(BIO_s_file_internal()); 91*6f9291ceSJung-uk Kim if (in == NULL) { 9274664626SKris Kennaway SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB); 9374664626SKris Kennaway goto end; 9474664626SKris Kennaway } 9574664626SKris Kennaway 96*6f9291ceSJung-uk Kim if (BIO_read_filename(in, file) <= 0) { 9774664626SKris Kennaway SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); 9874664626SKris Kennaway goto end; 9974664626SKris Kennaway } 100*6f9291ceSJung-uk Kim if (type == SSL_FILETYPE_ASN1) { 10174664626SKris Kennaway j = ERR_R_ASN1_LIB; 10274664626SKris Kennaway x = d2i_X509_bio(in, NULL); 103*6f9291ceSJung-uk Kim } else if (type == SSL_FILETYPE_PEM) { 10474664626SKris Kennaway j = ERR_R_PEM_LIB; 105*6f9291ceSJung-uk Kim x = PEM_read_bio_X509(in, NULL, ssl->ctx->default_passwd_callback, 106*6f9291ceSJung-uk Kim ssl->ctx->default_passwd_callback_userdata); 107*6f9291ceSJung-uk Kim } else { 10874664626SKris Kennaway SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); 10974664626SKris Kennaway goto end; 11074664626SKris Kennaway } 11174664626SKris Kennaway 112*6f9291ceSJung-uk Kim if (x == NULL) { 11374664626SKris Kennaway SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, j); 11474664626SKris Kennaway goto end; 11574664626SKris Kennaway } 11674664626SKris Kennaway 11774664626SKris Kennaway ret = SSL_use_certificate(ssl, x); 11874664626SKris Kennaway end: 119*6f9291ceSJung-uk Kim if (x != NULL) 120*6f9291ceSJung-uk Kim X509_free(x); 121*6f9291ceSJung-uk Kim if (in != NULL) 122*6f9291ceSJung-uk Kim BIO_free(in); 12374664626SKris Kennaway return (ret); 12474664626SKris Kennaway } 12574664626SKris Kennaway #endif 12674664626SKris Kennaway 1273b4e3dcbSSimon L. B. Nielsen int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len) 12874664626SKris Kennaway { 12974664626SKris Kennaway X509 *x; 13074664626SKris Kennaway int ret; 13174664626SKris Kennaway 13274664626SKris Kennaway x = d2i_X509(NULL, &d, (long)len); 133*6f9291ceSJung-uk Kim if (x == NULL) { 13474664626SKris Kennaway SSLerr(SSL_F_SSL_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); 13574664626SKris Kennaway return (0); 13674664626SKris Kennaway } 13774664626SKris Kennaway 13874664626SKris Kennaway ret = SSL_use_certificate(ssl, x); 13974664626SKris Kennaway X509_free(x); 14074664626SKris Kennaway return (ret); 14174664626SKris Kennaway } 14274664626SKris Kennaway 1435c87c606SMark Murray #ifndef OPENSSL_NO_RSA 14474664626SKris Kennaway int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) 14574664626SKris Kennaway { 14674664626SKris Kennaway EVP_PKEY *pkey; 14774664626SKris Kennaway int ret; 14874664626SKris Kennaway 149*6f9291ceSJung-uk Kim if (rsa == NULL) { 15074664626SKris Kennaway SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); 15174664626SKris Kennaway return (0); 15274664626SKris Kennaway } 153*6f9291ceSJung-uk Kim if (!ssl_cert_inst(&ssl->cert)) { 15474664626SKris Kennaway SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_MALLOC_FAILURE); 15574664626SKris Kennaway return (0); 15674664626SKris Kennaway } 157*6f9291ceSJung-uk Kim if ((pkey = EVP_PKEY_new()) == NULL) { 15874664626SKris Kennaway SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB); 15974664626SKris Kennaway return (0); 16074664626SKris Kennaway } 16174664626SKris Kennaway 1625c87c606SMark Murray RSA_up_ref(rsa); 16374664626SKris Kennaway EVP_PKEY_assign_RSA(pkey, rsa); 16474664626SKris Kennaway 16574664626SKris Kennaway ret = ssl_set_pkey(ssl->cert, pkey); 16674664626SKris Kennaway EVP_PKEY_free(pkey); 16774664626SKris Kennaway return (ret); 16874664626SKris Kennaway } 16974664626SKris Kennaway #endif 17074664626SKris Kennaway 17174664626SKris Kennaway static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) 17274664626SKris Kennaway { 1733b4e3dcbSSimon L. B. Nielsen int i; 17474664626SKris Kennaway 17574664626SKris Kennaway i = ssl_cert_type(NULL, pkey); 176*6f9291ceSJung-uk Kim if (i < 0) { 17774664626SKris Kennaway SSLerr(SSL_F_SSL_SET_PKEY, SSL_R_UNKNOWN_CERTIFICATE_TYPE); 17874664626SKris Kennaway return (0); 17974664626SKris Kennaway } 18074664626SKris Kennaway 181*6f9291ceSJung-uk Kim if (c->pkeys[i].x509 != NULL) { 18274664626SKris Kennaway EVP_PKEY *pktmp; 18374664626SKris Kennaway pktmp = X509_get_pubkey(c->pkeys[i].x509); 18474664626SKris Kennaway EVP_PKEY_copy_parameters(pktmp, pkey); 18574664626SKris Kennaway EVP_PKEY_free(pktmp); 18674664626SKris Kennaway ERR_clear_error(); 18774664626SKris Kennaway 1885c87c606SMark Murray #ifndef OPENSSL_NO_RSA 189*6f9291ceSJung-uk Kim /* 190*6f9291ceSJung-uk Kim * Don't check the public/private key, this is mostly for smart 191*6f9291ceSJung-uk Kim * cards. 192*6f9291ceSJung-uk Kim */ 19374664626SKris Kennaway if ((pkey->type == EVP_PKEY_RSA) && 194*6f9291ceSJung-uk Kim (RSA_flags(pkey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK)) ; 19574664626SKris Kennaway else 19674664626SKris Kennaway #endif 197*6f9291ceSJung-uk Kim if (!X509_check_private_key(c->pkeys[i].x509, pkey)) { 19874664626SKris Kennaway X509_free(c->pkeys[i].x509); 19974664626SKris Kennaway c->pkeys[i].x509 = NULL; 2003b4e3dcbSSimon L. B. Nielsen return 0; 2013b4e3dcbSSimon L. B. Nielsen } 20274664626SKris Kennaway } 20374664626SKris Kennaway 20474664626SKris Kennaway if (c->pkeys[i].privatekey != NULL) 20574664626SKris Kennaway EVP_PKEY_free(c->pkeys[i].privatekey); 20674664626SKris Kennaway CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); 20774664626SKris Kennaway c->pkeys[i].privatekey = pkey; 20874664626SKris Kennaway c->key = &(c->pkeys[i]); 20974664626SKris Kennaway 21074664626SKris Kennaway c->valid = 0; 21174664626SKris Kennaway return (1); 21274664626SKris Kennaway } 21374664626SKris Kennaway 2145c87c606SMark Murray #ifndef OPENSSL_NO_RSA 2155c87c606SMark Murray # ifndef OPENSSL_NO_STDIO 21674664626SKris Kennaway int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) 21774664626SKris Kennaway { 21874664626SKris Kennaway int j, ret = 0; 21974664626SKris Kennaway BIO *in; 22074664626SKris Kennaway RSA *rsa = NULL; 22174664626SKris Kennaway 22274664626SKris Kennaway in = BIO_new(BIO_s_file_internal()); 223*6f9291ceSJung-uk Kim if (in == NULL) { 22474664626SKris Kennaway SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB); 22574664626SKris Kennaway goto end; 22674664626SKris Kennaway } 22774664626SKris Kennaway 228*6f9291ceSJung-uk Kim if (BIO_read_filename(in, file) <= 0) { 22974664626SKris Kennaway SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB); 23074664626SKris Kennaway goto end; 23174664626SKris Kennaway } 232*6f9291ceSJung-uk Kim if (type == SSL_FILETYPE_ASN1) { 23374664626SKris Kennaway j = ERR_R_ASN1_LIB; 23474664626SKris Kennaway rsa = d2i_RSAPrivateKey_bio(in, NULL); 235*6f9291ceSJung-uk Kim } else if (type == SSL_FILETYPE_PEM) { 23674664626SKris Kennaway j = ERR_R_PEM_LIB; 23774664626SKris Kennaway rsa = PEM_read_bio_RSAPrivateKey(in, NULL, 238*6f9291ceSJung-uk Kim ssl->ctx->default_passwd_callback, 239*6f9291ceSJung-uk Kim ssl-> 240*6f9291ceSJung-uk Kim ctx->default_passwd_callback_userdata); 241*6f9291ceSJung-uk Kim } else { 24274664626SKris Kennaway SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); 24374664626SKris Kennaway goto end; 24474664626SKris Kennaway } 245*6f9291ceSJung-uk Kim if (rsa == NULL) { 24674664626SKris Kennaway SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, j); 24774664626SKris Kennaway goto end; 24874664626SKris Kennaway } 24974664626SKris Kennaway ret = SSL_use_RSAPrivateKey(ssl, rsa); 25074664626SKris Kennaway RSA_free(rsa); 25174664626SKris Kennaway end: 252*6f9291ceSJung-uk Kim if (in != NULL) 253*6f9291ceSJung-uk Kim BIO_free(in); 25474664626SKris Kennaway return (ret); 25574664626SKris Kennaway } 25674664626SKris Kennaway # endif 25774664626SKris Kennaway 25874664626SKris Kennaway int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len) 25974664626SKris Kennaway { 26074664626SKris Kennaway int ret; 2615c87c606SMark Murray const unsigned char *p; 26274664626SKris Kennaway RSA *rsa; 26374664626SKris Kennaway 26474664626SKris Kennaway p = d; 265*6f9291ceSJung-uk Kim if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) { 26674664626SKris Kennaway SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB); 26774664626SKris Kennaway return (0); 26874664626SKris Kennaway } 26974664626SKris Kennaway 27074664626SKris Kennaway ret = SSL_use_RSAPrivateKey(ssl, rsa); 27174664626SKris Kennaway RSA_free(rsa); 27274664626SKris Kennaway return (ret); 27374664626SKris Kennaway } 2745c87c606SMark Murray #endif /* !OPENSSL_NO_RSA */ 27574664626SKris Kennaway 27674664626SKris Kennaway int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) 27774664626SKris Kennaway { 27874664626SKris Kennaway int ret; 27974664626SKris Kennaway 280*6f9291ceSJung-uk Kim if (pkey == NULL) { 28174664626SKris Kennaway SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); 28274664626SKris Kennaway return (0); 28374664626SKris Kennaway } 284*6f9291ceSJung-uk Kim if (!ssl_cert_inst(&ssl->cert)) { 28574664626SKris Kennaway SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_MALLOC_FAILURE); 28674664626SKris Kennaway return (0); 28774664626SKris Kennaway } 28874664626SKris Kennaway ret = ssl_set_pkey(ssl->cert, pkey); 28974664626SKris Kennaway return (ret); 29074664626SKris Kennaway } 29174664626SKris Kennaway 2925c87c606SMark Murray #ifndef OPENSSL_NO_STDIO 29374664626SKris Kennaway int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) 29474664626SKris Kennaway { 29574664626SKris Kennaway int j, ret = 0; 29674664626SKris Kennaway BIO *in; 29774664626SKris Kennaway EVP_PKEY *pkey = NULL; 29874664626SKris Kennaway 29974664626SKris Kennaway in = BIO_new(BIO_s_file_internal()); 300*6f9291ceSJung-uk Kim if (in == NULL) { 30174664626SKris Kennaway SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB); 30274664626SKris Kennaway goto end; 30374664626SKris Kennaway } 30474664626SKris Kennaway 305*6f9291ceSJung-uk Kim if (BIO_read_filename(in, file) <= 0) { 30674664626SKris Kennaway SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB); 30774664626SKris Kennaway goto end; 30874664626SKris Kennaway } 309*6f9291ceSJung-uk Kim if (type == SSL_FILETYPE_PEM) { 31074664626SKris Kennaway j = ERR_R_PEM_LIB; 31174664626SKris Kennaway pkey = PEM_read_bio_PrivateKey(in, NULL, 312*6f9291ceSJung-uk Kim ssl->ctx->default_passwd_callback, 313*6f9291ceSJung-uk Kim ssl-> 314*6f9291ceSJung-uk Kim ctx->default_passwd_callback_userdata); 315*6f9291ceSJung-uk Kim } else if (type == SSL_FILETYPE_ASN1) { 3163b4e3dcbSSimon L. B. Nielsen j = ERR_R_ASN1_LIB; 3173b4e3dcbSSimon L. B. Nielsen pkey = d2i_PrivateKey_bio(in, NULL); 318*6f9291ceSJung-uk Kim } else { 31974664626SKris Kennaway SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); 32074664626SKris Kennaway goto end; 32174664626SKris Kennaway } 322*6f9291ceSJung-uk Kim if (pkey == NULL) { 32374664626SKris Kennaway SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, j); 32474664626SKris Kennaway goto end; 32574664626SKris Kennaway } 32674664626SKris Kennaway ret = SSL_use_PrivateKey(ssl, pkey); 32774664626SKris Kennaway EVP_PKEY_free(pkey); 32874664626SKris Kennaway end: 329*6f9291ceSJung-uk Kim if (in != NULL) 330*6f9291ceSJung-uk Kim BIO_free(in); 33174664626SKris Kennaway return (ret); 33274664626SKris Kennaway } 33374664626SKris Kennaway #endif 33474664626SKris Kennaway 335*6f9291ceSJung-uk Kim int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, 336*6f9291ceSJung-uk Kim long len) 33774664626SKris Kennaway { 33874664626SKris Kennaway int ret; 3393b4e3dcbSSimon L. B. Nielsen const unsigned char *p; 34074664626SKris Kennaway EVP_PKEY *pkey; 34174664626SKris Kennaway 34274664626SKris Kennaway p = d; 343*6f9291ceSJung-uk Kim if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) { 34474664626SKris Kennaway SSLerr(SSL_F_SSL_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB); 34574664626SKris Kennaway return (0); 34674664626SKris Kennaway } 34774664626SKris Kennaway 34874664626SKris Kennaway ret = SSL_use_PrivateKey(ssl, pkey); 34974664626SKris Kennaway EVP_PKEY_free(pkey); 35074664626SKris Kennaway return (ret); 35174664626SKris Kennaway } 35274664626SKris Kennaway 35374664626SKris Kennaway int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) 35474664626SKris Kennaway { 355*6f9291ceSJung-uk Kim if (x == NULL) { 35674664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); 35774664626SKris Kennaway return (0); 35874664626SKris Kennaway } 359*6f9291ceSJung-uk Kim if (!ssl_cert_inst(&ctx->cert)) { 36074664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, ERR_R_MALLOC_FAILURE); 36174664626SKris Kennaway return (0); 36274664626SKris Kennaway } 36374664626SKris Kennaway return (ssl_set_cert(ctx->cert, x)); 36474664626SKris Kennaway } 36574664626SKris Kennaway 36674664626SKris Kennaway static int ssl_set_cert(CERT *c, X509 *x) 36774664626SKris Kennaway { 36874664626SKris Kennaway EVP_PKEY *pkey; 3693b4e3dcbSSimon L. B. Nielsen int i; 37074664626SKris Kennaway 37174664626SKris Kennaway pkey = X509_get_pubkey(x); 372*6f9291ceSJung-uk Kim if (pkey == NULL) { 37374664626SKris Kennaway SSLerr(SSL_F_SSL_SET_CERT, SSL_R_X509_LIB); 37474664626SKris Kennaway return (0); 37574664626SKris Kennaway } 37674664626SKris Kennaway 37774664626SKris Kennaway i = ssl_cert_type(x, pkey); 378*6f9291ceSJung-uk Kim if (i < 0) { 37974664626SKris Kennaway SSLerr(SSL_F_SSL_SET_CERT, SSL_R_UNKNOWN_CERTIFICATE_TYPE); 38074664626SKris Kennaway EVP_PKEY_free(pkey); 38174664626SKris Kennaway return (0); 38274664626SKris Kennaway } 38374664626SKris Kennaway 384*6f9291ceSJung-uk Kim if (c->pkeys[i].privatekey != NULL) { 38574664626SKris Kennaway EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey); 38674664626SKris Kennaway ERR_clear_error(); 38774664626SKris Kennaway 3885c87c606SMark Murray #ifndef OPENSSL_NO_RSA 389*6f9291ceSJung-uk Kim /* 390*6f9291ceSJung-uk Kim * Don't check the public/private key, this is mostly for smart 391*6f9291ceSJung-uk Kim * cards. 392*6f9291ceSJung-uk Kim */ 39374664626SKris Kennaway if ((c->pkeys[i].privatekey->type == EVP_PKEY_RSA) && 39474664626SKris Kennaway (RSA_flags(c->pkeys[i].privatekey->pkey.rsa) & 395*6f9291ceSJung-uk Kim RSA_METHOD_FLAG_NO_CHECK)) ; 39674664626SKris Kennaway else 3973b4e3dcbSSimon L. B. Nielsen #endif /* OPENSSL_NO_RSA */ 398*6f9291ceSJung-uk Kim if (!X509_check_private_key(x, c->pkeys[i].privatekey)) { 399*6f9291ceSJung-uk Kim /* 400*6f9291ceSJung-uk Kim * don't fail for a cert/key mismatch, just free current private 401*6f9291ceSJung-uk Kim * key (when switching to a different cert & key, first this 402*6f9291ceSJung-uk Kim * function should be used, then ssl_set_pkey 403*6f9291ceSJung-uk Kim */ 40474664626SKris Kennaway EVP_PKEY_free(c->pkeys[i].privatekey); 40574664626SKris Kennaway c->pkeys[i].privatekey = NULL; 4063b4e3dcbSSimon L. B. Nielsen /* clear error queue */ 4073b4e3dcbSSimon L. B. Nielsen ERR_clear_error(); 40874664626SKris Kennaway } 4093b4e3dcbSSimon L. B. Nielsen } 4103b4e3dcbSSimon L. B. Nielsen 4113b4e3dcbSSimon L. B. Nielsen EVP_PKEY_free(pkey); 41274664626SKris Kennaway 41374664626SKris Kennaway if (c->pkeys[i].x509 != NULL) 41474664626SKris Kennaway X509_free(c->pkeys[i].x509); 41574664626SKris Kennaway CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); 41674664626SKris Kennaway c->pkeys[i].x509 = x; 41774664626SKris Kennaway c->key = &(c->pkeys[i]); 41874664626SKris Kennaway 41974664626SKris Kennaway c->valid = 0; 42074664626SKris Kennaway return (1); 42174664626SKris Kennaway } 42274664626SKris Kennaway 4235c87c606SMark Murray #ifndef OPENSSL_NO_STDIO 42474664626SKris Kennaway int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) 42574664626SKris Kennaway { 42674664626SKris Kennaway int j; 42774664626SKris Kennaway BIO *in; 42874664626SKris Kennaway int ret = 0; 42974664626SKris Kennaway X509 *x = NULL; 43074664626SKris Kennaway 43174664626SKris Kennaway in = BIO_new(BIO_s_file_internal()); 432*6f9291ceSJung-uk Kim if (in == NULL) { 43374664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB); 43474664626SKris Kennaway goto end; 43574664626SKris Kennaway } 43674664626SKris Kennaway 437*6f9291ceSJung-uk Kim if (BIO_read_filename(in, file) <= 0) { 43874664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); 43974664626SKris Kennaway goto end; 44074664626SKris Kennaway } 441*6f9291ceSJung-uk Kim if (type == SSL_FILETYPE_ASN1) { 44274664626SKris Kennaway j = ERR_R_ASN1_LIB; 44374664626SKris Kennaway x = d2i_X509_bio(in, NULL); 444*6f9291ceSJung-uk Kim } else if (type == SSL_FILETYPE_PEM) { 44574664626SKris Kennaway j = ERR_R_PEM_LIB; 446*6f9291ceSJung-uk Kim x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, 447*6f9291ceSJung-uk Kim ctx->default_passwd_callback_userdata); 448*6f9291ceSJung-uk Kim } else { 44974664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); 45074664626SKris Kennaway goto end; 45174664626SKris Kennaway } 45274664626SKris Kennaway 453*6f9291ceSJung-uk Kim if (x == NULL) { 45474664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, j); 45574664626SKris Kennaway goto end; 45674664626SKris Kennaway } 45774664626SKris Kennaway 45874664626SKris Kennaway ret = SSL_CTX_use_certificate(ctx, x); 45974664626SKris Kennaway end: 460*6f9291ceSJung-uk Kim if (x != NULL) 461*6f9291ceSJung-uk Kim X509_free(x); 462*6f9291ceSJung-uk Kim if (in != NULL) 463*6f9291ceSJung-uk Kim BIO_free(in); 46474664626SKris Kennaway return (ret); 46574664626SKris Kennaway } 46674664626SKris Kennaway #endif 46774664626SKris Kennaway 468*6f9291ceSJung-uk Kim int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, 469*6f9291ceSJung-uk Kim const unsigned char *d) 47074664626SKris Kennaway { 47174664626SKris Kennaway X509 *x; 47274664626SKris Kennaway int ret; 47374664626SKris Kennaway 47474664626SKris Kennaway x = d2i_X509(NULL, &d, (long)len); 475*6f9291ceSJung-uk Kim if (x == NULL) { 47674664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); 47774664626SKris Kennaway return (0); 47874664626SKris Kennaway } 47974664626SKris Kennaway 48074664626SKris Kennaway ret = SSL_CTX_use_certificate(ctx, x); 48174664626SKris Kennaway X509_free(x); 48274664626SKris Kennaway return (ret); 48374664626SKris Kennaway } 48474664626SKris Kennaway 4855c87c606SMark Murray #ifndef OPENSSL_NO_RSA 48674664626SKris Kennaway int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) 48774664626SKris Kennaway { 48874664626SKris Kennaway int ret; 48974664626SKris Kennaway EVP_PKEY *pkey; 49074664626SKris Kennaway 491*6f9291ceSJung-uk Kim if (rsa == NULL) { 49274664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); 49374664626SKris Kennaway return (0); 49474664626SKris Kennaway } 495*6f9291ceSJung-uk Kim if (!ssl_cert_inst(&ctx->cert)) { 49674664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_MALLOC_FAILURE); 49774664626SKris Kennaway return (0); 49874664626SKris Kennaway } 499*6f9291ceSJung-uk Kim if ((pkey = EVP_PKEY_new()) == NULL) { 50074664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB); 50174664626SKris Kennaway return (0); 50274664626SKris Kennaway } 50374664626SKris Kennaway 5045c87c606SMark Murray RSA_up_ref(rsa); 50574664626SKris Kennaway EVP_PKEY_assign_RSA(pkey, rsa); 50674664626SKris Kennaway 50774664626SKris Kennaway ret = ssl_set_pkey(ctx->cert, pkey); 50874664626SKris Kennaway EVP_PKEY_free(pkey); 50974664626SKris Kennaway return (ret); 51074664626SKris Kennaway } 51174664626SKris Kennaway 5125c87c606SMark Murray # ifndef OPENSSL_NO_STDIO 51374664626SKris Kennaway int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) 51474664626SKris Kennaway { 51574664626SKris Kennaway int j, ret = 0; 51674664626SKris Kennaway BIO *in; 51774664626SKris Kennaway RSA *rsa = NULL; 51874664626SKris Kennaway 51974664626SKris Kennaway in = BIO_new(BIO_s_file_internal()); 520*6f9291ceSJung-uk Kim if (in == NULL) { 52174664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB); 52274664626SKris Kennaway goto end; 52374664626SKris Kennaway } 52474664626SKris Kennaway 525*6f9291ceSJung-uk Kim if (BIO_read_filename(in, file) <= 0) { 52674664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB); 52774664626SKris Kennaway goto end; 52874664626SKris Kennaway } 529*6f9291ceSJung-uk Kim if (type == SSL_FILETYPE_ASN1) { 53074664626SKris Kennaway j = ERR_R_ASN1_LIB; 53174664626SKris Kennaway rsa = d2i_RSAPrivateKey_bio(in, NULL); 532*6f9291ceSJung-uk Kim } else if (type == SSL_FILETYPE_PEM) { 53374664626SKris Kennaway j = ERR_R_PEM_LIB; 53474664626SKris Kennaway rsa = PEM_read_bio_RSAPrivateKey(in, NULL, 535*6f9291ceSJung-uk Kim ctx->default_passwd_callback, 536*6f9291ceSJung-uk Kim ctx->default_passwd_callback_userdata); 537*6f9291ceSJung-uk Kim } else { 53874664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); 53974664626SKris Kennaway goto end; 54074664626SKris Kennaway } 541*6f9291ceSJung-uk Kim if (rsa == NULL) { 54274664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, j); 54374664626SKris Kennaway goto end; 54474664626SKris Kennaway } 54574664626SKris Kennaway ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); 54674664626SKris Kennaway RSA_free(rsa); 54774664626SKris Kennaway end: 548*6f9291ceSJung-uk Kim if (in != NULL) 549*6f9291ceSJung-uk Kim BIO_free(in); 55074664626SKris Kennaway return (ret); 55174664626SKris Kennaway } 55274664626SKris Kennaway # endif 55374664626SKris Kennaway 554*6f9291ceSJung-uk Kim int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, 555*6f9291ceSJung-uk Kim long len) 55674664626SKris Kennaway { 55774664626SKris Kennaway int ret; 5585c87c606SMark Murray const unsigned char *p; 55974664626SKris Kennaway RSA *rsa; 56074664626SKris Kennaway 56174664626SKris Kennaway p = d; 562*6f9291ceSJung-uk Kim if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) { 56374664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB); 56474664626SKris Kennaway return (0); 56574664626SKris Kennaway } 56674664626SKris Kennaway 56774664626SKris Kennaway ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); 56874664626SKris Kennaway RSA_free(rsa); 56974664626SKris Kennaway return (ret); 57074664626SKris Kennaway } 5715c87c606SMark Murray #endif /* !OPENSSL_NO_RSA */ 57274664626SKris Kennaway 57374664626SKris Kennaway int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) 57474664626SKris Kennaway { 575*6f9291ceSJung-uk Kim if (pkey == NULL) { 57674664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); 57774664626SKris Kennaway return (0); 57874664626SKris Kennaway } 579*6f9291ceSJung-uk Kim if (!ssl_cert_inst(&ctx->cert)) { 58074664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_MALLOC_FAILURE); 58174664626SKris Kennaway return (0); 58274664626SKris Kennaway } 58374664626SKris Kennaway return (ssl_set_pkey(ctx->cert, pkey)); 58474664626SKris Kennaway } 58574664626SKris Kennaway 5865c87c606SMark Murray #ifndef OPENSSL_NO_STDIO 58774664626SKris Kennaway int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) 58874664626SKris Kennaway { 58974664626SKris Kennaway int j, ret = 0; 59074664626SKris Kennaway BIO *in; 59174664626SKris Kennaway EVP_PKEY *pkey = NULL; 59274664626SKris Kennaway 59374664626SKris Kennaway in = BIO_new(BIO_s_file_internal()); 594*6f9291ceSJung-uk Kim if (in == NULL) { 59574664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB); 59674664626SKris Kennaway goto end; 59774664626SKris Kennaway } 59874664626SKris Kennaway 599*6f9291ceSJung-uk Kim if (BIO_read_filename(in, file) <= 0) { 60074664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB); 60174664626SKris Kennaway goto end; 60274664626SKris Kennaway } 603*6f9291ceSJung-uk Kim if (type == SSL_FILETYPE_PEM) { 60474664626SKris Kennaway j = ERR_R_PEM_LIB; 60574664626SKris Kennaway pkey = PEM_read_bio_PrivateKey(in, NULL, 606*6f9291ceSJung-uk Kim ctx->default_passwd_callback, 607*6f9291ceSJung-uk Kim ctx->default_passwd_callback_userdata); 608*6f9291ceSJung-uk Kim } else if (type == SSL_FILETYPE_ASN1) { 6093b4e3dcbSSimon L. B. Nielsen j = ERR_R_ASN1_LIB; 6103b4e3dcbSSimon L. B. Nielsen pkey = d2i_PrivateKey_bio(in, NULL); 611*6f9291ceSJung-uk Kim } else { 61274664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); 61374664626SKris Kennaway goto end; 61474664626SKris Kennaway } 615*6f9291ceSJung-uk Kim if (pkey == NULL) { 61674664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, j); 61774664626SKris Kennaway goto end; 61874664626SKris Kennaway } 61974664626SKris Kennaway ret = SSL_CTX_use_PrivateKey(ctx, pkey); 62074664626SKris Kennaway EVP_PKEY_free(pkey); 62174664626SKris Kennaway end: 622*6f9291ceSJung-uk Kim if (in != NULL) 623*6f9291ceSJung-uk Kim BIO_free(in); 62474664626SKris Kennaway return (ret); 62574664626SKris Kennaway } 62674664626SKris Kennaway #endif 62774664626SKris Kennaway 628*6f9291ceSJung-uk Kim int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, 629*6f9291ceSJung-uk Kim const unsigned char *d, long len) 63074664626SKris Kennaway { 63174664626SKris Kennaway int ret; 6323b4e3dcbSSimon L. B. Nielsen const unsigned char *p; 63374664626SKris Kennaway EVP_PKEY *pkey; 63474664626SKris Kennaway 63574664626SKris Kennaway p = d; 636*6f9291ceSJung-uk Kim if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) { 63774664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB); 63874664626SKris Kennaway return (0); 63974664626SKris Kennaway } 64074664626SKris Kennaway 64174664626SKris Kennaway ret = SSL_CTX_use_PrivateKey(ctx, pkey); 64274664626SKris Kennaway EVP_PKEY_free(pkey); 64374664626SKris Kennaway return (ret); 64474664626SKris Kennaway } 64574664626SKris Kennaway 6465c87c606SMark Murray #ifndef OPENSSL_NO_STDIO 647*6f9291ceSJung-uk Kim /* 648*6f9291ceSJung-uk Kim * Read a file that contains our certificate in "PEM" format, possibly 649*6f9291ceSJung-uk Kim * followed by a sequence of CA certificates that should be sent to the peer 650*6f9291ceSJung-uk Kim * in the Certificate message. 65174664626SKris Kennaway */ 65274664626SKris Kennaway int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) 65374664626SKris Kennaway { 65474664626SKris Kennaway BIO *in; 65574664626SKris Kennaway int ret = 0; 65674664626SKris Kennaway X509 *x = NULL; 65774664626SKris Kennaway 658*6f9291ceSJung-uk Kim ERR_clear_error(); /* clear error stack for 659*6f9291ceSJung-uk Kim * SSL_CTX_use_certificate() */ 660db522d3aSSimon L. B. Nielsen 66174664626SKris Kennaway in = BIO_new(BIO_s_file_internal()); 662*6f9291ceSJung-uk Kim if (in == NULL) { 66374664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB); 66474664626SKris Kennaway goto end; 66574664626SKris Kennaway } 66674664626SKris Kennaway 667*6f9291ceSJung-uk Kim if (BIO_read_filename(in, file) <= 0) { 66874664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_SYS_LIB); 66974664626SKris Kennaway goto end; 67074664626SKris Kennaway } 67174664626SKris Kennaway 67209286989SJung-uk Kim x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, 67309286989SJung-uk Kim ctx->default_passwd_callback_userdata); 674*6f9291ceSJung-uk Kim if (x == NULL) { 67574664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB); 67674664626SKris Kennaway goto end; 67774664626SKris Kennaway } 67874664626SKris Kennaway 67974664626SKris Kennaway ret = SSL_CTX_use_certificate(ctx, x); 68009286989SJung-uk Kim 68174664626SKris Kennaway if (ERR_peek_error() != 0) 682*6f9291ceSJung-uk Kim ret = 0; /* Key/certificate mismatch doesn't imply 683*6f9291ceSJung-uk Kim * ret==0 ... */ 684*6f9291ceSJung-uk Kim if (ret) { 685*6f9291ceSJung-uk Kim /* 686*6f9291ceSJung-uk Kim * If we could set up our certificate, now proceed to the CA 687*6f9291ceSJung-uk Kim * certificates. 68874664626SKris Kennaway */ 68974664626SKris Kennaway X509 *ca; 69074664626SKris Kennaway int r; 69174664626SKris Kennaway unsigned long err; 69274664626SKris Kennaway 693*6f9291ceSJung-uk Kim if (ctx->extra_certs != NULL) { 69474664626SKris Kennaway sk_X509_pop_free(ctx->extra_certs, X509_free); 69574664626SKris Kennaway ctx->extra_certs = NULL; 69674664626SKris Kennaway } 69774664626SKris Kennaway 69809286989SJung-uk Kim while ((ca = PEM_read_bio_X509(in, NULL, 69909286989SJung-uk Kim ctx->default_passwd_callback, 70009286989SJung-uk Kim ctx->default_passwd_callback_userdata)) 701*6f9291ceSJung-uk Kim != NULL) { 70274664626SKris Kennaway r = SSL_CTX_add_extra_chain_cert(ctx, ca); 703*6f9291ceSJung-uk Kim if (!r) { 70474664626SKris Kennaway X509_free(ca); 70574664626SKris Kennaway ret = 0; 70674664626SKris Kennaway goto end; 70774664626SKris Kennaway } 708*6f9291ceSJung-uk Kim /* 709*6f9291ceSJung-uk Kim * Note that we must not free r if it was successfully added to 710*6f9291ceSJung-uk Kim * the chain (while we must free the main certificate, since its 711*6f9291ceSJung-uk Kim * reference count is increased by SSL_CTX_use_certificate). 712*6f9291ceSJung-uk Kim */ 71374664626SKris Kennaway } 71474664626SKris Kennaway /* When the while loop ends, it's usually just EOF. */ 7155c87c606SMark Murray err = ERR_peek_last_error(); 716*6f9291ceSJung-uk Kim if (ERR_GET_LIB(err) == ERR_LIB_PEM 717*6f9291ceSJung-uk Kim && ERR_GET_REASON(err) == PEM_R_NO_START_LINE) 7183b4e3dcbSSimon L. B. Nielsen ERR_clear_error(); 71974664626SKris Kennaway else 72074664626SKris Kennaway ret = 0; /* some real error */ 72174664626SKris Kennaway } 72274664626SKris Kennaway 72374664626SKris Kennaway end: 724*6f9291ceSJung-uk Kim if (x != NULL) 725*6f9291ceSJung-uk Kim X509_free(x); 726*6f9291ceSJung-uk Kim if (in != NULL) 727*6f9291ceSJung-uk Kim BIO_free(in); 72874664626SKris Kennaway return (ret); 72974664626SKris Kennaway } 73074664626SKris Kennaway #endif 731