Fix seg fault with 0 p val in SKE
authorGuy Leaver (guleaver) <guleaver@cisco.com>
Fri, 7 Aug 2015 14:45:21 +0000 (15:45 +0100)
committerMatt Caswell <matt@openssl.org>
Tue, 11 Aug 2015 18:57:01 +0000 (19:57 +0100)
If a client receives a ServerKeyExchange for an anon DH ciphersuite with the
value of p set to 0 then a seg fault can occur. This commits adds a test to
reject p, g and pub key parameters that have a 0 value (in accordance with
RFC 5246)

The security vulnerability only affects master and 1.0.2, but the fix is
additionally applied to 1.0.1 for additional confidence.

CVE-2015-1794

Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
include/openssl/ssl.h
ssl/s3_clnt.c
ssl/ssl_err.c

index 4958e890b6f2439f506dc9ec1e7a3417c7bccca9..28c2fb98669a11ca4138b2630f64f0ac111acf3e 100644 (file)
@@ -2107,8 +2107,11 @@ void ERR_load_SSL_strings(void);
 # define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK              106
 # define SSL_R_BAD_DECOMPRESSION                          107
 # define SSL_R_BAD_DH_G_LENGTH                            108
+# define SSL_R_BAD_DH_G_VALUE                             375
 # define SSL_R_BAD_DH_PUB_KEY_LENGTH                      109
+# define SSL_R_BAD_DH_PUB_KEY_VALUE                       393
 # define SSL_R_BAD_DH_P_LENGTH                            110
+# define SSL_R_BAD_DH_P_VALUE                             395
 # define SSL_R_BAD_DIGEST_LENGTH                          111
 # define SSL_R_BAD_DSA_SIGNATURE                          112
 # define SSL_R_BAD_ECC_CERT                               304
index cd6918aa6b5dde1b14c443633be1dc5a1af2b510..1661b0ef8c7d2c2b5e2b913590cfe6ec4d68e40a 100644 (file)
@@ -1693,6 +1693,12 @@ int ssl3_get_key_exchange(SSL *s)
         }
         p += i;
 
+        if (BN_is_zero(dh->p)) {
+            SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_VALUE);
+            goto f_err;
+        }
+
+
         if (2 > n - param_len) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
@@ -1713,6 +1719,11 @@ int ssl3_get_key_exchange(SSL *s)
         }
         p += i;
 
+        if (BN_is_zero(dh->g)) {
+            SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE);
+            goto f_err;
+        }
+
         if (2 > n - param_len) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
@@ -1734,6 +1745,11 @@ int ssl3_get_key_exchange(SSL *s)
         p += i;
         n -= param_len;
 
+        if (BN_is_zero(dh->pub_key)) {
+            SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_PUB_KEY_VALUE);
+            goto f_err;
+        }
+
         if (!ssl_security(s, SSL_SECOP_TMP_DH, DH_security_bits(dh), 0, dh)) {
             al = SSL_AD_HANDSHAKE_FAILURE;
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_DH_KEY_TOO_SMALL);
index 2e1497bd85355121f5bf029195fbe09ff7743279..21836d831db32b15dd9bbbee9cbda63584a08442 100644 (file)
@@ -345,8 +345,11 @@ static ERR_STRING_DATA SSL_str_reasons[] = {
      "bad data returned by callback"},
     {ERR_REASON(SSL_R_BAD_DECOMPRESSION), "bad decompression"},
     {ERR_REASON(SSL_R_BAD_DH_G_LENGTH), "bad dh g length"},
+    {ERR_REASON(SSL_R_BAD_DH_G_VALUE), "bad dh g value"},
     {ERR_REASON(SSL_R_BAD_DH_PUB_KEY_LENGTH), "bad dh pub key length"},
+    {ERR_REASON(SSL_R_BAD_DH_PUB_KEY_VALUE), "bad dh pub key value"},
     {ERR_REASON(SSL_R_BAD_DH_P_LENGTH), "bad dh p length"},
+    {ERR_REASON(SSL_R_BAD_DH_P_VALUE), "bad dh p value"},
     {ERR_REASON(SSL_R_BAD_DIGEST_LENGTH), "bad digest length"},
     {ERR_REASON(SSL_R_BAD_DSA_SIGNATURE), "bad dsa signature"},
     {ERR_REASON(SSL_R_BAD_ECC_CERT), "bad ecc cert"},