Add a PKCS#12 fuzzer.

Change-Id: Iee3a3d46d283bd6cbb46940e630916aacdd71db6
Reviewed-on: https://boringssl-review.googlesource.com/28552
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/pkcs8/pkcs12_test.cc b/crypto/pkcs8/pkcs12_test.cc
index 5fb7903..e6c0e56 100644
--- a/crypto/pkcs8/pkcs12_test.cc
+++ b/crypto/pkcs8/pkcs12_test.cc
@@ -1234,11 +1234,17 @@
 }
 
 TEST(PKCS12Test, TestEmptyPassword) {
+#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+  return;  // The MAC check always passes in fuzzer mode.
+#endif
   TestImpl("EmptyPassword (empty password)", kEmptyPassword, "", nullptr);
   TestImpl("EmptyPassword (null password)", kEmptyPassword, nullptr, nullptr);
 }
 
 TEST(PKCS12Test, TestNullPassword) {
+#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+  return;  // The MAC check always passes in fuzzer mode.
+#endif
   TestImpl("NullPassword (empty password)", kNullPassword, "", nullptr);
   TestImpl("NullPassword (null password)", kNullPassword, nullptr, nullptr);
 }
diff --git a/crypto/pkcs8/pkcs8_x509.c b/crypto/pkcs8/pkcs8_x509.c
index 3cdbddb..23aad09 100644
--- a/crypto/pkcs8/pkcs8_x509.c
+++ b/crypto/pkcs8/pkcs8_x509.c
@@ -573,6 +573,9 @@
   }
 
   *out_mac_ok = CBS_mem_equal(expected_mac, hmac, hmac_len);
+#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+  *out_mac_ok = 1;
+#endif
   ret = 1;
 
 err:
diff --git a/fuzz/CMakeLists.txt b/fuzz/CMakeLists.txt
index eddb38c..a269696 100644
--- a/fuzz/CMakeLists.txt
+++ b/fuzz/CMakeLists.txt
@@ -2,127 +2,44 @@
 
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-missing-prototypes")
 
-add_executable(
-  bn_mod_exp
+add_executable(bn_mod_exp bn_mod_exp.cc)
+target_link_libraries(bn_mod_exp Fuzzer crypto)
 
-  bn_mod_exp.cc
-)
+add_executable(bn_div bn_div.cc)
+target_link_libraries(bn_div Fuzzer crypto)
 
-target_link_libraries(bn_mod_exp Fuzzer)
-target_link_libraries(bn_mod_exp crypto)
+add_executable(privkey privkey.cc)
+target_link_libraries(privkey Fuzzer crypto)
 
-add_executable(
-  bn_div
+add_executable(cert cert.cc)
+target_link_libraries(cert Fuzzer crypto)
 
-  bn_div.cc
-)
+add_executable(spki spki.cc)
+target_link_libraries(spki Fuzzer crypto)
 
-target_link_libraries(bn_div Fuzzer)
-target_link_libraries(bn_div crypto)
+add_executable(pkcs8 pkcs8.cc)
+target_link_libraries(pkcs8 Fuzzer crypto)
 
-add_executable(
-  privkey
+add_executable(pkcs12 pkcs12.cc)
+target_link_libraries(pkcs12 Fuzzer crypto)
 
-  privkey.cc
-)
+add_executable(server server.cc)
+target_link_libraries(server Fuzzer crypto ssl)
 
-target_link_libraries(privkey Fuzzer)
-target_link_libraries(privkey crypto)
+add_executable(client client.cc)
+target_link_libraries(client Fuzzer crypto ssl)
 
-add_executable(
-  cert
+add_executable(dtls_server dtls_server.cc)
+target_link_libraries(dtls_server Fuzzer crypto ssl)
 
-  cert.cc
-)
+add_executable(dtls_client dtls_client.cc)
+target_link_libraries(dtls_client Fuzzer crypto ssl)
 
-target_link_libraries(cert Fuzzer)
-target_link_libraries(cert crypto)
+add_executable(read_pem read_pem.cc)
+target_link_libraries(read_pem Fuzzer crypto)
 
