mirror of
				https://github.com/cuberite/polarssl.git
				synced 2025-11-03 20:22:59 -05:00 
			
		
		
		
	Fix ECDSA hash selection bug with TLS 1.0 and 1.1
This commit is contained in:
		
							parent
							
								
									9c9812a299
								
							
						
					
					
						commit
						4bd1284f59
					
				@ -1185,7 +1185,6 @@ static int ssl_parse_signature_algorithm( ssl_context *ssl,
 | 
				
			|||||||
                                          unsigned char **p,
 | 
					                                          unsigned char **p,
 | 
				
			||||||
                                          unsigned char *end,
 | 
					                                          unsigned char *end,
 | 
				
			||||||
                                          md_type_t *md_alg,
 | 
					                                          md_type_t *md_alg,
 | 
				
			||||||
                                          size_t *hash_len,
 | 
					 | 
				
			||||||
                                          pk_type_t *pk_alg )
 | 
					                                          pk_type_t *pk_alg )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ((void) ssl);
 | 
					    ((void) ssl);
 | 
				
			||||||
@ -1195,16 +1194,12 @@ static int ssl_parse_signature_algorithm( ssl_context *ssl,
 | 
				
			|||||||
    /* Only in TLS 1.2 */
 | 
					    /* Only in TLS 1.2 */
 | 
				
			||||||
    if( ssl->minor_ver != SSL_MINOR_VERSION_3 )
 | 
					    if( ssl->minor_ver != SSL_MINOR_VERSION_3 )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        *hash_len = 36;
 | 
					 | 
				
			||||||
        return( 0 );
 | 
					        return( 0 );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if( (*p) + 2 > end )
 | 
					    if( (*p) + 2 > end )
 | 
				
			||||||
        return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
 | 
					        return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Info from md_alg will be used instead */
 | 
					 | 
				
			||||||
    *hash_len = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /*
 | 
					    /*
 | 
				
			||||||
     * Get hash algorithm
 | 
					     * Get hash algorithm
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
@ -1361,7 +1356,7 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl )
 | 
				
			|||||||
         * Handle the digitally-signed structure
 | 
					         * Handle the digitally-signed structure
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        if( ssl_parse_signature_algorithm( ssl, &p, end,
 | 
					        if( ssl_parse_signature_algorithm( ssl, &p, end,
 | 
				
			||||||
                                           &md_alg, &hashlen, &pk_alg ) != 0 )
 | 
					                                           &md_alg, &pk_alg ) != 0 )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
 | 
					            SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
 | 
				
			||||||
            return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
 | 
					            return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
 | 
				
			||||||
@ -1380,6 +1375,13 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl )
 | 
				
			|||||||
            pk_alg = ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
 | 
					            pk_alg = ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Default hash for ECDSA is SHA-1 */
 | 
				
			||||||
 | 
					        if( pk_alg == POLARSSL_PK_ECDSA && md_alg == POLARSSL_MD_NONE )
 | 
				
			||||||
 | 
					            md_alg = POLARSSL_MD_SHA1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * Read signature
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
        sig_len = ( p[0] << 8 ) | p[1];
 | 
					        sig_len = ( p[0] << 8 ) | p[1];
 | 
				
			||||||
        p += 2;
 | 
					        p += 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1389,14 +1391,18 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl )
 | 
				
			|||||||
            return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
 | 
					            return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SSL_DEBUG_BUF( 3, "signature", p, sig_len );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /*
 | 
					        /*
 | 
				
			||||||
         * Compute the hash that has been signed
 | 
					         * Compute the hash that has been signed
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        if( ssl->minor_ver != SSL_MINOR_VERSION_3 )
 | 
					        if( md_alg == POLARSSL_MD_NONE )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            md5_context md5;
 | 
					            md5_context md5;
 | 
				
			||||||
            sha1_context sha1;
 | 
					            sha1_context sha1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            hashlen = 36;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /*
 | 
					            /*
 | 
				
			||||||
             * digitally-signed struct {
 | 
					             * digitally-signed struct {
 | 
				
			||||||
             *     opaque md5_hash[16];
 | 
					             *     opaque md5_hash[16];
 | 
				
			||||||
@ -1424,6 +1430,9 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl )
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            md_context_t ctx;
 | 
					            md_context_t ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* Info from md_alg will be used instead */
 | 
				
			||||||
 | 
					            hashlen = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /*
 | 
					            /*
 | 
				
			||||||
             * digitally-signed struct {
 | 
					             * digitally-signed struct {
 | 
				
			||||||
             *     opaque client_random[32];
 | 
					             *     opaque client_random[32];
 | 
				
			||||||
@ -1918,6 +1927,7 @@ static int ssl_write_certificate_verify( ssl_context *ssl )
 | 
				
			|||||||
    const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
 | 
					    const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
 | 
				
			||||||
    size_t n = 0, offset = 0;
 | 
					    size_t n = 0, offset = 0;
 | 
				
			||||||
    unsigned char hash[48];
 | 
					    unsigned char hash[48];
 | 
				
			||||||
 | 
					    unsigned char *hash_start = hash;
 | 
				
			||||||
    md_type_t md_alg = POLARSSL_MD_NONE;
 | 
					    md_type_t md_alg = POLARSSL_MD_NONE;
 | 
				
			||||||
    unsigned int hashlen;
 | 
					    unsigned int hashlen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1965,6 +1975,16 @@ static int ssl_write_certificate_verify( ssl_context *ssl )
 | 
				
			|||||||
         */
 | 
					         */
 | 
				
			||||||
        hashlen = 36;
 | 
					        hashlen = 36;
 | 
				
			||||||
        md_alg = POLARSSL_MD_NONE;
 | 
					        md_alg = POLARSSL_MD_NONE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * For ECDSA, default hash is SHA-1 only
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        if( pk_can_do( ssl->pk_key, POLARSSL_PK_ECDSA ) )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            hash_start += 16;
 | 
				
			||||||
 | 
					            hashlen -= 16;
 | 
				
			||||||
 | 
					            md_alg = POLARSSL_MD_SHA1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -2002,7 +2022,7 @@ static int ssl_write_certificate_verify( ssl_context *ssl )
 | 
				
			|||||||
        offset = 2;
 | 
					        offset = 2;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if( ( ret = pk_sign( ssl->pk_key, md_alg, hash, hashlen,
 | 
					    if( ( ret = pk_sign( ssl->pk_key, md_alg, hash_start, hashlen,
 | 
				
			||||||
                         ssl->out_msg + 6 + offset, &n,
 | 
					                         ssl->out_msg + 6 + offset, &n,
 | 
				
			||||||
                         ssl->f_rng, ssl->p_rng ) ) != 0 )
 | 
					                         ssl->f_rng, ssl->p_rng ) ) != 0 )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
				
			|||||||
