Wait for CertificateStatus message to verify certificate.

Applications may require the stapled OCSP response in order to verify
the certificate within the verification callback.

Change-Id: I8002e527f90c3ce7b6a66e3203c0a68371aac5ec
Reviewed-on: https://boringssl-review.googlesource.com/5730
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 485c29f..6e82fff 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -276,7 +276,7 @@
           if (s->s3->tmp.certificate_status_expected) {
             s->state = SSL3_ST_CR_CERT_STATUS_A;
           } else {
-            s->state = SSL3_ST_CR_KEY_EXCH_A;
+            s->state = SSL3_ST_VERIFY_SERVER_CERT;
           }
         } else {
           skip = 1;
@@ -285,6 +285,16 @@
         s->init_num = 0;
         break;
 
+      case SSL3_ST_VERIFY_SERVER_CERT:
+        ret = ssl3_verify_server_cert(s);
+        if (ret <= 0) {
+          goto end;
+        }
+
+        s->state = SSL3_ST_CR_KEY_EXCH_A;
+        s->init_num = 0;
+        break;
+
       case SSL3_ST_CR_KEY_EXCH_A:
       case SSL3_ST_CR_KEY_EXCH_B:
         ret = ssl3_get_server_key_exchange(s);
@@ -468,7 +478,7 @@
         if (ret <= 0) {
           goto end;
         }
-        s->state = SSL3_ST_CR_KEY_EXCH_A;
+        s->state = SSL3_ST_VERIFY_SERVER_CERT;
         s->init_num = 0;
         break;
 
@@ -946,7 +956,7 @@
 }
 
 int ssl3_get_server_certificate(SSL *s) {
-  int al, i, ok, ret = -1;
+  int al, ok, ret = -1;
   unsigned long n;
   X509 *x = NULL;
   STACK_OF(X509) *sk = NULL;
@@ -1004,14 +1014,6 @@
     x = NULL;
   }
 
-  i = ssl_verify_cert_chain(s, sk);
-  if (s->verify_mode != SSL_VERIFY_NONE && i <= 0) {
-    al = ssl_verify_alarm_type(s->verify_result);
-    OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED);
-    goto f_err;
-  }
-  ERR_clear_error(); /* but we keep s->verify_result */
-
   X509 *leaf = sk_X509_value(sk, 0);
   if (!ssl3_check_certificate_for_cipher(leaf, s->s3->tmp.new_cipher)) {
     al = SSL_AD_ILLEGAL_PARAMETER;
@@ -2197,3 +2199,17 @@
   }
   return i;
 }
+
+int ssl3_verify_server_cert(SSL *s) {
+  int ret = ssl_verify_cert_chain(s, s->session->cert_chain);
+  if (s->verify_mode != SSL_VERIFY_NONE && ret <= 0) {
+    int al = ssl_verify_alarm_type(s->verify_result);
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+    OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED);
+  } else {
+    ret = 1;
+    ERR_clear_error(); /* but we keep s->verify_result */
+  }
+
+  return ret;
+}