summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2020-10-15 16:45:54 +0100
committerMatt Caswell <matt@openssl.org>2020-11-18 14:14:52 +0000
commit163f6dc1f70f30de46a68137c36e70cae4d95cd8 (patch)
treec7f1c37b230a8f226b716b65736c2b1cb236cfd4
parent9912be1b33bf2a65672d70ad75e07e0d63d33df3 (diff)
Implement a replacement for SSL_set_tmp_dh()
The old function took a DH as a parameter. In the new version we pass an EVP_PKEY instead. Similarly for the SSL_CTX version of this function. Reviewed-by: Richard Levitte <levitte@openssl.org> (Merged from https://github.com/openssl/openssl/pull/13368)
-rw-r--r--apps/s_server.c87
-rw-r--r--include/openssl/ssl.h.in3
-rw-r--r--ssl/s3_lib.c20
-rw-r--r--ssl/ssl_conf.c48
-rw-r--r--ssl/ssl_lib.c26
-rw-r--r--ssl/tls_depr.c4
-rw-r--r--util/libssl.num2
7 files changed, 102 insertions, 88 deletions
diff --git a/apps/s_server.c b/apps/s_server.c
index 18d0fad174..839d9320ff 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -21,6 +21,7 @@
#include <openssl/e_os2.h>
#include <openssl/async.h>
#include <openssl/ssl.h>
+#include <openssl/decoder.h>
#ifndef OPENSSL_NO_SOCK
@@ -71,9 +72,6 @@ static int generate_session_id(SSL *ssl, unsigned char *id,
unsigned int *id_len);
static void init_session_cache_ctx(SSL_CTX *sctx);
static void free_sessions(void);
-#ifndef OPENSSL_NO_DH
-static DH *load_dh_param(const char *dhfile);
-#endif
static void print_connection_info(SSL *con);
static const int bufsize = 16 * 1024;
@@ -2030,62 +2028,67 @@ int s_server_main(int argc, char *argv[])
if (alpn_ctx.data)
SSL_CTX_set_alpn_select_cb(ctx, alpn_cb, &alpn_ctx);
-#ifndef OPENSSL_NO_DH
if (!no_dhe) {
- DH *dh = NULL;
+ EVP_PKEY *dhpkey = NULL;
if (dhfile != NULL)
- dh = load_dh_param(dhfile);
+ dhpkey = load_keyparams(dhfile, 0, "DH", "DH parameters");
else if (s_cert_file != NULL)
- dh = load_dh_param(s_cert_file);
+ dhpkey = load_keyparams(s_cert_file, 0, "DH", "DH parameters");
- if (dh != NULL) {
+ if (dhpkey != NULL) {
BIO_printf(bio_s_out, "Setting temp DH parameters\n");
} else {
BIO_printf(bio_s_out, "Using default temp DH parameters\n");
}
(void)BIO_flush(bio_s_out);
- if (dh == NULL) {
+ if (dhpkey == NULL) {
SSL_CTX_set_dh_auto(ctx, 1);
+ } else {
+ /*
+ * We need 2 references: one for use by ctx and one for use by
+ * ctx2
+ */
+ if (!EVP_PKEY_up_ref(dhpkey)) {
+ EVP_PKEY_free(dhpkey);
+ goto end;
+ }
+ if (!SSL_CTX_set0_tmp_dh_pkey(ctx, dhpkey)) {
+ BIO_puts(bio_err, "Error setting temp DH parameters\n");
+ ERR_print_errors(bio_err);
+ /* Free 2 references */
+ EVP_PKEY_free(dhpkey);
+ EVP_PKEY_free(dhpkey);
+ goto end;
+ }
}
-# ifndef OPENSSL_NO_DEPRECATED_3_0
- /* TODO(3.0): We need a 3.0 friendly way of doing this */
- else if (!SSL_CTX_set_tmp_dh(ctx, dh)) {
- BIO_puts(bio_err, "Error setting temp DH parameters\n");
- ERR_print_errors(bio_err);
- DH_free(dh);
- goto end;
- }
-# endif
if (ctx2 != NULL) {
- if (!dhfile) {
- DH *dh2 = load_dh_param(s_cert_file2);
- if (dh2 != NULL) {
+ if (dhfile != NULL) {
+ EVP_PKEY *dhpkey2 = load_keyparams(s_cert_file2, 0, "DH",
+ "DH parameters");
+
+ if (dhpkey2 != NULL) {
BIO_printf(bio_s_out, "Setting temp DH parameters\n");
(void)BIO_flush(bio_s_out);
- DH_free(dh);
- dh = dh2;
+ EVP_PKEY_free(dhpkey);
+ dhpkey = dhpkey2;
}
}
- if (dh == NULL) {
+ if (dhpkey == NULL) {
SSL_CTX_set_dh_auto(ctx2, 1);
- }
-# ifndef OPENSSL_NO_DEPRECATED_3_0
- /* TODO(3.0): We need a 3.0 friendly way of doing this */
- else if (!SSL_CTX_set_tmp_dh(ctx2, dh)) {
+ } else if (!SSL_CTX_set0_tmp_dh_pkey(ctx2, dhpkey)) {
BIO_puts(bio_err, "Error setting temp DH parameters\n");
ERR_print_errors(bio_err);
- DH_free(dh);
+ EVP_PKEY_free(dhpkey);
goto end;
}
-# endif
+ dhpkey = NULL;
}
- DH_free(dh);
+ EVP_PKEY_free(dhpkey);
}
-#endif
if (!set_cert_key_stuff(ctx, s_cert, s_key, s_chain, build_chain))
goto end;
@@ -3011,26 +3014,6 @@ static void print_connection_info(SSL *con)
(void)BIO_flush(bio_s_out);
}
-#ifndef OPENSSL_NO_DH
-static DH *load_dh_param(const char *dhfile)
-{
-# ifndef OPENSSL_NO_DEPRECATED_3_0
- /* TODO(3.0): Use a decoder for this */
- DH *ret = NULL;
- BIO *bio;
-
- if ((bio = BIO_new_file(dhfile, "r")) == NULL)
- goto err;
- ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
- err:
- BIO_free(bio);
- return ret;
-# else
- return NULL;
-# endif
-}
-#endif
-
static int www_body(int s, int stype, int prot, unsigned char *context)
{
char *buf = NULL;
diff --git a/include/openssl/ssl.h.in b/include/openssl/ssl.h.in
index cd3abd8c26..a02227be0c 100644
--- a/include/openssl/ssl.h.in
+++ b/include/openssl/ssl.h.in
@@ -1505,6 +1505,9 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
# define SSL_get_server_tmp_key(s, pk) \
SSL_get_peer_tmp_key(s, pk)
+int SSL_set0_tmp_dh_pkey(SSL *s, EVP_PKEY *dhpkey);
+int SSL_CTX_set0_tmp_dh_pkey(SSL_CTX *ctx, EVP_PKEY *dhpkey);
+
/*
* The following symbol names are old and obsolete. They are kept
* for compatibility reasons only and should not be used anymore.
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 664844302a..8a572b8dd3 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -3465,15 +3465,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
- if (!ssl_security(s, SSL_SECOP_TMP_DH,
- EVP_PKEY_security_bits(pkdh), 0, pkdh)) {
- ERR_raise(ERR_LIB_SSL, SSL_R_DH_KEY_TOO_SMALL);
- EVP_PKEY_free(pkdh);
- return 0;
- }
- EVP_PKEY_free(s->cert->dh_tmp);
- s->cert->dh_tmp = pkdh;
- return 1;
+ return SSL_set0_tmp_dh_pkey(s, pkdh);
}
break;
case SSL_CTRL_SET_TMP_DH_CB:
@@ -3816,15 +3808,7 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
- if (!ssl_ctx_security(ctx, SSL_SECOP_TMP_DH,
- EVP_PKEY_security_bits(pkdh), 0, pkdh)) {
- ERR_raise(ERR_LIB_SSL, SSL_R_DH_KEY_TOO_SMALL);
- EVP_PKEY_free(pkdh);
- return 0;
- }
- EVP_PKEY_free(ctx->cert->dh_tmp);
- ctx->cert->dh_tmp = pkdh;
- return 1;
+ return SSL_CTX_set0_tmp_dh_pkey(ctx, pkdh);
}
case SSL_CTRL_SET_TMP_DH_CB:
{
diff --git a/ssl/ssl_conf.c b/ssl/ssl_conf.c
index 2311df5d84..2e8240c73b 100644
--- a/ssl/ssl_conf.c
+++ b/ssl/ssl_conf.c
@@ -11,7 +11,8 @@
#include "ssl_local.h"
#include <openssl/conf.h>
#include <openssl/objects.h>
-#include <openssl/dh.h>
+#include <openssl/decoder.h>
+#include <openssl/core_dispatch.h>
#include "internal/nelem.h"
/*
@@ -574,34 +575,51 @@ static int cmd_ClientCAStore(SSL_CONF_CTX *cctx, const char *value)
return cmd_RequestCAStore(cctx, value);
}
-#if !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_DEPRECATED_3_0)
-/* TODO(3.0): We need a 3.0 friendly way of doing this */
static int cmd_DHParameters(SSL_CONF_CTX *cctx, const char *value)
{
int rv = 0;
- DH *dh = NULL;
+ EVP_PKEY *dhpkey = NULL;
BIO *in = NULL;
- if (cctx->ctx || cctx->ssl) {
+ SSL_CTX *sslctx = (cctx->ssl != NULL) ? cctx->ssl->ctx : cctx->ctx;
+ OSSL_DECODER_CTX *decoderctx = NULL;
+
+ if (cctx->ctx != NULL || cctx->ssl != NULL) {
in = BIO_new(BIO_s_file());
if (in == NULL)
goto end;
if (BIO_read_filename(in, value) <= 0)
goto end;
- dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
- if (dh == NULL)
+
+ decoderctx
+ = OSSL_DECODER_CTX_new_by_EVP_PKEY(&dhpkey, "PEM", NULL, "DH",
+ OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+ sslctx->libctx, sslctx->propq);
+ if (decoderctx == NULL
+ || !OSSL_DECODER_from_bio(decoderctx, in)) {
+ OSSL_DECODER_CTX_free(decoderctx);
+ goto end;
+ }
+ OSSL_DECODER_CTX_free(decoderctx);
+
+ if (dhpkey == NULL)
goto end;
- } else
+ } else {
return 1;
- if (cctx->ctx)
- rv = SSL_CTX_set_tmp_dh(cctx->ctx, dh);
- if (cctx->ssl)
- rv = SSL_set_tmp_dh(cctx->ssl, dh);
+ }
+
+ if (cctx->ctx != NULL) {
+ if ((rv = SSL_CTX_set0_tmp_dh_pkey(cctx->ctx, dhpkey)) > 0)
+ dhpkey = NULL;
+ }
+ if (cctx->ssl != NULL) {
+ if ((rv = SSL_set0_tmp_dh_pkey(cctx->ssl, dhpkey)) > 0)
+ dhpkey = NULL;
+ }
end:
- DH_free(dh);
+ EVP_PKEY_free(dhpkey);
BIO_free(in);
return rv > 0;
}
-#endif
static int cmd_RecordPadding(SSL_CONF_CTX *cctx, const char *value)
{
@@ -727,11 +745,9 @@ static const ssl_conf_cmd_tbl ssl_conf_cmds[] = {
SSL_CONF_CMD(ClientCAStore, NULL,
SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
SSL_CONF_TYPE_STORE),
-#if !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_DEPRECATED_3_0)
SSL_CONF_CMD(DHParameters, "dhparam",
SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
SSL_CONF_TYPE_FILE),
-#endif
SSL_CONF_CMD_STRING(RecordPadding, "record_padding", 0),
SSL_CONF_CMD_STRING(NumTickets, "num_tickets", SSL_CONF_FLAG_SERVER),
};
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index bd7b838250..8f6771da3d 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -5955,3 +5955,29 @@ void ssl_evp_md_free(const EVP_MD *md)
EVP_MD_free((EVP_MD *)md);
}
}
+
+int SSL_set0_tmp_dh_pkey(SSL *s, EVP_PKEY *dhpkey)
+{
+ if (!ssl_security(s, SSL_SECOP_TMP_DH,
+ EVP_PKEY_security_bits(dhpkey), 0, dhpkey)) {
+ SSLerr(0, SSL_R_DH_KEY_TOO_SMALL);
+ EVP_PKEY_free(dhpkey);
+ return 0;
+ }
+ EVP_PKEY_free(s->cert->dh_tmp);
+ s->cert->dh_tmp = dhpkey;
+ return 1;
+}
+
+int SSL_CTX_set0_tmp_dh_pkey(SSL_CTX *ctx, EVP_PKEY *dhpkey)
+{
+ if (!ssl_ctx_security(ctx, SSL_SECOP_TMP_DH,
+ EVP_PKEY_security_bits(dhpkey), 0, dhpkey)) {
+ SSLerr(0, SSL_R_DH_KEY_TOO_SMALL);
+ EVP_PKEY_free(dhpkey);
+ return 0;
+ }
+ EVP_PKEY_free(ctx->cert->dh_tmp);
+ ctx->cert->dh_tmp = dhpkey;
+ return 1;
+}
diff --git a/ssl/tls_depr.c b/ssl/tls_depr.c
index 1ed47dd8de..6f2103ad91 100644
--- a/ssl/tls_depr.c
+++ b/ssl/tls_depr.c
@@ -144,7 +144,7 @@ HMAC_CTX *ssl_hmac_get0_HMAC_CTX(SSL_HMAC *ctx)
}
/* Some deprecated public APIs pass DH objects */
-#ifndef OPENSSL_NO_DH
+# ifndef OPENSSL_NO_DH
EVP_PKEY *ssl_dh_to_pkey(DH *dh)
{
EVP_PKEY *ret;
@@ -158,6 +158,6 @@ EVP_PKEY *ssl_dh_to_pkey(DH *dh)
}
return ret;
}
-#endif
+# endif
#endif
diff --git a/util/libssl.num b/util/libssl.num
index 8b22c719e6..75e45bb17f 100644
--- a/util/libssl.num
+++ b/util/libssl.num
@@ -517,3 +517,5 @@ SSL_new_session_ticket ? 3_0_0 EXIST::FUNCTION:
SSL_get0_peer_certificate ? 3_0_0 EXIST::FUNCTION:
SSL_get1_peer_certificate ? 3_0_0 EXIST::FUNCTION:
SSL_load_client_CA_file_ex ? 3_0_0 EXIST::FUNCTION:
+SSL_set0_tmp_dh_pkey ? 3_0_0 EXIST::FUNCTION:
+SSL_CTX_set0_tmp_dh_pkey ? 3_0_0 EXIST::FUNCTION: