1*e71b7053SJung-uk Kim /* 2*e71b7053SJung-uk Kim * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. 374664626SKris Kennaway * 4*e71b7053SJung-uk Kim * Licensed under the OpenSSL license (the "License"). You may not use 5*e71b7053SJung-uk Kim * this file except in compliance with the License. You can obtain a copy 6*e71b7053SJung-uk Kim * in the file LICENSE in the source distribution or at 7*e71b7053SJung-uk Kim * https://www.openssl.org/source/license.html 874664626SKris Kennaway */ 974664626SKris Kennaway 1074664626SKris Kennaway #include <stdio.h> 115c87c606SMark Murray #include "ssl_locl.h" 12*e71b7053SJung-uk Kim #include "packet_locl.h" 1374664626SKris Kennaway #include <openssl/bio.h> 1474664626SKris Kennaway #include <openssl/objects.h> 1574664626SKris Kennaway #include <openssl/evp.h> 1674664626SKris Kennaway #include <openssl/x509.h> 1774664626SKris Kennaway #include <openssl/pem.h> 1874664626SKris Kennaway 1974664626SKris Kennaway static int ssl_set_cert(CERT *c, X509 *x509); 2074664626SKris Kennaway static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey); 21*e71b7053SJung-uk Kim 22*e71b7053SJung-uk Kim #define SYNTHV1CONTEXT (SSL_EXT_TLS1_2_AND_BELOW_ONLY \ 23*e71b7053SJung-uk Kim | SSL_EXT_CLIENT_HELLO \ 24*e71b7053SJung-uk Kim | SSL_EXT_TLS1_2_SERVER_HELLO \ 25*e71b7053SJung-uk Kim | SSL_EXT_IGNORE_ON_RESUMPTION) 26*e71b7053SJung-uk Kim 2774664626SKris Kennaway int SSL_use_certificate(SSL *ssl, X509 *x) 2874664626SKris Kennaway { 29*e71b7053SJung-uk Kim int rv; 306f9291ceSJung-uk Kim if (x == NULL) { 3174664626SKris Kennaway SSLerr(SSL_F_SSL_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); 32*e71b7053SJung-uk Kim return 0; 3374664626SKris Kennaway } 34*e71b7053SJung-uk Kim rv = ssl_security_cert(ssl, NULL, x, 0, 1); 35*e71b7053SJung-uk Kim if (rv != 1) { 36*e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_USE_CERTIFICATE, rv); 37*e71b7053SJung-uk Kim return 0; 3874664626SKris Kennaway } 3974664626SKris Kennaway 40*e71b7053SJung-uk Kim return ssl_set_cert(ssl->cert, x); 41*e71b7053SJung-uk Kim } 42*e71b7053SJung-uk Kim 4374664626SKris Kennaway int SSL_use_certificate_file(SSL *ssl, const char *file, int type) 4474664626SKris Kennaway { 4574664626SKris Kennaway int j; 4674664626SKris Kennaway BIO *in; 4774664626SKris Kennaway int ret = 0; 4874664626SKris Kennaway X509 *x = NULL; 4974664626SKris Kennaway 50*e71b7053SJung-uk Kim in = BIO_new(BIO_s_file()); 516f9291ceSJung-uk Kim if (in == NULL) { 5274664626SKris Kennaway SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB); 5374664626SKris Kennaway goto end; 5474664626SKris Kennaway } 5574664626SKris Kennaway 566f9291ceSJung-uk Kim if (BIO_read_filename(in, file) <= 0) { 5774664626SKris Kennaway SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); 5874664626SKris Kennaway goto end; 5974664626SKris Kennaway } 606f9291ceSJung-uk Kim if (type == SSL_FILETYPE_ASN1) { 6174664626SKris Kennaway j = ERR_R_ASN1_LIB; 6274664626SKris Kennaway x = d2i_X509_bio(in, NULL); 636f9291ceSJung-uk Kim } else if (type == SSL_FILETYPE_PEM) { 6474664626SKris Kennaway j = ERR_R_PEM_LIB; 65*e71b7053SJung-uk Kim x = PEM_read_bio_X509(in, NULL, ssl->default_passwd_callback, 66*e71b7053SJung-uk Kim ssl->default_passwd_callback_userdata); 676f9291ceSJung-uk Kim } else { 6874664626SKris Kennaway SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); 6974664626SKris Kennaway goto end; 7074664626SKris Kennaway } 7174664626SKris Kennaway 726f9291ceSJung-uk Kim if (x == NULL) { 7374664626SKris Kennaway SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, j); 7474664626SKris Kennaway goto end; 7574664626SKris Kennaway } 7674664626SKris Kennaway 7774664626SKris Kennaway ret = SSL_use_certificate(ssl, x); 7874664626SKris Kennaway end: 796f9291ceSJung-uk Kim X509_free(x); 806f9291ceSJung-uk Kim BIO_free(in); 81*e71b7053SJung-uk Kim return ret; 8274664626SKris Kennaway } 8374664626SKris Kennaway 843b4e3dcbSSimon L. B. Nielsen int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len) 8574664626SKris Kennaway { 8674664626SKris Kennaway X509 *x; 8774664626SKris Kennaway int ret; 8874664626SKris Kennaway 8974664626SKris Kennaway x = d2i_X509(NULL, &d, (long)len); 906f9291ceSJung-uk Kim if (x == NULL) { 9174664626SKris Kennaway SSLerr(SSL_F_SSL_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); 92*e71b7053SJung-uk Kim return 0; 9374664626SKris Kennaway } 9474664626SKris Kennaway 9574664626SKris Kennaway ret = SSL_use_certificate(ssl, x); 9674664626SKris Kennaway X509_free(x); 97*e71b7053SJung-uk Kim return ret; 9874664626SKris Kennaway } 9974664626SKris Kennaway 1005c87c606SMark Murray #ifndef OPENSSL_NO_RSA 10174664626SKris Kennaway int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) 10274664626SKris Kennaway { 10374664626SKris Kennaway EVP_PKEY *pkey; 10474664626SKris Kennaway int ret; 10574664626SKris Kennaway 1066f9291ceSJung-uk Kim if (rsa == NULL) { 10774664626SKris Kennaway SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); 108*e71b7053SJung-uk Kim return 0; 10974664626SKris Kennaway } 1106f9291ceSJung-uk Kim if ((pkey = EVP_PKEY_new()) == NULL) { 11174664626SKris Kennaway SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB); 112*e71b7053SJung-uk Kim return 0; 11374664626SKris Kennaway } 11474664626SKris Kennaway 1155c87c606SMark Murray RSA_up_ref(rsa); 11680815a77SJung-uk Kim if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) { 11780815a77SJung-uk Kim RSA_free(rsa); 118*e71b7053SJung-uk Kim EVP_PKEY_free(pkey); 11980815a77SJung-uk Kim return 0; 12080815a77SJung-uk Kim } 12174664626SKris Kennaway 12274664626SKris Kennaway ret = ssl_set_pkey(ssl->cert, pkey); 12374664626SKris Kennaway EVP_PKEY_free(pkey); 124*e71b7053SJung-uk Kim return ret; 12574664626SKris Kennaway } 12674664626SKris Kennaway #endif 12774664626SKris Kennaway 12874664626SKris Kennaway static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) 12974664626SKris Kennaway { 130*e71b7053SJung-uk Kim size_t i; 131*e71b7053SJung-uk Kim 132*e71b7053SJung-uk Kim if (ssl_cert_lookup_by_pkey(pkey, &i) == NULL) { 13374664626SKris Kennaway SSLerr(SSL_F_SSL_SET_PKEY, SSL_R_UNKNOWN_CERTIFICATE_TYPE); 134*e71b7053SJung-uk Kim return 0; 13574664626SKris Kennaway } 13674664626SKris Kennaway 1376f9291ceSJung-uk Kim if (c->pkeys[i].x509 != NULL) { 13874664626SKris Kennaway EVP_PKEY *pktmp; 139*e71b7053SJung-uk Kim pktmp = X509_get0_pubkey(c->pkeys[i].x509); 14080815a77SJung-uk Kim if (pktmp == NULL) { 14180815a77SJung-uk Kim SSLerr(SSL_F_SSL_SET_PKEY, ERR_R_MALLOC_FAILURE); 14280815a77SJung-uk Kim return 0; 14380815a77SJung-uk Kim } 14480815a77SJung-uk Kim /* 14580815a77SJung-uk Kim * The return code from EVP_PKEY_copy_parameters is deliberately 14680815a77SJung-uk Kim * ignored. Some EVP_PKEY types cannot do this. 14780815a77SJung-uk Kim */ 14874664626SKris Kennaway EVP_PKEY_copy_parameters(pktmp, pkey); 14974664626SKris Kennaway ERR_clear_error(); 15074664626SKris Kennaway 1515c87c606SMark Murray #ifndef OPENSSL_NO_RSA 1526f9291ceSJung-uk Kim /* 1536f9291ceSJung-uk Kim * Don't check the public/private key, this is mostly for smart 1546f9291ceSJung-uk Kim * cards. 1556f9291ceSJung-uk Kim */ 156*e71b7053SJung-uk Kim if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA 157*e71b7053SJung-uk Kim && RSA_flags(EVP_PKEY_get0_RSA(pkey)) & RSA_METHOD_FLAG_NO_CHECK) ; 15874664626SKris Kennaway else 15974664626SKris Kennaway #endif 1606f9291ceSJung-uk Kim if (!X509_check_private_key(c->pkeys[i].x509, pkey)) { 16174664626SKris Kennaway X509_free(c->pkeys[i].x509); 16274664626SKris Kennaway c->pkeys[i].x509 = NULL; 1633b4e3dcbSSimon L. B. Nielsen return 0; 1643b4e3dcbSSimon L. B. Nielsen } 16574664626SKris Kennaway } 16674664626SKris Kennaway 16774664626SKris Kennaway EVP_PKEY_free(c->pkeys[i].privatekey); 168*e71b7053SJung-uk Kim EVP_PKEY_up_ref(pkey); 16974664626SKris Kennaway c->pkeys[i].privatekey = pkey; 170*e71b7053SJung-uk Kim c->key = &c->pkeys[i]; 171*e71b7053SJung-uk Kim return 1; 17274664626SKris Kennaway } 17374664626SKris Kennaway 1745c87c606SMark Murray #ifndef OPENSSL_NO_RSA 17574664626SKris Kennaway int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) 17674664626SKris Kennaway { 17774664626SKris Kennaway int j, ret = 0; 17874664626SKris Kennaway BIO *in; 17974664626SKris Kennaway RSA *rsa = NULL; 18074664626SKris Kennaway 181*e71b7053SJung-uk Kim in = BIO_new(BIO_s_file()); 1826f9291ceSJung-uk Kim if (in == NULL) { 18374664626SKris Kennaway SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB); 18474664626SKris Kennaway goto end; 18574664626SKris Kennaway } 18674664626SKris Kennaway 1876f9291ceSJung-uk Kim if (BIO_read_filename(in, file) <= 0) { 18874664626SKris Kennaway SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB); 18974664626SKris Kennaway goto end; 19074664626SKris Kennaway } 1916f9291ceSJung-uk Kim if (type == SSL_FILETYPE_ASN1) { 19274664626SKris Kennaway j = ERR_R_ASN1_LIB; 19374664626SKris Kennaway rsa = d2i_RSAPrivateKey_bio(in, NULL); 1946f9291ceSJung-uk Kim } else if (type == SSL_FILETYPE_PEM) { 19574664626SKris Kennaway j = ERR_R_PEM_LIB; 19674664626SKris Kennaway rsa = PEM_read_bio_RSAPrivateKey(in, NULL, 197*e71b7053SJung-uk Kim ssl->default_passwd_callback, 198*e71b7053SJung-uk Kim ssl->default_passwd_callback_userdata); 1996f9291ceSJung-uk Kim } else { 20074664626SKris Kennaway SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); 20174664626SKris Kennaway goto end; 20274664626SKris Kennaway } 2036f9291ceSJung-uk Kim if (rsa == NULL) { 20474664626SKris Kennaway SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, j); 20574664626SKris Kennaway goto end; 20674664626SKris Kennaway } 20774664626SKris Kennaway ret = SSL_use_RSAPrivateKey(ssl, rsa); 20874664626SKris Kennaway RSA_free(rsa); 20974664626SKris Kennaway end: 2106f9291ceSJung-uk Kim BIO_free(in); 211*e71b7053SJung-uk Kim return ret; 21274664626SKris Kennaway } 21374664626SKris Kennaway 214*e71b7053SJung-uk Kim int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, long len) 21574664626SKris Kennaway { 21674664626SKris Kennaway int ret; 2175c87c606SMark Murray const unsigned char *p; 21874664626SKris Kennaway RSA *rsa; 21974664626SKris Kennaway 22074664626SKris Kennaway p = d; 2216f9291ceSJung-uk Kim if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) { 22274664626SKris Kennaway SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB); 223*e71b7053SJung-uk Kim return 0; 22474664626SKris Kennaway } 22574664626SKris Kennaway 22674664626SKris Kennaway ret = SSL_use_RSAPrivateKey(ssl, rsa); 22774664626SKris Kennaway RSA_free(rsa); 228*e71b7053SJung-uk Kim return ret; 22974664626SKris Kennaway } 2305c87c606SMark Murray #endif /* !OPENSSL_NO_RSA */ 23174664626SKris Kennaway 23274664626SKris Kennaway int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) 23374664626SKris Kennaway { 23474664626SKris Kennaway int ret; 23574664626SKris Kennaway 2366f9291ceSJung-uk Kim if (pkey == NULL) { 23774664626SKris Kennaway SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); 238*e71b7053SJung-uk Kim return 0; 23974664626SKris Kennaway } 24074664626SKris Kennaway ret = ssl_set_pkey(ssl->cert, pkey); 241*e71b7053SJung-uk Kim return ret; 24274664626SKris Kennaway } 24374664626SKris Kennaway 24474664626SKris Kennaway int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) 24574664626SKris Kennaway { 24674664626SKris Kennaway int j, ret = 0; 24774664626SKris Kennaway BIO *in; 24874664626SKris Kennaway EVP_PKEY *pkey = NULL; 24974664626SKris Kennaway 250*e71b7053SJung-uk Kim in = BIO_new(BIO_s_file()); 2516f9291ceSJung-uk Kim if (in == NULL) { 25274664626SKris Kennaway SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB); 25374664626SKris Kennaway goto end; 25474664626SKris Kennaway } 25574664626SKris Kennaway 2566f9291ceSJung-uk Kim if (BIO_read_filename(in, file) <= 0) { 25774664626SKris Kennaway SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB); 25874664626SKris Kennaway goto end; 25974664626SKris Kennaway } 2606f9291ceSJung-uk Kim if (type == SSL_FILETYPE_PEM) { 26174664626SKris Kennaway j = ERR_R_PEM_LIB; 26274664626SKris Kennaway pkey = PEM_read_bio_PrivateKey(in, NULL, 263*e71b7053SJung-uk Kim ssl->default_passwd_callback, 264*e71b7053SJung-uk Kim ssl->default_passwd_callback_userdata); 2656f9291ceSJung-uk Kim } else if (type == SSL_FILETYPE_ASN1) { 2663b4e3dcbSSimon L. B. Nielsen j = ERR_R_ASN1_LIB; 2673b4e3dcbSSimon L. B. Nielsen pkey = d2i_PrivateKey_bio(in, NULL); 2686f9291ceSJung-uk Kim } else { 26974664626SKris Kennaway SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); 27074664626SKris Kennaway goto end; 27174664626SKris Kennaway } 2726f9291ceSJung-uk Kim if (pkey == NULL) { 27374664626SKris Kennaway SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, j); 27474664626SKris Kennaway goto end; 27574664626SKris Kennaway } 27674664626SKris Kennaway ret = SSL_use_PrivateKey(ssl, pkey); 27774664626SKris Kennaway EVP_PKEY_free(pkey); 27874664626SKris Kennaway end: 2796f9291ceSJung-uk Kim BIO_free(in); 280*e71b7053SJung-uk Kim return ret; 28174664626SKris Kennaway } 28274664626SKris Kennaway 2836f9291ceSJung-uk Kim int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, 2846f9291ceSJung-uk Kim long len) 28574664626SKris Kennaway { 28674664626SKris Kennaway int ret; 2873b4e3dcbSSimon L. B. Nielsen const unsigned char *p; 28874664626SKris Kennaway EVP_PKEY *pkey; 28974664626SKris Kennaway 29074664626SKris Kennaway p = d; 2916f9291ceSJung-uk Kim if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) { 29274664626SKris Kennaway SSLerr(SSL_F_SSL_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB); 293*e71b7053SJung-uk Kim return 0; 29474664626SKris Kennaway } 29574664626SKris Kennaway 29674664626SKris Kennaway ret = SSL_use_PrivateKey(ssl, pkey); 29774664626SKris Kennaway EVP_PKEY_free(pkey); 298*e71b7053SJung-uk Kim return ret; 29974664626SKris Kennaway } 30074664626SKris Kennaway 30174664626SKris Kennaway int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) 30274664626SKris Kennaway { 303*e71b7053SJung-uk Kim int rv; 3046f9291ceSJung-uk Kim if (x == NULL) { 30574664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); 306*e71b7053SJung-uk Kim return 0; 30774664626SKris Kennaway } 308*e71b7053SJung-uk Kim rv = ssl_security_cert(NULL, ctx, x, 0, 1); 309*e71b7053SJung-uk Kim if (rv != 1) { 310*e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, rv); 311*e71b7053SJung-uk Kim return 0; 31274664626SKris Kennaway } 313*e71b7053SJung-uk Kim return ssl_set_cert(ctx->cert, x); 31474664626SKris Kennaway } 31574664626SKris Kennaway 31674664626SKris Kennaway static int ssl_set_cert(CERT *c, X509 *x) 31774664626SKris Kennaway { 31874664626SKris Kennaway EVP_PKEY *pkey; 319*e71b7053SJung-uk Kim size_t i; 32074664626SKris Kennaway 321*e71b7053SJung-uk Kim pkey = X509_get0_pubkey(x); 3226f9291ceSJung-uk Kim if (pkey == NULL) { 32374664626SKris Kennaway SSLerr(SSL_F_SSL_SET_CERT, SSL_R_X509_LIB); 324*e71b7053SJung-uk Kim return 0; 32574664626SKris Kennaway } 32674664626SKris Kennaway 327*e71b7053SJung-uk Kim if (ssl_cert_lookup_by_pkey(pkey, &i) == NULL) { 32874664626SKris Kennaway SSLerr(SSL_F_SSL_SET_CERT, SSL_R_UNKNOWN_CERTIFICATE_TYPE); 329*e71b7053SJung-uk Kim return 0; 33074664626SKris Kennaway } 331*e71b7053SJung-uk Kim #ifndef OPENSSL_NO_EC 332*e71b7053SJung-uk Kim if (i == SSL_PKEY_ECC && !EC_KEY_can_sign(EVP_PKEY_get0_EC_KEY(pkey))) { 333*e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_SET_CERT, SSL_R_ECC_CERT_NOT_FOR_SIGNING); 334*e71b7053SJung-uk Kim return 0; 335*e71b7053SJung-uk Kim } 336*e71b7053SJung-uk Kim #endif 3376f9291ceSJung-uk Kim if (c->pkeys[i].privatekey != NULL) { 33880815a77SJung-uk Kim /* 33980815a77SJung-uk Kim * The return code from EVP_PKEY_copy_parameters is deliberately 34080815a77SJung-uk Kim * ignored. Some EVP_PKEY types cannot do this. 34180815a77SJung-uk Kim */ 34274664626SKris Kennaway EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey); 34374664626SKris Kennaway ERR_clear_error(); 34474664626SKris Kennaway 3455c87c606SMark Murray #ifndef OPENSSL_NO_RSA 3466f9291ceSJung-uk Kim /* 3476f9291ceSJung-uk Kim * Don't check the public/private key, this is mostly for smart 3486f9291ceSJung-uk Kim * cards. 3496f9291ceSJung-uk Kim */ 350*e71b7053SJung-uk Kim if (EVP_PKEY_id(c->pkeys[i].privatekey) == EVP_PKEY_RSA 351*e71b7053SJung-uk Kim && RSA_flags(EVP_PKEY_get0_RSA(c->pkeys[i].privatekey)) & 352*e71b7053SJung-uk Kim RSA_METHOD_FLAG_NO_CHECK) ; 35374664626SKris Kennaway else 3543b4e3dcbSSimon L. B. Nielsen #endif /* OPENSSL_NO_RSA */ 3556f9291ceSJung-uk Kim if (!X509_check_private_key(x, c->pkeys[i].privatekey)) { 3566f9291ceSJung-uk Kim /* 3576f9291ceSJung-uk Kim * don't fail for a cert/key mismatch, just free current private 3586f9291ceSJung-uk Kim * key (when switching to a different cert & key, first this 3596f9291ceSJung-uk Kim * function should be used, then ssl_set_pkey 3606f9291ceSJung-uk Kim */ 36174664626SKris Kennaway EVP_PKEY_free(c->pkeys[i].privatekey); 36274664626SKris Kennaway c->pkeys[i].privatekey = NULL; 3633b4e3dcbSSimon L. B. Nielsen /* clear error queue */ 3643b4e3dcbSSimon L. B. Nielsen ERR_clear_error(); 36574664626SKris Kennaway } 3663b4e3dcbSSimon L. B. Nielsen } 3673b4e3dcbSSimon L. B. Nielsen 36874664626SKris Kennaway X509_free(c->pkeys[i].x509); 369*e71b7053SJung-uk Kim X509_up_ref(x); 37074664626SKris Kennaway c->pkeys[i].x509 = x; 37174664626SKris Kennaway c->key = &(c->pkeys[i]); 37274664626SKris Kennaway 373*e71b7053SJung-uk Kim return 1; 37474664626SKris Kennaway } 37574664626SKris Kennaway 37674664626SKris Kennaway int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) 37774664626SKris Kennaway { 37874664626SKris Kennaway int j; 37974664626SKris Kennaway BIO *in; 38074664626SKris Kennaway int ret = 0; 38174664626SKris Kennaway X509 *x = NULL; 38274664626SKris Kennaway 383*e71b7053SJung-uk Kim in = BIO_new(BIO_s_file()); 3846f9291ceSJung-uk Kim if (in == NULL) { 38574664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB); 38674664626SKris Kennaway goto end; 38774664626SKris Kennaway } 38874664626SKris Kennaway 3896f9291ceSJung-uk Kim if (BIO_read_filename(in, file) <= 0) { 39074664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); 39174664626SKris Kennaway goto end; 39274664626SKris Kennaway } 3936f9291ceSJung-uk Kim if (type == SSL_FILETYPE_ASN1) { 39474664626SKris Kennaway j = ERR_R_ASN1_LIB; 39574664626SKris Kennaway x = d2i_X509_bio(in, NULL); 3966f9291ceSJung-uk Kim } else if (type == SSL_FILETYPE_PEM) { 39774664626SKris Kennaway j = ERR_R_PEM_LIB; 3986f9291ceSJung-uk Kim x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, 3996f9291ceSJung-uk Kim ctx->default_passwd_callback_userdata); 4006f9291ceSJung-uk Kim } else { 40174664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); 40274664626SKris Kennaway goto end; 40374664626SKris Kennaway } 40474664626SKris Kennaway 4056f9291ceSJung-uk Kim if (x == NULL) { 40674664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, j); 40774664626SKris Kennaway goto end; 40874664626SKris Kennaway } 40974664626SKris Kennaway 41074664626SKris Kennaway ret = SSL_CTX_use_certificate(ctx, x); 41174664626SKris Kennaway end: 4126f9291ceSJung-uk Kim X509_free(x); 4136f9291ceSJung-uk Kim BIO_free(in); 414*e71b7053SJung-uk Kim return ret; 41574664626SKris Kennaway } 41674664626SKris Kennaway 417*e71b7053SJung-uk Kim int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d) 41874664626SKris Kennaway { 41974664626SKris Kennaway X509 *x; 42074664626SKris Kennaway int ret; 42174664626SKris Kennaway 42274664626SKris Kennaway x = d2i_X509(NULL, &d, (long)len); 4236f9291ceSJung-uk Kim if (x == NULL) { 42474664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); 425*e71b7053SJung-uk Kim return 0; 42674664626SKris Kennaway } 42774664626SKris Kennaway 42874664626SKris Kennaway ret = SSL_CTX_use_certificate(ctx, x); 42974664626SKris Kennaway X509_free(x); 430*e71b7053SJung-uk Kim return ret; 43174664626SKris Kennaway } 43274664626SKris Kennaway 4335c87c606SMark Murray #ifndef OPENSSL_NO_RSA 43474664626SKris Kennaway int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) 43574664626SKris Kennaway { 43674664626SKris Kennaway int ret; 43774664626SKris Kennaway EVP_PKEY *pkey; 43874664626SKris Kennaway 4396f9291ceSJung-uk Kim if (rsa == NULL) { 44074664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); 441*e71b7053SJung-uk Kim return 0; 44274664626SKris Kennaway } 4436f9291ceSJung-uk Kim if ((pkey = EVP_PKEY_new()) == NULL) { 44474664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB); 445*e71b7053SJung-uk Kim return 0; 44674664626SKris Kennaway } 44774664626SKris Kennaway 4485c87c606SMark Murray RSA_up_ref(rsa); 44980815a77SJung-uk Kim if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) { 45080815a77SJung-uk Kim RSA_free(rsa); 451*e71b7053SJung-uk Kim EVP_PKEY_free(pkey); 45280815a77SJung-uk Kim return 0; 45380815a77SJung-uk Kim } 45474664626SKris Kennaway 45574664626SKris Kennaway ret = ssl_set_pkey(ctx->cert, pkey); 45674664626SKris Kennaway EVP_PKEY_free(pkey); 457*e71b7053SJung-uk Kim return ret; 45874664626SKris Kennaway } 45974664626SKris Kennaway 46074664626SKris Kennaway int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) 46174664626SKris Kennaway { 46274664626SKris Kennaway int j, ret = 0; 46374664626SKris Kennaway BIO *in; 46474664626SKris Kennaway RSA *rsa = NULL; 46574664626SKris Kennaway 466*e71b7053SJung-uk Kim in = BIO_new(BIO_s_file()); 4676f9291ceSJung-uk Kim if (in == NULL) { 46874664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB); 46974664626SKris Kennaway goto end; 47074664626SKris Kennaway } 47174664626SKris Kennaway 4726f9291ceSJung-uk Kim if (BIO_read_filename(in, file) <= 0) { 47374664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB); 47474664626SKris Kennaway goto end; 47574664626SKris Kennaway } 4766f9291ceSJung-uk Kim if (type == SSL_FILETYPE_ASN1) { 47774664626SKris Kennaway j = ERR_R_ASN1_LIB; 47874664626SKris Kennaway rsa = d2i_RSAPrivateKey_bio(in, NULL); 4796f9291ceSJung-uk Kim } else if (type == SSL_FILETYPE_PEM) { 48074664626SKris Kennaway j = ERR_R_PEM_LIB; 48174664626SKris Kennaway rsa = PEM_read_bio_RSAPrivateKey(in, NULL, 4826f9291ceSJung-uk Kim ctx->default_passwd_callback, 4836f9291ceSJung-uk Kim ctx->default_passwd_callback_userdata); 4846f9291ceSJung-uk Kim } else { 48574664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); 48674664626SKris Kennaway goto end; 48774664626SKris Kennaway } 4886f9291ceSJung-uk Kim if (rsa == NULL) { 48974664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, j); 49074664626SKris Kennaway goto end; 49174664626SKris Kennaway } 49274664626SKris Kennaway ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); 49374664626SKris Kennaway RSA_free(rsa); 49474664626SKris Kennaway end: 4956f9291ceSJung-uk Kim BIO_free(in); 496*e71b7053SJung-uk Kim return ret; 49774664626SKris Kennaway } 49874664626SKris Kennaway 4996f9291ceSJung-uk Kim int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, 5006f9291ceSJung-uk Kim long len) 50174664626SKris Kennaway { 50274664626SKris Kennaway int ret; 5035c87c606SMark Murray const unsigned char *p; 50474664626SKris Kennaway RSA *rsa; 50574664626SKris Kennaway 50674664626SKris Kennaway p = d; 5076f9291ceSJung-uk Kim if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) { 50874664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB); 509*e71b7053SJung-uk Kim return 0; 51074664626SKris Kennaway } 51174664626SKris Kennaway 51274664626SKris Kennaway ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); 51374664626SKris Kennaway RSA_free(rsa); 514*e71b7053SJung-uk Kim return ret; 51574664626SKris Kennaway } 5165c87c606SMark Murray #endif /* !OPENSSL_NO_RSA */ 51774664626SKris Kennaway 51874664626SKris Kennaway int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) 51974664626SKris Kennaway { 5206f9291ceSJung-uk Kim if (pkey == NULL) { 52174664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); 522*e71b7053SJung-uk Kim return 0; 52374664626SKris Kennaway } 524*e71b7053SJung-uk Kim return ssl_set_pkey(ctx->cert, pkey); 52574664626SKris Kennaway } 52674664626SKris Kennaway 52774664626SKris Kennaway int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) 52874664626SKris Kennaway { 52974664626SKris Kennaway int j, ret = 0; 53074664626SKris Kennaway BIO *in; 53174664626SKris Kennaway EVP_PKEY *pkey = NULL; 53274664626SKris Kennaway 533*e71b7053SJung-uk Kim in = BIO_new(BIO_s_file()); 5346f9291ceSJung-uk Kim if (in == NULL) { 53574664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB); 53674664626SKris Kennaway goto end; 53774664626SKris Kennaway } 53874664626SKris Kennaway 5396f9291ceSJung-uk Kim if (BIO_read_filename(in, file) <= 0) { 54074664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB); 54174664626SKris Kennaway goto end; 54274664626SKris Kennaway } 5436f9291ceSJung-uk Kim if (type == SSL_FILETYPE_PEM) { 54474664626SKris Kennaway j = ERR_R_PEM_LIB; 54574664626SKris Kennaway pkey = PEM_read_bio_PrivateKey(in, NULL, 5466f9291ceSJung-uk Kim ctx->default_passwd_callback, 5476f9291ceSJung-uk Kim ctx->default_passwd_callback_userdata); 5486f9291ceSJung-uk Kim } else if (type == SSL_FILETYPE_ASN1) { 5493b4e3dcbSSimon L. B. Nielsen j = ERR_R_ASN1_LIB; 5503b4e3dcbSSimon L. B. Nielsen pkey = d2i_PrivateKey_bio(in, NULL); 5516f9291ceSJung-uk Kim } else { 55274664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); 55374664626SKris Kennaway goto end; 55474664626SKris Kennaway } 5556f9291ceSJung-uk Kim if (pkey == NULL) { 55674664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, j); 55774664626SKris Kennaway goto end; 55874664626SKris Kennaway } 55974664626SKris Kennaway ret = SSL_CTX_use_PrivateKey(ctx, pkey); 56074664626SKris Kennaway EVP_PKEY_free(pkey); 56174664626SKris Kennaway end: 5626f9291ceSJung-uk Kim BIO_free(in); 563*e71b7053SJung-uk Kim return ret; 56474664626SKris Kennaway } 56574664626SKris Kennaway 5666f9291ceSJung-uk Kim int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, 5676f9291ceSJung-uk Kim const unsigned char *d, long len) 56874664626SKris Kennaway { 56974664626SKris Kennaway int ret; 5703b4e3dcbSSimon L. B. Nielsen const unsigned char *p; 57174664626SKris Kennaway EVP_PKEY *pkey; 57274664626SKris Kennaway 57374664626SKris Kennaway p = d; 5746f9291ceSJung-uk Kim if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) { 57574664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB); 576*e71b7053SJung-uk Kim return 0; 57774664626SKris Kennaway } 57874664626SKris Kennaway 57974664626SKris Kennaway ret = SSL_CTX_use_PrivateKey(ctx, pkey); 58074664626SKris Kennaway EVP_PKEY_free(pkey); 581*e71b7053SJung-uk Kim return ret; 58274664626SKris Kennaway } 58374664626SKris Kennaway 5846f9291ceSJung-uk Kim /* 5856f9291ceSJung-uk Kim * Read a file that contains our certificate in "PEM" format, possibly 5866f9291ceSJung-uk Kim * followed by a sequence of CA certificates that should be sent to the peer 5876f9291ceSJung-uk Kim * in the Certificate message. 58874664626SKris Kennaway */ 589*e71b7053SJung-uk Kim static int use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file) 59074664626SKris Kennaway { 59174664626SKris Kennaway BIO *in; 59274664626SKris Kennaway int ret = 0; 59374664626SKris Kennaway X509 *x = NULL; 594*e71b7053SJung-uk Kim pem_password_cb *passwd_callback; 595*e71b7053SJung-uk Kim void *passwd_callback_userdata; 59674664626SKris Kennaway 5976f9291ceSJung-uk Kim ERR_clear_error(); /* clear error stack for 5986f9291ceSJung-uk Kim * SSL_CTX_use_certificate() */ 599db522d3aSSimon L. B. Nielsen 600*e71b7053SJung-uk Kim if (ctx != NULL) { 601*e71b7053SJung-uk Kim passwd_callback = ctx->default_passwd_callback; 602*e71b7053SJung-uk Kim passwd_callback_userdata = ctx->default_passwd_callback_userdata; 603*e71b7053SJung-uk Kim } else { 604*e71b7053SJung-uk Kim passwd_callback = ssl->default_passwd_callback; 605*e71b7053SJung-uk Kim passwd_callback_userdata = ssl->default_passwd_callback_userdata; 606*e71b7053SJung-uk Kim } 607*e71b7053SJung-uk Kim 608*e71b7053SJung-uk Kim in = BIO_new(BIO_s_file()); 6096f9291ceSJung-uk Kim if (in == NULL) { 610*e71b7053SJung-uk Kim SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB); 61174664626SKris Kennaway goto end; 61274664626SKris Kennaway } 61374664626SKris Kennaway 6146f9291ceSJung-uk Kim if (BIO_read_filename(in, file) <= 0) { 615*e71b7053SJung-uk Kim SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_SYS_LIB); 61674664626SKris Kennaway goto end; 61774664626SKris Kennaway } 61874664626SKris Kennaway 619*e71b7053SJung-uk Kim x = PEM_read_bio_X509_AUX(in, NULL, passwd_callback, 620*e71b7053SJung-uk Kim passwd_callback_userdata); 6216f9291ceSJung-uk Kim if (x == NULL) { 622*e71b7053SJung-uk Kim SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB); 62374664626SKris Kennaway goto end; 62474664626SKris Kennaway } 62574664626SKris Kennaway 626*e71b7053SJung-uk Kim if (ctx) 62774664626SKris Kennaway ret = SSL_CTX_use_certificate(ctx, x); 628*e71b7053SJung-uk Kim else 629*e71b7053SJung-uk Kim ret = SSL_use_certificate(ssl, x); 63009286989SJung-uk Kim 63174664626SKris Kennaway if (ERR_peek_error() != 0) 6326f9291ceSJung-uk Kim ret = 0; /* Key/certificate mismatch doesn't imply 6336f9291ceSJung-uk Kim * ret==0 ... */ 6346f9291ceSJung-uk Kim if (ret) { 6356f9291ceSJung-uk Kim /* 6366f9291ceSJung-uk Kim * If we could set up our certificate, now proceed to the CA 6376f9291ceSJung-uk Kim * certificates. 63874664626SKris Kennaway */ 63974664626SKris Kennaway X509 *ca; 64074664626SKris Kennaway int r; 64174664626SKris Kennaway unsigned long err; 64274664626SKris Kennaway 643*e71b7053SJung-uk Kim if (ctx) 644*e71b7053SJung-uk Kim r = SSL_CTX_clear_chain_certs(ctx); 645*e71b7053SJung-uk Kim else 646*e71b7053SJung-uk Kim r = SSL_clear_chain_certs(ssl); 64774664626SKris Kennaway 648*e71b7053SJung-uk Kim if (r == 0) { 649*e71b7053SJung-uk Kim ret = 0; 650*e71b7053SJung-uk Kim goto end; 651*e71b7053SJung-uk Kim } 652*e71b7053SJung-uk Kim 653*e71b7053SJung-uk Kim while ((ca = PEM_read_bio_X509(in, NULL, passwd_callback, 654*e71b7053SJung-uk Kim passwd_callback_userdata)) 6556f9291ceSJung-uk Kim != NULL) { 656*e71b7053SJung-uk Kim if (ctx) 6577bded2dbSJung-uk Kim r = SSL_CTX_add0_chain_cert(ctx, ca); 658*e71b7053SJung-uk Kim else 659*e71b7053SJung-uk Kim r = SSL_add0_chain_cert(ssl, ca); 660*e71b7053SJung-uk Kim /* 661*e71b7053SJung-uk Kim * Note that we must not free ca if it was successfully added to 662*e71b7053SJung-uk Kim * the chain (while we must free the main certificate, since its 663*e71b7053SJung-uk Kim * reference count is increased by SSL_CTX_use_certificate). 664*e71b7053SJung-uk Kim */ 6656f9291ceSJung-uk Kim if (!r) { 66674664626SKris Kennaway X509_free(ca); 66774664626SKris Kennaway ret = 0; 66874664626SKris Kennaway goto end; 66974664626SKris Kennaway } 67074664626SKris Kennaway } 67174664626SKris Kennaway /* When the while loop ends, it's usually just EOF. */ 6725c87c606SMark Murray err = ERR_peek_last_error(); 6736f9291ceSJung-uk Kim if (ERR_GET_LIB(err) == ERR_LIB_PEM 6746f9291ceSJung-uk Kim && ERR_GET_REASON(err) == PEM_R_NO_START_LINE) 6753b4e3dcbSSimon L. B. Nielsen ERR_clear_error(); 67674664626SKris Kennaway else 67774664626SKris Kennaway ret = 0; /* some real error */ 67874664626SKris Kennaway } 67974664626SKris Kennaway 68074664626SKris Kennaway end: 6816f9291ceSJung-uk Kim X509_free(x); 6826f9291ceSJung-uk Kim BIO_free(in); 683*e71b7053SJung-uk Kim return ret; 68474664626SKris Kennaway } 6857bded2dbSJung-uk Kim 686*e71b7053SJung-uk Kim int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) 687*e71b7053SJung-uk Kim { 688*e71b7053SJung-uk Kim return use_certificate_chain_file(ctx, NULL, file); 689*e71b7053SJung-uk Kim } 690*e71b7053SJung-uk Kim 691*e71b7053SJung-uk Kim int SSL_use_certificate_chain_file(SSL *ssl, const char *file) 692*e71b7053SJung-uk Kim { 693*e71b7053SJung-uk Kim return use_certificate_chain_file(NULL, ssl, file); 694*e71b7053SJung-uk Kim } 695*e71b7053SJung-uk Kim 6967bded2dbSJung-uk Kim static int serverinfo_find_extension(const unsigned char *serverinfo, 6977bded2dbSJung-uk Kim size_t serverinfo_length, 6987bded2dbSJung-uk Kim unsigned int extension_type, 6997bded2dbSJung-uk Kim const unsigned char **extension_data, 7007bded2dbSJung-uk Kim size_t *extension_length) 7017bded2dbSJung-uk Kim { 702*e71b7053SJung-uk Kim PACKET pkt, data; 703*e71b7053SJung-uk Kim 7047bded2dbSJung-uk Kim *extension_data = NULL; 7057bded2dbSJung-uk Kim *extension_length = 0; 7067bded2dbSJung-uk Kim if (serverinfo == NULL || serverinfo_length == 0) 70780815a77SJung-uk Kim return -1; 708*e71b7053SJung-uk Kim 709*e71b7053SJung-uk Kim if (!PACKET_buf_init(&pkt, serverinfo, serverinfo_length)) 710*e71b7053SJung-uk Kim return -1; 711*e71b7053SJung-uk Kim 7127bded2dbSJung-uk Kim for (;;) { 7137bded2dbSJung-uk Kim unsigned int type = 0; 714*e71b7053SJung-uk Kim unsigned long context = 0; 7157bded2dbSJung-uk Kim 7167bded2dbSJung-uk Kim /* end of serverinfo */ 717*e71b7053SJung-uk Kim if (PACKET_remaining(&pkt) == 0) 71880815a77SJung-uk Kim return 0; /* Extension not found */ 7197bded2dbSJung-uk Kim 720*e71b7053SJung-uk Kim if (!PACKET_get_net_4(&pkt, &context) 721*e71b7053SJung-uk Kim || !PACKET_get_net_2(&pkt, &type) 722*e71b7053SJung-uk Kim || !PACKET_get_length_prefixed_2(&pkt, &data)) 723*e71b7053SJung-uk Kim return -1; 7247bded2dbSJung-uk Kim 7257bded2dbSJung-uk Kim if (type == extension_type) { 726*e71b7053SJung-uk Kim *extension_data = PACKET_data(&data); 727*e71b7053SJung-uk Kim *extension_length = PACKET_remaining(&data);; 7287bded2dbSJung-uk Kim return 1; /* Success */ 7297bded2dbSJung-uk Kim } 7307bded2dbSJung-uk Kim } 731*e71b7053SJung-uk Kim /* Unreachable */ 7327bded2dbSJung-uk Kim } 7337bded2dbSJung-uk Kim 734*e71b7053SJung-uk Kim static int serverinfoex_srv_parse_cb(SSL *s, unsigned int ext_type, 735*e71b7053SJung-uk Kim unsigned int context, 7367bded2dbSJung-uk Kim const unsigned char *in, 737*e71b7053SJung-uk Kim size_t inlen, X509 *x, size_t chainidx, 738*e71b7053SJung-uk Kim int *al, void *arg) 7397bded2dbSJung-uk Kim { 7407bded2dbSJung-uk Kim 7417bded2dbSJung-uk Kim if (inlen != 0) { 7427bded2dbSJung-uk Kim *al = SSL_AD_DECODE_ERROR; 7437bded2dbSJung-uk Kim return 0; 7447bded2dbSJung-uk Kim } 7457bded2dbSJung-uk Kim 7467bded2dbSJung-uk Kim return 1; 7477bded2dbSJung-uk Kim } 7487bded2dbSJung-uk Kim 749*e71b7053SJung-uk Kim static int serverinfo_srv_parse_cb(SSL *s, unsigned int ext_type, 750*e71b7053SJung-uk Kim const unsigned char *in, 751*e71b7053SJung-uk Kim size_t inlen, int *al, void *arg) 752*e71b7053SJung-uk Kim { 753*e71b7053SJung-uk Kim return serverinfoex_srv_parse_cb(s, ext_type, 0, in, inlen, NULL, 0, al, 754*e71b7053SJung-uk Kim arg); 755*e71b7053SJung-uk Kim } 756*e71b7053SJung-uk Kim 757*e71b7053SJung-uk Kim static int serverinfoex_srv_add_cb(SSL *s, unsigned int ext_type, 758*e71b7053SJung-uk Kim unsigned int context, 759*e71b7053SJung-uk Kim const unsigned char **out, 760*e71b7053SJung-uk Kim size_t *outlen, X509 *x, size_t chainidx, 7617bded2dbSJung-uk Kim int *al, void *arg) 7627bded2dbSJung-uk Kim { 7637bded2dbSJung-uk Kim const unsigned char *serverinfo = NULL; 7647bded2dbSJung-uk Kim size_t serverinfo_length = 0; 7657bded2dbSJung-uk Kim 766*e71b7053SJung-uk Kim /* We only support extensions for the first Certificate */ 767*e71b7053SJung-uk Kim if ((context & SSL_EXT_TLS1_3_CERTIFICATE) != 0 && chainidx > 0) 768*e71b7053SJung-uk Kim return 0; 769*e71b7053SJung-uk Kim 7707bded2dbSJung-uk Kim /* Is there serverinfo data for the chosen server cert? */ 7717bded2dbSJung-uk Kim if ((ssl_get_server_cert_serverinfo(s, &serverinfo, 7727bded2dbSJung-uk Kim &serverinfo_length)) != 0) { 7737bded2dbSJung-uk Kim /* Find the relevant extension from the serverinfo */ 7747bded2dbSJung-uk Kim int retval = serverinfo_find_extension(serverinfo, serverinfo_length, 7757bded2dbSJung-uk Kim ext_type, out, outlen); 77680815a77SJung-uk Kim if (retval == -1) { 777*e71b7053SJung-uk Kim *al = SSL_AD_INTERNAL_ERROR; 77880815a77SJung-uk Kim return -1; /* Error */ 77980815a77SJung-uk Kim } 7807bded2dbSJung-uk Kim if (retval == 0) 78180815a77SJung-uk Kim return 0; /* No extension found, don't send extension */ 7827bded2dbSJung-uk Kim return 1; /* Send extension */ 7837bded2dbSJung-uk Kim } 784b8721c16SJung-uk Kim return 0; /* No serverinfo data found, don't send 7857bded2dbSJung-uk Kim * extension */ 7867bded2dbSJung-uk Kim } 7877bded2dbSJung-uk Kim 788*e71b7053SJung-uk Kim static int serverinfo_srv_add_cb(SSL *s, unsigned int ext_type, 789*e71b7053SJung-uk Kim const unsigned char **out, size_t *outlen, 790*e71b7053SJung-uk Kim int *al, void *arg) 791*e71b7053SJung-uk Kim { 792*e71b7053SJung-uk Kim return serverinfoex_srv_add_cb(s, ext_type, 0, out, outlen, NULL, 0, al, 793*e71b7053SJung-uk Kim arg); 794*e71b7053SJung-uk Kim } 795*e71b7053SJung-uk Kim 7967bded2dbSJung-uk Kim /* 7977bded2dbSJung-uk Kim * With a NULL context, this function just checks that the serverinfo data 7987bded2dbSJung-uk Kim * parses correctly. With a non-NULL context, it registers callbacks for 7997bded2dbSJung-uk Kim * the included extensions. 8007bded2dbSJung-uk Kim */ 801*e71b7053SJung-uk Kim static int serverinfo_process_buffer(unsigned int version, 802*e71b7053SJung-uk Kim const unsigned char *serverinfo, 8037bded2dbSJung-uk Kim size_t serverinfo_length, SSL_CTX *ctx) 8047bded2dbSJung-uk Kim { 805*e71b7053SJung-uk Kim PACKET pkt; 806*e71b7053SJung-uk Kim 8077bded2dbSJung-uk Kim if (serverinfo == NULL || serverinfo_length == 0) 8087bded2dbSJung-uk Kim return 0; 8097bded2dbSJung-uk Kim 810*e71b7053SJung-uk Kim if (version != SSL_SERVERINFOV1 && version != SSL_SERVERINFOV2) 8117bded2dbSJung-uk Kim return 0; 8127bded2dbSJung-uk Kim 813*e71b7053SJung-uk Kim if (!PACKET_buf_init(&pkt, serverinfo, serverinfo_length)) 814*e71b7053SJung-uk Kim return 0; 815b8721c16SJung-uk Kim 816*e71b7053SJung-uk Kim while (PACKET_remaining(&pkt)) { 817*e71b7053SJung-uk Kim unsigned long context = 0; 818*e71b7053SJung-uk Kim unsigned int ext_type = 0; 819*e71b7053SJung-uk Kim PACKET data; 820b8721c16SJung-uk Kim 821*e71b7053SJung-uk Kim if ((version == SSL_SERVERINFOV2 && !PACKET_get_net_4(&pkt, &context)) 822*e71b7053SJung-uk Kim || !PACKET_get_net_2(&pkt, &ext_type) 823*e71b7053SJung-uk Kim || !PACKET_get_length_prefixed_2(&pkt, &data)) 824*e71b7053SJung-uk Kim return 0; 825*e71b7053SJung-uk Kim 826*e71b7053SJung-uk Kim if (ctx == NULL) 827*e71b7053SJung-uk Kim continue; 828*e71b7053SJung-uk Kim 829*e71b7053SJung-uk Kim /* 830*e71b7053SJung-uk Kim * The old style custom extensions API could be set separately for 831*e71b7053SJung-uk Kim * server/client, i.e. you could set one custom extension for a client, 832*e71b7053SJung-uk Kim * and *for the same extension in the same SSL_CTX* you could set a 833*e71b7053SJung-uk Kim * custom extension for the server as well. It seems quite weird to be 834*e71b7053SJung-uk Kim * setting a custom extension for both client and server in a single 835*e71b7053SJung-uk Kim * SSL_CTX - but theoretically possible. This isn't possible in the 836*e71b7053SJung-uk Kim * new API. Therefore, if we have V1 serverinfo we use the old API. We 837*e71b7053SJung-uk Kim * also use the old API even if we have V2 serverinfo but the context 838*e71b7053SJung-uk Kim * looks like an old style <= TLSv1.2 extension. 839*e71b7053SJung-uk Kim */ 840*e71b7053SJung-uk Kim if (version == SSL_SERVERINFOV1 || context == SYNTHV1CONTEXT) { 841*e71b7053SJung-uk Kim if (!SSL_CTX_add_server_custom_ext(ctx, ext_type, 8427bded2dbSJung-uk Kim serverinfo_srv_add_cb, 8437bded2dbSJung-uk Kim NULL, NULL, 8447bded2dbSJung-uk Kim serverinfo_srv_parse_cb, 8457bded2dbSJung-uk Kim NULL)) 8467bded2dbSJung-uk Kim return 0; 847*e71b7053SJung-uk Kim } else { 848*e71b7053SJung-uk Kim if (!SSL_CTX_add_custom_ext(ctx, ext_type, context, 849*e71b7053SJung-uk Kim serverinfoex_srv_add_cb, 850*e71b7053SJung-uk Kim NULL, NULL, 851*e71b7053SJung-uk Kim serverinfoex_srv_parse_cb, 852*e71b7053SJung-uk Kim NULL)) 8537bded2dbSJung-uk Kim return 0; 8547bded2dbSJung-uk Kim } 8557bded2dbSJung-uk Kim } 8567bded2dbSJung-uk Kim 857*e71b7053SJung-uk Kim return 1; 858*e71b7053SJung-uk Kim } 859*e71b7053SJung-uk Kim 860*e71b7053SJung-uk Kim int SSL_CTX_use_serverinfo_ex(SSL_CTX *ctx, unsigned int version, 861*e71b7053SJung-uk Kim const unsigned char *serverinfo, 8627bded2dbSJung-uk Kim size_t serverinfo_length) 8637bded2dbSJung-uk Kim { 864aeb5019cSJung-uk Kim unsigned char *new_serverinfo; 865aeb5019cSJung-uk Kim 8667bded2dbSJung-uk Kim if (ctx == NULL || serverinfo == NULL || serverinfo_length == 0) { 867*e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_EX, ERR_R_PASSED_NULL_PARAMETER); 8687bded2dbSJung-uk Kim return 0; 8697bded2dbSJung-uk Kim } 870*e71b7053SJung-uk Kim if (!serverinfo_process_buffer(version, serverinfo, serverinfo_length, 871*e71b7053SJung-uk Kim NULL)) { 872*e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_EX, SSL_R_INVALID_SERVERINFO_DATA); 8737bded2dbSJung-uk Kim return 0; 8747bded2dbSJung-uk Kim } 8757bded2dbSJung-uk Kim if (ctx->cert->key == NULL) { 876*e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_EX, ERR_R_INTERNAL_ERROR); 8777bded2dbSJung-uk Kim return 0; 8787bded2dbSJung-uk Kim } 879aeb5019cSJung-uk Kim new_serverinfo = OPENSSL_realloc(ctx->cert->key->serverinfo, 8807bded2dbSJung-uk Kim serverinfo_length); 881aeb5019cSJung-uk Kim if (new_serverinfo == NULL) { 882*e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_EX, ERR_R_MALLOC_FAILURE); 8837bded2dbSJung-uk Kim return 0; 8847bded2dbSJung-uk Kim } 885aeb5019cSJung-uk Kim ctx->cert->key->serverinfo = new_serverinfo; 8867bded2dbSJung-uk Kim memcpy(ctx->cert->key->serverinfo, serverinfo, serverinfo_length); 8877bded2dbSJung-uk Kim ctx->cert->key->serverinfo_length = serverinfo_length; 8887bded2dbSJung-uk Kim 8897bded2dbSJung-uk Kim /* 8907bded2dbSJung-uk Kim * Now that the serverinfo is validated and stored, go ahead and 8917bded2dbSJung-uk Kim * register callbacks. 8927bded2dbSJung-uk Kim */ 893*e71b7053SJung-uk Kim if (!serverinfo_process_buffer(version, serverinfo, serverinfo_length, 894*e71b7053SJung-uk Kim ctx)) { 895*e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_EX, SSL_R_INVALID_SERVERINFO_DATA); 8967bded2dbSJung-uk Kim return 0; 8977bded2dbSJung-uk Kim } 8987bded2dbSJung-uk Kim return 1; 8997bded2dbSJung-uk Kim } 9007bded2dbSJung-uk Kim 901*e71b7053SJung-uk Kim int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, 902*e71b7053SJung-uk Kim size_t serverinfo_length) 903*e71b7053SJung-uk Kim { 904*e71b7053SJung-uk Kim return SSL_CTX_use_serverinfo_ex(ctx, SSL_SERVERINFOV1, serverinfo, 905*e71b7053SJung-uk Kim serverinfo_length); 906*e71b7053SJung-uk Kim } 907*e71b7053SJung-uk Kim 9087bded2dbSJung-uk Kim int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) 9097bded2dbSJung-uk Kim { 9107bded2dbSJung-uk Kim unsigned char *serverinfo = NULL; 911*e71b7053SJung-uk Kim unsigned char *tmp; 9127bded2dbSJung-uk Kim size_t serverinfo_length = 0; 9137bded2dbSJung-uk Kim unsigned char *extension = 0; 9147bded2dbSJung-uk Kim long extension_length = 0; 9157bded2dbSJung-uk Kim char *name = NULL; 9167bded2dbSJung-uk Kim char *header = NULL; 917*e71b7053SJung-uk Kim char namePrefix1[] = "SERVERINFO FOR "; 918*e71b7053SJung-uk Kim char namePrefix2[] = "SERVERINFOV2 FOR "; 9197bded2dbSJung-uk Kim int ret = 0; 9207bded2dbSJung-uk Kim BIO *bin = NULL; 921*e71b7053SJung-uk Kim size_t num_extensions = 0, contextoff = 0; 9227bded2dbSJung-uk Kim 9237bded2dbSJung-uk Kim if (ctx == NULL || file == NULL) { 924*e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_PASSED_NULL_PARAMETER); 9257bded2dbSJung-uk Kim goto end; 9267bded2dbSJung-uk Kim } 9277bded2dbSJung-uk Kim 928*e71b7053SJung-uk Kim bin = BIO_new(BIO_s_file()); 9297bded2dbSJung-uk Kim if (bin == NULL) { 9307bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_BUF_LIB); 9317bded2dbSJung-uk Kim goto end; 9327bded2dbSJung-uk Kim } 9337bded2dbSJung-uk Kim if (BIO_read_filename(bin, file) <= 0) { 9347bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_SYS_LIB); 9357bded2dbSJung-uk Kim goto end; 9367bded2dbSJung-uk Kim } 9377bded2dbSJung-uk Kim 9387bded2dbSJung-uk Kim for (num_extensions = 0;; num_extensions++) { 939*e71b7053SJung-uk Kim unsigned int version; 940*e71b7053SJung-uk Kim 9417bded2dbSJung-uk Kim if (PEM_read_bio(bin, &name, &header, &extension, &extension_length) 9427bded2dbSJung-uk Kim == 0) { 9437bded2dbSJung-uk Kim /* 9447bded2dbSJung-uk Kim * There must be at least one extension in this file 9457bded2dbSJung-uk Kim */ 9467bded2dbSJung-uk Kim if (num_extensions == 0) { 9477bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, 9487bded2dbSJung-uk Kim SSL_R_NO_PEM_EXTENSIONS); 9497bded2dbSJung-uk Kim goto end; 9507bded2dbSJung-uk Kim } else /* End of file, we're done */ 9517bded2dbSJung-uk Kim break; 9527bded2dbSJung-uk Kim } 9537bded2dbSJung-uk Kim /* Check that PEM name starts with "BEGIN SERVERINFO FOR " */ 954*e71b7053SJung-uk Kim if (strlen(name) < strlen(namePrefix1)) { 955*e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_PEM_NAME_TOO_SHORT); 956*e71b7053SJung-uk Kim goto end; 957*e71b7053SJung-uk Kim } 958*e71b7053SJung-uk Kim if (strncmp(name, namePrefix1, strlen(namePrefix1)) == 0) { 959*e71b7053SJung-uk Kim version = SSL_SERVERINFOV1; 960*e71b7053SJung-uk Kim } else { 961*e71b7053SJung-uk Kim if (strlen(name) < strlen(namePrefix2)) { 9627bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, 9637bded2dbSJung-uk Kim SSL_R_PEM_NAME_TOO_SHORT); 9647bded2dbSJung-uk Kim goto end; 9657bded2dbSJung-uk Kim } 966*e71b7053SJung-uk Kim if (strncmp(name, namePrefix2, strlen(namePrefix2)) != 0) { 9677bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, 9687bded2dbSJung-uk Kim SSL_R_PEM_NAME_BAD_PREFIX); 9697bded2dbSJung-uk Kim goto end; 9707bded2dbSJung-uk Kim } 971*e71b7053SJung-uk Kim version = SSL_SERVERINFOV2; 972*e71b7053SJung-uk Kim } 9737bded2dbSJung-uk Kim /* 9747bded2dbSJung-uk Kim * Check that the decoded PEM data is plausible (valid length field) 9757bded2dbSJung-uk Kim */ 976*e71b7053SJung-uk Kim if (version == SSL_SERVERINFOV1) { 977*e71b7053SJung-uk Kim /* 4 byte header: 2 bytes type, 2 bytes len */ 9787bded2dbSJung-uk Kim if (extension_length < 4 979*e71b7053SJung-uk Kim || (extension[2] << 8) + extension[3] 980*e71b7053SJung-uk Kim != extension_length - 4) { 9817bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_BAD_DATA); 9827bded2dbSJung-uk Kim goto end; 9837bded2dbSJung-uk Kim } 984*e71b7053SJung-uk Kim /* 985*e71b7053SJung-uk Kim * File does not have a context value so we must take account of 986*e71b7053SJung-uk Kim * this later. 987*e71b7053SJung-uk Kim */ 988*e71b7053SJung-uk Kim contextoff = 4; 989*e71b7053SJung-uk Kim } else { 990*e71b7053SJung-uk Kim /* 8 byte header: 4 bytes context, 2 bytes type, 2 bytes len */ 991*e71b7053SJung-uk Kim if (extension_length < 8 992*e71b7053SJung-uk Kim || (extension[6] << 8) + extension[7] 993*e71b7053SJung-uk Kim != extension_length - 8) { 994*e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_BAD_DATA); 995*e71b7053SJung-uk Kim goto end; 996*e71b7053SJung-uk Kim } 997*e71b7053SJung-uk Kim } 9987bded2dbSJung-uk Kim /* Append the decoded extension to the serverinfo buffer */ 999*e71b7053SJung-uk Kim tmp = OPENSSL_realloc(serverinfo, serverinfo_length + extension_length 1000*e71b7053SJung-uk Kim + contextoff); 1001*e71b7053SJung-uk Kim if (tmp == NULL) { 10027bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_MALLOC_FAILURE); 10037bded2dbSJung-uk Kim goto end; 10047bded2dbSJung-uk Kim } 1005*e71b7053SJung-uk Kim serverinfo = tmp; 1006*e71b7053SJung-uk Kim if (contextoff > 0) { 1007*e71b7053SJung-uk Kim unsigned char *sinfo = serverinfo + serverinfo_length; 1008*e71b7053SJung-uk Kim 1009*e71b7053SJung-uk Kim /* We know this only uses the last 2 bytes */ 1010*e71b7053SJung-uk Kim sinfo[0] = 0; 1011*e71b7053SJung-uk Kim sinfo[1] = 0; 1012*e71b7053SJung-uk Kim sinfo[2] = (SYNTHV1CONTEXT >> 8) & 0xff; 1013*e71b7053SJung-uk Kim sinfo[3] = SYNTHV1CONTEXT & 0xff; 1014*e71b7053SJung-uk Kim } 1015*e71b7053SJung-uk Kim memcpy(serverinfo + serverinfo_length + contextoff, 1016*e71b7053SJung-uk Kim extension, extension_length); 1017*e71b7053SJung-uk Kim serverinfo_length += extension_length + contextoff; 10187bded2dbSJung-uk Kim 10197bded2dbSJung-uk Kim OPENSSL_free(name); 10207bded2dbSJung-uk Kim name = NULL; 10217bded2dbSJung-uk Kim OPENSSL_free(header); 10227bded2dbSJung-uk Kim header = NULL; 10237bded2dbSJung-uk Kim OPENSSL_free(extension); 10247bded2dbSJung-uk Kim extension = NULL; 10257bded2dbSJung-uk Kim } 10267bded2dbSJung-uk Kim 1027*e71b7053SJung-uk Kim ret = SSL_CTX_use_serverinfo_ex(ctx, SSL_SERVERINFOV2, serverinfo, 1028*e71b7053SJung-uk Kim serverinfo_length); 10297bded2dbSJung-uk Kim end: 10307bded2dbSJung-uk Kim /* SSL_CTX_use_serverinfo makes a local copy of the serverinfo. */ 10317bded2dbSJung-uk Kim OPENSSL_free(name); 10327bded2dbSJung-uk Kim OPENSSL_free(header); 10337bded2dbSJung-uk Kim OPENSSL_free(extension); 10347bded2dbSJung-uk Kim OPENSSL_free(serverinfo); 10357bded2dbSJung-uk Kim BIO_free(bin); 10367bded2dbSJung-uk Kim return ret; 10377bded2dbSJung-uk Kim } 1038*e71b7053SJung-uk Kim 1039*e71b7053SJung-uk Kim static int ssl_set_cert_and_key(SSL *ssl, SSL_CTX *ctx, X509 *x509, EVP_PKEY *privatekey, 1040*e71b7053SJung-uk Kim STACK_OF(X509) *chain, int override) 1041*e71b7053SJung-uk Kim { 1042*e71b7053SJung-uk Kim int ret = 0; 1043*e71b7053SJung-uk Kim size_t i; 1044*e71b7053SJung-uk Kim int j; 1045*e71b7053SJung-uk Kim int rv; 1046*e71b7053SJung-uk Kim CERT *c = ssl != NULL ? ssl->cert : ctx->cert; 1047*e71b7053SJung-uk Kim STACK_OF(X509) *dup_chain = NULL; 1048*e71b7053SJung-uk Kim EVP_PKEY *pubkey = NULL; 1049*e71b7053SJung-uk Kim 1050*e71b7053SJung-uk Kim /* Do all security checks before anything else */ 1051*e71b7053SJung-uk Kim rv = ssl_security_cert(ssl, ctx, x509, 0, 1); 1052*e71b7053SJung-uk Kim if (rv != 1) { 1053*e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, rv); 1054*e71b7053SJung-uk Kim goto out; 1055*e71b7053SJung-uk Kim } 1056*e71b7053SJung-uk Kim for (j = 0; j < sk_X509_num(chain); j++) { 1057*e71b7053SJung-uk Kim rv = ssl_security_cert(ssl, ctx, sk_X509_value(chain, j), 0, 0); 1058*e71b7053SJung-uk Kim if (rv != 1) { 1059*e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, rv); 1060*e71b7053SJung-uk Kim goto out; 1061*e71b7053SJung-uk Kim } 1062*e71b7053SJung-uk Kim } 1063*e71b7053SJung-uk Kim 1064*e71b7053SJung-uk Kim pubkey = X509_get_pubkey(x509); /* bumps reference */ 1065*e71b7053SJung-uk Kim if (pubkey == NULL) 1066*e71b7053SJung-uk Kim goto out; 1067*e71b7053SJung-uk Kim if (privatekey == NULL) { 1068*e71b7053SJung-uk Kim privatekey = pubkey; 1069*e71b7053SJung-uk Kim } else { 1070*e71b7053SJung-uk Kim /* For RSA, which has no parameters, missing returns 0 */ 1071*e71b7053SJung-uk Kim if (EVP_PKEY_missing_parameters(privatekey)) { 1072*e71b7053SJung-uk Kim if (EVP_PKEY_missing_parameters(pubkey)) { 1073*e71b7053SJung-uk Kim /* nobody has parameters? - error */ 1074*e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, SSL_R_MISSING_PARAMETERS); 1075*e71b7053SJung-uk Kim goto out; 1076*e71b7053SJung-uk Kim } else { 1077*e71b7053SJung-uk Kim /* copy to privatekey from pubkey */ 1078*e71b7053SJung-uk Kim EVP_PKEY_copy_parameters(privatekey, pubkey); 1079*e71b7053SJung-uk Kim } 1080*e71b7053SJung-uk Kim } else if (EVP_PKEY_missing_parameters(pubkey)) { 1081*e71b7053SJung-uk Kim /* copy to pubkey from privatekey */ 1082*e71b7053SJung-uk Kim EVP_PKEY_copy_parameters(pubkey, privatekey); 1083*e71b7053SJung-uk Kim } /* else both have parameters */ 1084*e71b7053SJung-uk Kim 1085*e71b7053SJung-uk Kim /* Copied from ssl_set_cert/pkey */ 1086*e71b7053SJung-uk Kim #ifndef OPENSSL_NO_RSA 1087*e71b7053SJung-uk Kim if ((EVP_PKEY_id(privatekey) == EVP_PKEY_RSA) && 1088*e71b7053SJung-uk Kim ((RSA_flags(EVP_PKEY_get0_RSA(privatekey)) & RSA_METHOD_FLAG_NO_CHECK))) 1089*e71b7053SJung-uk Kim /* no-op */ ; 1090*e71b7053SJung-uk Kim else 1091*e71b7053SJung-uk Kim #endif 1092*e71b7053SJung-uk Kim /* check that key <-> cert match */ 1093*e71b7053SJung-uk Kim if (EVP_PKEY_cmp(pubkey, privatekey) != 1) { 1094*e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, SSL_R_PRIVATE_KEY_MISMATCH); 1095*e71b7053SJung-uk Kim goto out; 1096*e71b7053SJung-uk Kim } 1097*e71b7053SJung-uk Kim } 1098*e71b7053SJung-uk Kim if (ssl_cert_lookup_by_pkey(pubkey, &i) == NULL) { 1099*e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, SSL_R_UNKNOWN_CERTIFICATE_TYPE); 1100*e71b7053SJung-uk Kim goto out; 1101*e71b7053SJung-uk Kim } 1102*e71b7053SJung-uk Kim 1103*e71b7053SJung-uk Kim if (!override && (c->pkeys[i].x509 != NULL 1104*e71b7053SJung-uk Kim || c->pkeys[i].privatekey != NULL 1105*e71b7053SJung-uk Kim || c->pkeys[i].chain != NULL)) { 1106*e71b7053SJung-uk Kim /* No override, and something already there */ 1107*e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, SSL_R_NOT_REPLACING_CERTIFICATE); 1108*e71b7053SJung-uk Kim goto out; 1109*e71b7053SJung-uk Kim } 1110*e71b7053SJung-uk Kim 1111*e71b7053SJung-uk Kim if (chain != NULL) { 1112*e71b7053SJung-uk Kim dup_chain = X509_chain_up_ref(chain); 1113*e71b7053SJung-uk Kim if (dup_chain == NULL) { 1114*e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, ERR_R_MALLOC_FAILURE); 1115*e71b7053SJung-uk Kim goto out; 1116*e71b7053SJung-uk Kim } 1117*e71b7053SJung-uk Kim } 1118*e71b7053SJung-uk Kim 1119*e71b7053SJung-uk Kim sk_X509_pop_free(c->pkeys[i].chain, X509_free); 1120*e71b7053SJung-uk Kim c->pkeys[i].chain = dup_chain; 1121*e71b7053SJung-uk Kim 1122*e71b7053SJung-uk Kim X509_free(c->pkeys[i].x509); 1123*e71b7053SJung-uk Kim X509_up_ref(x509); 1124*e71b7053SJung-uk Kim c->pkeys[i].x509 = x509; 1125*e71b7053SJung-uk Kim 1126*e71b7053SJung-uk Kim EVP_PKEY_free(c->pkeys[i].privatekey); 1127*e71b7053SJung-uk Kim EVP_PKEY_up_ref(privatekey); 1128*e71b7053SJung-uk Kim c->pkeys[i].privatekey = privatekey; 1129*e71b7053SJung-uk Kim 1130*e71b7053SJung-uk Kim c->key = &(c->pkeys[i]); 1131*e71b7053SJung-uk Kim 1132*e71b7053SJung-uk Kim ret = 1; 1133*e71b7053SJung-uk Kim out: 1134*e71b7053SJung-uk Kim EVP_PKEY_free(pubkey); 1135*e71b7053SJung-uk Kim return ret; 1136*e71b7053SJung-uk Kim } 1137*e71b7053SJung-uk Kim 1138*e71b7053SJung-uk Kim int SSL_use_cert_and_key(SSL *ssl, X509 *x509, EVP_PKEY *privatekey, 1139*e71b7053SJung-uk Kim STACK_OF(X509) *chain, int override) 1140*e71b7053SJung-uk Kim { 1141*e71b7053SJung-uk Kim return ssl_set_cert_and_key(ssl, NULL, x509, privatekey, chain, override); 1142*e71b7053SJung-uk Kim } 1143*e71b7053SJung-uk Kim 1144*e71b7053SJung-uk Kim int SSL_CTX_use_cert_and_key(SSL_CTX *ctx, X509 *x509, EVP_PKEY *privatekey, 1145*e71b7053SJung-uk Kim STACK_OF(X509) *chain, int override) 1146*e71b7053SJung-uk Kim { 1147*e71b7053SJung-uk Kim return ssl_set_cert_and_key(NULL, ctx, x509, privatekey, chain, override); 1148*e71b7053SJung-uk Kim } 1149