Fix SSLv3 alert if no Client Ceritifcate sent after a request for one
authorMatt Caswell <matt@openssl.org>
Wed, 22 Jun 2016 18:43:46 +0000 (19:43 +0100)
committerMatt Caswell <matt@openssl.org>
Mon, 18 Jul 2016 13:30:14 +0000 (14:30 +0100)
In TLS if the server sends a CertificateRequest and the client does not
provide one, if the server cannot continue it should send a
HandshakeFailure alert. In SSLv3 the same should happen, but instead we
were sending an UnexpectedMessage alert. This is incorrect - the message
isn't unexpected - it is valid for the client not to send one - its just
that we cannot continue without one.

Reviewed-by: Emilia Käsper <emilia@openssl.org>
ssl/statem/statem.c
ssl/statem/statem_clnt.c
ssl/statem/statem_srvr.c

index 28483e7944ff6e7cd0bfc1a59bf732d1cfad01a3..c34110b0ca7b55982f289955a388284bbe44812f 100644 (file)
@@ -531,8 +531,7 @@ static SUB_STATE_RETURN read_state_machine(SSL *s) {
              * to that state if so
              */
             if(!transition(s, mt)) {
-                ssl3_send_alert(s, SSL3_AL_FATAL, SSL3_AD_UNEXPECTED_MESSAGE);
-                SSLerr(SSL_F_READ_STATE_MACHINE, SSL_R_UNEXPECTED_MESSAGE);
+                ossl_statem_set_error(s);
                 return SUB_STATE_ERROR;
             }
 
index 2ab1f8e3f0073b85eb2f55b07e921210d3891d02..864f76cfcd9c5cdb993d521fd765f0405f40cde7 100644 (file)
@@ -175,7 +175,7 @@ int ossl_statem_client_read_transition(SSL *s, int mt)
             } else {
                 ske_expected = key_exchange_expected(s);
                 if (ske_expected < 0)
-                    return 0;
+                    goto err;
                 /* SKE is optional for some PSK ciphersuites */
                 if (ske_expected
                         || ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_PSK)
@@ -210,7 +210,7 @@ int ossl_statem_client_read_transition(SSL *s, int mt)
     case TLS_ST_CR_CERT_STATUS:
         ske_expected = key_exchange_expected(s);
         if (ske_expected < 0)
-            return 0;
+            goto err;
         /* SKE is optional for some PSK ciphersuites */
         if (ske_expected
                 || ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_PSK)
@@ -219,7 +219,7 @@ int ossl_statem_client_read_transition(SSL *s, int mt)
                 st->hand_state = TLS_ST_CR_KEY_EXCH;
                 return 1;
             }
-            return 0;
+            goto err;
         }
         /* Fall through */
 
@@ -229,7 +229,7 @@ int ossl_statem_client_read_transition(SSL *s, int mt)
                 st->hand_state = TLS_ST_CR_CERT_REQ;
                 return 1;
             }
-            return 0;
+            goto err;
         }
         /* Fall through */
 
@@ -270,7 +270,10 @@ int ossl_statem_client_read_transition(SSL *s, int mt)
         break;
     }
 
+ err:
     /* No valid transition found */
+    ssl3_send_alert(s, SSL3_AL_FATAL, SSL3_AD_UNEXPECTED_MESSAGE);
+    SSLerr(SSL_F_READ_STATE_MACHINE, SSL_R_UNEXPECTED_MESSAGE);
     return 0;
 }
 
index 773591cd3862a8e87648909d704a900ee6e0d422..c0115232282491337de4d71ca31472f6594e5367 100644 (file)
@@ -114,6 +114,17 @@ int ossl_statem_server_read_transition(SSL *s, int mt)
                 return 1;
             }
         }
+        if (mt == SSL3_MT_CLIENT_KEY_EXCHANGE && s->s3->tmp.cert_request
+                && s->version == SSL3_VERSION) {
+            /*
+             * This isn't an unexpected message as such - we're just not going
+             * to accept it.
+             */
+            ssl3_send_alert(s, SSL3_AL_FATAL, SSL3_AD_HANDSHAKE_FAILURE);
+            SSLerr(SSL_F_READ_STATE_MACHINE,
+                   SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
+            return 0;
+        }
         break;
 
     case TLS_ST_SR_CERT:
@@ -197,6 +208,8 @@ int ossl_statem_server_read_transition(SSL *s, int mt)
     }
 
     /* No valid transition found */
+    ssl3_send_alert(s, SSL3_AL_FATAL, SSL3_AD_UNEXPECTED_MESSAGE);
+    SSLerr(SSL_F_READ_STATE_MACHINE, SSL_R_UNEXPECTED_MESSAGE);
     return 0;
 }