Fix ECDSA hash selection bug with TLS 1.0 and 1.1
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 38b4029..29e9316 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -1185,7 +1185,6 @@
unsigned char **p,
unsigned char *end,
md_type_t *md_alg,
- size_t *hash_len,
pk_type_t *pk_alg )
{
((void) ssl);
@@ -1195,16 +1194,12 @@
/* Only in TLS 1.2 */
if( ssl->minor_ver != SSL_MINOR_VERSION_3 )
{
- *hash_len = 36;
return( 0 );
}
if( (*p) + 2 > end )
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
- /* Info from md_alg will be used instead */
- *hash_len = 0;
-
/*
* Get hash algorithm
*/
@@ -1361,7 +1356,7 @@
* Handle the digitally-signed structure
*/
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" ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
@@ -1380,6 +1375,13 @@
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];
p += 2;
@@ -1389,14 +1391,18 @@
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
+ SSL_DEBUG_BUF( 3, "signature", p, sig_len );
+
/*
* Compute the hash that has been signed
*/
- if( ssl->minor_ver != SSL_MINOR_VERSION_3 )
+ if( md_alg == POLARSSL_MD_NONE )
{
md5_context md5;
sha1_context sha1;
+ hashlen = 36;
+
/*
* digitally-signed struct {
* opaque md5_hash[16];
@@ -1424,6 +1430,9 @@
{
md_context_t ctx;
+ /* Info from md_alg will be used instead */
+ hashlen = 0;
+
/*
* digitally-signed struct {
* opaque client_random[32];
@@ -1918,6 +1927,7 @@
const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
size_t n = 0, offset = 0;
unsigned char hash[48];
+ unsigned char *hash_start = hash;
md_type_t md_alg = POLARSSL_MD_NONE;
unsigned int hashlen;
@@ -1965,6 +1975,16 @@
*/
hashlen = 36;
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
{
@@ -2002,7 +2022,7 @@
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->f_rng, ssl->p_rng ) ) != 0 )
{