/* Copyright 2014 The BoringSSL Authors
 *
 * 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_data.h"
#include "../test/test_util.h"


// 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[] = "Hello, 世界";

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, bssl::BytesAsStringView(
                                 bssl::Span(actual_name, 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", bssl::StringAsBytes(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", bssl::StringAsBytes(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", bssl::StringAsBytes(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", bssl::StringAsBytes(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", bssl::StringAsBytes(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", bssl::StringAsBytes(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)", bssl::StringAsBytes(data), "",
           nullptr);
  TestImpl("EmptyPassword (null password)", bssl::StringAsBytes(data), nullptr,
           nullptr);

  // The above input, modified to have a constructed string.
  data = GetTestData("crypto/pkcs8/test/empty_password_ber.p12");
  TestImpl("EmptyPassword (BER, empty password)", bssl::StringAsBytes(data), "",
           nullptr);
  TestImpl("EmptyPassword (BER, null password)", bssl::StringAsBytes(data),
           nullptr, nullptr);

  // The constructed string with too much recursion.
  data = GetTestData("crypto/pkcs8/test/empty_password_ber_nested.p12");
  bssl::UniquePtr<STACK_OF(X509)> certs(sk_X509_new_null());
  ASSERT_TRUE(certs);
  EVP_PKEY *key = nullptr;
  CBS pkcs12 = bssl::StringAsBytes(data);
  EXPECT_FALSE(PKCS12_get_key_and_certs(&key, certs.get(), &pkcs12, ""));
}

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)", bssl::StringAsBytes(data), "",
           nullptr);
  TestImpl("NullPassword (null password)", bssl::StringAsBytes(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", bssl::StringAsBytes(data), kUnicodePassword, nullptr);
}

TEST(PKCS12Test, TestWindowsCompat) {
  std::string data = GetTestData("crypto/pkcs8/test/windows.p12");
  TestCompat(bssl::StringAsBytes(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, bssl::BytesAsStringView(
                          bssl::Span(actual_name, 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, "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()});
}

TEST(PKCS12Test, CreateWithAlias) {
  bssl::UniquePtr<EVP_PKEY> key = MakeTestKey();
  ASSERT_TRUE(key);
  bssl::UniquePtr<X509> cert1 = MakeTestCert(key.get());
  ASSERT_TRUE(cert1);
  bssl::UniquePtr<X509> cert2 = MakeTestCert(key.get());
  ASSERT_TRUE(cert2);

  std::string alias = "I'm an alias";
  int res = X509_alias_set1(
      cert1.get(), reinterpret_cast<const unsigned char *>(alias.data()),
      alias.size());
  ASSERT_EQ(res, 1);

  std::vector<X509 *> certs = {cert1.get(), cert2.get()};
  std::vector<uint8_t> der;
  ASSERT_TRUE(PKCS12CreateVector(&der, key.get(), certs));

  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);

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

  bssl::UniquePtr<EVP_PKEY> delete_key(parsed_key);
  bssl::UniquePtr<X509> delete_cert(parsed_cert);
  bssl::UniquePtr<STACK_OF(X509)> delete_ca_certs(ca_certs);
  ASSERT_EQ(sk_X509_num(ca_certs), 1UL);

  int alias_len = 0;
  const unsigned char *parsed_alias =
      X509_alias_get0(sk_X509_value(ca_certs, 0), &alias_len);
  ASSERT_TRUE(parsed_alias);
  ASSERT_EQ(alias,
            bssl::BytesAsStringView(bssl::Span(parsed_alias, alias_len)));
}

// PKCS#12 is built on top of PKCS#7, a misdesigned, overgeneralized combinator
// format. One of the features of PKCS#7 is that the content of every
// ContentInfo may be omitted, to indicate that the value is "supplied by other
// means". This is commonly used for "detached signatures", where the signature
// is supplied separately.
//
// This does not make sense in the context of PKCS#12. But because PKCS#7
// combined many unrelated use cases into the same format, so PKCS#12 (and any
// other use of PKCS#7) must account for and reject inputs.
TEST(PKCS12Test, MissingContent) {
  {
    std::string data = GetTestData("crypto/pkcs8/test/bad1.p12");
    bssl::UniquePtr<STACK_OF(X509)> certs(sk_X509_new_null());
    ASSERT_TRUE(certs);
    EVP_PKEY *key = nullptr;
    CBS cbs = bssl::StringAsBytes(data);
    EXPECT_FALSE(PKCS12_get_key_and_certs(&key, certs.get(), &cbs, ""));
  }
  {
    std::string data = GetTestData("crypto/pkcs8/test/bad2.p12");
    bssl::UniquePtr<STACK_OF(X509)> certs(sk_X509_new_null());
    ASSERT_TRUE(certs);
    EVP_PKEY *key = nullptr;
    CBS cbs = bssl::StringAsBytes(data);
    EXPECT_FALSE(PKCS12_get_key_and_certs(&key, certs.get(), &cbs, ""));
  }
  {
    std::string data = GetTestData("crypto/pkcs8/test/bad3.p12");
    bssl::UniquePtr<STACK_OF(X509)> certs(sk_X509_new_null());
    ASSERT_TRUE(certs);
    EVP_PKEY *key = nullptr;
    CBS cbs = bssl::StringAsBytes(data);
    EXPECT_FALSE(PKCS12_get_key_and_certs(&key, certs.get(), &cbs, ""));
  }
}
