summaryrefslogtreecommitdiff
path: root/src/openvpn/ssl_openssl.c
diff options
context:
space:
mode:
authorAlberto Gonzalez Iniesta <agi@inittab.org>2017-06-22 13:16:46 +0200
committerAlberto Gonzalez Iniesta <agi@inittab.org>2017-06-22 13:16:46 +0200
commit9683f890944ffb114f5f8214f694e0b339cf5a5a (patch)
treefa391f5f343554b2861b1f8722d0a2a627e1c1fc /src/openvpn/ssl_openssl.c
parent3a2bbdb05ca6a6996e424c9fb225cb0d53804125 (diff)
New upstream version 2.4.3upstream/2.4.3
Diffstat (limited to 'src/openvpn/ssl_openssl.c')
-rw-r--r--src/openvpn/ssl_openssl.c107
1 files changed, 63 insertions, 44 deletions
diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
index eae1e22..e589dcd 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -17,10 +17,9 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/**
@@ -45,6 +44,7 @@
#include "ssl_backend.h"
#include "ssl_common.h"
#include "base64.h"
+#include "openssl_compat.h"
#ifdef ENABLE_CRYPTOAPI
#include "cryptoapi.h"
@@ -321,7 +321,8 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
/* Translate IANA cipher suite names to OpenSSL names */
begin_of_cipher = end_of_cipher = 0;
- for (; begin_of_cipher < strlen(ciphers); begin_of_cipher = end_of_cipher) {
+ for (; begin_of_cipher < strlen(ciphers); begin_of_cipher = end_of_cipher)
+ {
end_of_cipher += strcspn(&ciphers[begin_of_cipher], ":");
cipher_pair = tls_get_cipher_name_pair(&ciphers[begin_of_cipher], end_of_cipher - begin_of_cipher);
@@ -353,7 +354,8 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
}
/* Make sure new cipher name fits in cipher string */
- if (((sizeof(openssl_ciphers)-1) - openssl_ciphers_len) < current_cipher_len)
+ if ((SIZE_MAX - openssl_ciphers_len) < current_cipher_len
+ || ((sizeof(openssl_ciphers)-1) < openssl_ciphers_len + current_cipher_len))
{
msg(M_FATAL,
"Failed to set restricted TLS cipher list, too long (>%d).",
@@ -507,10 +509,18 @@ tls_ctx_load_ecdh_params(struct tls_root_ctx *ctx, const char *curve_name
const EC_GROUP *ecgrp = NULL;
EVP_PKEY *pkey = NULL;
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER)
+ pkey = SSL_CTX_get0_privatekey(ctx->ctx);
+#else
/* Little hack to get private key ref from SSL_CTX, yay OpenSSL... */
- SSL ssl;
- ssl.cert = ctx->ctx->cert;
- pkey = SSL_get_privatekey(&ssl);
+ SSL *ssl = SSL_new(ctx->ctx);
+ if (!ssl)
+ {
+ crypto_msg(M_FATAL, "SSL_new failed");
+ }
+ pkey = SSL_get_privatekey(ssl);
+ SSL_free(ssl);
+#endif
msg(D_TLS_DEBUG, "Extracting ECDH curve from private key");
@@ -649,7 +659,8 @@ tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file,
{
for (i = 0; i < sk_X509_num(ca); i++)
{
- if (!X509_STORE_add_cert(ctx->ctx->cert_store,sk_X509_value(ca, i)))
+ X509_STORE *cert_store = SSL_CTX_get_cert_store(ctx->ctx);
+ if (!X509_STORE_add_cert(cert_store,sk_X509_value(ca, i)))
{
crypto_msg(M_FATAL,"Cannot add certificate to certificate chain (X509_STORE_add_cert)");
}
@@ -751,8 +762,9 @@ tls_ctx_load_cert_file_and_copy(struct tls_root_ctx *ctx,
goto end;
}
- x = PEM_read_bio_X509(in, NULL, ctx->ctx->default_passwd_callback,
- ctx->ctx->default_passwd_callback_userdata);
+ x = PEM_read_bio_X509(in, NULL,
+ SSL_CTX_get_default_passwd_cb(ctx->ctx),
+ SSL_CTX_get_default_passwd_cb_userdata(ctx->ctx));
if (x == NULL)
{
SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_PEM_LIB);
@@ -834,8 +846,8 @@ tls_ctx_load_priv_file(struct tls_root_ctx *ctx, const char *priv_key_file,
}
pkey = PEM_read_bio_PrivateKey(in, NULL,
- ssl_ctx->default_passwd_callback,
- ssl_ctx->default_passwd_callback_userdata);
+ SSL_CTX_get_default_passwd_cb(ctx->ctx),
+ SSL_CTX_get_default_passwd_cb_userdata(ctx->ctx));
if (!pkey)
{
goto end;
@@ -888,15 +900,15 @@ backend_tls_ctx_reload_crl(struct tls_root_ctx *ssl_ctx, const char *crl_file,
/* Always start with a cleared CRL list, for that we
* we need to manually find the CRL object from the stack
* and remove it */
- for (int i = 0; i < sk_X509_OBJECT_num(store->objs); i++)
+ STACK_OF(X509_OBJECT) *objs = X509_STORE_get0_objects(store);
+ for (int i = 0; i < sk_X509_OBJECT_num(objs); i++)
{
- X509_OBJECT *obj = sk_X509_OBJECT_value(store->objs, i);
+ X509_OBJECT *obj = sk_X509_OBJECT_value(objs, i);
ASSERT(obj);
- if (obj->type == X509_LU_CRL)
+ if (X509_OBJECT_get_type(obj) == X509_LU_CRL)
{
- sk_X509_OBJECT_delete(store->objs, i);
- X509_OBJECT_free_contents(obj);
- OPENSSL_free(obj);
+ sk_X509_OBJECT_delete(objs, i);
+ X509_OBJECT_free(obj);
}
}
@@ -964,10 +976,13 @@ rsa_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i
/* called at RSA_free */
static int
-rsa_finish(RSA *rsa)
+openvpn_extkey_rsa_finish(RSA *rsa)
{
- free((void *)rsa->meth);
- rsa->meth = NULL;
+ /* meth was allocated in tls_ctx_use_external_private_key() ; since
+ * this function is called when the parent RSA object is destroyed,
+ * it is no longer used after this point so kill it. */
+ const RSA_METHOD *meth = RSA_get_method(rsa);
+ RSA_meth_free((RSA_METHOD *)meth);
return 1;
}
@@ -983,7 +998,7 @@ rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i
if (padding != RSA_PKCS1_PADDING)
{
- RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
+ RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
goto done;
}
@@ -1041,16 +1056,16 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
ASSERT(NULL != cert);
/* allocate custom RSA method object */
- ALLOC_OBJ_CLEAR(rsa_meth, RSA_METHOD);
- rsa_meth->name = "OpenVPN external private key RSA Method";
- rsa_meth->rsa_pub_enc = rsa_pub_enc;
- rsa_meth->rsa_pub_dec = rsa_pub_dec;
- rsa_meth->rsa_priv_enc = rsa_priv_enc;
- rsa_meth->rsa_priv_dec = rsa_priv_dec;
- rsa_meth->init = NULL;
- rsa_meth->finish = rsa_finish;
- rsa_meth->flags = RSA_METHOD_FLAG_NO_CHECK;
- rsa_meth->app_data = NULL;
+ rsa_meth = RSA_meth_new("OpenVPN external private key RSA Method",
+ RSA_METHOD_FLAG_NO_CHECK);
+ check_malloc_return(rsa_meth);
+ RSA_meth_set_pub_enc(rsa_meth, rsa_pub_enc);
+ RSA_meth_set_pub_dec(rsa_meth, rsa_pub_dec);
+ RSA_meth_set_priv_enc(rsa_meth, rsa_priv_enc);
+ RSA_meth_set_priv_dec(rsa_meth, rsa_priv_dec);
+ RSA_meth_set_init(rsa_meth, NULL);
+ RSA_meth_set_finish(rsa_meth, openvpn_extkey_rsa_finish);
+ RSA_meth_set0_app_data(rsa_meth, NULL);
/* allocate RSA object */
rsa = RSA_new();
@@ -1061,12 +1076,16 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
}
/* get the public key */
- ASSERT(cert->cert_info->key->pkey); /* NULL before SSL_CTX_use_certificate() is called */
- pub_rsa = cert->cert_info->key->pkey->pkey.rsa;
+ EVP_PKEY *pkey = X509_get0_pubkey(cert);
+ ASSERT(pkey); /* NULL before SSL_CTX_use_certificate() is called */
+ pub_rsa = EVP_PKEY_get0_RSA(pkey);
/* initialize RSA object */
- rsa->n = BN_dup(pub_rsa->n);
- rsa->flags |= RSA_FLAG_EXT_PKEY;
+ const BIGNUM *n = NULL;
+ const BIGNUM *e = NULL;
+ RSA_get0_key(pub_rsa, &n, &e, NULL);
+ RSA_set0_key(rsa, BN_dup(n), BN_dup(e), NULL);
+ RSA_set_flags(rsa, RSA_flags(rsa) | RSA_FLAG_EXT_PKEY);
if (!RSA_set_method(rsa, rsa_meth))
{
goto err;
@@ -1667,17 +1686,17 @@ print_details(struct key_state_ssl *ks_ssl, const char *prefix)
EVP_PKEY *pkey = X509_get_pubkey(cert);
if (pkey != NULL)
{
- if (pkey->type == EVP_PKEY_RSA && pkey->pkey.rsa != NULL
- && pkey->pkey.rsa->n != NULL)
+ if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA && EVP_PKEY_get0_RSA(pkey) != NULL)
{
+ RSA *rsa = EVP_PKEY_get0_RSA(pkey);
openvpn_snprintf(s2, sizeof(s2), ", %d bit RSA",
- BN_num_bits(pkey->pkey.rsa->n));
+ RSA_bits(rsa));
}
- else if (pkey->type == EVP_PKEY_DSA && pkey->pkey.dsa != NULL
- && pkey->pkey.dsa->p != NULL)
+ else if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA && EVP_PKEY_get0_DSA(pkey) != NULL)
{
+ DSA *dsa = EVP_PKEY_get0_DSA(pkey);
openvpn_snprintf(s2, sizeof(s2), ", %d bit DSA",
- BN_num_bits(pkey->pkey.dsa->p));
+ DSA_bits(dsa));
}
EVP_PKEY_free(pkey);
}