/* Copyright (c) 2014, 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 <gtest/gtest.h>

#include <openssl/bio.h>
#include <openssl/bytestring.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pkcs8.h>
#include <openssl/mem.h>
#include <openssl/span.h>
#include <openssl/stack.h>
#include <openssl/x509.h>

#include "../test/test_util.h"


std::string GetTestData(const char *path);

// kPassword is the password shared by most of the sample PKCS#12 files.
static const char kPassword[] = "foo";

// kUnicodePassword is the password for unicode_password.p12
static const char kUnicodePassword[] = u8"Hello, 世界";

static bssl::Span<const uint8_t> StringToBytes(const std::string &str) {
  return bssl::MakeConstSpan(reinterpret_cast<const uint8_t *>(str.data()),
                             str.size());
}

static void TestImpl(const char *name, bssl::Span<const uint8_t> der,
                     const char *password,
                     const char *friendly_name) {
  SCOPED_TRACE(name);
  bssl::UniquePtr<STACK_OF(X509)> certs(sk_X509_new_null());
  ASSERT_TRUE(certs);

  EVP_PKEY *key = nullptr;
  CBS pkcs12 = der;
  ASSERT_TRUE(PKCS12_get_key_and_certs(&key, certs.get(), &pkcs12, password));
  bssl::UniquePtr<EVP_PKEY> delete_key(key);

  ASSERT_EQ(1u, sk_X509_num(certs.get()));
  ASSERT_TRUE(key);

  int actual_name_len;
  const uint8_t *actual_name =
      X509_alias_get0(sk_X509_value(certs.get(), 0), &actual_name_len);
  if (friendly_name == nullptr) {
    EXPECT_EQ(nullptr, actual_name);
  } else {
    EXPECT_EQ(friendly_name,
              std::string(reinterpret_cast<const char *>(actual_name),
                          static_cast<size_t>(actual_name_len)));
  }
}

static void TestCompat(bssl::Span<const uint8_t> der) {
  bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(der.data(), der.size()));
  ASSERT_TRUE(bio);

  bssl::UniquePtr<PKCS12> p12(d2i_PKCS12_bio(bio.get(), nullptr));
  ASSERT_TRUE(p12);

  ASSERT_FALSE(PKCS12_verify_mac(p12.get(), "badpass", 7));
  ASSERT_TRUE(PKCS12_verify_mac(p12.get(), kPassword, sizeof(kPassword) - 1));

  EVP_PKEY *key = nullptr;
  X509 *cert = nullptr;
  STACK_OF(X509) *ca_certs = nullptr;
  ASSERT_TRUE(PKCS12_parse(p12.get(), kPassword, &key, &cert, &ca_certs));

  bssl::UniquePtr<EVP_PKEY> delete_key(key);
  bssl::UniquePtr<X509> delete_cert(cert);
  bssl::UniquePtr<STACK_OF(X509)> delete_ca_certs(ca_certs);

  ASSERT_TRUE(key);
  ASSERT_TRUE(cert);
  ASSERT_EQ(0u, sk_X509_num(ca_certs));
}

TEST(PKCS12Test, TestOpenSSL) {
  // openssl.p12 was generated by OpenSSL with:
  //   openssl pkcs12 -export -inkey key.pem -in cacert.pem
  std::string data = GetTestData("crypto/pkcs8/test/openssl.p12");
  TestImpl("OpenSSL", StringToBytes(data), kPassword, nullptr);
}

TEST(PKCS12Test, TestNSS) {
  // nss.p12 is the result of importing the OpenSSL example PKCS#12 into Chrome
  // on Linux and then exporting it again.
  std::string data = GetTestData("crypto/pkcs8/test/nss.p12");
  TestImpl("NSS", StringToBytes(data), kPassword, "Internet Widgits Pty Ltd");
}

TEST(PKCS12Test, TestWindows) {
  // windows.p12 is a dummy key and certificate exported from the certificate
  // manager on Windows 7. It has a friendlyName, but only on the key, where we
  // ignore it, and not the certificate.
  std::string data = GetTestData("crypto/pkcs8/test/windows.p12");
  TestImpl("Windows", StringToBytes(data), kPassword, nullptr);
}

TEST(PKCS12Test, TestPBES2) {
  // pbes2_sha1.p12 is a PKCS#12 file using PBES2 and HMAC-SHA-1 created with:
  // openssl pkcs12 -export -inkey key.pem -in cert.pem -keypbe AES-128-CBC
  // -certpbe AES-128-CBC
  //
  // This was generated with an older OpenSSL, which used hmacWithSHA1 as the
  // PRF. (There is currently no way to specify the PRF in the pkcs12 command.)
  std::string data = GetTestData("crypto/pkcs8/test/pbes2_sha1.p12");
  TestImpl("kPBES2WithSHA1", StringToBytes(data), kPassword, nullptr);

  // pbes2_sha256.p12 is a PKCS#12 file using PBES2 and HMAC-SHA-256. It was
  // generated in the same way as pbes2_sha1.p12, but using OpenSSL 1.1.1b,
  // which uses hmacWithSHA256 as the PRF.
  data = GetTestData("crypto/pkcs8/test/pbes2_sha256.p12");
  TestImpl("kPBES2WithSHA256", StringToBytes(data), kPassword, nullptr);
}

TEST(PKCS12Test, TestNoEncryption) {
  // no_encryption.p12 is a PKCS#12 file with neither the key or certificate is
  // encrypted. It was generated with:
  //
  //   openssl pkcs12 -export -inkey ecdsa_p256_key.pem -in ecdsa_p256_cert.pem -keypbe NONE -certpbe NONE -password pass:foo
  std::string data = GetTestData("crypto/pkcs8/test/no_encryption.p12");
  TestImpl("kNoEncryption", StringToBytes(data), kPassword, nullptr);
}

TEST(PKCS12Test, TestEmptyPassword) {
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
  return;  // The MAC check always passes in fuzzer mode.
#endif

  // Generated with
  //   openssl pkcs12 -export -inkey ecdsa_p256_key.pem -in ecdsa_p256_cert.pem -password pass:  
  std::string data = GetTestData("crypto/pkcs8/test/empty_password.p12");
  TestImpl("EmptyPassword (empty password)", StringToBytes(data), "", nullptr);
  TestImpl("EmptyPassword (null password)", StringToBytes(data), nullptr,
           nullptr);
}

TEST(PKCS12Test, TestNullPassword) {
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
  return;  // The MAC check always passes in fuzzer mode.
#endif

  // Generated with
  //   openssl pkcs12 -export -inkey ecdsa_p256_key.pem -in ecdsa_p256_cert.pem -password pass:
  // But with OpenSSL patched to pass NULL into PKCS12_create and
  // PKCS12_set_mac.
  std::string data = GetTestData("crypto/pkcs8/test/null_password.p12");
  TestImpl("NullPassword (empty password)", StringToBytes(data), "", nullptr);
  TestImpl("NullPassword (null password)", StringToBytes(data), nullptr,
           nullptr);
}

TEST(PKCS12Test, TestUnicode) {
  // Generated with
  //   openssl pkcs12 -export -inkey ecdsa_p256_key.pem -in ecdsa_p256_cert.pem -password pass:"Hello, 世界"
  std::string data = GetTestData("crypto/pkcs8/test/unicode_password.p12");
  TestImpl("Unicode", StringToBytes(data), kUnicodePassword, nullptr);
}

TEST(PKCS12Test, TestWindowsCompat) {
  std::string data = GetTestData("crypto/pkcs8/test/windows.p12");
  TestCompat(StringToBytes(data));
}

// kTestKey is a test P-256 key.
static const uint8_t kTestKey[] = {
    0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
    0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
    0x03, 0x01, 0x07, 0x04, 0x6d, 0x30, 0x6b, 0x02, 0x01, 0x01, 0x04, 0x20,
    0x07, 0x0f, 0x08, 0x72, 0x7a, 0xd4, 0xa0, 0x4a, 0x9c, 0xdd, 0x59, 0xc9,
    0x4d, 0x89, 0x68, 0x77, 0x08, 0xb5, 0x6f, 0xc9, 0x5d, 0x30, 0x77, 0x0e,
    0xe8, 0xd1, 0xc9, 0xce, 0x0a, 0x8b, 0xb4, 0x6a, 0xa1, 0x44, 0x03, 0x42,
    0x00, 0x04, 0xe6, 0x2b, 0x69, 0xe2, 0xbf, 0x65, 0x9f, 0x97, 0xbe, 0x2f,
    0x1e, 0x0d, 0x94, 0x8a, 0x4c, 0xd5, 0x97, 0x6b, 0xb7, 0xa9, 0x1e, 0x0d,
    0x46, 0xfb, 0xdd, 0xa9, 0xa9, 0x1e, 0x9d, 0xdc, 0xba, 0x5a, 0x01, 0xe7,
    0xd6, 0x97, 0xa8, 0x0a, 0x18, 0xf9, 0xc3, 0xc4, 0xa3, 0x1e, 0x56, 0xe2,
    0x7c, 0x83, 0x48, 0xdb, 0x16, 0x1a, 0x1c, 0xf5, 0x1d, 0x7e, 0xf1, 0x94,
    0x2d, 0x4b, 0xcf, 0x72, 0x22, 0xc1};

// kTestCert is a certificate for |kTestKey|.
static const uint8_t kTestCert[] = {
    0x30, 0x82, 0x01, 0xcf, 0x30, 0x82, 0x01, 0x76, 0xa0, 0x03, 0x02, 0x01,
    0x02, 0x02, 0x09, 0x00, 0xd9, 0x4c, 0x04, 0xda, 0x49, 0x7d, 0xbf, 0xeb,
    0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01, 0x30,
    0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
    0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c,
    0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31,
    0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49, 0x6e,
    0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69,
    0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e,
    0x17, 0x0d, 0x31, 0x34, 0x30, 0x34, 0x32, 0x33, 0x32, 0x33, 0x32, 0x31,
    0x35, 0x37, 0x5a, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x35, 0x32, 0x33, 0x32,
    0x33, 0x32, 0x31, 0x35, 0x37, 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09,
    0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30,
    0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65,
    0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03,
    0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
    0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74,
    0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a,
    0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
    0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xe6, 0x2b, 0x69, 0xe2,
    0xbf, 0x65, 0x9f, 0x97, 0xbe, 0x2f, 0x1e, 0x0d, 0x94, 0x8a, 0x4c, 0xd5,
    0x97, 0x6b, 0xb7, 0xa9, 0x1e, 0x0d, 0x46, 0xfb, 0xdd, 0xa9, 0xa9, 0x1e,
    0x9d, 0xdc, 0xba, 0x5a, 0x01, 0xe7, 0xd6, 0x97, 0xa8, 0x0a, 0x18, 0xf9,
    0xc3, 0xc4, 0xa3, 0x1e, 0x56, 0xe2, 0x7c, 0x83, 0x48, 0xdb, 0x16, 0x1a,
    0x1c, 0xf5, 0x1d, 0x7e, 0xf1, 0x94, 0x2d, 0x4b, 0xcf, 0x72, 0x22, 0xc1,
    0xa3, 0x50, 0x30, 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
    0x16, 0x04, 0x14, 0xab, 0x84, 0xd2, 0xac, 0xab, 0x95, 0xf0, 0x82, 0x4e,
    0x16, 0x78, 0x07, 0x55, 0x57, 0x5f, 0xe4, 0x26, 0x8d, 0x82, 0xd1, 0x30,
    0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
    0xab, 0x84, 0xd2, 0xac, 0xab, 0x95, 0xf0, 0x82, 0x4e, 0x16, 0x78, 0x07,
    0x55, 0x57, 0x5f, 0xe4, 0x26, 0x8d, 0x82, 0xd1, 0x30, 0x0c, 0x06, 0x03,
    0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x09,
    0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01, 0x03, 0x48, 0x00,
    0x30, 0x45, 0x02, 0x21, 0x00, 0xf2, 0xa0, 0x35, 0x5e, 0x51, 0x3a, 0x36,
    0xc3, 0x82, 0x79, 0x9b, 0xee, 0x27, 0x50, 0x85, 0x8e, 0x70, 0x06, 0x74,
    0x95, 0x57, 0xd2, 0x29, 0x74, 0x00, 0xf4, 0xbe, 0x15, 0x87, 0x5d, 0xc4,
    0x07, 0x02, 0x20, 0x7c, 0x1e, 0x79, 0x14, 0x6a, 0x21, 0x83, 0xf0, 0x7a,
    0x74, 0x68, 0x79, 0x5f, 0x14, 0x99, 0x9a, 0x68, 0xb4, 0xf1, 0xcb, 0x9e,
    0x15, 0x5e, 0xe6, 0x1f, 0x32, 0x52, 0x61, 0x5e, 0x75, 0xc9, 0x14};

// kTestCert2 is a different test certificate.
static const uint8_t kTestCert2[] = {
    0x30, 0x82, 0x02, 0x65, 0x30, 0x82, 0x01, 0xeb, 0xa0, 0x03, 0x02, 0x01,
    0x02, 0x02, 0x09, 0x00, 0xdf, 0xbf, 0x2e, 0xe6, 0xe9, 0x0f, 0x0c, 0x4d,
    0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01, 0x30,
    0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
    0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
    0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31,
    0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e,
    0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69,
    0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e,
    0x17, 0x0d, 0x31, 0x36, 0x30, 0x37, 0x30, 0x39, 0x30, 0x30, 0x30, 0x31,
    0x33, 0x32, 0x5a, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x38, 0x30, 0x38, 0x30,
    0x30, 0x30, 0x31, 0x33, 0x32, 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09,
    0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30,
    0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65,
    0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03,
    0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
    0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74,
    0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2a,
    0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00,
    0x22, 0x03, 0x62, 0x00, 0x04, 0x0e, 0x75, 0x32, 0x4d, 0xab, 0x18, 0x99,
    0xf8, 0x1e, 0xbc, 0xb4, 0x26, 0x55, 0xe0, 0x61, 0x09, 0xc0, 0x32, 0x75,
    0xf2, 0x32, 0xbd, 0x80, 0x5c, 0xef, 0x79, 0xf7, 0x04, 0x01, 0x09, 0x6e,
    0x06, 0x28, 0xe3, 0xac, 0xc8, 0xdf, 0x94, 0xbf, 0x91, 0x64, 0x04, 0xfa,
    0xe0, 0x4c, 0x56, 0xcd, 0xe7, 0x51, 0x32, 0x9f, 0x4f, 0x0f, 0xd0, 0x96,
    0x4f, 0x3f, 0x61, 0x1b, 0xf2, 0xb3, 0xe2, 0xaf, 0xe5, 0xf7, 0x9d, 0x98,
    0xb0, 0x88, 0x72, 0xec, 0xb4, 0xc6, 0x5f, 0x3c, 0x32, 0xef, 0x9e, 0x3d,
    0x59, 0x43, 0xa2, 0xf8, 0xdd, 0xda, 0x5b, 0xca, 0x6c, 0x0e, 0x3b, 0x70,
    0xcd, 0x63, 0x59, 0x5e, 0xa5, 0xa3, 0x81, 0xa7, 0x30, 0x81, 0xa4, 0x30,
    0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa9, 0x98,
    0x3e, 0x30, 0x03, 0x70, 0xe9, 0x68, 0x80, 0xe3, 0x14, 0xe8, 0x3f, 0x70,
    0x95, 0xfb, 0x48, 0x58, 0xc8, 0xfa, 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d,
    0x23, 0x04, 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xa9, 0x98, 0x3e, 0x30, 0x03,
    0x70, 0xe9, 0x68, 0x80, 0xe3, 0x14, 0xe8, 0x3f, 0x70, 0x95, 0xfb, 0x48,
    0x58, 0xc8, 0xfa, 0xa1, 0x49, 0xa4, 0x47, 0x30, 0x45, 0x31, 0x0b, 0x30,
    0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13,
    0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d,
    0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06,
    0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e,
    0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50,
    0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, 0x00, 0xdf, 0xbf, 0x2e,
    0xe6, 0xe9, 0x0f, 0x0c, 0x4d, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13,
    0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x09, 0x06, 0x07, 0x2a,
    0x86, 0x48, 0xce, 0x3d, 0x04, 0x01, 0x03, 0x69, 0x00, 0x30, 0x66, 0x02,
    0x31, 0x00, 0xd3, 0x7c, 0xbd, 0x0e, 0x91, 0x11, 0xa7, 0x4b, 0x96, 0x5e,
    0xb6, 0xcc, 0x5a, 0x80, 0x0b, 0x99, 0xa8, 0xcd, 0x99, 0xca, 0xfe, 0x5a,
    0xda, 0x0e, 0xee, 0xe9, 0xe1, 0x4b, 0x0b, 0x1d, 0xab, 0xa5, 0x3b, 0x90,
    0x9d, 0xd5, 0x8e, 0xb4, 0x49, 0xe6, 0x56, 0x8d, 0xf0, 0x8d, 0x30, 0xed,
    0x90, 0x37, 0x02, 0x31, 0x00, 0xa0, 0xfb, 0x4e, 0x57, 0x4a, 0xa1, 0x05,
    0x72, 0xac, 0x5d, 0x5c, 0xc6, 0x49, 0x32, 0x1a, 0xa3, 0xda, 0x34, 0xbe,
    0xb5, 0x6b, 0x9c, 0x76, 0x00, 0xec, 0xb6, 0x9f, 0xf5, 0x2b, 0x32, 0x64,
    0x6e, 0xcb, 0xa9, 0x4a, 0x30, 0x73, 0x23, 0x27, 0x23, 0x54, 0x12, 0x8b,
    0x75, 0x1c, 0x2d, 0x36, 0x0f};

static bssl::UniquePtr<X509> LoadX509(bssl::Span<const uint8_t> der) {
  const uint8_t *ptr = der.data();
  return bssl::UniquePtr<X509>(d2i_X509(nullptr, &ptr, der.size()));
}

static bssl::UniquePtr<EVP_PKEY> LoadPrivateKey(bssl::Span<const uint8_t> der) {
  CBS cbs = der;
  return bssl::UniquePtr<EVP_PKEY>(EVP_parse_private_key(&cbs));
}

static void TestRoundTrip(const char *password, const char *name,
                          bssl::Span<const uint8_t> key_der,
                          bssl::Span<const uint8_t> cert_der,
                          std::vector<bssl::Span<const uint8_t>> chain_der,
                          int key_nid, int cert_nid, int iterations,
                          int mac_iterations) {
  bssl::UniquePtr<EVP_PKEY> key;
  if (!key_der.empty()) {
    key = LoadPrivateKey(key_der);
    ASSERT_TRUE(key);
  }
  bssl::UniquePtr<X509> cert;
  if (!cert_der.empty()) {
    cert = LoadX509(cert_der);
    ASSERT_TRUE(cert);
  }
  bssl::UniquePtr<STACK_OF(X509)> chain;
  if (!chain_der.empty()) {
    chain.reset(sk_X509_new_null());
    ASSERT_TRUE(chain);
    for (auto der : chain_der) {
      bssl::UniquePtr<X509> x509 = LoadX509(der);
      ASSERT_TRUE(x509);
      ASSERT_TRUE(bssl::PushToStack(chain.get(), std::move(x509)));
    }
  }

  // Make a PKCS#12 blob.
  bssl::UniquePtr<PKCS12> pkcs12(
      PKCS12_create(password, name, key.get(), cert.get(), chain.get(), key_nid,
                    cert_nid, iterations, mac_iterations, 0));
  ASSERT_TRUE(pkcs12);
  uint8_t *der = nullptr;
  int len = i2d_PKCS12(pkcs12.get(), &der);
  ASSERT_GT(len, 0);
  bssl::UniquePtr<uint8_t> free_der(der);

  // Check that the result round-trips.
  CBS cbs;
  CBS_init(&cbs, der, len);
  EVP_PKEY *key2 = nullptr;
  bssl::UniquePtr<STACK_OF(X509)> certs2(sk_X509_new_null());
  ASSERT_TRUE(certs2);
  ASSERT_TRUE(PKCS12_get_key_and_certs(&key2, certs2.get(), &cbs, password));
  bssl::UniquePtr<EVP_PKEY> free_key2(key2);
  // Note |EVP_PKEY_cmp| returns one for equality while |X509_cmp| returns zero.
  if (key) {
    EXPECT_EQ(1, EVP_PKEY_cmp(key2, key.get()));
  } else {
    EXPECT_FALSE(key2);
  }
  size_t offset = cert ? 1 : 0;
  ASSERT_EQ(offset + chain_der.size(), sk_X509_num(certs2.get()));
  if (cert) {
    EXPECT_EQ(0, X509_cmp(cert.get(), sk_X509_value(certs2.get(), 0)));
  }
  for (size_t i = 0; i < chain_der.size(); i++) {
    EXPECT_EQ(0, X509_cmp(sk_X509_value(chain.get(), i),
                          sk_X509_value(certs2.get(), i + offset)));
  }
  if (sk_X509_num(certs2.get()) > 0) {
    int actual_name_len;
    const uint8_t *actual_name =
        X509_alias_get0(sk_X509_value(certs2.get(), 0), &actual_name_len);
    if (name == NULL) {
      EXPECT_EQ(nullptr, actual_name);
    } else {
      EXPECT_EQ(name, std::string(reinterpret_cast<const char *>(actual_name),
                                  static_cast<size_t>(actual_name_len)));
    }
  }

  // Check that writing to a |BIO| does the same thing.
  bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
  ASSERT_TRUE(bio);
  ASSERT_TRUE(i2d_PKCS12_bio(bio.get(), pkcs12.get()));
  const uint8_t *bio_data;
  size_t bio_len;
  ASSERT_TRUE(BIO_mem_contents(bio.get(), &bio_data, &bio_len));
  EXPECT_EQ(Bytes(bio_data, bio_len), Bytes(der, len));
}

TEST(PKCS12Test, RoundTrip) {
  TestRoundTrip(kPassword, nullptr /* no name */,
                bssl::Span<const uint8_t>(kTestKey),
                bssl::Span<const uint8_t>(kTestCert),
                {bssl::Span<const uint8_t>(kTestCert2)}, 0, 0, 0, 0);

  // Test some Unicode.
  TestRoundTrip(kPassword, u8"Hello, 世界!",
                bssl::Span<const uint8_t>(kTestKey),
                bssl::Span<const uint8_t>(kTestCert),
                {bssl::Span<const uint8_t>(kTestCert2)}, 0, 0, 0, 0);
  TestRoundTrip(kUnicodePassword, nullptr /* no name */,
                bssl::Span<const uint8_t>(kTestKey),
                bssl::Span<const uint8_t>(kTestCert),
                {bssl::Span<const uint8_t>(kTestCert2)}, 0, 0, 0, 0);

  // Test various fields being missing.
  TestRoundTrip(kPassword, nullptr /* no name */, {} /* no key */,
                bssl::Span<const uint8_t>(kTestCert),
                {bssl::Span<const uint8_t>(kTestCert2)}, 0, 0, 0, 0);
  TestRoundTrip(
      kPassword, nullptr /* no name */, bssl::Span<const uint8_t>(kTestKey),
      bssl::Span<const uint8_t>(kTestCert), {} /* no chain */, 0, 0, 0, 0);
  TestRoundTrip(kPassword, nullptr /* no name */,
                bssl::Span<const uint8_t>(kTestKey), {} /* no leaf */,
                {} /* no chain */, 0, 0, 0, 0);

  // Test encryption parameters.
  TestRoundTrip(
      kPassword, nullptr /* no name */, bssl::Span<const uint8_t>(kTestKey),
      bssl::Span<const uint8_t>(kTestCert),
      {bssl::Span<const uint8_t>(kTestCert2)}, NID_pbe_WithSHA1And40BitRC2_CBC,
      NID_pbe_WithSHA1And40BitRC2_CBC, 100, 100);
  TestRoundTrip(
      kPassword, nullptr /* no name */, bssl::Span<const uint8_t>(kTestKey),
      bssl::Span<const uint8_t>(kTestCert),
      {bssl::Span<const uint8_t>(kTestCert2)}, NID_pbe_WithSHA1And128BitRC4,
      NID_pbe_WithSHA1And128BitRC4, 100, 100);
  TestRoundTrip(kPassword, nullptr /* no name */,
                bssl::Span<const uint8_t>(kTestKey),
                bssl::Span<const uint8_t>(kTestCert),
                {bssl::Span<const uint8_t>(kTestCert2)},
                NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
                NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 100, 100);

  // Test unencrypted and partially unencrypted PKCS#12 files.
  TestRoundTrip(kPassword, /*name=*/nullptr,
                bssl::Span<const uint8_t>(kTestKey),
                bssl::Span<const uint8_t>(kTestCert),
                {bssl::Span<const uint8_t>(kTestCert2)},
                /*key_nid=*/-1,
                /*cert_nid=*/-1, /*iterations=*/100, /*mac_iterations=*/100);
  TestRoundTrip(kPassword, /*name=*/nullptr,
                bssl::Span<const uint8_t>(kTestKey),
                bssl::Span<const uint8_t>(kTestCert),
                {bssl::Span<const uint8_t>(kTestCert2)},
                /*key_nid=*/NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
                /*cert_nid=*/-1, /*iterations=*/100, /*mac_iterations=*/100);
  TestRoundTrip(kPassword, /*name=*/nullptr,
                bssl::Span<const uint8_t>(kTestKey),
                bssl::Span<const uint8_t>(kTestCert),
                {bssl::Span<const uint8_t>(kTestCert2)},
                /*key_nid=*/-1,
                /*cert_nid=*/NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
                /*iterations=*/100, /*mac_iterations=*/100);
}

