Specific error for suites in common but none good
diff --git a/ChangeLog b/ChangeLog
index b38d56f..efaadfb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,11 @@
* Certificate selection based on signature hash, prefering SHA-1 over SHA-2
for pre-1.2 clients when multiple certificates are available.
+Changes
+ * A specific error is now returned when there are ciphersuites in common
+ but none of them is usable due to external factors such as no certificate
+ with a suitable (extended)KeyUsage or curvem or no PSK set.
+
= PolarSSL 1.3.9 released 2014-10-20
Security
* Lowest common hash was selected from signature_algorithms extension in
diff --git a/include/polarssl/error.h b/include/polarssl/error.h
index 7ce2828..6a1143f 100644
--- a/include/polarssl/error.h
+++ b/include/polarssl/error.h
@@ -91,7 +91,7 @@
* ECP 4 8 (Started from top)
* MD 5 4
* CIPHER 6 6
- * SSL 6 10 (Started from top)
+ * SSL 6 11 (Started from top)
* SSL 7 31
*
* Module dependent error code (5 bits 0x.00.-0x.F8.)
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index 194e944..1e9fb39 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -146,6 +146,7 @@
#define POLARSSL_ERR_SSL_INTERNAL_ERROR -0x6C00 /**< Internal error (eg, unexpected failure in lower-level module) */
#define POLARSSL_ERR_SSL_COUNTER_WRAPPING -0x6B80 /**< A counter would wrap (eg, too many messages exchanged). */
#define POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO -0x6B00 /**< Unexpected message at ServerHello in renegotiation. */
+#define POLARSSL_ERR_SSL_NO_USABLE_CIPHERSUITE -0x6A80 /**< None of the common ciphersuites is usable (eg, no suitable certificate) */
/*
* Various constants
diff --git a/library/error.c b/library/error.c
index 73504d4..0095636 100644
--- a/library/error.c
+++ b/library/error.c
@@ -452,6 +452,8 @@
snprintf( buf, buflen, "SSL - A counter would wrap (eg, too many messages exchanged)" );
if( use_ret == -(POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO) )
snprintf( buf, buflen, "SSL - Unexpected message at ServerHello in renegotiation" );
+ if( use_ret == -(POLARSSL_ERR_SSL_NO_USABLE_CIPHERSUITE) )
+ snprintf( buf, buflen, "SSL - None of the common ciphersuites is usable (eg, no suitable certificate)" );
#endif /* POLARSSL_SSL_TLS_C */
#if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C)
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 04608ee..384207a 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -903,7 +903,7 @@
#if defined(POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO)
static int ssl_parse_client_hello_v2( ssl_context *ssl )
{
- int ret;
+ int ret, got_common_suite;
unsigned int i, j;
size_t n;
unsigned int ciph_len, sess_len, chal_len;
@@ -1072,6 +1072,7 @@
}
}
+ got_common_suite = 0;
ciphersuites = ssl->ciphersuite_list[ssl->minor_ver];
ciphersuite_info = NULL;
#if defined(POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE)
@@ -1089,6 +1090,8 @@
p[2] != ( ( ciphersuites[i] ) & 0xFF ) )
continue;
+ got_common_suite = 1;
+
if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i],
&ciphersuite_info ) ) != 0 )
return( ret );
@@ -1098,9 +1101,17 @@
}
}
- SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) );
-
- return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN );
+ if( got_common_suite )
+ {
+ SSL_DEBUG_MSG( 1, ( "got ciphersuites in common, "
+ "but none of them usable" ) );
+ return( POLARSSL_ERR_SSL_NO_USABLE_CIPHERSUITE );
+ }
+ else
+ {
+ SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) );
+ return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN );
+ }
have_ciphersuite_v2:
ssl->session_negotiate->ciphersuite = ciphersuites[i];
@@ -1132,7 +1143,7 @@
static int ssl_parse_client_hello( ssl_context *ssl )
{
- int ret;
+ int ret, got_common_suite;
unsigned int i, j;
size_t n;
unsigned int ciph_len, sess_len;
@@ -1552,6 +1563,7 @@
* (At the end because we need information from the EC-based extensions
* and certificate from the SNI callback triggered by the SNI extension.)
*/
+ got_common_suite = 0;
ciphersuites = ssl->ciphersuite_list[ssl->minor_ver];
ciphersuite_info = NULL;
#if defined(POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE)
@@ -1568,6 +1580,8 @@
p[1] != ( ( ciphersuites[i] ) & 0xFF ) )
continue;
+ got_common_suite = 1;
+
if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i],
&ciphersuite_info ) ) != 0 )
return( ret );
@@ -1577,12 +1591,19 @@
}
}
- SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) );
-
- if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
- return( ret );
-
- return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN );
+ if( got_common_suite )
+ {
+ SSL_DEBUG_MSG( 1, ( "got ciphersuites in common, "
+ "but none of them usable" ) );
+ ssl_send_fatal_handshake_failure( ssl );
+ return( POLARSSL_ERR_SSL_NO_USABLE_CIPHERSUITE );
+ }
+ else
+ {
+ SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) );
+ ssl_send_fatal_handshake_failure( ssl );
+ return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN );
+ }
have_ciphersuite:
ssl->session_negotiate->ciphersuite = ciphersuites[i];
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 2cf4b6e..a37ea93 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -1562,7 +1562,7 @@
"$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=foo psk=abc123" \
0 \
- -S "SSL - The server has no ciphersuites in common" \
+ -S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
@@ -1571,7 +1571,7 @@
"$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=foo psk=abc123" \
1 \
- -s "SSL - The server has no ciphersuites in common" \
+ -s "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
@@ -1580,7 +1580,7 @@
"$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=foo psk=abc123" \
1 \
- -S "SSL - The server has no ciphersuites in common" \
+ -S "SSL - None of the common ciphersuites is usable" \
-s "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
@@ -1589,7 +1589,7 @@
"$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=abc psk=dead" \
0 \
- -S "SSL - The server has no ciphersuites in common" \
+ -S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
@@ -1598,7 +1598,7 @@
"$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=def psk=beef" \
0 \
- -S "SSL - The server has no ciphersuites in common" \
+ -S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
@@ -1607,7 +1607,7 @@
"$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=ghi psk=beef" \
1 \
- -S "SSL - The server has no ciphersuites in common" \
+ -S "SSL - None of the common ciphersuites is usable" \
-s "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
@@ -1616,7 +1616,7 @@
"$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=abc psk=beef" \
1 \
- -S "SSL - The server has no ciphersuites in common" \
+ -S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-s "SSL - Verification of the message MAC failed"