Add a flag to toggle the buggy RSA parser.

It's about time we got rid of this. As a first step, introduce a flag,
so that some consumers may stage this change in appropriately.

BUG=chromium:534766,chromium:532048

Change-Id: Id53f0bacf5bdbf85dd71d1262d9f3a9ce3c4111f
Reviewed-on: https://boringssl-review.googlesource.com/16104
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/crypto/evp/p_rsa_asn1.c b/crypto/evp/p_rsa_asn1.c
index 306ff7d..866fc59 100644
--- a/crypto/evp/p_rsa_asn1.c
+++ b/crypto/evp/p_rsa_asn1.c
@@ -63,9 +63,19 @@
 #include <openssl/rsa.h>
 
 #include "../fipsmodule/rsa/internal.h"
+#include "../internal.h"
 #include "internal.h"
 
 
+static struct CRYPTO_STATIC_MUTEX g_buggy_lock = CRYPTO_STATIC_MUTEX_INIT;
+static int g_buggy = 1;
+
+void EVP_set_buggy_rsa_parser(int buggy) {
+  CRYPTO_STATIC_MUTEX_lock_write(&g_buggy_lock);
+  g_buggy = buggy;
+  CRYPTO_STATIC_MUTEX_unlock_write(&g_buggy_lock);
+}
+
 static int rsa_pub_encode(CBB *out, const EVP_PKEY *key) {
   /* See RFC 3279, section 2.3.1. */
   CBB spki, algorithm, oid, null, key_bitstring;
@@ -86,6 +96,11 @@
 }
 
 static int rsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
+  int buggy;
+  CRYPTO_STATIC_MUTEX_lock_read(&g_buggy_lock);
+  buggy = g_buggy;
+  CRYPTO_STATIC_MUTEX_unlock_read(&g_buggy_lock);
+
   /* See RFC 3279, section 2.3.1. */
 
   /* The parameters must be NULL. */
@@ -103,7 +118,7 @@
    * TODO(davidben): Switch this to the strict version in March 2016 or when
    * Chromium can force client certificates down a different codepath, whichever
    * comes first. */
-  RSA *rsa = RSA_parse_public_key_buggy(key);
+  RSA *rsa = buggy ? RSA_parse_public_key_buggy(key) : RSA_parse_public_key(key);
   if (rsa == NULL || CBS_len(key) != 0) {
     OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
     RSA_free(rsa);
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index cb2731e..4527109 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -225,6 +225,10 @@
  * success and zero on error. */
 OPENSSL_EXPORT int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key);
 
+/* EVP_set_buggy_rsa_parser configures whether |RSA_parse_public_key_buggy| is
+ * used by |EVP_parse_public_key|. By default, it is used. */
+OPENSSL_EXPORT void EVP_set_buggy_rsa_parser(int buggy);
+
 
 /* Signing */