Put SCTs and OCSP responses in CRYPTO_BUFFERs.

They both can be moderately large. This should hopefully relieve a little
memory pressure from both connections to hosts which serve SCTs and
TLS 1.3's single-use tickets.

Change-Id: I034bbf057fe5a064015a0f554b3ae9ea7797cd4e
Reviewed-on: https://boringssl-review.googlesource.com/19584
Commit-Queue: Steven Valdez <svaldez@google.com>
Reviewed-by: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/ssl_asn1.cc b/ssl/ssl_asn1.cc
index 0cf90d1..b87c795 100644
--- a/ssl/ssl_asn1.cc
+++ b/ssl/ssl_asn1.cc
@@ -311,20 +311,22 @@
     }
   }
 
-  if (in->tlsext_signed_cert_timestamp_list_length > 0) {
+  if (in->signed_cert_timestamp_list != nullptr) {
     if (!CBB_add_asn1(&session, &child, kSignedCertTimestampListTag) ||
         !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
-        !CBB_add_bytes(&child2, in->tlsext_signed_cert_timestamp_list,
-                       in->tlsext_signed_cert_timestamp_list_length)) {
+        !CBB_add_bytes(&child2,
+                       CRYPTO_BUFFER_data(in->signed_cert_timestamp_list),
+                       CRYPTO_BUFFER_len(in->signed_cert_timestamp_list))) {
       OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
       return 0;
     }
   }
 
-  if (in->ocsp_response_length > 0) {
+  if (in->ocsp_response != nullptr) {
     if (!CBB_add_asn1(&session, &child, kOCSPResponseTag) ||
         !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
-        !CBB_add_bytes(&child2, in->ocsp_response, in->ocsp_response_length)) {
+        !CBB_add_bytes(&child2, CRYPTO_BUFFER_data(in->ocsp_response),
+                       CRYPTO_BUFFER_len(in->ocsp_response))) {
       OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
       return 0;
     }
@@ -470,6 +472,29 @@
   return 1;
 }
 
+static int SSL_SESSION_parse_crypto_buffer(CBS *cbs, CRYPTO_BUFFER **out,
+                                           unsigned tag,
+                                           CRYPTO_BUFFER_POOL *pool) {
+  if (!CBS_peek_asn1_tag(cbs, tag)) {
+    return 1;
+  }
+
+  CBS child, value;
+  if (!CBS_get_asn1(cbs, &child, tag) ||
+      !CBS_get_asn1(&child, &value, CBS_ASN1_OCTETSTRING) ||
+      CBS_len(&child) != 0) {
+    OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
+    return 0;
+  }
+  CRYPTO_BUFFER_free(*out);
+  *out = CRYPTO_BUFFER_new_from_CBS(&value, pool);
+  if (*out == nullptr) {
+    OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+    return 0;
+  }
+  return 1;
+}
+
 /* SSL_SESSION_parse_bounded_octet_string parses an optional ASN.1 OCTET STRING
  * explicitly tagged with |tag| of size at most |max_out|. */
 static int SSL_SESSION_parse_bounded_octet_string(
@@ -635,13 +660,11 @@
           &session, ret->original_handshake_hash,
           &ret->original_handshake_hash_len,
           sizeof(ret->original_handshake_hash), kOriginalHandshakeHashTag) ||
-      !SSL_SESSION_parse_octet_string(
-          &session, &ret->tlsext_signed_cert_timestamp_list,
-          &ret->tlsext_signed_cert_timestamp_list_length,
-          kSignedCertTimestampListTag) ||
-      !SSL_SESSION_parse_octet_string(
-          &session, &ret->ocsp_response, &ret->ocsp_response_length,
-          kOCSPResponseTag)) {
+      !SSL_SESSION_parse_crypto_buffer(&session,
+                                       &ret->signed_cert_timestamp_list,
+                                       kSignedCertTimestampListTag, pool) ||
+      !SSL_SESSION_parse_crypto_buffer(&session, &ret->ocsp_response,
+                                       kOCSPResponseTag, pool)) {
     return nullptr;
   }