Commit 61e72d76 authored by Guy Leaver (guleaver)'s avatar Guy Leaver (guleaver) Committed by Matt Caswell
Browse files

Fix seg fault with 0 p val in SKE



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: default avatarRichard Levitte <levitte@openssl.org>
Reviewed-by: default avatarMatt Caswell <matt@openssl.org>
parent 870063c8
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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
+16 −0
Original line number Diff line number Diff line
@@ -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);
+3 −0
Original line number Diff line number Diff line
@@ -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"},