[openssl-commits] [openssl] master update
Dr. Stephen Henson
steve at openssl.org
Wed Dec 23 22:30:11 UTC 2015
The branch master has been updated
via e2b420fdd708e14a0b43a21cd2377cafb0d54c02 (commit)
via 6c4e6670d7cb21401962a4c09cf073ac97485640 (commit)
via fb79abe3787a40998e305e2b8447df669afedd39 (commit)
via ffaef3f1526ed87a46f82fa4924d5b08f2a2e631 (commit)
from d938e8dfee16e6bb5427eac7bda32337634ce130 (commit)
- Log -----------------------------------------------------------------
commit e2b420fdd708e14a0b43a21cd2377cafb0d54c02
Author: Dr. Stephen Henson <steve at openssl.org>
Date: Thu Dec 17 00:05:26 2015 +0000
Server side EVP_PKEY DH support
Reviewed-by: Matt Caswell <matt at openssl.org>
commit 6c4e6670d7cb21401962a4c09cf073ac97485640
Author: Dr. Stephen Henson <steve at openssl.org>
Date: Fri Dec 18 15:58:28 2015 +0000
utility function
Reviewed-by: Matt Caswell <matt at openssl.org>
commit fb79abe3787a40998e305e2b8447df669afedd39
Author: Dr. Stephen Henson <steve at openssl.org>
Date: Thu Dec 17 01:07:46 2015 +0000
EVP_PKEY DH client support.
Reviewed-by: Matt Caswell <matt at openssl.org>
commit ffaef3f1526ed87a46f82fa4924d5b08f2a2e631
Author: Dr. Stephen Henson <steve at openssl.org>
Date: Thu Dec 17 02:57:20 2015 +0000
Always generate DH keys for ephemeral DH cipher suites.
Reviewed-by: Matt Caswell <matt at openssl.org>
-----------------------------------------------------------------------
Summary of changes:
doc/ssl/SSL_CTX_set_tmp_dh_callback.pod | 29 ++------
include/openssl/ssl.h | 6 +-
ssl/s3_lib.c | 116 +++++++++++++++-----------------
ssl/ssl_cert.c | 25 +------
ssl/ssl_locl.h | 8 +--
ssl/statem/statem_clnt.c | 89 +++++++++---------------
ssl/statem/statem_srvr.c | 106 +++++++++++++++--------------
7 files changed, 154 insertions(+), 225 deletions(-)
diff --git a/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod b/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod
index 3e08b88..57bf211 100644
--- a/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod
+++ b/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod
@@ -48,25 +48,8 @@ even if he gets hold of the normal (certified) key, as this key was
only used for signing.
In order to perform a DH key exchange the server must use a DH group
-(DH parameters) and generate a DH key.
-The server will always generate a new DH key during the negotiation
-if either the DH parameters are supplied via callback or the
-SSL_OP_SINGLE_DH_USE option of SSL_CTX_set_options(3) is set (or both).
-It will immediately create a DH key if DH parameters are supplied via
-SSL_CTX_set_tmp_dh() and SSL_OP_SINGLE_DH_USE is not set.
-In this case,
-it may happen that a key is generated on initialization without later
-being needed, while on the other hand the computer time during the
-negotiation is being saved.
-
-If "strong" primes were used to generate the DH parameters, it is not strictly
-necessary to generate a new key for each handshake but it does improve forward
-secrecy. If it is not assured that "strong" primes were used,
-SSL_OP_SINGLE_DH_USE must be used in order to prevent small subgroup
-attacks. Always using SSL_OP_SINGLE_DH_USE has an impact on the
-computer time needed during negotiation, but it is not very large, so
-application authors/users should consider always enabling this option.
-The option is required to implement perfect forward secrecy (PFS).
+(DH parameters) and generate a DH key. The server will always generate
+a new DH key during the negotiation.
As generating DH parameters is extremely time consuming, an application
should not generate the parameters on the fly but supply the parameters.
@@ -92,10 +75,9 @@ can supply the DH parameters via a callback function.
Previous versions of the callback used B<is_export> and B<keylength>
parameters to control parameter generation for export and non-export
cipher suites. Modern servers that do not support export ciphersuites
-are advised to either use SSL_CTX_set_tmp_dh() in combination with
-SSL_OP_SINGLE_DH_USE, or alternatively, use the callback but ignore
-B<keylength> and B<is_export> and simply supply at least 2048-bit
-parameters in the callback.
+are advised to either use SSL_CTX_set_tmp_dh() or alternatively, use
+the callback but ignore B<keylength> and B<is_export> and simply
+supply at least 2048-bit parameters in the callback.
=head1 EXAMPLES
@@ -127,7 +109,6 @@ partly left out.)
if (SSL_CTX_set_tmp_dh(ctx, dh_2048) != 1) {
/* Error. */
}
- SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);
...
=head1 RETURN VALUES
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index e841360..0b9e5d7 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -411,8 +411,8 @@ typedef int (*custom_ext_parse_cb) (SSL *s, unsigned int ext_type,
# define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x00040000U
/* Does nothing: retained for compatibility */
# define SSL_OP_SINGLE_ECDH_USE 0x0
-/* If set, always create a new key when using tmp_dh parameters */
-# define SSL_OP_SINGLE_DH_USE 0x00100000U
+/* Does nothing: retained for compatibility */
+# define SSL_OP_SINGLE_DH_USE 0x0
/* Does nothing: retained for compatibiity */
# define SSL_OP_EPHEMERAL_RSA 0x0
/*
@@ -1836,7 +1836,7 @@ __owur const char *SSL_CIPHER_standard_name(const SSL_CIPHER *c);
/* Sanity check of curve server selects */
# define SSL_SECOP_CURVE_CHECK (6 | SSL_SECOP_OTHER_CURVE)
/* Temporary DH key */
-# define SSL_SECOP_TMP_DH (7 | SSL_SECOP_OTHER_DH)
+# define SSL_SECOP_TMP_DH (7 | SSL_SECOP_OTHER_PKEY)
/* SSL/TLS version */
# define SSL_SECOP_VERSION (9 | SSL_SECOP_OTHER_NONE)
/* Session tickets */
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 4fc4426..848953a 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -3377,11 +3377,13 @@ void ssl3_free(SSL *s)
#ifndef OPENSSL_NO_DH
DH_free(s->s3->tmp.dh);
- DH_free(s->s3->peer_dh_tmp);
#endif
+
#ifndef OPENSSL_NO_EC
EVP_PKEY_free(s->s3->tmp.pkey);
s->s3->tmp.pkey = NULL;
+#endif
+#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)
EVP_PKEY_free(s->s3->peer_tmp);
s->s3->peer_tmp = NULL;
#endif
@@ -3414,15 +3416,15 @@ void ssl3_clear(SSL *s)
#ifndef OPENSSL_NO_DH
DH_free(s->s3->tmp.dh);
s->s3->tmp.dh = NULL;
- DH_free(s->s3->peer_dh_tmp);
- s->s3->peer_dh_tmp = NULL;
#endif
#ifndef OPENSSL_NO_EC
EVP_PKEY_free(s->s3->tmp.pkey);
s->s3->tmp.pkey = NULL;
+ s->s3->is_probably_safari = 0;
+#endif
+#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)
EVP_PKEY_free(s->s3->peer_tmp);
s->s3->peer_tmp = NULL;
- s->s3->is_probably_safari = 0;
#endif /* !OPENSSL_NO_EC */
ssl3_free_digest_list(s);
@@ -3486,28 +3488,24 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
case SSL_CTRL_SET_TMP_DH:
{
DH *dh = (DH *)parg;
+ EVP_PKEY *pkdh = NULL;
if (dh == NULL) {
SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER);
return (ret);
}
+ pkdh = ssl_dh_to_pkey(dh);
+ if (pkdh == NULL) {
+ SSLerr(SSL_F_SSL3_CTRL, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
if (!ssl_security(s, SSL_SECOP_TMP_DH,
- DH_security_bits(dh), 0, dh)) {
+ EVP_PKEY_security_bits(pkdh), 0, pkdh)) {
SSLerr(SSL_F_SSL3_CTRL, SSL_R_DH_KEY_TOO_SMALL);
- return (ret);
- }
- if ((dh = DHparams_dup(dh)) == NULL) {
- SSLerr(SSL_F_SSL3_CTRL, ERR_R_DH_LIB);
- return (ret);
+ EVP_PKEY_free(pkdh);
+ return ret;
}
- if (!(s->options & SSL_OP_SINGLE_DH_USE)) {
- if (!DH_generate_key(dh)) {
- DH_free(dh);
- SSLerr(SSL_F_SSL3_CTRL, ERR_R_DH_LIB);
- return (ret);
- }
- }
- DH_free(s->cert->dh_tmp);
- s->cert->dh_tmp = dh;
+ EVP_PKEY_free(s->cert->dh_tmp);
+ s->cert->dh_tmp = pkdh;
ret = 1;
}
break;
@@ -3766,34 +3764,17 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
return 0;
case SSL_CTRL_GET_SERVER_TMP_KEY:
- if (s->server || !s->session)
- return 0;
- else {
- EVP_PKEY *ptmp;
- int rv = 0;
-#if !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_EC)
- if (s->s3->peer_dh_tmp == NULL && s->s3->peer_tmp == NULL)
- return 0;
-#endif
- ptmp = EVP_PKEY_new();
- if (ptmp == NULL)
- return 0;
-#ifndef OPENSSL_NO_DH
- else if (s->s3->peer_dh_tmp != NULL)
- rv = EVP_PKEY_set1_DH(ptmp, s->s3->peer_dh_tmp);
-#endif
-#ifndef OPENSSL_NO_EC
- else if (s->s3->peer_tmp != NULL)
- rv = EVP_PKEY_set1_EC_KEY(ptmp,
- EVP_PKEY_get0_EC_KEY(s->s3->peer_tmp));
-#endif
- if (rv) {
- *(EVP_PKEY **)parg = ptmp;
- return 1;
- }
- EVP_PKEY_free(ptmp);
+#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC)
+ if (s->server || s->session == NULL || s->s3->peer_tmp == NULL) {
return 0;
+ } else {
+ EVP_PKEY_up_ref(s->s3->peer_tmp);
+ *(EVP_PKEY **)parg = s->s3->peer_tmp;
+ return 1;
}
+#else
+ return 0;
+#endif
#ifndef OPENSSL_NO_EC
case SSL_CTRL_GET_EC_POINT_FORMATS:
{
@@ -3873,29 +3854,25 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
#ifndef OPENSSL_NO_DH
case SSL_CTRL_SET_TMP_DH:
{
- DH *new = NULL, *dh;
- CERT *cert;
-
- cert = ctx->cert;
- dh = (DH *)parg;
- if (!ssl_ctx_security(ctx, SSL_SECOP_TMP_DH,
- DH_security_bits(dh), 0, dh)) {
- SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_DH_KEY_TOO_SMALL);
+ DH *dh = (DH *)parg;
+ EVP_PKEY *pkdh = NULL;
+ if (dh == NULL) {
+ SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
- if ((new = DHparams_dup(dh)) == NULL) {
- SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_DH_LIB);
+ pkdh = ssl_dh_to_pkey(dh);
+ if (pkdh == NULL) {
+ SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_MALLOC_FAILURE);
return 0;
}
- if (!(ctx->options & SSL_OP_SINGLE_DH_USE)) {
- if (!DH_generate_key(new)) {
- SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_DH_LIB);
- DH_free(new);
- return 0;
- }
+ if (!ssl_ctx_security(ctx, SSL_SECOP_TMP_DH,
+ EVP_PKEY_security_bits(pkdh), 0, pkdh)) {
+ SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_DH_KEY_TOO_SMALL);
+ EVP_PKEY_free(pkdh);
+ return 1;
}
- DH_free(cert->dh_tmp);
- cert->dh_tmp = new;
+ EVP_PKEY_free(ctx->cert->dh_tmp);
+ ctx->cert->dh_tmp = pkdh;
return 1;
}
/*
@@ -4663,3 +4640,16 @@ int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey)
EVP_PKEY_CTX_free(pctx);
return rv;
}
+
+EVP_PKEY *ssl_dh_to_pkey(DH *dh)
+{
+ EVP_PKEY *ret;
+ if (dh == NULL)
+ return NULL;
+ ret = EVP_PKEY_new();
+ if (EVP_PKEY_set1_DH(ret, dh) <= 0) {
+ EVP_PKEY_free(ret);
+ return NULL;
+ }
+ return ret;
+}
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index 41e34ce..f01d3a7 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -197,27 +197,8 @@ CERT *ssl_cert_dup(CERT *cert)
#ifndef OPENSSL_NO_DH
if (cert->dh_tmp != NULL) {
- ret->dh_tmp = DHparams_dup(cert->dh_tmp);
- if (ret->dh_tmp == NULL) {
- SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_DH_LIB);
- goto err;
- }
- if (cert->dh_tmp->priv_key) {
- BIGNUM *b = BN_dup(cert->dh_tmp->priv_key);
- if (!b) {
- SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
- goto err;
- }
- ret->dh_tmp->priv_key = b;
- }
- if (cert->dh_tmp->pub_key) {
- BIGNUM *b = BN_dup(cert->dh_tmp->pub_key);
- if (!b) {
- SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
- goto err;
- }
- ret->dh_tmp->pub_key = b;
- }
+ ret->dh_tmp = cert->dh_tmp;
+ EVP_PKEY_up_ref(ret->dh_tmp);
}
ret->dh_tmp_cb = cert->dh_tmp_cb;
ret->dh_tmp_auto = cert->dh_tmp_auto;
@@ -370,7 +351,7 @@ void ssl_cert_free(CERT *c)
#endif
#ifndef OPENSSL_NO_DH
- DH_free(c->dh_tmp);
+ EVP_PKEY_free(c->dh_tmp);
#endif
ssl_cert_clear_certs(c);
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 8a66789..4afb0d4 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -1327,10 +1327,7 @@ typedef struct ssl3_state_st {
# endif /* !OPENSSL_NO_EC */
/* For clients: peer temporary key */
-# ifndef OPENSSL_NO_DH
- DH *peer_dh_tmp;
-# endif
-# ifndef OPENSSL_NO_EC
+# if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)
EVP_PKEY *peer_tmp;
# endif
@@ -1492,7 +1489,7 @@ typedef struct cert_st {
*/
CERT_PKEY *key;
# ifndef OPENSSL_NO_DH
- DH *dh_tmp;
+ EVP_PKEY *dh_tmp;
DH *(*dh_tmp_cb) (SSL *ssl, int is_export, int keysize);
int dh_tmp_auto;
# endif
@@ -1862,6 +1859,7 @@ __owur int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen,
int free_pms);
__owur EVP_PKEY *ssl_generate_pkey(EVP_PKEY *pm, int nid);
__owur int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey);
+__owur EVP_PKEY *ssl_dh_to_pkey(DH *dh);
__owur const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p);
__owur int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p);
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index e7c9413..46cb4b0 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -1581,9 +1581,6 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
#ifndef OPENSSL_NO_RSA
RSA *rsa = NULL;
#endif
-#ifndef OPENSSL_NO_DH
- DH *dh = NULL;
-#endif
#ifndef OPENSSL_NO_EC
EVP_PKEY_CTX *pctx = NULL;
#endif
@@ -1600,11 +1597,7 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
save_param_start = *pkt;
-#ifndef OPENSSL_NO_DH
- DH_free(s->s3->peer_dh_tmp);
- s->s3->peer_dh_tmp = NULL;
-#endif
-#ifndef OPENSSL_NO_EC
+#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)
EVP_PKEY_free(s->s3->peer_tmp);
s->s3->peer_tmp = NULL;
#endif
@@ -1695,6 +1688,8 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) {
PACKET prime, generator, pub_key;
+ DH *dh;
+
if (!PACKET_get_length_prefixed_2(pkt, &prime)
|| !PACKET_get_length_prefixed_2(pkt, &generator)
|| !PACKET_get_length_prefixed_2(pkt, &pub_key)) {
@@ -1702,8 +1697,18 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
goto f_err;
}
- if ((dh = DH_new()) == NULL) {
- SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_DH_LIB);
+ s->s3->peer_tmp = EVP_PKEY_new();
+ dh = DH_new();
+
+ if (s->s3->peer_tmp == NULL || dh == NULL) {
+ SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
+ DH_free(dh);
+ goto err;
+ }
+
+ if (EVP_PKEY_assign_DH(s->s3->peer_tmp, dh) == 0) {
+ SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_EVP_LIB);
+ DH_free(dh);
goto err;
}
@@ -1731,9 +1736,6 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
if (alg_a & (SSL_aRSA|SSL_aDSS))
pkey = X509_get_pubkey(s->session->peer);
/* else anonymous DH, so no certificate or pkey. */
-
- s->s3->peer_dh_tmp = dh;
- dh = NULL;
}
#endif /* !OPENSSL_NO_DH */
@@ -1915,9 +1917,6 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
#ifndef OPENSSL_NO_RSA
RSA_free(rsa);
#endif
-#ifndef OPENSSL_NO_DH
- DH_free(dh);
-#endif
#ifndef OPENSSL_NO_EC
EVP_PKEY_CTX_free(pctx);
#endif
@@ -2243,8 +2242,10 @@ int tls_construct_client_key_exchange(SSL *s)
unsigned char *q;
EVP_PKEY *pkey = NULL;
#endif
-#ifndef OPENSSL_NO_EC
+#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)
EVP_PKEY *ckey = NULL, *skey = NULL;
+#endif
+#ifndef OPENSSL_NO_EC
unsigned char *encodedPoint = NULL;
int encoded_pt_len = 0;
#endif
@@ -2391,52 +2392,30 @@ psk_err:
#endif
#ifndef OPENSSL_NO_DH
else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) {
- DH *dh_srvr, *dh_clnt;
- if (s->s3->peer_dh_tmp == NULL) {
+ DH *dh_clnt = NULL;
+ skey = s->s3->peer_tmp;
+ if (skey == NULL) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
ERR_R_INTERNAL_ERROR);
goto err;
}
- dh_srvr = s->s3->peer_dh_tmp;
- /* generate a new random key */
- if ((dh_clnt = DHparams_dup(dh_srvr)) == NULL) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB);
- goto err;
- }
- if (!DH_generate_key(dh_clnt)) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB);
- DH_free(dh_clnt);
- goto err;
- }
-
- pmslen = DH_size(dh_clnt);
- pms = OPENSSL_malloc(pmslen);
- if (pms == NULL)
- goto memerr;
-
- /*
- * use the 'p' output buffer for the DH key, but make sure to
- * clear it out afterwards
- */
-
- n = DH_compute_key(pms, dh_srvr->pub_key, dh_clnt);
- if (s->s3->peer_dh_tmp == NULL)
- DH_free(dh_srvr);
+ ckey = ssl_generate_pkey(skey, NID_undef);
+ dh_clnt = EVP_PKEY_get0_DH(ckey);
- if (n <= 0) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB);
- DH_free(dh_clnt);
+ if (dh_clnt == NULL || ssl_derive(s, ckey, skey) == 0) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
+ ERR_R_INTERNAL_ERROR);
goto err;
}
- pmslen = n;
+
/* send off the data */
n = BN_num_bytes(dh_clnt->pub_key);
s2n(n, p);
BN_bn2bin(dh_clnt->pub_key, p);
n += 2;
-
- DH_free(dh_clnt);
+ EVP_PKEY_free(ckey);
+ ckey = NULL;
}
#endif
@@ -2666,6 +2645,8 @@ psk_err:
s->s3->tmp.pms = NULL;
#ifndef OPENSSL_NO_EC
OPENSSL_free(encodedPoint);
+#endif
+#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)
EVP_PKEY_free(ckey);
#endif
#ifndef OPENSSL_NO_PSK
@@ -2927,9 +2908,6 @@ int ssl3_check_cert_and_algorithm(SSL *s)
#endif
long alg_k, alg_a;
EVP_PKEY *pkey = NULL;
-#ifndef OPENSSL_NO_DH
- DH *dh;
-#endif
int al = SSL_AD_HANDSHAKE_FAILURE;
alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
@@ -2938,9 +2916,6 @@ int ssl3_check_cert_and_algorithm(SSL *s)
/* we don't have a certificate */
if ((alg_a & SSL_aNULL) || (alg_k & SSL_kPSK))
return (1);
-#ifndef OPENSSL_NO_DH
- dh = s->s3->peer_dh_tmp;
-#endif
/* This is the passed certificate */
@@ -2989,7 +2964,7 @@ int ssl3_check_cert_and_algorithm(SSL *s)
}
#endif
#ifndef OPENSSL_NO_DH
- if ((alg_k & SSL_kDHE) && (dh == NULL)) {
+ if ((alg_k & SSL_kDHE) && (s->s3->peer_tmp == NULL)) {
al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR);
goto f_err;
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
index b8b18b7..89f064c 100644
--- a/ssl/statem/statem_srvr.c
+++ b/ssl/statem/statem_srvr.c
@@ -1714,7 +1714,7 @@ int tls_construct_server_done(SSL *s)
int tls_construct_server_key_exchange(SSL *s)
{
#ifndef OPENSSL_NO_DH
- DH *dh = NULL, *dhp;
+ EVP_PKEY *pkdh = NULL;
#endif
#ifndef OPENSSL_NO_EC
unsigned char *encodedPoint = NULL;
@@ -1761,60 +1761,66 @@ int tls_construct_server_key_exchange(SSL *s)
if (type & (SSL_kDHE | SSL_kDHEPSK)) {
CERT *cert = s->cert;
+ EVP_PKEY *pkdhp = NULL;
+ DH *dh;
+
if (s->cert->dh_tmp_auto) {
- dhp = ssl_get_auto_dh(s);
- if (dhp == NULL) {
+ DH *dhp = ssl_get_auto_dh(s);
+ pkdh = EVP_PKEY_new();
+ if (pkdh == NULL || dhp == NULL) {
+ DH_free(dhp);
al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
ERR_R_INTERNAL_ERROR);
goto f_err;
}
- } else
- dhp = cert->dh_tmp;
- if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL))
- dhp = s->cert->dh_tmp_cb(s, 0, 1024);
- if (dhp == NULL) {
+ EVP_PKEY_assign_DH(pkdh, dhp);
+ pkdhp = pkdh;
+ } else {
+ pkdhp = cert->dh_tmp;
+ }
+ if ((pkdhp == NULL) && (s->cert->dh_tmp_cb != NULL)) {
+ DH *dhp = s->cert->dh_tmp_cb(s, 0, 1024);
+ pkdh = ssl_dh_to_pkey(dhp);
+ if (pkdh == NULL) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
+ ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ }
+ pkdhp = pkdh;
+ }
+ if (pkdhp == NULL) {
al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
SSL_R_MISSING_TMP_DH_KEY);
goto f_err;
}
if (!ssl_security(s, SSL_SECOP_TMP_DH,
- DH_security_bits(dhp), 0, dhp)) {
+ EVP_PKEY_security_bits(pkdhp), 0, pkdhp)) {
al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
SSL_R_DH_KEY_TOO_SMALL);
goto f_err;
}
- if (s->s3->tmp.dh != NULL) {
+ if (s->s3->tmp.pkey != NULL) {
SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
ERR_R_INTERNAL_ERROR);
goto err;
}
- if (s->cert->dh_tmp_auto)
- dh = dhp;
- else if ((dh = DHparams_dup(dhp)) == NULL) {
- SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_DH_LIB);
+ s->s3->tmp.pkey = ssl_generate_pkey(pkdhp, NID_undef);
+
+ if (s->s3->tmp.pkey == NULL) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_EVP_LIB);
goto err;
}
- s->s3->tmp.dh = dh;
- if ((dhp->pub_key == NULL ||
- dhp->priv_key == NULL ||
- (s->options & SSL_OP_SINGLE_DH_USE))) {
- if (!DH_generate_key(dh)) {
- SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_DH_LIB);
- goto err;
- }
- } else {
- dh->pub_key = BN_dup(dhp->pub_key);
- dh->priv_key = BN_dup(dhp->priv_key);
- if ((dh->pub_key == NULL) || (dh->priv_key == NULL)) {
- SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_DH_LIB);
- goto err;
- }
- }
+ dh = EVP_PKEY_get0_DH(s->s3->tmp.pkey);
+
+ EVP_PKEY_free(pkdh);
+ pkdh = NULL;
+
r[0] = dh->p;
r[1] = dh->g;
r[2] = dh->pub_key;
@@ -2029,6 +2035,9 @@ int tls_construct_server_key_exchange(SSL *s)
f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
err:
+#ifndef OPENSSL_NO_DH
+ EVP_PKEY_free(pkdh);
+#endif
#ifndef OPENSSL_NO_EC
OPENSSL_free(encodedPoint);
#endif
@@ -2118,10 +2127,6 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt)
RSA *rsa = NULL;
EVP_PKEY *pkey = NULL;
#endif
-#ifndef OPENSSL_NO_DH
- BIGNUM *pub = NULL;
- DH *dh_srvr;
-#endif
#ifndef OPENSSL_NO_EC
EVP_PKEY *ckey = NULL;
#endif
@@ -2345,7 +2350,8 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt)
#endif
#ifndef OPENSSL_NO_DH
if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) {
- unsigned char shared[(OPENSSL_DH_MAX_MODULUS_BITS + 7) / 8];
+ EVP_PKEY *skey = NULL;
+ DH *cdh;
if (!PACKET_get_net_2(pkt, &i)) {
if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) {
@@ -2361,13 +2367,13 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt)
SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG);
goto err;
}
- if (s->s3->tmp.dh == NULL) {
+ skey = s->s3->tmp.pkey;
+ if (skey == NULL) {
al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
SSL_R_MISSING_TMP_DH_KEY);
goto f_err;
- } else
- dh_srvr = s->s3->tmp.dh;
+ }
if (PACKET_remaining(pkt) == 0L) {
al = SSL_AD_HANDSHAKE_FAILURE;
@@ -2382,29 +2388,27 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt)
ERR_R_INTERNAL_ERROR);
goto f_err;
}
- pub = BN_bin2bn(data, i, NULL);
- if (pub == NULL) {
+ ckey = EVP_PKEY_new();
+ if (ckey == NULL || EVP_PKEY_copy_parameters(ckey, skey) == 0) {
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_BN_LIB);
goto err;
}
-
- i = DH_compute_key(shared, pub, dh_srvr);
-
- if (i <= 0) {
- SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB);
- BN_clear_free(pub);
+ cdh = EVP_PKEY_get0_DH(ckey);
+ cdh->pub_key = BN_bin2bn(data, i, NULL);
+ if (cdh->pub_key == NULL) {
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_BN_LIB);
goto err;
}
- DH_free(s->s3->tmp.dh);
- s->s3->tmp.dh = NULL;
- BN_clear_free(pub);
- pub = NULL;
- if (!ssl_generate_master_secret(s, shared, i, 0)) {
+ if (ssl_derive(s, skey, ckey) == 0) {
al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
goto f_err;
}
+
+ EVP_PKEY_free(ckey);
+ ckey = NULL;
+
} else
#endif
More information about the openssl-commits
mailing list