Skip to content

Commit

Permalink
Fix reachable assert in SSLv2 servers.
Browse files Browse the repository at this point in the history
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: Richard Levitte <levitte@openssl.org>
Reviewed-by: Tim Hudson <tjh@openssl.org>
  • Loading branch information
ekasper authored and mattcaswell committed Mar 19, 2015
1 parent 9104dc4 commit 1a08063
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 13 deletions.
2 changes: 1 addition & 1 deletion ssl/s2_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
57 changes: 45 additions & 12 deletions ssl/s2_srvr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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
Expand All @@ -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);
Expand Down

0 comments on commit 1a08063

Please sign in to comment.