ECDH downgrade bug fix.
[openssl.git] / ssl / s3_clnt.c
index 4ca2774f233408038cc63a75231d1eb072913ffb..2313fbc1e749c94003330c6d12812b0f7997b5a2 100644 (file)
@@ -1376,6 +1376,8 @@ int ssl3_get_key_exchange(SSL *s)
        int encoded_pt_len = 0;
 #endif
 
        int encoded_pt_len = 0;
 #endif
 
+       EVP_MD_CTX_init(&md_ctx);
+
        /* use same message size as in ssl3_get_certificate_request()
         * as ServerKeyExchange message may be skipped */
        n=s->method->ssl_get_message(s,
        /* use same message size as in ssl3_get_certificate_request()
         * as ServerKeyExchange message may be skipped */
        n=s->method->ssl_get_message(s,
@@ -1386,14 +1388,26 @@ int ssl3_get_key_exchange(SSL *s)
                &ok);
        if (!ok) return((int)n);
 
                &ok);
        if (!ok) return((int)n);
 
+       alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
+
        if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE)
                {
        if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE)
                {
+               /*
+                * Can't skip server key exchange if this is an ephemeral
+                * ciphersuite.
+                */
+               if (alg_k & (SSL_kDHE|SSL_kECDHE))
+                       {
+                       SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE);
+                       al = SSL_AD_UNEXPECTED_MESSAGE;
+                       goto f_err;
+                       }
 #ifndef OPENSSL_NO_PSK
                /* In plain PSK ciphersuite, ServerKeyExchange can be
                   omitted if no identity hint is sent. Set
                   session->sess_cert anyway to avoid problems
                   later.*/
 #ifndef OPENSSL_NO_PSK
                /* In plain PSK ciphersuite, ServerKeyExchange can be
                   omitted if no identity hint is sent. Set
                   session->sess_cert anyway to avoid problems
                   later.*/
-               if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)
+               if (alg_k & SSL_kPSK)
                        {
                        s->session->sess_cert=ssl_sess_cert_new();
                        if (s->ctx->psk_identity_hint)
                        {
                        s->session->sess_cert=ssl_sess_cert_new();
                        if (s->ctx->psk_identity_hint)
@@ -1438,9 +1452,7 @@ int ssl3_get_key_exchange(SSL *s)
        /* Total length of the parameters including the length prefix */
        param_len=0;
 
        /* Total length of the parameters including the length prefix */
        param_len=0;
 
-       alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
        alg_a=s->s3->tmp.new_cipher->algorithm_auth;
        alg_a=s->s3->tmp.new_cipher->algorithm_auth;
-       EVP_MD_CTX_init(&md_ctx);
 
        al=SSL_AD_DECODE_ERROR;
 
 
        al=SSL_AD_DECODE_ERROR;