static bssl::UniquePtr<EVP_PKEY> MakeTestKey() {
  bssl::UniquePtr<EC_KEY> ec_key(
      EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
  if (!ec_key ||
      !EC_KEY_generate_key(ec_key.get())) {
    return nullptr;
  }
  bssl::UniquePtr<EVP_PKEY> evp_pkey(EVP_PKEY_new());
  if (!evp_pkey ||
      !EVP_PKEY_assign_EC_KEY(evp_pkey.get(), ec_key.release())) {
    return nullptr;
  }
  return evp_pkey;
}

static bssl::UniquePtr<X509> MakeTestCert(EVP_PKEY *key) {
  bssl::UniquePtr<X509> x509(X509_new());
  if (!x509) {
    return nullptr;
  }
  X509_NAME* subject = X509_get_subject_name(x509.get());
  if (!X509_gmtime_adj(X509_get_notBefore(x509.get()), 0) ||
      !X509_gmtime_adj(X509_get_notAfter(x509.get()), 60 * 60 * 24) ||
      !X509_NAME_add_entry_by_txt(subject, "CN", MBSTRING_ASC,
                                  reinterpret_cast<const uint8_t *>("Test"), -1,
                                  -1, 0) ||
      !X509_set_issuer_name(x509.get(), subject) ||
      !X509_set_pubkey(x509.get(), key) ||
      !X509_sign(x509.get(), key, EVP_sha256())) {
    return nullptr;
  }
  return x509;
}

static bool PKCS12CreateVector(std::vector<uint8_t> *out, EVP_PKEY *pkey,
                               const std::vector<X509 *> &certs) {
  bssl::UniquePtr<STACK_OF(X509)> chain(sk_X509_new_null());
  if (!chain) {
    return false;
  }

  for (X509 *cert : certs) {
    if (!bssl::PushToStack(chain.get(), bssl::UpRef(cert))) {
      return false;
    }
  }

  bssl::UniquePtr<PKCS12> p12(PKCS12_create(kPassword, nullptr /* name */, pkey,
                                            nullptr /* cert */, chain.get(), 0,
                                            0, 0, 0, 0));
  if (!p12) {
    return false;
  }

  int len = i2d_PKCS12(p12.get(), nullptr);
  if (len < 0) {
    return false;
  }
  out->resize(static_cast<size_t>(len));
  uint8_t *ptr = out->data();
  return i2d_PKCS12(p12.get(), &ptr) == len;
}

static void ExpectPKCS12Parse(bssl::Span<const uint8_t> in,
                              EVP_PKEY *expect_key, X509 *expect_cert,
                              const std::vector<X509 *> &expect_ca_certs) {
  bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(in.data(), in.size()));
  ASSERT_TRUE(bio);

  bssl::UniquePtr<PKCS12> p12(d2i_PKCS12_bio(bio.get(), nullptr));
  ASSERT_TRUE(p12);

  EVP_PKEY *key = nullptr;
  X509 *cert = nullptr;
  STACK_OF(X509) *ca_certs = nullptr;
  ASSERT_TRUE(PKCS12_parse(p12.get(), kPassword, &key, &cert, &ca_certs));

  bssl::UniquePtr<EVP_PKEY> delete_key(key);
  bssl::UniquePtr<X509> delete_cert(cert);
  bssl::UniquePtr<STACK_OF(X509)> delete_ca_certs(ca_certs);

  if (expect_key == nullptr) {
    EXPECT_FALSE(key);
  } else {
    ASSERT_TRUE(key);
    EXPECT_EQ(1, EVP_PKEY_cmp(key, expect_key));
  }

  if (expect_cert == nullptr) {
    EXPECT_FALSE(cert);
  } else {
    ASSERT_TRUE(cert);
    EXPECT_EQ(0, X509_cmp(cert, expect_cert));
  }

  ASSERT_EQ(expect_ca_certs.size(), sk_X509_num(ca_certs));
  for (size_t i = 0; i < expect_ca_certs.size(); i++) {
    EXPECT_EQ(0, X509_cmp(expect_ca_certs[i], sk_X509_value(ca_certs, i)));
  }
}

