Commit 1a08063a authored by Emilia Kasper's avatar Emilia Kasper Committed by Matt Caswell
Browse files

Fix reachable assert in SSLv2 servers.



This assert is reachable for servers that support SSLv2 and export ciphers.
Therefore, such servers can be DoSed by sending a specially crafted
SSLv2 CLIENT-MASTER-KEY.

Also fix s2_srvr.c to error out early if the key lengths are malformed.
These lengths are sent unencrypted, so this does not introduce an oracle.

CVE-2015-0293

This issue was discovered by Sean Burford (Google) and Emilia Käsper of
the OpenSSL development team.

Reviewed-by: default avatarRichard Levitte <levitte@openssl.org>
Reviewed-by: default avatarTim Hudson <tjh@openssl.org>
parent 9104dc42
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -496,7 +496,7 @@ int ssl2_generate_key_material(SSL *s)

        OPENSSL_assert(s->session->master_key_length >= 0
                       && s->session->master_key_length
                       < (int)sizeof(s->session->master_key));
                       <= (int)sizeof(s->session->master_key));
        EVP_DigestUpdate(&ctx, s->session->master_key,
                         s->session->master_key_length);
        EVP_DigestUpdate(&ctx, &c, 1);
+45 −12
Original line number Diff line number Diff line
@@ -454,11 +454,6 @@ static int get_client_master_key(SSL *s)
        SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_NO_PRIVATEKEY);
        return (-1);
    }
    i = ssl_rsa_private_decrypt(s->cert, s->s2->tmp.enc,
                                &(p[s->s2->tmp.clear]),
                                &(p[s->s2->tmp.clear]),
                                (s->s2->ssl2_rollback) ? RSA_SSLV23_PADDING :
                                RSA_PKCS1_PADDING);

    is_export = SSL_C_IS_EXPORT(s->session->cipher);

@@ -475,23 +470,61 @@ static int get_client_master_key(SSL *s)
    } else
        ek = 5;

    /*
     * The format of the CLIENT-MASTER-KEY message is
     * 1 byte message type
     * 3 bytes cipher
     * 2-byte clear key length (stored in s->s2->tmp.clear)
     * 2-byte encrypted key length (stored in s->s2->tmp.enc)
     * 2-byte key args length (IV etc)
     * clear key
     * encrypted key
     * key args
     *
     * If the cipher is an export cipher, then the encrypted key bytes
     * are a fixed portion of the total key (5 or 8 bytes). The size of
     * this portion is in |ek|. If the cipher is not an export cipher,
     * then the entire key material is encrypted (i.e., clear key length
     * must be zero).
     */
    if ((!is_export && s->s2->tmp.clear != 0) ||
        (is_export && s->s2->tmp.clear + ek != EVP_CIPHER_key_length(c))) {
        ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
        SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_BAD_LENGTH);
        return -1;
    }
    /*
     * The encrypted blob must decrypt to the encrypted portion of the key.
     * Decryption can't be expanding, so if we don't have enough encrypted
     * bytes to fit the key in the buffer, stop now.
     */
    if ((is_export && s->s2->tmp.enc < ek) ||
        (!is_export && s->s2->tmp.enc < EVP_CIPHER_key_length(c))) {
        ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_LENGTH_TOO_SHORT);
        return -1;
    }

    i = ssl_rsa_private_decrypt(s->cert, s->s2->tmp.enc,
                                &(p[s->s2->tmp.clear]),
                                &(p[s->s2->tmp.clear]),
                                (s->s2->ssl2_rollback) ? RSA_SSLV23_PADDING :
                                RSA_PKCS1_PADDING);

    /* bad decrypt */
# if 1
    /*
     * If a bad decrypt, continue with protocol but with a random master
     * secret (Bleichenbacher attack)
     */
    if ((i < 0) || ((!is_export && (i != EVP_CIPHER_key_length(c)))
                    || (is_export && ((i != ek)
                                      || (s->s2->tmp.clear +
                                          (unsigned int)i != (unsigned int)
                                          EVP_CIPHER_key_length(c)))))) {
    if ((i < 0) || ((!is_export && i != EVP_CIPHER_key_length(c))
                    || (is_export && i != ek))) {
        ERR_clear_error();
        if (is_export)
            i = ek;
        else
            i = EVP_CIPHER_key_length(c);
        if (RAND_pseudo_bytes(p, i) <= 0)
        if (RAND_pseudo_bytes(&p[s->s2->tmp.clear], i) <= 0)
            return 0;
    }
# else
@@ -513,7 +546,7 @@ static int get_client_master_key(SSL *s)
# endif

    if (is_export)
        i += s->s2->tmp.clear;
        i = EVP_CIPHER_key_length(c);

    if (i > SSL_MAX_MASTER_KEY_LENGTH) {
        ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);