Emulate the client_cert_cb with cert_cb.

This avoids needing a extra state around client certificates to avoid
calling the callbacks twice. This does, however, come with a behavior
change: configuring both callbacks won't work. No consumer does this.

(Except bssl_shim which needed slight tweaks.)

Change-Id: Ia5426ed2620e40eecdcf352216c4a46764e31a9a
Reviewed-on: https://boringssl-review.googlesource.com/12690
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/handshake_client.c b/ssl/handshake_client.c
index 028b905..b73215b 100644
--- a/ssl/handshake_client.c
+++ b/ssl/handshake_client.c
@@ -326,7 +326,6 @@
 
       case SSL3_ST_CW_CERT_A:
       case SSL3_ST_CW_CERT_B:
-      case SSL3_ST_CW_CERT_C:
         if (hs->cert_request) {
           ret = ssl3_send_client_certificate(hs);
           if (ret <= 0) {
@@ -1459,53 +1458,41 @@
 
 static int ssl3_send_client_certificate(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  if (ssl->state == SSL3_ST_CW_CERT_A) {
-    /* Call cert_cb to update the certificate. */
-    if (ssl->cert->cert_cb) {
-      int ret = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
-      if (ret < 0) {
-        ssl->rwstate = SSL_X509_LOOKUP;
-        return -1;
-      }
-      if (ret == 0) {
-        OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR);
-        ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
-        return -1;
-      }
-    }
-
-    ssl->state = SSL3_ST_CW_CERT_B;
-  }
-
   if (ssl->state == SSL3_ST_CW_CERT_B) {
-    /* Call client_cert_cb to update the certificate. */
-    int should_retry;
-    if (!ssl_do_client_cert_cb(ssl, &should_retry)) {
-      if (should_retry) {
-        ssl->rwstate = SSL_X509_LOOKUP;
-      }
+    return ssl->method->write_message(ssl);
+  }
+  assert(ssl->state == SSL3_ST_CW_CERT_A);
+
+  /* Call cert_cb to update the certificate. */
+  if (ssl->cert->cert_cb) {
+    int ret = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
+    if (ret < 0) {
+      ssl->rwstate = SSL_X509_LOOKUP;
       return -1;
     }
-
-    if (!ssl_has_certificate(ssl)) {
-      hs->cert_request = 0;
-      /* Without a client certificate, the handshake buffer may be released. */
-      ssl3_free_handshake_buffer(ssl);
-
-      if (ssl->version == SSL3_VERSION) {
-        /* In SSL 3.0, send no certificate by skipping both messages. */
-        ssl3_send_alert(ssl, SSL3_AL_WARNING, SSL_AD_NO_CERTIFICATE);
-        return 1;
-      }
-    }
-
-    if (!ssl3_output_cert_chain(ssl)) {
+    if (ret == 0) {
+      OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR);
+      ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
       return -1;
     }
-    ssl->state = SSL3_ST_CW_CERT_C;
   }
 
-  assert(ssl->state == SSL3_ST_CW_CERT_C);
+  if (!ssl_has_certificate(ssl)) {
+    hs->cert_request = 0;
+    /* Without a client certificate, the handshake buffer may be released. */
+    ssl3_free_handshake_buffer(ssl);
+
+    if (ssl->version == SSL3_VERSION) {
+      /* In SSL 3.0, send no certificate by skipping both messages. */
+      ssl3_send_alert(ssl, SSL3_AL_WARNING, SSL_AD_NO_CERTIFICATE);
+      return 1;
+    }
+  }
+
+  if (!ssl3_output_cert_chain(ssl)) {
+    return -1;
+  }
+  ssl->state = SSL3_ST_CW_CERT_B;
   return ssl->method->write_message(ssl);
 }