Add use counters for SSL_OP_TLS_D5_BUG and SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER.

These are theh two remaining quirks (SSL_OP_LEGACY_SERVER_CONNECT
aside). Add counters so we can determine whether there are still clients
that trip up these cases.

Change-Id: I7e92f42f3830c1df675445ec15a852e5659eb499
Reviewed-on: https://boringssl-review.googlesource.com/6290
Reviewed-by: Adam Langley <alangley@gmail.com>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index f71e219..274a20a 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -2526,6 +2526,20 @@
 OPENSSL_EXPORT void SSL_set_max_send_fragment(SSL *ssl,
                                               size_t max_send_fragment);
 
+/* OPENSSL_get_big_buffer_use_count returns the total number of invalid TLS
+ * records that were accepted because of |SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER|.
+ *
+ * TODO(davidben): Remove this when (hopefully!) the quirk is demonstrated to be
+ * unnecessary. */
+OPENSSL_EXPORT uint64_t OPENSSL_get_big_buffer_use_count(void);
+
+/* OPENSSL_get_d5_bug_use_count returns the total number of invalid RSA
+ * ClientKeyExchanges that were accepted because of |SSL_OP_TLS_D5_BUG|.
+ *
+ * TODO(davidben): Remove this when (hopefully!) the quirk is demonstrated to be
+ * unnecessary. */
+OPENSSL_EXPORT uint64_t OPENSSL_get_d5_bug_use_count(void);
+
 
 /* Underdocumented functions.
  *
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index 25ab802..4f48462 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -1575,6 +1575,16 @@
   return -1;
 }
 
+static struct CRYPTO_STATIC_MUTEX g_d5_bug_lock = CRYPTO_STATIC_MUTEX_INIT;
+static uint64_t g_d5_bug_use_count = 0;
+
+uint64_t OPENSSL_get_d5_bug_use_count(void) {
+  CRYPTO_STATIC_MUTEX_lock_read(&g_d5_bug_lock);
+  uint64_t ret = g_d5_bug_use_count;
+  CRYPTO_STATIC_MUTEX_unlock(&g_d5_bug_lock);
+  return ret;
+}
+
 int ssl3_get_client_key_exchange(SSL *s) {
   int al, ok;
   long n;
@@ -1684,6 +1694,10 @@
           OPENSSL_PUT_ERROR(SSL, SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
           goto f_err;
         } else {
+          CRYPTO_STATIC_MUTEX_lock_write(&g_d5_bug_lock);
+          g_d5_bug_use_count++;
+          CRYPTO_STATIC_MUTEX_unlock(&g_d5_bug_lock);
+
           encrypted_premaster_secret = copy;
         }
       }
diff --git a/ssl/tls_record.c b/ssl/tls_record.c
index 36e31b4..bdc5c01 100644
--- a/ssl/tls_record.c
+++ b/ssl/tls_record.c
@@ -114,6 +114,7 @@
 #include <openssl/err.h>
 
 #include "internal.h"
+#include "../crypto/internal.h"
 
 
 /* kMaxEmptyRecords is the number of consecutive, empty records that will be
@@ -122,6 +123,16 @@
  * forever. */
 static const uint8_t kMaxEmptyRecords = 32;
 
+static struct CRYPTO_STATIC_MUTEX g_big_buffer_lock = CRYPTO_STATIC_MUTEX_INIT;
+static uint64_t g_big_buffer_use_count = 0;
+
+uint64_t OPENSSL_get_big_buffer_use_count(void) {
+  CRYPTO_STATIC_MUTEX_lock_read(&g_big_buffer_lock);
+  uint64_t ret = g_big_buffer_use_count;
+  CRYPTO_STATIC_MUTEX_unlock(&g_big_buffer_lock);
+  return ret;
+}
+
 size_t ssl_record_prefix_len(const SSL *ssl) {
   if (SSL_IS_DTLS(ssl)) {
     return DTLS1_RT_HEADER_LENGTH +
@@ -230,6 +241,14 @@
     return ssl_open_record_error;
   }
 
+  if (extra > 0 &&
+      (ciphertext_len > SSL3_RT_MAX_ENCRYPTED_LENGTH ||
+       plaintext_len > SSL3_RT_MAX_PLAIN_LENGTH)) {
+    CRYPTO_STATIC_MUTEX_lock_write(&g_big_buffer_lock);
+    g_big_buffer_use_count++;
+    CRYPTO_STATIC_MUTEX_unlock(&g_big_buffer_lock);
+  }
+
   /* Limit the number of consecutive empty records. */
   if (plaintext_len == 0) {
     ssl->s3->empty_record_count++;