// 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) {
  // 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) {
  // 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);
  if (key) {
    EXPECT_EQ(1, EVP_PKEY_eq(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 == nullptr) {
      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 */, kTestKey, kTestCert,
                {kTestCert2}, 0, 0, 0, 0);

  // Test some Unicode.
  TestRoundTrip(kPassword, "Hello, 世界!", kTestKey, kTestCert, {kTestCert2}, 0,
                0, 0, 0);
  TestRoundTrip(kUnicodePassword, nullptr /* no name */, kTestKey, kTestCert,
                {kTestCert2}, 0, 0, 0, 0);

  // Test various fields being missing.
  TestRoundTrip(kPassword, nullptr /* no name */, {} /* no key */, kTestCert,
                {kTestCert2}, 0, 0, 0, 0);
  TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
                {} /* no chain */, 0, 0, 0, 0);
  TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, {} /* no leaf */,
                {} /* no chain */, 0, 0, 0, 0);

  // Test encryption parameters.
  TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
                {kTestCert2}, NID_pbe_WithSHA1And40BitRC2_CBC,
                NID_pbe_WithSHA1And40BitRC2_CBC, 100, 100);
  TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
                {kTestCert2}, NID_pbe_WithSHA1And128BitRC4,
                NID_pbe_WithSHA1And128BitRC4, 100, 100);
  TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
                {kTestCert2}, NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
                NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 100, 100);

  // PBES2 ciphers.
  TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
                {kTestCert2}, NID_rc2_cbc, NID_rc2_cbc, 100, 100);
  TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
                {kTestCert2}, NID_des_ede3_cbc, NID_des_ede3_cbc, 100, 100);
  TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
                {kTestCert2}, NID_aes_128_cbc, NID_aes_128_cbc, 100, 100);
  TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
                {kTestCert2}, NID_aes_192_cbc, NID_aes_192_cbc, 100, 100);
  TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
                {kTestCert2}, NID_aes_256_cbc, NID_aes_256_cbc, 100, 100);

  // Mix and match.
  TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
                {kTestCert2}, NID_pbe_WithSHA1And40BitRC2_CBC,
                NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 100, 100);
  TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
                {kTestCert2}, NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
                NID_aes_256_cbc, 100, 100);
  TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
                {kTestCert2}, NID_aes_256_cbc,
                NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 100, 100);
  TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
                {kTestCert2}, NID_aes_128_cbc, NID_aes_256_cbc, 100, 100);

  // Test unencrypted and partially unencrypted PKCS#12 files.
  TestRoundTrip(kPassword, /*name=*/nullptr, kTestKey, kTestCert, {kTestCert2},
                /*key_nid=*/-1,
                /*cert_nid=*/-1, /*iterations=*/100, /*mac_iterations=*/100);
  TestRoundTrip(kPassword, /*name=*/nullptr, kTestKey, kTestCert, {kTestCert2},
                /*key_nid=*/NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
                /*cert_nid=*/-1, /*iterations=*/100, /*mac_iterations=*/100);
  TestRoundTrip(kPassword, /*name=*/nullptr, kTestKey, kTestCert, {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_eq(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, ""));
  }
}
