Add more error state transitions (client)
authorMatt Caswell <matt@openssl.org>
Thu, 30 Apr 2015 10:32:35 +0000 (11:32 +0100)
committerMatt Caswell <matt@openssl.org>
Tue, 5 May 2015 18:45:55 +0000 (19:45 +0100)
Ensure all fatal errors transition into the new error state on the client
side.

Reviewed-by: Rich Salz <rsalz@openssl.org>
ssl/s3_clnt.c

index f81f1602377271ba5819cda84e9af346bda59c7f..f936fa353531e5a27e8b0e60ae588d675871526f 100644 (file)
@@ -237,6 +237,7 @@ int ssl3_connect(SSL *s)
 
             if ((s->version & 0xff00) != 0x0300) {
                 SSLerr(SSL_F_SSL3_CONNECT, ERR_R_INTERNAL_ERROR);
+                s->state = SSL_ST_ERR;
                 ret = -1;
                 goto end;
             }
@@ -252,10 +253,12 @@ int ssl3_connect(SSL *s)
             if (s->init_buf == NULL) {
                 if ((buf = BUF_MEM_new()) == NULL) {
                     ret = -1;
+                    s->state = SSL_ST_ERR;
                     goto end;
                 }
                 if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
                     ret = -1;
+                    s->state = SSL_ST_ERR;
                     goto end;
                 }
                 s->init_buf = buf;
@@ -270,6 +273,7 @@ int ssl3_connect(SSL *s)
             /* setup buffing BIO */
             if (!ssl_init_wbio_buffer(s, 0)) {
                 ret = -1;
+                s->state = SSL_ST_ERR;
                 goto end;
             }
 
@@ -377,6 +381,7 @@ int ssl3_connect(SSL *s)
              */
             if (!ssl3_check_cert_and_algorithm(s)) {
                 ret = -1;
+                s->state = SSL_ST_ERR;
                 goto end;
             }
             break;
@@ -400,6 +405,7 @@ int ssl3_connect(SSL *s)
                 if ((ret = SRP_Calc_A_param(s)) <= 0) {
                     SSLerr(SSL_F_SSL3_CONNECT, SSL_R_SRP_A_CALC);
                     ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+                    s->state = SSL_ST_ERR;
                     goto end;
                 }
             }
@@ -491,6 +497,7 @@ int ssl3_connect(SSL *s)
 #endif
             if (!s->method->ssl3_enc->setup_key_block(s)) {
                 ret = -1;
+                s->state = SSL_ST_ERR;
                 goto end;
             }
 
@@ -498,6 +505,7 @@ int ssl3_connect(SSL *s)
                                                           SSL3_CHANGE_CIPHER_CLIENT_WRITE))
             {
                 ret = -1;
+                s->state = SSL_ST_ERR;
                 goto end;
             }
 
@@ -629,6 +637,7 @@ int ssl3_connect(SSL *s)
             goto end;
             /* break; */
 
+        case SSL_ST_ERR:
         default:
             SSLerr(SSL_F_SSL3_CONNECT, SSL_R_UNKNOWN_STATE);
             ret = -1;
@@ -874,6 +883,7 @@ int ssl3_client_hello(SSL *s)
     /* SSL3_ST_CW_CLNT_HELLO_B */
     return ssl_do_write(s);
  err:
+    s->state = SSL_ST_ERR;
     return (-1);
 }
 
@@ -1145,6 +1155,7 @@ int ssl3_get_server_hello(SSL *s)
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
  err:
+    s->state = SSL_ST_ERR;
     return (-1);
 }
 
@@ -1185,7 +1196,7 @@ int ssl3_get_server_certificate(SSL *s)
 
     if ((sk = sk_X509_new_null()) == NULL) {
         SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, ERR_R_MALLOC_FAILURE);
-        goto done;
+        goto err;
     }
 
     n2l3(p, llen);
@@ -1218,7 +1229,7 @@ int ssl3_get_server_certificate(SSL *s)
         }
         if (!sk_X509_push(sk, x)) {
             SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, ERR_R_MALLOC_FAILURE);
-            goto done;
+            goto err;
         }
         x = NULL;
         nc += l + 3;
@@ -1246,7 +1257,7 @@ int ssl3_get_server_certificate(SSL *s)
 
     sc = ssl_sess_cert_new();
     if (sc == NULL)
-        goto done;
+        goto err;
 
     ssl_sess_cert_free(s->session->sess_cert);
     s->session->sess_cert = sc;
@@ -1332,6 +1343,8 @@ int ssl3_get_server_certificate(SSL *s)
 
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ err:
+    s->state = SSL_ST_ERR;
  done:
     EVP_PKEY_free(pkey);
     X509_free(x);
@@ -1987,6 +2000,7 @@ int ssl3_get_key_exchange(SSL *s)
     EC_KEY_free(ecdh);
 #endif
     EVP_MD_CTX_cleanup(&md_ctx);
+    s->state = SSL_ST_ERR;
     return (-1);
 }
 
@@ -2143,7 +2157,10 @@ int ssl3_get_certificate_request(SSL *s)
     ca_sk = NULL;
 
     ret = 1;
+    goto done;
  err:
+    s->state = SSL_ST_ERR;
+ done:
     sk_X509_NAME_pop_free(ca_sk, X509_NAME_free);
     return (ret);
 }
@@ -2213,6 +2230,7 @@ int ssl3_get_new_session_ticket(SSL *s)
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
  err:
+    s->state = SSL_ST_ERR;
     return (-1);
 }
 
@@ -2272,6 +2290,7 @@ int ssl3_get_cert_status(SSL *s)
     return 1;
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
+    s->state = SSL_ST_ERR;
     return (-1);
 }
 #endif
@@ -2293,6 +2312,7 @@ int ssl3_get_server_done(SSL *s)
         /* should contain no data */
         ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
         SSLerr(SSL_F_SSL3_GET_SERVER_DONE, SSL_R_LENGTH_MISMATCH);
+        s->state = SSL_ST_ERR;
         return -1;
     }
     ret = 1;
@@ -3079,6 +3099,7 @@ int ssl3_send_client_key_exchange(SSL *s)
     EC_KEY_free(clnt_ecdh);
     EVP_PKEY_free(srvr_pub_pkey);
 #endif
+    s->state = SSL_ST_ERR;
     return (-1);
 }
 
@@ -3218,6 +3239,7 @@ int ssl3_send_client_verify(SSL *s)
  err:
     EVP_MD_CTX_cleanup(&mctx);
     EVP_PKEY_CTX_free(pctx);
+    s->state = SSL_ST_ERR;
     return (-1);
 }
 
@@ -3281,6 +3303,7 @@ int ssl3_send_client_certificate(SSL *s)
             }
             if (i == 0) {
                 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+                s->state = SSL_ST_ERR;
                 return 0;
             }
             s->rwstate = SSL_NOTHING;
@@ -3339,6 +3362,7 @@ int ssl3_send_client_certificate(SSL *s)
                                      2) ? NULL : s->cert->key)) {
             SSLerr(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR);
             ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+            s->state = SSL_ST_ERR;
             return 0;
         }
     }