-add_executable(
-  spki
+add_executable(ssl_ctx_api ssl_ctx_api.cc)
+target_link_libraries(ssl_ctx_api Fuzzer crypto ssl)
 
-  spki.cc
-)
-
-target_link_libraries(spki Fuzzer)
-target_link_libraries(spki crypto)
-
-add_executable(
-  pkcs8
-
-  pkcs8.cc
-)
-
-target_link_libraries(pkcs8 Fuzzer)
-target_link_libraries(pkcs8 crypto)
-
-add_executable(
-  server
-
-  server.cc
-)
-
-target_link_libraries(server Fuzzer)
-target_link_libraries(server crypto)
-target_link_libraries(server ssl)
-
-add_executable(
-  client
-
-  client.cc
-)
-
-target_link_libraries(client Fuzzer)
-target_link_libraries(client crypto)
-target_link_libraries(client ssl)
-
-add_executable(
-  dtls_server
-
-  dtls_server.cc
-)
-
-target_link_libraries(dtls_server Fuzzer)
-target_link_libraries(dtls_server crypto)
-target_link_libraries(dtls_server ssl)
-
-add_executable(
-  dtls_client
-
-  dtls_client.cc
-)
-
-target_link_libraries(dtls_client Fuzzer)
-target_link_libraries(dtls_client crypto)
-target_link_libraries(dtls_client ssl)
-
-add_executable(
-  read_pem
-
-  read_pem.cc
-)
-
-target_link_libraries(read_pem Fuzzer)
-target_link_libraries(read_pem crypto)
-
-add_executable(
-  ssl_ctx_api
-
-  ssl_ctx_api.cc
-)
-
-target_link_libraries(ssl_ctx_api Fuzzer)
-target_link_libraries(ssl_ctx_api crypto)
-target_link_libraries(ssl_ctx_api ssl)
-
-add_executable(
-  session
-
-  session.cc
-
-  $<TARGET_OBJECTS:test_support>
-)
-
-target_link_libraries(session Fuzzer)
-target_link_libraries(session crypto)
-target_link_libraries(session ssl)
+add_executable(session session.cc)
+target_link_libraries(session Fuzzer crypto ssl)
diff --git a/fuzz/pkcs12.cc b/fuzz/pkcs12.cc
new file mode 100644
index 0000000..85bb0e3
--- /dev/null
+++ b/fuzz/pkcs12.cc
@@ -0,0 +1,29 @@
+/* Copyright (c) 2018, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/bytestring.h>
+#include <openssl/evp.h>
+#include <openssl/pkcs8.h>
+#include <openssl/x509.h>
+
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
+  bssl::UniquePtr<STACK_OF(X509)> certs(sk_X509_new_null());
+  EVP_PKEY *key = nullptr;
+  CBS cbs;
+  CBS_init(&cbs, buf, len);
+  PKCS12_get_key_and_certs(&key, certs.get(), &cbs, "foo");
+  EVP_PKEY_free(key);
+  return 0;
+}
diff --git a/fuzz/pkcs12_corpus/04191202c1f7d978bcb3a4c1316d88b046689e31 b/fuzz/pkcs12_corpus/04191202c1f7d978bcb3a4c1316d88b046689e31
new file mode 100644
index 0000000..5ead05f
--- /dev/null
+++ b/fuzz/pkcs12_corpus/04191202c1f7d978bcb3a4c1316d88b046689e31
Binary files differ
diff --git a/fuzz/pkcs12_corpus/7dbf598a00e4d22ac2ae1bc658fbc6596901d53f b/fuzz/pkcs12_corpus/7dbf598a00e4d22ac2ae1bc658fbc6596901d53f
new file mode 100644
index 0000000..2abe60f
--- /dev/null
+++ b/fuzz/pkcs12_corpus/7dbf598a00e4d22ac2ae1bc658fbc6596901d53f
Binary files differ
diff --git a/fuzz/pkcs12_corpus/aab806b45129f3284cf9598951cdd57a86e63ab5 b/fuzz/pkcs12_corpus/aab806b45129f3284cf9598951cdd57a86e63ab5
new file mode 100644
index 0000000..1049426
--- /dev/null
+++ b/fuzz/pkcs12_corpus/aab806b45129f3284cf9598951cdd57a86e63ab5
Binary files differ
diff --git a/fuzz/pkcs12_corpus/fff673b3287ad0d26ffa212d14d94ce2d015c7ab b/fuzz/pkcs12_corpus/fff673b3287ad0d26ffa212d14d94ce2d015c7ab
new file mode 100644
index 0000000..f7cd26f
--- /dev/null
+++ b/fuzz/pkcs12_corpus/fff673b3287ad0d26ffa212d14d94ce2d015c7ab
Binary files differ