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: Richard Levitte <levitte@openssl.org> Reviewed-by: Tim Hudson <tjh@openssl.org>
This commit is contained in:
		 Emilia Kasper
					Emilia Kasper
				
			
				
					committed by
					
						 Matt Caswell
						Matt Caswell
					
				
			
			
				
	
			
			
			 Matt Caswell
						Matt Caswell
					
				
			
						parent
						
							544e3e3b69
						
					
				
				
					commit
					65c588c140
				
			| @@ -417,7 +417,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); | ||||
|   | ||||
| @@ -452,11 +452,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); | ||||
|  | ||||
| @@ -473,23 +468,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 | ||||
| @@ -511,7 +544,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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user