// Copyright 2014 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#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, ""));
  }
}
