1e71b7053SJung-uk Kim /* 2*cfc39718SJung-uk Kim * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. 374664626SKris Kennaway * 4e71b7053SJung-uk Kim * Licensed under the OpenSSL license (the "License"). You may not use 5e71b7053SJung-uk Kim * this file except in compliance with the License. You can obtain a copy 6e71b7053SJung-uk Kim * in the file LICENSE in the source distribution or at 7e71b7053SJung-uk Kim * https://www.openssl.org/source/license.html 874664626SKris Kennaway */ 974664626SKris Kennaway 1074664626SKris Kennaway #include <stdio.h> 1117f01e99SJung-uk Kim #include "ssl_local.h" 1217f01e99SJung-uk Kim #include "packet_local.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); 21e71b7053SJung-uk Kim 22e71b7053SJung-uk Kim #define SYNTHV1CONTEXT (SSL_EXT_TLS1_2_AND_BELOW_ONLY \ 23e71b7053SJung-uk Kim | SSL_EXT_CLIENT_HELLO \ 24e71b7053SJung-uk Kim | SSL_EXT_TLS1_2_SERVER_HELLO \ 25e71b7053SJung-uk Kim | SSL_EXT_IGNORE_ON_RESUMPTION) 26e71b7053SJung-uk Kim 2774664626SKris Kennaway int SSL_use_certificate(SSL *ssl, X509 *x) 2874664626SKris Kennaway { 29e71b7053SJung-uk Kim int rv; 306f9291ceSJung-uk Kim if (x == NULL) { 3174664626SKris Kennaway SSLerr(SSL_F_SSL_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); 32e71b7053SJung-uk Kim return 0; 3374664626SKris Kennaway } 34e71b7053SJung-uk Kim rv = ssl_security_cert(ssl, NULL, x, 0, 1); 35e71b7053SJung-uk Kim if (rv != 1) { 36e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_USE_CERTIFICATE, rv); 37e71b7053SJung-uk Kim return 0; 3874664626SKris Kennaway } 3974664626SKris Kennaway 40e71b7053SJung-uk Kim return ssl_set_cert(ssl->cert, x); 41e71b7053SJung-uk Kim } 42e71b7053SJung-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 50e71b7053SJung-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; 65e71b7053SJung-uk Kim x = PEM_read_bio_X509(in, NULL, ssl->default_passwd_callback, 66e71b7053SJung-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); 81e71b7053SJung-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); 92e71b7053SJung-uk Kim return 0; 9374664626SKris Kennaway } 9474664626SKris Kennaway 9574664626SKris Kennaway ret = SSL_use_certificate(ssl, x); 9674664626SKris Kennaway X509_free(x); 97e71b7053SJung-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); 108e71b7053SJung-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); 112e71b7053SJung-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); 118e71b7053SJung-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); 124e71b7053SJung-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 { 130e71b7053SJung-uk Kim size_t i; 131e71b7053SJung-uk Kim 132e71b7053SJung-uk Kim if (ssl_cert_lookup_by_pkey(pkey, &i) == NULL) { 13374664626SKris Kennaway SSLerr(SSL_F_SSL_SET_PKEY, SSL_R_UNKNOWN_CERTIFICATE_TYPE); 134e71b7053SJung-uk Kim return 0; 13574664626SKris Kennaway } 13674664626SKris Kennaway 1376f9291ceSJung-uk Kim if (c->pkeys[i].x509 != NULL) { 13874664626SKris Kennaway EVP_PKEY *pktmp; 139e71b7053SJung-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 1516f9291ceSJung-uk Kim if (!X509_check_private_key(c->pkeys[i].x509, pkey)) { 15274664626SKris Kennaway X509_free(c->pkeys[i].x509); 15374664626SKris Kennaway c->pkeys[i].x509 = NULL; 1543b4e3dcbSSimon L. B. Nielsen return 0; 1553b4e3dcbSSimon L. B. Nielsen } 15674664626SKris Kennaway } 15774664626SKris Kennaway 15874664626SKris Kennaway EVP_PKEY_free(c->pkeys[i].privatekey); 159e71b7053SJung-uk Kim EVP_PKEY_up_ref(pkey); 16074664626SKris Kennaway c->pkeys[i].privatekey = pkey; 161e71b7053SJung-uk Kim c->key = &c->pkeys[i]; 162e71b7053SJung-uk Kim return 1; 16374664626SKris Kennaway } 16474664626SKris Kennaway 1655c87c606SMark Murray #ifndef OPENSSL_NO_RSA 16674664626SKris Kennaway int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) 16774664626SKris Kennaway { 16874664626SKris Kennaway int j, ret = 0; 16974664626SKris Kennaway BIO *in; 17074664626SKris Kennaway RSA *rsa = NULL; 17174664626SKris Kennaway 172e71b7053SJung-uk Kim in = BIO_new(BIO_s_file()); 1736f9291ceSJung-uk Kim if (in == NULL) { 17474664626SKris Kennaway SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB); 17574664626SKris Kennaway goto end; 17674664626SKris Kennaway } 17774664626SKris Kennaway 1786f9291ceSJung-uk Kim if (BIO_read_filename(in, file) <= 0) { 17974664626SKris Kennaway SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB); 18074664626SKris Kennaway goto end; 18174664626SKris Kennaway } 1826f9291ceSJung-uk Kim if (type == SSL_FILETYPE_ASN1) { 18374664626SKris Kennaway j = ERR_R_ASN1_LIB; 18474664626SKris Kennaway rsa = d2i_RSAPrivateKey_bio(in, NULL); 1856f9291ceSJung-uk Kim } else if (type == SSL_FILETYPE_PEM) { 18674664626SKris Kennaway j = ERR_R_PEM_LIB; 18774664626SKris Kennaway rsa = PEM_read_bio_RSAPrivateKey(in, NULL, 188e71b7053SJung-uk Kim ssl->default_passwd_callback, 189e71b7053SJung-uk Kim ssl->default_passwd_callback_userdata); 1906f9291ceSJung-uk Kim } else { 19174664626SKris Kennaway SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); 19274664626SKris Kennaway goto end; 19374664626SKris Kennaway } 1946f9291ceSJung-uk Kim if (rsa == NULL) { 19574664626SKris Kennaway SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, j); 19674664626SKris Kennaway goto end; 19774664626SKris Kennaway } 19874664626SKris Kennaway ret = SSL_use_RSAPrivateKey(ssl, rsa); 19974664626SKris Kennaway RSA_free(rsa); 20074664626SKris Kennaway end: 2016f9291ceSJung-uk Kim BIO_free(in); 202e71b7053SJung-uk Kim return ret; 20374664626SKris Kennaway } 20474664626SKris Kennaway 205e71b7053SJung-uk Kim int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, long len) 20674664626SKris Kennaway { 20774664626SKris Kennaway int ret; 2085c87c606SMark Murray const unsigned char *p; 20974664626SKris Kennaway RSA *rsa; 21074664626SKris Kennaway 21174664626SKris Kennaway p = d; 2126f9291ceSJung-uk Kim if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) { 21374664626SKris Kennaway SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB); 214e71b7053SJung-uk Kim return 0; 21574664626SKris Kennaway } 21674664626SKris Kennaway 21774664626SKris Kennaway ret = SSL_use_RSAPrivateKey(ssl, rsa); 21874664626SKris Kennaway RSA_free(rsa); 219e71b7053SJung-uk Kim return ret; 22074664626SKris Kennaway } 2215c87c606SMark Murray #endif /* !OPENSSL_NO_RSA */ 22274664626SKris Kennaway 22374664626SKris Kennaway int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) 22474664626SKris Kennaway { 22574664626SKris Kennaway int ret; 22674664626SKris Kennaway 2276f9291ceSJung-uk Kim if (pkey == NULL) { 22874664626SKris Kennaway SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); 229e71b7053SJung-uk Kim return 0; 23074664626SKris Kennaway } 23174664626SKris Kennaway ret = ssl_set_pkey(ssl->cert, pkey); 232e71b7053SJung-uk Kim return ret; 23374664626SKris Kennaway } 23474664626SKris Kennaway 23574664626SKris Kennaway int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) 23674664626SKris Kennaway { 23774664626SKris Kennaway int j, ret = 0; 23874664626SKris Kennaway BIO *in; 23974664626SKris Kennaway EVP_PKEY *pkey = NULL; 24074664626SKris Kennaway 241e71b7053SJung-uk Kim in = BIO_new(BIO_s_file()); 2426f9291ceSJung-uk Kim if (in == NULL) { 24374664626SKris Kennaway SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB); 24474664626SKris Kennaway goto end; 24574664626SKris Kennaway } 24674664626SKris Kennaway 2476f9291ceSJung-uk Kim if (BIO_read_filename(in, file) <= 0) { 24874664626SKris Kennaway SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB); 24974664626SKris Kennaway goto end; 25074664626SKris Kennaway } 2516f9291ceSJung-uk Kim if (type == SSL_FILETYPE_PEM) { 25274664626SKris Kennaway j = ERR_R_PEM_LIB; 25374664626SKris Kennaway pkey = PEM_read_bio_PrivateKey(in, NULL, 254e71b7053SJung-uk Kim ssl->default_passwd_callback, 255e71b7053SJung-uk Kim ssl->default_passwd_callback_userdata); 2566f9291ceSJung-uk Kim } else if (type == SSL_FILETYPE_ASN1) { 2573b4e3dcbSSimon L. B. Nielsen j = ERR_R_ASN1_LIB; 2583b4e3dcbSSimon L. B. Nielsen pkey = d2i_PrivateKey_bio(in, NULL); 2596f9291ceSJung-uk Kim } else { 26074664626SKris Kennaway SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); 26174664626SKris Kennaway goto end; 26274664626SKris Kennaway } 2636f9291ceSJung-uk Kim if (pkey == NULL) { 26474664626SKris Kennaway SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, j); 26574664626SKris Kennaway goto end; 26674664626SKris Kennaway } 26774664626SKris Kennaway ret = SSL_use_PrivateKey(ssl, pkey); 26874664626SKris Kennaway EVP_PKEY_free(pkey); 26974664626SKris Kennaway end: 2706f9291ceSJung-uk Kim BIO_free(in); 271e71b7053SJung-uk Kim return ret; 27274664626SKris Kennaway } 27374664626SKris Kennaway 2746f9291ceSJung-uk Kim int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, 2756f9291ceSJung-uk Kim long len) 27674664626SKris Kennaway { 27774664626SKris Kennaway int ret; 2783b4e3dcbSSimon L. B. Nielsen const unsigned char *p; 27974664626SKris Kennaway EVP_PKEY *pkey; 28074664626SKris Kennaway 28174664626SKris Kennaway p = d; 2826f9291ceSJung-uk Kim if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) { 28374664626SKris Kennaway SSLerr(SSL_F_SSL_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB); 284e71b7053SJung-uk Kim return 0; 28574664626SKris Kennaway } 28674664626SKris Kennaway 28774664626SKris Kennaway ret = SSL_use_PrivateKey(ssl, pkey); 28874664626SKris Kennaway EVP_PKEY_free(pkey); 289e71b7053SJung-uk Kim return ret; 29074664626SKris Kennaway } 29174664626SKris Kennaway 29274664626SKris Kennaway int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) 29374664626SKris Kennaway { 294e71b7053SJung-uk Kim int rv; 2956f9291ceSJung-uk Kim if (x == NULL) { 29674664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); 297e71b7053SJung-uk Kim return 0; 29874664626SKris Kennaway } 299e71b7053SJung-uk Kim rv = ssl_security_cert(NULL, ctx, x, 0, 1); 300e71b7053SJung-uk Kim if (rv != 1) { 301e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, rv); 302e71b7053SJung-uk Kim return 0; 30374664626SKris Kennaway } 304e71b7053SJung-uk Kim return ssl_set_cert(ctx->cert, x); 30574664626SKris Kennaway } 30674664626SKris Kennaway 30774664626SKris Kennaway static int ssl_set_cert(CERT *c, X509 *x) 30874664626SKris Kennaway { 30974664626SKris Kennaway EVP_PKEY *pkey; 310e71b7053SJung-uk Kim size_t i; 31174664626SKris Kennaway 312e71b7053SJung-uk Kim pkey = X509_get0_pubkey(x); 3136f9291ceSJung-uk Kim if (pkey == NULL) { 31474664626SKris Kennaway SSLerr(SSL_F_SSL_SET_CERT, SSL_R_X509_LIB); 315e71b7053SJung-uk Kim return 0; 31674664626SKris Kennaway } 31774664626SKris Kennaway 318e71b7053SJung-uk Kim if (ssl_cert_lookup_by_pkey(pkey, &i) == NULL) { 31974664626SKris Kennaway SSLerr(SSL_F_SSL_SET_CERT, SSL_R_UNKNOWN_CERTIFICATE_TYPE); 320e71b7053SJung-uk Kim return 0; 32174664626SKris Kennaway } 322e71b7053SJung-uk Kim #ifndef OPENSSL_NO_EC 323e71b7053SJung-uk Kim if (i == SSL_PKEY_ECC && !EC_KEY_can_sign(EVP_PKEY_get0_EC_KEY(pkey))) { 324e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_SET_CERT, SSL_R_ECC_CERT_NOT_FOR_SIGNING); 325e71b7053SJung-uk Kim return 0; 326e71b7053SJung-uk Kim } 327e71b7053SJung-uk Kim #endif 3286f9291ceSJung-uk Kim if (c->pkeys[i].privatekey != NULL) { 32980815a77SJung-uk Kim /* 33080815a77SJung-uk Kim * The return code from EVP_PKEY_copy_parameters is deliberately 33180815a77SJung-uk Kim * ignored. Some EVP_PKEY types cannot do this. 33280815a77SJung-uk Kim */ 33374664626SKris Kennaway EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey); 33474664626SKris Kennaway ERR_clear_error(); 33574664626SKris Kennaway 3366f9291ceSJung-uk Kim if (!X509_check_private_key(x, c->pkeys[i].privatekey)) { 3376f9291ceSJung-uk Kim /* 3386f9291ceSJung-uk Kim * don't fail for a cert/key mismatch, just free current private 3396f9291ceSJung-uk Kim * key (when switching to a different cert & key, first this 3406f9291ceSJung-uk Kim * function should be used, then ssl_set_pkey 3416f9291ceSJung-uk Kim */ 34274664626SKris Kennaway EVP_PKEY_free(c->pkeys[i].privatekey); 34374664626SKris Kennaway c->pkeys[i].privatekey = NULL; 3443b4e3dcbSSimon L. B. Nielsen /* clear error queue */ 3453b4e3dcbSSimon L. B. Nielsen ERR_clear_error(); 34674664626SKris Kennaway } 3473b4e3dcbSSimon L. B. Nielsen } 3483b4e3dcbSSimon L. B. Nielsen 34974664626SKris Kennaway X509_free(c->pkeys[i].x509); 350e71b7053SJung-uk Kim X509_up_ref(x); 35174664626SKris Kennaway c->pkeys[i].x509 = x; 35274664626SKris Kennaway c->key = &(c->pkeys[i]); 35374664626SKris Kennaway 354e71b7053SJung-uk Kim return 1; 35574664626SKris Kennaway } 35674664626SKris Kennaway 35774664626SKris Kennaway int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) 35874664626SKris Kennaway { 35974664626SKris Kennaway int j; 36074664626SKris Kennaway BIO *in; 36174664626SKris Kennaway int ret = 0; 36274664626SKris Kennaway X509 *x = NULL; 36374664626SKris Kennaway 364e71b7053SJung-uk Kim in = BIO_new(BIO_s_file()); 3656f9291ceSJung-uk Kim if (in == NULL) { 36674664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB); 36774664626SKris Kennaway goto end; 36874664626SKris Kennaway } 36974664626SKris Kennaway 3706f9291ceSJung-uk Kim if (BIO_read_filename(in, file) <= 0) { 37174664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); 37274664626SKris Kennaway goto end; 37374664626SKris Kennaway } 3746f9291ceSJung-uk Kim if (type == SSL_FILETYPE_ASN1) { 37574664626SKris Kennaway j = ERR_R_ASN1_LIB; 37674664626SKris Kennaway x = d2i_X509_bio(in, NULL); 3776f9291ceSJung-uk Kim } else if (type == SSL_FILETYPE_PEM) { 37874664626SKris Kennaway j = ERR_R_PEM_LIB; 3796f9291ceSJung-uk Kim x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, 3806f9291ceSJung-uk Kim ctx->default_passwd_callback_userdata); 3816f9291ceSJung-uk Kim } else { 38274664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); 38374664626SKris Kennaway goto end; 38474664626SKris Kennaway } 38574664626SKris Kennaway 3866f9291ceSJung-uk Kim if (x == NULL) { 38774664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, j); 38874664626SKris Kennaway goto end; 38974664626SKris Kennaway } 39074664626SKris Kennaway 39174664626SKris Kennaway ret = SSL_CTX_use_certificate(ctx, x); 39274664626SKris Kennaway end: 3936f9291ceSJung-uk Kim X509_free(x); 3946f9291ceSJung-uk Kim BIO_free(in); 395e71b7053SJung-uk Kim return ret; 39674664626SKris Kennaway } 39774664626SKris Kennaway 398e71b7053SJung-uk Kim int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d) 39974664626SKris Kennaway { 40074664626SKris Kennaway X509 *x; 40174664626SKris Kennaway int ret; 40274664626SKris Kennaway 40374664626SKris Kennaway x = d2i_X509(NULL, &d, (long)len); 4046f9291ceSJung-uk Kim if (x == NULL) { 40574664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); 406e71b7053SJung-uk Kim return 0; 40774664626SKris Kennaway } 40874664626SKris Kennaway 40974664626SKris Kennaway ret = SSL_CTX_use_certificate(ctx, x); 41074664626SKris Kennaway X509_free(x); 411e71b7053SJung-uk Kim return ret; 41274664626SKris Kennaway } 41374664626SKris Kennaway 4145c87c606SMark Murray #ifndef OPENSSL_NO_RSA 41574664626SKris Kennaway int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) 41674664626SKris Kennaway { 41774664626SKris Kennaway int ret; 41874664626SKris Kennaway EVP_PKEY *pkey; 41974664626SKris Kennaway 4206f9291ceSJung-uk Kim if (rsa == NULL) { 42174664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); 422e71b7053SJung-uk Kim return 0; 42374664626SKris Kennaway } 4246f9291ceSJung-uk Kim if ((pkey = EVP_PKEY_new()) == NULL) { 42574664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB); 426e71b7053SJung-uk Kim return 0; 42774664626SKris Kennaway } 42874664626SKris Kennaway 4295c87c606SMark Murray RSA_up_ref(rsa); 43080815a77SJung-uk Kim if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) { 43180815a77SJung-uk Kim RSA_free(rsa); 432e71b7053SJung-uk Kim EVP_PKEY_free(pkey); 43380815a77SJung-uk Kim return 0; 43480815a77SJung-uk Kim } 43574664626SKris Kennaway 43674664626SKris Kennaway ret = ssl_set_pkey(ctx->cert, pkey); 43774664626SKris Kennaway EVP_PKEY_free(pkey); 438e71b7053SJung-uk Kim return ret; 43974664626SKris Kennaway } 44074664626SKris Kennaway 44174664626SKris Kennaway int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) 44274664626SKris Kennaway { 44374664626SKris Kennaway int j, ret = 0; 44474664626SKris Kennaway BIO *in; 44574664626SKris Kennaway RSA *rsa = NULL; 44674664626SKris Kennaway 447e71b7053SJung-uk Kim in = BIO_new(BIO_s_file()); 4486f9291ceSJung-uk Kim if (in == NULL) { 44974664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB); 45074664626SKris Kennaway goto end; 45174664626SKris Kennaway } 45274664626SKris Kennaway 4536f9291ceSJung-uk Kim if (BIO_read_filename(in, file) <= 0) { 45474664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB); 45574664626SKris Kennaway goto end; 45674664626SKris Kennaway } 4576f9291ceSJung-uk Kim if (type == SSL_FILETYPE_ASN1) { 45874664626SKris Kennaway j = ERR_R_ASN1_LIB; 45974664626SKris Kennaway rsa = d2i_RSAPrivateKey_bio(in, NULL); 4606f9291ceSJung-uk Kim } else if (type == SSL_FILETYPE_PEM) { 46174664626SKris Kennaway j = ERR_R_PEM_LIB; 46274664626SKris Kennaway rsa = PEM_read_bio_RSAPrivateKey(in, NULL, 4636f9291ceSJung-uk Kim ctx->default_passwd_callback, 4646f9291ceSJung-uk Kim ctx->default_passwd_callback_userdata); 4656f9291ceSJung-uk Kim } else { 46674664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); 46774664626SKris Kennaway goto end; 46874664626SKris Kennaway } 4696f9291ceSJung-uk Kim if (rsa == NULL) { 47074664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, j); 47174664626SKris Kennaway goto end; 47274664626SKris Kennaway } 47374664626SKris Kennaway ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); 47474664626SKris Kennaway RSA_free(rsa); 47574664626SKris Kennaway end: 4766f9291ceSJung-uk Kim BIO_free(in); 477e71b7053SJung-uk Kim return ret; 47874664626SKris Kennaway } 47974664626SKris Kennaway 4806f9291ceSJung-uk Kim int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, 4816f9291ceSJung-uk Kim long len) 48274664626SKris Kennaway { 48374664626SKris Kennaway int ret; 4845c87c606SMark Murray const unsigned char *p; 48574664626SKris Kennaway RSA *rsa; 48674664626SKris Kennaway 48774664626SKris Kennaway p = d; 4886f9291ceSJung-uk Kim if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) { 48974664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB); 490e71b7053SJung-uk Kim return 0; 49174664626SKris Kennaway } 49274664626SKris Kennaway 49374664626SKris Kennaway ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); 49474664626SKris Kennaway RSA_free(rsa); 495e71b7053SJung-uk Kim return ret; 49674664626SKris Kennaway } 4975c87c606SMark Murray #endif /* !OPENSSL_NO_RSA */ 49874664626SKris Kennaway 49974664626SKris Kennaway int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) 50074664626SKris Kennaway { 5016f9291ceSJung-uk Kim if (pkey == NULL) { 50274664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); 503e71b7053SJung-uk Kim return 0; 50474664626SKris Kennaway } 505e71b7053SJung-uk Kim return ssl_set_pkey(ctx->cert, pkey); 50674664626SKris Kennaway } 50774664626SKris Kennaway 50874664626SKris Kennaway int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) 50974664626SKris Kennaway { 51074664626SKris Kennaway int j, ret = 0; 51174664626SKris Kennaway BIO *in; 51274664626SKris Kennaway EVP_PKEY *pkey = NULL; 51374664626SKris Kennaway 514e71b7053SJung-uk Kim in = BIO_new(BIO_s_file()); 5156f9291ceSJung-uk Kim if (in == NULL) { 51674664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB); 51774664626SKris Kennaway goto end; 51874664626SKris Kennaway } 51974664626SKris Kennaway 5206f9291ceSJung-uk Kim if (BIO_read_filename(in, file) <= 0) { 52174664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB); 52274664626SKris Kennaway goto end; 52374664626SKris Kennaway } 5246f9291ceSJung-uk Kim if (type == SSL_FILETYPE_PEM) { 52574664626SKris Kennaway j = ERR_R_PEM_LIB; 52674664626SKris Kennaway pkey = PEM_read_bio_PrivateKey(in, NULL, 5276f9291ceSJung-uk Kim ctx->default_passwd_callback, 5286f9291ceSJung-uk Kim ctx->default_passwd_callback_userdata); 5296f9291ceSJung-uk Kim } else if (type == SSL_FILETYPE_ASN1) { 5303b4e3dcbSSimon L. B. Nielsen j = ERR_R_ASN1_LIB; 5313b4e3dcbSSimon L. B. Nielsen pkey = d2i_PrivateKey_bio(in, NULL); 5326f9291ceSJung-uk Kim } else { 53374664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); 53474664626SKris Kennaway goto end; 53574664626SKris Kennaway } 5366f9291ceSJung-uk Kim if (pkey == NULL) { 53774664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, j); 53874664626SKris Kennaway goto end; 53974664626SKris Kennaway } 54074664626SKris Kennaway ret = SSL_CTX_use_PrivateKey(ctx, pkey); 54174664626SKris Kennaway EVP_PKEY_free(pkey); 54274664626SKris Kennaway end: 5436f9291ceSJung-uk Kim BIO_free(in); 544e71b7053SJung-uk Kim return ret; 54574664626SKris Kennaway } 54674664626SKris Kennaway 5476f9291ceSJung-uk Kim int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, 5486f9291ceSJung-uk Kim const unsigned char *d, long len) 54974664626SKris Kennaway { 55074664626SKris Kennaway int ret; 5513b4e3dcbSSimon L. B. Nielsen const unsigned char *p; 55274664626SKris Kennaway EVP_PKEY *pkey; 55374664626SKris Kennaway 55474664626SKris Kennaway p = d; 5556f9291ceSJung-uk Kim if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) { 55674664626SKris Kennaway SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB); 557e71b7053SJung-uk Kim return 0; 55874664626SKris Kennaway } 55974664626SKris Kennaway 56074664626SKris Kennaway ret = SSL_CTX_use_PrivateKey(ctx, pkey); 56174664626SKris Kennaway EVP_PKEY_free(pkey); 562e71b7053SJung-uk Kim return ret; 56374664626SKris Kennaway } 56474664626SKris Kennaway 5656f9291ceSJung-uk Kim /* 5666f9291ceSJung-uk Kim * Read a file that contains our certificate in "PEM" format, possibly 5676f9291ceSJung-uk Kim * followed by a sequence of CA certificates that should be sent to the peer 5686f9291ceSJung-uk Kim * in the Certificate message. 56974664626SKris Kennaway */ 570e71b7053SJung-uk Kim static int use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file) 57174664626SKris Kennaway { 57274664626SKris Kennaway BIO *in; 57374664626SKris Kennaway int ret = 0; 57474664626SKris Kennaway X509 *x = NULL; 575e71b7053SJung-uk Kim pem_password_cb *passwd_callback; 576e71b7053SJung-uk Kim void *passwd_callback_userdata; 57774664626SKris Kennaway 5786f9291ceSJung-uk Kim ERR_clear_error(); /* clear error stack for 5796f9291ceSJung-uk Kim * SSL_CTX_use_certificate() */ 580db522d3aSSimon L. B. Nielsen 581e71b7053SJung-uk Kim if (ctx != NULL) { 582e71b7053SJung-uk Kim passwd_callback = ctx->default_passwd_callback; 583e71b7053SJung-uk Kim passwd_callback_userdata = ctx->default_passwd_callback_userdata; 584e71b7053SJung-uk Kim } else { 585e71b7053SJung-uk Kim passwd_callback = ssl->default_passwd_callback; 586e71b7053SJung-uk Kim passwd_callback_userdata = ssl->default_passwd_callback_userdata; 587e71b7053SJung-uk Kim } 588e71b7053SJung-uk Kim 589e71b7053SJung-uk Kim in = BIO_new(BIO_s_file()); 5906f9291ceSJung-uk Kim if (in == NULL) { 591e71b7053SJung-uk Kim SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB); 59274664626SKris Kennaway goto end; 59374664626SKris Kennaway } 59474664626SKris Kennaway 5956f9291ceSJung-uk Kim if (BIO_read_filename(in, file) <= 0) { 596e71b7053SJung-uk Kim SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_SYS_LIB); 59774664626SKris Kennaway goto end; 59874664626SKris Kennaway } 59974664626SKris Kennaway 600e71b7053SJung-uk Kim x = PEM_read_bio_X509_AUX(in, NULL, passwd_callback, 601e71b7053SJung-uk Kim passwd_callback_userdata); 6026f9291ceSJung-uk Kim if (x == NULL) { 603e71b7053SJung-uk Kim SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB); 60474664626SKris Kennaway goto end; 60574664626SKris Kennaway } 60674664626SKris Kennaway 607e71b7053SJung-uk Kim if (ctx) 60874664626SKris Kennaway ret = SSL_CTX_use_certificate(ctx, x); 609e71b7053SJung-uk Kim else 610e71b7053SJung-uk Kim ret = SSL_use_certificate(ssl, x); 61109286989SJung-uk Kim 61274664626SKris Kennaway if (ERR_peek_error() != 0) 6136f9291ceSJung-uk Kim ret = 0; /* Key/certificate mismatch doesn't imply 6146f9291ceSJung-uk Kim * ret==0 ... */ 6156f9291ceSJung-uk Kim if (ret) { 6166f9291ceSJung-uk Kim /* 6176f9291ceSJung-uk Kim * If we could set up our certificate, now proceed to the CA 6186f9291ceSJung-uk Kim * certificates. 61974664626SKris Kennaway */ 62074664626SKris Kennaway X509 *ca; 62174664626SKris Kennaway int r; 62274664626SKris Kennaway unsigned long err; 62374664626SKris Kennaway 624e71b7053SJung-uk Kim if (ctx) 625e71b7053SJung-uk Kim r = SSL_CTX_clear_chain_certs(ctx); 626e71b7053SJung-uk Kim else 627e71b7053SJung-uk Kim r = SSL_clear_chain_certs(ssl); 62874664626SKris Kennaway 629e71b7053SJung-uk Kim if (r == 0) { 630e71b7053SJung-uk Kim ret = 0; 631e71b7053SJung-uk Kim goto end; 632e71b7053SJung-uk Kim } 633e71b7053SJung-uk Kim 634e71b7053SJung-uk Kim while ((ca = PEM_read_bio_X509(in, NULL, passwd_callback, 635e71b7053SJung-uk Kim passwd_callback_userdata)) 6366f9291ceSJung-uk Kim != NULL) { 637e71b7053SJung-uk Kim if (ctx) 6387bded2dbSJung-uk Kim r = SSL_CTX_add0_chain_cert(ctx, ca); 639e71b7053SJung-uk Kim else 640e71b7053SJung-uk Kim r = SSL_add0_chain_cert(ssl, ca); 641e71b7053SJung-uk Kim /* 642e71b7053SJung-uk Kim * Note that we must not free ca if it was successfully added to 643e71b7053SJung-uk Kim * the chain (while we must free the main certificate, since its 644e71b7053SJung-uk Kim * reference count is increased by SSL_CTX_use_certificate). 645e71b7053SJung-uk Kim */ 6466f9291ceSJung-uk Kim if (!r) { 64774664626SKris Kennaway X509_free(ca); 64874664626SKris Kennaway ret = 0; 64974664626SKris Kennaway goto end; 65074664626SKris Kennaway } 65174664626SKris Kennaway } 65274664626SKris Kennaway /* When the while loop ends, it's usually just EOF. */ 6535c87c606SMark Murray err = ERR_peek_last_error(); 6546f9291ceSJung-uk Kim if (ERR_GET_LIB(err) == ERR_LIB_PEM 6556f9291ceSJung-uk Kim && ERR_GET_REASON(err) == PEM_R_NO_START_LINE) 6563b4e3dcbSSimon L. B. Nielsen ERR_clear_error(); 65774664626SKris Kennaway else 65874664626SKris Kennaway ret = 0; /* some real error */ 65974664626SKris Kennaway } 66074664626SKris Kennaway 66174664626SKris Kennaway end: 6626f9291ceSJung-uk Kim X509_free(x); 6636f9291ceSJung-uk Kim BIO_free(in); 664e71b7053SJung-uk Kim return ret; 66574664626SKris Kennaway } 6667bded2dbSJung-uk Kim 667e71b7053SJung-uk Kim int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) 668e71b7053SJung-uk Kim { 669e71b7053SJung-uk Kim return use_certificate_chain_file(ctx, NULL, file); 670e71b7053SJung-uk Kim } 671e71b7053SJung-uk Kim 672e71b7053SJung-uk Kim int SSL_use_certificate_chain_file(SSL *ssl, const char *file) 673e71b7053SJung-uk Kim { 674e71b7053SJung-uk Kim return use_certificate_chain_file(NULL, ssl, file); 675e71b7053SJung-uk Kim } 676e71b7053SJung-uk Kim 6777bded2dbSJung-uk Kim static int serverinfo_find_extension(const unsigned char *serverinfo, 6787bded2dbSJung-uk Kim size_t serverinfo_length, 6797bded2dbSJung-uk Kim unsigned int extension_type, 6807bded2dbSJung-uk Kim const unsigned char **extension_data, 6817bded2dbSJung-uk Kim size_t *extension_length) 6827bded2dbSJung-uk Kim { 683e71b7053SJung-uk Kim PACKET pkt, data; 684e71b7053SJung-uk Kim 6857bded2dbSJung-uk Kim *extension_data = NULL; 6867bded2dbSJung-uk Kim *extension_length = 0; 6877bded2dbSJung-uk Kim if (serverinfo == NULL || serverinfo_length == 0) 68880815a77SJung-uk Kim return -1; 689e71b7053SJung-uk Kim 690e71b7053SJung-uk Kim if (!PACKET_buf_init(&pkt, serverinfo, serverinfo_length)) 691e71b7053SJung-uk Kim return -1; 692e71b7053SJung-uk Kim 6937bded2dbSJung-uk Kim for (;;) { 6947bded2dbSJung-uk Kim unsigned int type = 0; 695e71b7053SJung-uk Kim unsigned long context = 0; 6967bded2dbSJung-uk Kim 6977bded2dbSJung-uk Kim /* end of serverinfo */ 698e71b7053SJung-uk Kim if (PACKET_remaining(&pkt) == 0) 69980815a77SJung-uk Kim return 0; /* Extension not found */ 7007bded2dbSJung-uk Kim 701e71b7053SJung-uk Kim if (!PACKET_get_net_4(&pkt, &context) 702e71b7053SJung-uk Kim || !PACKET_get_net_2(&pkt, &type) 703e71b7053SJung-uk Kim || !PACKET_get_length_prefixed_2(&pkt, &data)) 704e71b7053SJung-uk Kim return -1; 7057bded2dbSJung-uk Kim 7067bded2dbSJung-uk Kim if (type == extension_type) { 707e71b7053SJung-uk Kim *extension_data = PACKET_data(&data); 708e71b7053SJung-uk Kim *extension_length = PACKET_remaining(&data);; 7097bded2dbSJung-uk Kim return 1; /* Success */ 7107bded2dbSJung-uk Kim } 7117bded2dbSJung-uk Kim } 712e71b7053SJung-uk Kim /* Unreachable */ 7137bded2dbSJung-uk Kim } 7147bded2dbSJung-uk Kim 715e71b7053SJung-uk Kim static int serverinfoex_srv_parse_cb(SSL *s, unsigned int ext_type, 716e71b7053SJung-uk Kim unsigned int context, 7177bded2dbSJung-uk Kim const unsigned char *in, 718e71b7053SJung-uk Kim size_t inlen, X509 *x, size_t chainidx, 719e71b7053SJung-uk Kim int *al, void *arg) 7207bded2dbSJung-uk Kim { 7217bded2dbSJung-uk Kim 7227bded2dbSJung-uk Kim if (inlen != 0) { 7237bded2dbSJung-uk Kim *al = SSL_AD_DECODE_ERROR; 7247bded2dbSJung-uk Kim return 0; 7257bded2dbSJung-uk Kim } 7267bded2dbSJung-uk Kim 7277bded2dbSJung-uk Kim return 1; 7287bded2dbSJung-uk Kim } 7297bded2dbSJung-uk Kim 730*cfc39718SJung-uk Kim static size_t extension_contextoff(unsigned int version) 731*cfc39718SJung-uk Kim { 732*cfc39718SJung-uk Kim return version == SSL_SERVERINFOV1 ? 4 : 0; 733*cfc39718SJung-uk Kim } 734*cfc39718SJung-uk Kim 735*cfc39718SJung-uk Kim static size_t extension_append_length(unsigned int version, size_t extension_length) 736*cfc39718SJung-uk Kim { 737*cfc39718SJung-uk Kim return extension_length + extension_contextoff(version); 738*cfc39718SJung-uk Kim } 739*cfc39718SJung-uk Kim 740*cfc39718SJung-uk Kim static void extension_append(unsigned int version, 741*cfc39718SJung-uk Kim const unsigned char *extension, 742*cfc39718SJung-uk Kim const size_t extension_length, 743*cfc39718SJung-uk Kim unsigned char *serverinfo) 744*cfc39718SJung-uk Kim { 745*cfc39718SJung-uk Kim const size_t contextoff = extension_contextoff(version); 746*cfc39718SJung-uk Kim 747*cfc39718SJung-uk Kim if (contextoff > 0) { 748*cfc39718SJung-uk Kim /* We know this only uses the last 2 bytes */ 749*cfc39718SJung-uk Kim serverinfo[0] = 0; 750*cfc39718SJung-uk Kim serverinfo[1] = 0; 751*cfc39718SJung-uk Kim serverinfo[2] = (SYNTHV1CONTEXT >> 8) & 0xff; 752*cfc39718SJung-uk Kim serverinfo[3] = SYNTHV1CONTEXT & 0xff; 753*cfc39718SJung-uk Kim } 754*cfc39718SJung-uk Kim 755*cfc39718SJung-uk Kim memcpy(serverinfo + contextoff, extension, extension_length); 756*cfc39718SJung-uk Kim } 757*cfc39718SJung-uk Kim 758e71b7053SJung-uk Kim static int serverinfo_srv_parse_cb(SSL *s, unsigned int ext_type, 759e71b7053SJung-uk Kim const unsigned char *in, 760e71b7053SJung-uk Kim size_t inlen, int *al, void *arg) 761e71b7053SJung-uk Kim { 762e71b7053SJung-uk Kim return serverinfoex_srv_parse_cb(s, ext_type, 0, in, inlen, NULL, 0, al, 763e71b7053SJung-uk Kim arg); 764e71b7053SJung-uk Kim } 765e71b7053SJung-uk Kim 766e71b7053SJung-uk Kim static int serverinfoex_srv_add_cb(SSL *s, unsigned int ext_type, 767e71b7053SJung-uk Kim unsigned int context, 768e71b7053SJung-uk Kim const unsigned char **out, 769e71b7053SJung-uk Kim size_t *outlen, X509 *x, size_t chainidx, 7707bded2dbSJung-uk Kim int *al, void *arg) 7717bded2dbSJung-uk Kim { 7727bded2dbSJung-uk Kim const unsigned char *serverinfo = NULL; 7737bded2dbSJung-uk Kim size_t serverinfo_length = 0; 7747bded2dbSJung-uk Kim 775e71b7053SJung-uk Kim /* We only support extensions for the first Certificate */ 776e71b7053SJung-uk Kim if ((context & SSL_EXT_TLS1_3_CERTIFICATE) != 0 && chainidx > 0) 777e71b7053SJung-uk Kim return 0; 778e71b7053SJung-uk Kim 7797bded2dbSJung-uk Kim /* Is there serverinfo data for the chosen server cert? */ 7807bded2dbSJung-uk Kim if ((ssl_get_server_cert_serverinfo(s, &serverinfo, 7817bded2dbSJung-uk Kim &serverinfo_length)) != 0) { 7827bded2dbSJung-uk Kim /* Find the relevant extension from the serverinfo */ 7837bded2dbSJung-uk Kim int retval = serverinfo_find_extension(serverinfo, serverinfo_length, 7847bded2dbSJung-uk Kim ext_type, out, outlen); 78580815a77SJung-uk Kim if (retval == -1) { 786e71b7053SJung-uk Kim *al = SSL_AD_INTERNAL_ERROR; 78780815a77SJung-uk Kim return -1; /* Error */ 78880815a77SJung-uk Kim } 7897bded2dbSJung-uk Kim if (retval == 0) 79080815a77SJung-uk Kim return 0; /* No extension found, don't send extension */ 7917bded2dbSJung-uk Kim return 1; /* Send extension */ 7927bded2dbSJung-uk Kim } 793b8721c16SJung-uk Kim return 0; /* No serverinfo data found, don't send 7947bded2dbSJung-uk Kim * extension */ 7957bded2dbSJung-uk Kim } 7967bded2dbSJung-uk Kim 797e71b7053SJung-uk Kim static int serverinfo_srv_add_cb(SSL *s, unsigned int ext_type, 798e71b7053SJung-uk Kim const unsigned char **out, size_t *outlen, 799e71b7053SJung-uk Kim int *al, void *arg) 800e71b7053SJung-uk Kim { 801e71b7053SJung-uk Kim return serverinfoex_srv_add_cb(s, ext_type, 0, out, outlen, NULL, 0, al, 802e71b7053SJung-uk Kim arg); 803e71b7053SJung-uk Kim } 804e71b7053SJung-uk Kim 8057bded2dbSJung-uk Kim /* 8067bded2dbSJung-uk Kim * With a NULL context, this function just checks that the serverinfo data 8077bded2dbSJung-uk Kim * parses correctly. With a non-NULL context, it registers callbacks for 8087bded2dbSJung-uk Kim * the included extensions. 8097bded2dbSJung-uk Kim */ 810e71b7053SJung-uk Kim static int serverinfo_process_buffer(unsigned int version, 811e71b7053SJung-uk Kim const unsigned char *serverinfo, 8127bded2dbSJung-uk Kim size_t serverinfo_length, SSL_CTX *ctx) 8137bded2dbSJung-uk Kim { 814e71b7053SJung-uk Kim PACKET pkt; 815e71b7053SJung-uk Kim 8167bded2dbSJung-uk Kim if (serverinfo == NULL || serverinfo_length == 0) 8177bded2dbSJung-uk Kim return 0; 8187bded2dbSJung-uk Kim 819e71b7053SJung-uk Kim if (version != SSL_SERVERINFOV1 && version != SSL_SERVERINFOV2) 8207bded2dbSJung-uk Kim return 0; 8217bded2dbSJung-uk Kim 822e71b7053SJung-uk Kim if (!PACKET_buf_init(&pkt, serverinfo, serverinfo_length)) 823e71b7053SJung-uk Kim return 0; 824b8721c16SJung-uk Kim 825e71b7053SJung-uk Kim while (PACKET_remaining(&pkt)) { 826e71b7053SJung-uk Kim unsigned long context = 0; 827e71b7053SJung-uk Kim unsigned int ext_type = 0; 828e71b7053SJung-uk Kim PACKET data; 829b8721c16SJung-uk Kim 830e71b7053SJung-uk Kim if ((version == SSL_SERVERINFOV2 && !PACKET_get_net_4(&pkt, &context)) 831e71b7053SJung-uk Kim || !PACKET_get_net_2(&pkt, &ext_type) 832e71b7053SJung-uk Kim || !PACKET_get_length_prefixed_2(&pkt, &data)) 833e71b7053SJung-uk Kim return 0; 834e71b7053SJung-uk Kim 835e71b7053SJung-uk Kim if (ctx == NULL) 836e71b7053SJung-uk Kim continue; 837e71b7053SJung-uk Kim 838e71b7053SJung-uk Kim /* 839e71b7053SJung-uk Kim * The old style custom extensions API could be set separately for 840e71b7053SJung-uk Kim * server/client, i.e. you could set one custom extension for a client, 841e71b7053SJung-uk Kim * and *for the same extension in the same SSL_CTX* you could set a 842e71b7053SJung-uk Kim * custom extension for the server as well. It seems quite weird to be 843e71b7053SJung-uk Kim * setting a custom extension for both client and server in a single 844e71b7053SJung-uk Kim * SSL_CTX - but theoretically possible. This isn't possible in the 845e71b7053SJung-uk Kim * new API. Therefore, if we have V1 serverinfo we use the old API. We 846e71b7053SJung-uk Kim * also use the old API even if we have V2 serverinfo but the context 847e71b7053SJung-uk Kim * looks like an old style <= TLSv1.2 extension. 848e71b7053SJung-uk Kim */ 849e71b7053SJung-uk Kim if (version == SSL_SERVERINFOV1 || context == SYNTHV1CONTEXT) { 850e71b7053SJung-uk Kim if (!SSL_CTX_add_server_custom_ext(ctx, ext_type, 8517bded2dbSJung-uk Kim serverinfo_srv_add_cb, 8527bded2dbSJung-uk Kim NULL, NULL, 8537bded2dbSJung-uk Kim serverinfo_srv_parse_cb, 8547bded2dbSJung-uk Kim NULL)) 8557bded2dbSJung-uk Kim return 0; 856e71b7053SJung-uk Kim } else { 857e71b7053SJung-uk Kim if (!SSL_CTX_add_custom_ext(ctx, ext_type, context, 858e71b7053SJung-uk Kim serverinfoex_srv_add_cb, 859e71b7053SJung-uk Kim NULL, NULL, 860e71b7053SJung-uk Kim serverinfoex_srv_parse_cb, 861e71b7053SJung-uk Kim NULL)) 8627bded2dbSJung-uk Kim return 0; 8637bded2dbSJung-uk Kim } 8647bded2dbSJung-uk Kim } 8657bded2dbSJung-uk Kim 866e71b7053SJung-uk Kim return 1; 867e71b7053SJung-uk Kim } 868e71b7053SJung-uk Kim 869e71b7053SJung-uk Kim int SSL_CTX_use_serverinfo_ex(SSL_CTX *ctx, unsigned int version, 870e71b7053SJung-uk Kim const unsigned char *serverinfo, 8717bded2dbSJung-uk Kim size_t serverinfo_length) 8727bded2dbSJung-uk Kim { 873*cfc39718SJung-uk Kim unsigned char *new_serverinfo = NULL; 874aeb5019cSJung-uk Kim 8757bded2dbSJung-uk Kim if (ctx == NULL || serverinfo == NULL || serverinfo_length == 0) { 876e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_EX, ERR_R_PASSED_NULL_PARAMETER); 8777bded2dbSJung-uk Kim return 0; 8787bded2dbSJung-uk Kim } 879*cfc39718SJung-uk Kim if (version == SSL_SERVERINFOV1) { 880*cfc39718SJung-uk Kim /* 881*cfc39718SJung-uk Kim * Convert serverinfo version v1 to v2 and call yourself recursively 882*cfc39718SJung-uk Kim * over the converted serverinfo. 883*cfc39718SJung-uk Kim */ 884*cfc39718SJung-uk Kim const size_t sinfo_length = extension_append_length(SSL_SERVERINFOV1, 885*cfc39718SJung-uk Kim serverinfo_length); 886*cfc39718SJung-uk Kim unsigned char *sinfo; 887*cfc39718SJung-uk Kim int ret; 888*cfc39718SJung-uk Kim 889*cfc39718SJung-uk Kim sinfo = OPENSSL_malloc(sinfo_length); 890*cfc39718SJung-uk Kim if (sinfo == NULL) { 891*cfc39718SJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_EX, ERR_R_MALLOC_FAILURE); 892*cfc39718SJung-uk Kim return 0; 893*cfc39718SJung-uk Kim } 894*cfc39718SJung-uk Kim 895*cfc39718SJung-uk Kim extension_append(SSL_SERVERINFOV1, serverinfo, serverinfo_length, sinfo); 896*cfc39718SJung-uk Kim 897*cfc39718SJung-uk Kim ret = SSL_CTX_use_serverinfo_ex(ctx, SSL_SERVERINFOV2, sinfo, 898*cfc39718SJung-uk Kim sinfo_length); 899*cfc39718SJung-uk Kim 900*cfc39718SJung-uk Kim OPENSSL_free(sinfo); 901*cfc39718SJung-uk Kim return ret; 902*cfc39718SJung-uk Kim } 903e71b7053SJung-uk Kim if (!serverinfo_process_buffer(version, serverinfo, serverinfo_length, 904e71b7053SJung-uk Kim NULL)) { 905e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_EX, SSL_R_INVALID_SERVERINFO_DATA); 9067bded2dbSJung-uk Kim return 0; 9077bded2dbSJung-uk Kim } 9087bded2dbSJung-uk Kim if (ctx->cert->key == NULL) { 909e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_EX, ERR_R_INTERNAL_ERROR); 9107bded2dbSJung-uk Kim return 0; 9117bded2dbSJung-uk Kim } 912aeb5019cSJung-uk Kim new_serverinfo = OPENSSL_realloc(ctx->cert->key->serverinfo, 9137bded2dbSJung-uk Kim serverinfo_length); 914aeb5019cSJung-uk Kim if (new_serverinfo == NULL) { 915e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_EX, ERR_R_MALLOC_FAILURE); 9167bded2dbSJung-uk Kim return 0; 9177bded2dbSJung-uk Kim } 918aeb5019cSJung-uk Kim ctx->cert->key->serverinfo = new_serverinfo; 9197bded2dbSJung-uk Kim memcpy(ctx->cert->key->serverinfo, serverinfo, serverinfo_length); 9207bded2dbSJung-uk Kim ctx->cert->key->serverinfo_length = serverinfo_length; 9217bded2dbSJung-uk Kim 9227bded2dbSJung-uk Kim /* 9237bded2dbSJung-uk Kim * Now that the serverinfo is validated and stored, go ahead and 9247bded2dbSJung-uk Kim * register callbacks. 9257bded2dbSJung-uk Kim */ 926e71b7053SJung-uk Kim if (!serverinfo_process_buffer(version, serverinfo, serverinfo_length, 927e71b7053SJung-uk Kim ctx)) { 928e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_EX, SSL_R_INVALID_SERVERINFO_DATA); 9297bded2dbSJung-uk Kim return 0; 9307bded2dbSJung-uk Kim } 9317bded2dbSJung-uk Kim return 1; 9327bded2dbSJung-uk Kim } 9337bded2dbSJung-uk Kim 934e71b7053SJung-uk Kim int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, 935e71b7053SJung-uk Kim size_t serverinfo_length) 936e71b7053SJung-uk Kim { 937e71b7053SJung-uk Kim return SSL_CTX_use_serverinfo_ex(ctx, SSL_SERVERINFOV1, serverinfo, 938e71b7053SJung-uk Kim serverinfo_length); 939e71b7053SJung-uk Kim } 940e71b7053SJung-uk Kim 9417bded2dbSJung-uk Kim int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) 9427bded2dbSJung-uk Kim { 9437bded2dbSJung-uk Kim unsigned char *serverinfo = NULL; 944e71b7053SJung-uk Kim unsigned char *tmp; 9457bded2dbSJung-uk Kim size_t serverinfo_length = 0; 9467bded2dbSJung-uk Kim unsigned char *extension = 0; 9477bded2dbSJung-uk Kim long extension_length = 0; 9487bded2dbSJung-uk Kim char *name = NULL; 9497bded2dbSJung-uk Kim char *header = NULL; 950e71b7053SJung-uk Kim char namePrefix1[] = "SERVERINFO FOR "; 951e71b7053SJung-uk Kim char namePrefix2[] = "SERVERINFOV2 FOR "; 9527bded2dbSJung-uk Kim int ret = 0; 9537bded2dbSJung-uk Kim BIO *bin = NULL; 954*cfc39718SJung-uk Kim size_t num_extensions = 0; 9557bded2dbSJung-uk Kim 9567bded2dbSJung-uk Kim if (ctx == NULL || file == NULL) { 957e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_PASSED_NULL_PARAMETER); 9587bded2dbSJung-uk Kim goto end; 9597bded2dbSJung-uk Kim } 9607bded2dbSJung-uk Kim 961e71b7053SJung-uk Kim bin = BIO_new(BIO_s_file()); 9627bded2dbSJung-uk Kim if (bin == NULL) { 9637bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_BUF_LIB); 9647bded2dbSJung-uk Kim goto end; 9657bded2dbSJung-uk Kim } 9667bded2dbSJung-uk Kim if (BIO_read_filename(bin, file) <= 0) { 9677bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_SYS_LIB); 9687bded2dbSJung-uk Kim goto end; 9697bded2dbSJung-uk Kim } 9707bded2dbSJung-uk Kim 9717bded2dbSJung-uk Kim for (num_extensions = 0;; num_extensions++) { 972e71b7053SJung-uk Kim unsigned int version; 973*cfc39718SJung-uk Kim size_t append_length; 974e71b7053SJung-uk Kim 9757bded2dbSJung-uk Kim if (PEM_read_bio(bin, &name, &header, &extension, &extension_length) 9767bded2dbSJung-uk Kim == 0) { 9777bded2dbSJung-uk Kim /* 9787bded2dbSJung-uk Kim * There must be at least one extension in this file 9797bded2dbSJung-uk Kim */ 9807bded2dbSJung-uk Kim if (num_extensions == 0) { 9817bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, 9827bded2dbSJung-uk Kim SSL_R_NO_PEM_EXTENSIONS); 9837bded2dbSJung-uk Kim goto end; 9847bded2dbSJung-uk Kim } else /* End of file, we're done */ 9857bded2dbSJung-uk Kim break; 9867bded2dbSJung-uk Kim } 9877bded2dbSJung-uk Kim /* Check that PEM name starts with "BEGIN SERVERINFO FOR " */ 988e71b7053SJung-uk Kim if (strlen(name) < strlen(namePrefix1)) { 989e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_PEM_NAME_TOO_SHORT); 990e71b7053SJung-uk Kim goto end; 991e71b7053SJung-uk Kim } 992e71b7053SJung-uk Kim if (strncmp(name, namePrefix1, strlen(namePrefix1)) == 0) { 993e71b7053SJung-uk Kim version = SSL_SERVERINFOV1; 994e71b7053SJung-uk Kim } else { 995e71b7053SJung-uk Kim if (strlen(name) < strlen(namePrefix2)) { 9967bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, 9977bded2dbSJung-uk Kim SSL_R_PEM_NAME_TOO_SHORT); 9987bded2dbSJung-uk Kim goto end; 9997bded2dbSJung-uk Kim } 1000e71b7053SJung-uk Kim if (strncmp(name, namePrefix2, strlen(namePrefix2)) != 0) { 10017bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, 10027bded2dbSJung-uk Kim SSL_R_PEM_NAME_BAD_PREFIX); 10037bded2dbSJung-uk Kim goto end; 10047bded2dbSJung-uk Kim } 1005e71b7053SJung-uk Kim version = SSL_SERVERINFOV2; 1006e71b7053SJung-uk Kim } 10077bded2dbSJung-uk Kim /* 10087bded2dbSJung-uk Kim * Check that the decoded PEM data is plausible (valid length field) 10097bded2dbSJung-uk Kim */ 1010e71b7053SJung-uk Kim if (version == SSL_SERVERINFOV1) { 1011e71b7053SJung-uk Kim /* 4 byte header: 2 bytes type, 2 bytes len */ 10127bded2dbSJung-uk Kim if (extension_length < 4 1013e71b7053SJung-uk Kim || (extension[2] << 8) + extension[3] 1014e71b7053SJung-uk Kim != extension_length - 4) { 10157bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_BAD_DATA); 10167bded2dbSJung-uk Kim goto end; 10177bded2dbSJung-uk Kim } 1018e71b7053SJung-uk Kim } else { 1019e71b7053SJung-uk Kim /* 8 byte header: 4 bytes context, 2 bytes type, 2 bytes len */ 1020e71b7053SJung-uk Kim if (extension_length < 8 1021e71b7053SJung-uk Kim || (extension[6] << 8) + extension[7] 1022e71b7053SJung-uk Kim != extension_length - 8) { 1023e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_BAD_DATA); 1024e71b7053SJung-uk Kim goto end; 1025e71b7053SJung-uk Kim } 1026e71b7053SJung-uk Kim } 10277bded2dbSJung-uk Kim /* Append the decoded extension to the serverinfo buffer */ 1028*cfc39718SJung-uk Kim append_length = extension_append_length(version, extension_length); 1029*cfc39718SJung-uk Kim tmp = OPENSSL_realloc(serverinfo, serverinfo_length + append_length); 1030e71b7053SJung-uk Kim if (tmp == NULL) { 10317bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_MALLOC_FAILURE); 10327bded2dbSJung-uk Kim goto end; 10337bded2dbSJung-uk Kim } 1034e71b7053SJung-uk Kim serverinfo = tmp; 1035*cfc39718SJung-uk Kim extension_append(version, extension, extension_length, 1036*cfc39718SJung-uk Kim serverinfo + serverinfo_length); 1037*cfc39718SJung-uk Kim serverinfo_length += append_length; 10387bded2dbSJung-uk Kim 10397bded2dbSJung-uk Kim OPENSSL_free(name); 10407bded2dbSJung-uk Kim name = NULL; 10417bded2dbSJung-uk Kim OPENSSL_free(header); 10427bded2dbSJung-uk Kim header = NULL; 10437bded2dbSJung-uk Kim OPENSSL_free(extension); 10447bded2dbSJung-uk Kim extension = NULL; 10457bded2dbSJung-uk Kim } 10467bded2dbSJung-uk Kim 1047e71b7053SJung-uk Kim ret = SSL_CTX_use_serverinfo_ex(ctx, SSL_SERVERINFOV2, serverinfo, 1048e71b7053SJung-uk Kim serverinfo_length); 10497bded2dbSJung-uk Kim end: 10507bded2dbSJung-uk Kim /* SSL_CTX_use_serverinfo makes a local copy of the serverinfo. */ 10517bded2dbSJung-uk Kim OPENSSL_free(name); 10527bded2dbSJung-uk Kim OPENSSL_free(header); 10537bded2dbSJung-uk Kim OPENSSL_free(extension); 10547bded2dbSJung-uk Kim OPENSSL_free(serverinfo); 10557bded2dbSJung-uk Kim BIO_free(bin); 10567bded2dbSJung-uk Kim return ret; 10577bded2dbSJung-uk Kim } 1058e71b7053SJung-uk Kim 1059e71b7053SJung-uk Kim static int ssl_set_cert_and_key(SSL *ssl, SSL_CTX *ctx, X509 *x509, EVP_PKEY *privatekey, 1060e71b7053SJung-uk Kim STACK_OF(X509) *chain, int override) 1061e71b7053SJung-uk Kim { 1062e71b7053SJung-uk Kim int ret = 0; 1063e71b7053SJung-uk Kim size_t i; 1064e71b7053SJung-uk Kim int j; 1065e71b7053SJung-uk Kim int rv; 1066e71b7053SJung-uk Kim CERT *c = ssl != NULL ? ssl->cert : ctx->cert; 1067e71b7053SJung-uk Kim STACK_OF(X509) *dup_chain = NULL; 1068e71b7053SJung-uk Kim EVP_PKEY *pubkey = NULL; 1069e71b7053SJung-uk Kim 1070e71b7053SJung-uk Kim /* Do all security checks before anything else */ 1071e71b7053SJung-uk Kim rv = ssl_security_cert(ssl, ctx, x509, 0, 1); 1072e71b7053SJung-uk Kim if (rv != 1) { 1073e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, rv); 1074e71b7053SJung-uk Kim goto out; 1075e71b7053SJung-uk Kim } 1076e71b7053SJung-uk Kim for (j = 0; j < sk_X509_num(chain); j++) { 1077e71b7053SJung-uk Kim rv = ssl_security_cert(ssl, ctx, sk_X509_value(chain, j), 0, 0); 1078e71b7053SJung-uk Kim if (rv != 1) { 1079e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, rv); 1080e71b7053SJung-uk Kim goto out; 1081e71b7053SJung-uk Kim } 1082e71b7053SJung-uk Kim } 1083e71b7053SJung-uk Kim 1084e71b7053SJung-uk Kim pubkey = X509_get_pubkey(x509); /* bumps reference */ 1085e71b7053SJung-uk Kim if (pubkey == NULL) 1086e71b7053SJung-uk Kim goto out; 1087e71b7053SJung-uk Kim if (privatekey == NULL) { 1088e71b7053SJung-uk Kim privatekey = pubkey; 1089e71b7053SJung-uk Kim } else { 1090e71b7053SJung-uk Kim /* For RSA, which has no parameters, missing returns 0 */ 1091e71b7053SJung-uk Kim if (EVP_PKEY_missing_parameters(privatekey)) { 1092e71b7053SJung-uk Kim if (EVP_PKEY_missing_parameters(pubkey)) { 1093e71b7053SJung-uk Kim /* nobody has parameters? - error */ 1094e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, SSL_R_MISSING_PARAMETERS); 1095e71b7053SJung-uk Kim goto out; 1096e71b7053SJung-uk Kim } else { 1097e71b7053SJung-uk Kim /* copy to privatekey from pubkey */ 1098e71b7053SJung-uk Kim EVP_PKEY_copy_parameters(privatekey, pubkey); 1099e71b7053SJung-uk Kim } 1100e71b7053SJung-uk Kim } else if (EVP_PKEY_missing_parameters(pubkey)) { 1101e71b7053SJung-uk Kim /* copy to pubkey from privatekey */ 1102e71b7053SJung-uk Kim EVP_PKEY_copy_parameters(pubkey, privatekey); 1103e71b7053SJung-uk Kim } /* else both have parameters */ 1104e71b7053SJung-uk Kim 1105e71b7053SJung-uk Kim /* check that key <-> cert match */ 1106e71b7053SJung-uk Kim if (EVP_PKEY_cmp(pubkey, privatekey) != 1) { 1107e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, SSL_R_PRIVATE_KEY_MISMATCH); 1108e71b7053SJung-uk Kim goto out; 1109e71b7053SJung-uk Kim } 1110e71b7053SJung-uk Kim } 1111e71b7053SJung-uk Kim if (ssl_cert_lookup_by_pkey(pubkey, &i) == NULL) { 1112e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, SSL_R_UNKNOWN_CERTIFICATE_TYPE); 1113e71b7053SJung-uk Kim goto out; 1114e71b7053SJung-uk Kim } 1115e71b7053SJung-uk Kim 1116e71b7053SJung-uk Kim if (!override && (c->pkeys[i].x509 != NULL 1117e71b7053SJung-uk Kim || c->pkeys[i].privatekey != NULL 1118e71b7053SJung-uk Kim || c->pkeys[i].chain != NULL)) { 1119e71b7053SJung-uk Kim /* No override, and something already there */ 1120e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, SSL_R_NOT_REPLACING_CERTIFICATE); 1121e71b7053SJung-uk Kim goto out; 1122e71b7053SJung-uk Kim } 1123e71b7053SJung-uk Kim 1124e71b7053SJung-uk Kim if (chain != NULL) { 1125e71b7053SJung-uk Kim dup_chain = X509_chain_up_ref(chain); 1126e71b7053SJung-uk Kim if (dup_chain == NULL) { 1127e71b7053SJung-uk Kim SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, ERR_R_MALLOC_FAILURE); 1128e71b7053SJung-uk Kim goto out; 1129e71b7053SJung-uk Kim } 1130e71b7053SJung-uk Kim } 1131e71b7053SJung-uk Kim 1132e71b7053SJung-uk Kim sk_X509_pop_free(c->pkeys[i].chain, X509_free); 1133e71b7053SJung-uk Kim c->pkeys[i].chain = dup_chain; 1134e71b7053SJung-uk Kim 1135e71b7053SJung-uk Kim X509_free(c->pkeys[i].x509); 1136e71b7053SJung-uk Kim X509_up_ref(x509); 1137e71b7053SJung-uk Kim c->pkeys[i].x509 = x509; 1138e71b7053SJung-uk Kim 1139e71b7053SJung-uk Kim EVP_PKEY_free(c->pkeys[i].privatekey); 1140e71b7053SJung-uk Kim EVP_PKEY_up_ref(privatekey); 1141e71b7053SJung-uk Kim c->pkeys[i].privatekey = privatekey; 1142e71b7053SJung-uk Kim 1143e71b7053SJung-uk Kim c->key = &(c->pkeys[i]); 1144e71b7053SJung-uk Kim 1145e71b7053SJung-uk Kim ret = 1; 1146e71b7053SJung-uk Kim out: 1147e71b7053SJung-uk Kim EVP_PKEY_free(pubkey); 1148e71b7053SJung-uk Kim return ret; 1149e71b7053SJung-uk Kim } 1150e71b7053SJung-uk Kim 1151e71b7053SJung-uk Kim int SSL_use_cert_and_key(SSL *ssl, X509 *x509, EVP_PKEY *privatekey, 1152e71b7053SJung-uk Kim STACK_OF(X509) *chain, int override) 1153e71b7053SJung-uk Kim { 1154e71b7053SJung-uk Kim return ssl_set_cert_and_key(ssl, NULL, x509, privatekey, chain, override); 1155e71b7053SJung-uk Kim } 1156e71b7053SJung-uk Kim 1157e71b7053SJung-uk Kim int SSL_CTX_use_cert_and_key(SSL_CTX *ctx, X509 *x509, EVP_PKEY *privatekey, 1158e71b7053SJung-uk Kim STACK_OF(X509) *chain, int override) 1159e71b7053SJung-uk Kim { 1160e71b7053SJung-uk Kim return ssl_set_cert_and_key(NULL, ctx, x509, privatekey, chain, override); 1161e71b7053SJung-uk Kim } 1162