// Test that |PKCS12_parse| returns values in the expected order.
TEST(PKCS12Test, Order) {
  bssl::UniquePtr<EVP_PKEY> key1 = MakeTestKey();
  ASSERT_TRUE(key1);
  bssl::UniquePtr<X509> cert1 = MakeTestCert(key1.get());
  ASSERT_TRUE(cert1);
  bssl::UniquePtr<X509> cert1b = MakeTestCert(key1.get());
  ASSERT_TRUE(cert1b);
  bssl::UniquePtr<EVP_PKEY> key2 = MakeTestKey();
  ASSERT_TRUE(key2);
  bssl::UniquePtr<X509> cert2 = MakeTestCert(key2.get());
  ASSERT_TRUE(cert2);
  bssl::UniquePtr<EVP_PKEY> key3 = MakeTestKey();
  ASSERT_TRUE(key3);
  bssl::UniquePtr<X509> cert3 = MakeTestCert(key3.get());
  ASSERT_TRUE(cert3);

  // PKCS12_parse uses the key to select the main certificate.
  std::vector<uint8_t> p12;
  ASSERT_TRUE(PKCS12CreateVector(&p12, key1.get(),
                                 {cert1.get(), cert2.get(), cert3.get()}));
  ExpectPKCS12Parse(p12, key1.get(), cert1.get(), {cert2.get(), cert3.get()});

  ASSERT_TRUE(PKCS12CreateVector(&p12, key1.get(),
                                 {cert3.get(), cert1.get(), cert2.get()}));
  ExpectPKCS12Parse(p12, key1.get(), cert1.get(), {cert3.get(), cert2.get()});

  ASSERT_TRUE(PKCS12CreateVector(&p12, key1.get(),
                                 {cert2.get(), cert3.get(), cert1.get()}));
  ExpectPKCS12Parse(p12, key1.get(), cert1.get(), {cert2.get(), cert3.get()});

  // In case of duplicates, the last one is selected. (It is unlikely anything
  // depends on which is selected, but we match OpenSSL.)
  ASSERT_TRUE(
      PKCS12CreateVector(&p12, key1.get(), {cert1.get(), cert1b.get()}));
  ExpectPKCS12Parse(p12, key1.get(), cert1b.get(), {cert1.get()});

  // If there is no key, all certificates are returned as "CA" certificates.
  ASSERT_TRUE(PKCS12CreateVector(&p12, nullptr,
                                 {cert1.get(), cert2.get(), cert3.get()}));
  ExpectPKCS12Parse(p12, nullptr, nullptr,
                    {cert1.get(), cert2.get(), cert3.get()});

  // The same happens if there is a key, but it does not match any certificate.
  ASSERT_TRUE(PKCS12CreateVector(&p12, key1.get(), {cert2.get(), cert3.get()}));
  ExpectPKCS12Parse(p12, key1.get(), nullptr, {cert2.get(), cert3.get()});
}
