Convert the status_request (OCSP stapling) extension to the new system

Change-Id: I31dd9e9f523aee3700bb2f07a1624d124b157d3e
Reviewed-on: https://boringssl-review.googlesource.com/5363
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index d44205e..e8ac683 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -1348,6 +1348,58 @@
 }
 
 
+/* OCSP Stapling.
+ *
+ * https://tools.ietf.org/html/rfc6066#section-8 */
+
+static void ext_ocsp_init(SSL *ssl) {
+  ssl->s3->tmp.certificate_status_expected = 0;
+}
+
+static int ext_ocsp_add_clienthello(SSL *ssl, CBB *out) {
+  if (!ssl->ocsp_stapling_enabled) {
+    return 1;
+  }
+
+  CBB contents;
+  if (!CBB_add_u16(out, TLSEXT_TYPE_status_request) ||
+      !CBB_add_u16_length_prefixed(out, &contents) ||
+      !CBB_add_u8(&contents, TLSEXT_STATUSTYPE_ocsp) ||
+      !CBB_add_u16(&contents, 0 /* empty responder ID list */) ||
+      !CBB_add_u16(&contents, 0 /* empty request extensions */) ||
+      !CBB_flush(out)) {
+    return 0;
+  }
+
+  return 1;
+}
+
+static int ext_ocsp_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+                                         CBS *contents) {
+  if (contents == NULL) {
+    return 1;
+  }
+
+  if (CBS_len(contents) != 0) {
+    return 0;
+  }
+
+  ssl->s3->tmp.certificate_status_expected = 1;
+  return 1;
+}
+
+static int ext_ocsp_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+                                      CBS *contents) {
+  /* OCSP stapling as a server is not supported. */
+  return 1;
+}
+
+static int ext_ocsp_add_serverhello(SSL *ssl, CBB *out) {
+  /* OCSP stapling as a server is not supported. */
+  return 1;
+}
+
+
 /* kExtensions contains all the supported extensions. */
 static const struct tls_extension kExtensions[] = {
   {
@@ -1393,6 +1445,14 @@
     ext_sigalgs_parse_clienthello,
     ext_sigalgs_add_serverhello,
   },
+  {
+    TLSEXT_TYPE_status_request,
+    ext_ocsp_init,
+    ext_ocsp_add_clienthello,
+    ext_ocsp_parse_serverhello,
+    ext_ocsp_parse_clienthello,
+    ext_ocsp_add_serverhello,
+  },
 };
 
 #define kNumExtensions (sizeof(kExtensions) / sizeof(struct tls_extension))
@@ -1489,24 +1549,6 @@
   ret += CBB_len(&cbb);
   CBB_cleanup(&cbb);
 
-  if (s->ocsp_stapling_enabled) {
-    /* The status_request extension is excessively extensible at every layer.
-     * On the client, only support requesting OCSP responses with an empty
-     * responder_id_list and no extensions. */
-    if (limit - ret - 4 - 1 - 2 - 2 < 0) {
-      return NULL;
-    }
-
-    s2n(TLSEXT_TYPE_status_request, ret);
-    s2n(1 + 2 + 2, ret);
-    /* status_type */
-    *(ret++) = TLSEXT_STATUSTYPE_ocsp;
-    /* responder_id_list - empty */
-    s2n(0, ret);
-    /* request_extensions - empty */
-    s2n(0, ret);
-  }
-
   if (s->ctx->next_proto_select_cb && !s->s3->initial_handshake_complete &&
       !SSL_IS_DTLS(s)) {
     /* The client advertises an emtpy extension to indicate its support for
@@ -1746,14 +1788,6 @@
   }
   /* Currently the server should not respond with a SupportedCurves extension */
 
-  if (s->s3->tmp.certificate_status_expected) {
-    if ((long)(limit - ret - 4) < 0) {
-      return NULL;
-    }
-    s2n(TLSEXT_TYPE_status_request, ret);
-    s2n(0, ret);
-  }
-
   if (s->srtp_profile) {
     int el;
 
@@ -1891,7 +1925,6 @@
 
   s->srtp_profile = NULL;
   s->s3->next_proto_neg_seen = 0;
-  s->s3->tmp.certificate_status_expected = 0;
 
   OPENSSL_free(s->s3->alpn_selected);
   s->s3->alpn_selected = NULL;
@@ -2105,7 +2138,6 @@
    * systematically reset on a new handshake; perhaps allocate it fresh each
    * time so it's not even kept around post-handshake. */
   s->s3->next_proto_neg_seen = 0;
-  s->s3->tmp.certificate_status_expected = 0;
   s->srtp_profile = NULL;
 
   OPENSSL_free(s->s3->alpn_selected);
@@ -2185,21 +2217,6 @@
         *out_alert = SSL_AD_INTERNAL_ERROR;
         return 0;
       }
-    } else if (type == TLSEXT_TYPE_status_request) {
-      /* The extension MUST be empty and may only sent if we've requested a
-       * status request message. */
-      if (CBS_len(&extension) != 0) {
-        *out_alert = SSL_AD_DECODE_ERROR;
-        return 0;
-      }
-
-      if (!s->ocsp_stapling_enabled) {
-        *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
-        return 0;
-      }
-
-      /* Set a flag to expect a CertificateStatus message */
-      s->s3->tmp.certificate_status_expected = 1;
     } else if (type == TLSEXT_TYPE_next_proto_neg &&
                !s->s3->initial_handshake_complete && !SSL_IS_DTLS(s)) {
       uint8_t *selected;