@ -1950,10 +1950,34 @@ static int ssl_write_server_key_exchange( ssl_context *ssl )
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        size_t signature_len = 0;
 | 
					        size_t signature_len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * Choose hash algorithm. NONE means MD5 + SHA1 here.
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            md_alg = ssl_md_alg_from_hash( ssl->handshake->sig_alg );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if( md_alg == POLARSSL_MD_NONE )
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                SSL_DEBUG_MSG( 1, ( "should never happen" ) );
 | 
				
			||||||
 | 
					                return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if ( ciphersuite_info->key_exchange ==
 | 
				
			||||||
 | 
					                  POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            md_alg = POLARSSL_MD_SHA1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            md_alg = POLARSSL_MD_NONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /*
 | 
					        /*
 | 
				
			||||||
         * Compute the hash to be signed
 | 
					         * Compute the hash to be signed
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        if( ssl->minor_ver != SSL_MINOR_VERSION_3 )
 | 
					        if( md_alg == POLARSSL_MD_NONE )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            md5_context md5;
 | 
					            md5_context md5;
 | 
				
			||||||
            sha1_context sha1;
 | 
					            sha1_context sha1;
 | 
				
			||||||
@ -1982,7 +2006,6 @@ static int ssl_write_server_key_exchange( ssl_context *ssl )
 | 
				
			|||||||
            sha1_finish( &sha1, hash + 16 );
 | 
					            sha1_finish( &sha1, hash + 16 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            hashlen = 36;
 | 
					            hashlen = 36;
 | 
				
			||||||
            md_alg = POLARSSL_MD_NONE;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@ -1998,13 +2021,6 @@ static int ssl_write_server_key_exchange( ssl_context *ssl )
 | 
				
			|||||||
             *     ServerDHParams params;
 | 
					             *     ServerDHParams params;
 | 
				
			||||||
             * };
 | 
					             * };
 | 
				
			||||||
             */
 | 
					             */
 | 
				
			||||||
            if( ( md_alg = ssl_md_alg_from_hash( ssl->handshake->sig_alg ) )
 | 
					 | 
				
			||||||
                         == POLARSSL_MD_NONE )
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                SSL_DEBUG_MSG( 1, ( "should never happen" ) );
 | 
					 | 
				
			||||||
                return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if( ( ret = md_init_ctx( &ctx, md_info_from_type(md_alg) ) ) != 0 )
 | 
					            if( ( ret = md_init_ctx( &ctx, md_info_from_type(md_alg) ) ) != 0 )
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                SSL_DEBUG_RET( 1, "md_init_ctx", ret );
 | 
					                SSL_DEBUG_RET( 1, "md_init_ctx", ret );
 | 
				
			||||||
@ -2498,6 +2514,7 @@ static int ssl_parse_certificate_verify( ssl_context *ssl )
 | 
				
			|||||||
    int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
 | 
					    int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
 | 
				
			||||||
    size_t sa_len, sig_len;
 | 
					    size_t sa_len, sig_len;
 | 
				
			||||||
    unsigned char hash[48];
 | 
					    unsigned char hash[48];
 | 
				
			||||||
 | 
					    unsigned char *hash_start = hash;
 | 
				
			||||||
    size_t hashlen;
 | 
					    size_t hashlen;
 | 
				
			||||||
    pk_type_t pk_alg;
 | 
					    pk_type_t pk_alg;
 | 
				
			||||||
    md_type_t md_alg;
 | 
					    md_type_t md_alg;
 | 
				
			||||||
@ -2556,6 +2573,15 @@ static int ssl_parse_certificate_verify( ssl_context *ssl )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        md_alg = POLARSSL_MD_NONE;
 | 
					        md_alg = POLARSSL_MD_NONE;
 | 
				
			||||||
        hashlen = 36;
 | 
					        hashlen = 36;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* For ECDSA, use SHA-1, not MD-5 + SHA-1 */
 | 
				
			||||||
 | 
					        if( pk_can_do( &ssl->session_negotiate->peer_cert->pk,
 | 
				
			||||||
 | 
					                        POLARSSL_PK_ECDSA ) )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            hash_start += 16;
 | 
				
			||||||
 | 
					            hashlen -= 16;
 | 
				
			||||||
 | 
					            md_alg = POLARSSL_MD_SHA1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -2607,7 +2633,7 @@ static int ssl_parse_certificate_verify( ssl_context *ssl )
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if( ( ret = pk_verify( &ssl->session_negotiate->peer_cert->pk,
 | 
					    if( ( ret = pk_verify( &ssl->session_negotiate->peer_cert->pk,
 | 
				
			||||||
                           md_alg, hash, hashlen,
 | 
					                           md_alg, hash_start, hashlen,
 | 
				
			||||||
                           ssl->in_msg + 6 + sa_len, sig_len ) ) != 0 )
 | 
					                           ssl->in_msg + 6 + sa_len, sig_len ) ) != 0 )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        SSL_DEBUG_RET( 1, "pk_verify", ret );
 | 
					        SSL_DEBUG_RET( 1, "pk_verify", ret );
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user