Remember suitable hash function for any signature algorithm.

This commit changes `ssl_parse_signature_algorithms_ext` to remember
one suitable ( := supported by client and by our config ) hash
algorithm per signature algorithm.

It also modifies the ciphersuite checking function
`ssl_ciphersuite_match` to refuse a suite if there
is no suitable hash algorithm.

Finally, it adds the corresponding entry to the ChangeLog.
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 8604997..7cf968d 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -3526,7 +3526,11 @@
 #endif /* POLARSSL_SSL_PROTO_TLS1_2 */
 
     handshake->update_checksum = ssl_update_checksum_start;
-    handshake->sig_alg = SSL_HASH_SHA1;
+
+#if defined(POLARSSL_SSL_PROTO_TLS1_2) && \
+    defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
+    ssl_sig_hash_set_init( &handshake->hash_algs );
+#endif
 
 #if defined(POLARSSL_DHM_C)
     dhm_init( &handshake->dhm_ctx );
@@ -5166,6 +5170,19 @@
     return( SSL_SIG_ANON );
 }
 
+unsigned char ssl_sig_from_pk_alg( pk_type_t type )
+{
+    switch( type ) {
+        case POLARSSL_PK_RSA:
+            return( SSL_SIG_RSA );
+        case POLARSSL_PK_ECDSA:
+        case POLARSSL_PK_ECKEY:
+            return( SSL_SIG_ECDSA );
+        default:
+            return( SSL_SIG_ANON );
+    }
+}
+
 pk_type_t ssl_pk_alg_from_sig( unsigned char sig )
 {
     switch( sig )
@@ -5184,6 +5201,57 @@
 }
 #endif /* POLARSSL_PK_C */
 
+#if defined(POLARSSL_SSL_PROTO_TLS1_2) && \
+    defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
+
+/* Find an entry in a signature-hash set matching a given hash algorithm. */
+md_type_t ssl_sig_hash_set_find( ssl_sig_hash_set_t *set,
+                                 pk_type_t sig_alg )
+{
+    switch( sig_alg )
+    {
+        case POLARSSL_PK_RSA:
+            return( set->rsa );
+        case POLARSSL_PK_ECDSA:
+            return( set->ecdsa );
+        default:
+            return( POLARSSL_MD_NONE );
+    }
+}
+
+/* Add a signature-hash-pair to a signature-hash set */
+void ssl_sig_hash_set_add( ssl_sig_hash_set_t *set,
+                           pk_type_t sig_alg,
+                           md_type_t md_alg )
+{
+    switch( sig_alg )
+    {
+        case POLARSSL_PK_RSA:
+            if( set->rsa == POLARSSL_MD_NONE )
+                set->rsa = md_alg;
+            break;
+
+        case POLARSSL_PK_ECDSA:
+            if( set->ecdsa == POLARSSL_MD_NONE )
+                set->ecdsa = md_alg;
+            break;
+
+        default:
+            break;
+    }
+}
+
+/* Allow exactly one hash algorithm for each signature. */
+void ssl_sig_hash_set_const_hash( ssl_sig_hash_set_t *set,
+                                   md_type_t md_alg )
+{
+    set->rsa   = md_alg;
+    set->ecdsa = md_alg;
+}
+
+#endif /* POLARSSL_SSL_PROTO_TLS1_2) &&
+          POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED */
+
 /*
  * Convert between SSL_HASH_XXX and POLARSSL_MD_XXX
  */
@@ -5216,6 +5284,38 @@
     }
 }
 
+/*
+ * Convert from POLARSSL_MD_XXX to SSL_HASH_XXX
+ */
+unsigned char ssl_hash_from_md_alg( md_type_t md )
+{
+    switch( md )
+    {
+#if defined(POLARSSL_MD5_C)
+        case POLARSSL_MD_MD5:
+            return( SSL_HASH_MD5 );
+#endif
+#if defined(POLARSSL_SHA1_C)
+        case POLARSSL_MD_SHA1:
+            return( SSL_HASH_SHA1 );
+#endif
+#if defined(POLARSSL_SHA256_C)
+        case POLARSSL_MD_SHA224:
+            return( SSL_HASH_SHA224 );
+        case POLARSSL_MD_SHA256:
+            return( SSL_HASH_SHA256 );
+#endif
+#if defined(POLARSSL_SHA512_C)
+        case POLARSSL_MD_SHA384:
+            return( SSL_HASH_SHA384 );
+        case POLARSSL_MD_SHA512:
+            return( SSL_HASH_SHA512 );
+#endif
+        default:
+            return( SSL_HASH_NONE );
+    }
+}
+
 #if defined(POLARSSL_SSL_SET_CURVES)
 /*
  * Check is a curve proposed by the peer is in our list.
@@ -5233,6 +5333,30 @@
 }
 #endif /* POLARSSL_SSL_SET_CURVES */
 
+#if defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
+/*
+ * Check if a hash proposed by the peer is in our list.
+ * Return 0 if we're willing to use it, -1 otherwise.
+ */
+int ssl_check_sig_hash( md_type_t md )
+{
+    const int *cur;
+
+    for( cur = md_list(); *cur != POLARSSL_MD_NONE; cur++ )
+    {
+#if !defined(POLARSSL_SSL_ENABLE_MD5_SIGNATURES)
+        /* Skip MD5 */
+        if( *cur == POLARSSL_MD_MD5 )
+            continue;
+#endif
+        if( *cur == (int) md )
+            return( 0 );
+    }
+
+    return( -1 );
+}
+#endif /* POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED */
+
 #if defined(POLARSSL_X509_CRT_PARSE_C)
 int ssl_check_cert_usage( const x509_crt *cert,
                           const ssl_ciphersuite_t *ciphersuite,