// Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
//
// 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 <openssl/pkcs8.h>

#include <limits.h>

#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/bio.h>
#include <openssl/buf.h>
#include <openssl/bytestring.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/mem.h>
#include <openssl/rand.h>
#include <openssl/x509.h>

#include "../bytestring/internal.h"
#include "../internal.h"
#include "../x509/internal.h"
#include "internal.h"


int pkcs12_iterations_acceptable(uint64_t iterations) {
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
  static const uint64_t kIterationsLimit = 2048;
#else
  // Windows imposes a limit of 600K. Mozilla say: “so them increasing
  // maximum to something like 100M or 1G (to have few decades of breathing
  // room) would be very welcome”[1]. So here we set the limit to 100M.
  //
  // [1] https://bugzilla.mozilla.org/show_bug.cgi?id=1436873#c14
  static const uint64_t kIterationsLimit = 100 * 1000000;
#endif

  assert(kIterationsLimit <= UINT32_MAX);
  return 0 < iterations && iterations <= kIterationsLimit;
}

ASN1_SEQUENCE(PKCS8_PRIV_KEY_INFO) = {
    ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, version, ASN1_INTEGER),
    ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkeyalg, X509_ALGOR),
    ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkey, ASN1_OCTET_STRING),
    ASN1_IMP_SET_OF_OPT(PKCS8_PRIV_KEY_INFO, attributes, X509_ATTRIBUTE, 0),
} ASN1_SEQUENCE_END(PKCS8_PRIV_KEY_INFO)

IMPLEMENT_ASN1_FUNCTIONS_const(PKCS8_PRIV_KEY_INFO)

EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8) {
  uint8_t *der = NULL;
  int der_len = i2d_PKCS8_PRIV_KEY_INFO(p8, &der);
  if (der_len < 0) {
    return NULL;
  }

  CBS cbs;
  CBS_init(&cbs, der, (size_t)der_len);
  EVP_PKEY *ret = EVP_parse_private_key(&cbs);
  if (ret == NULL || CBS_len(&cbs) != 0) {
    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
    EVP_PKEY_free(ret);
    OPENSSL_free(der);
    return NULL;
  }

  OPENSSL_free(der);
  return ret;
}

PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(const EVP_PKEY *pkey) {
  CBB cbb;
  uint8_t *der = NULL;
  size_t der_len;
  if (!CBB_init(&cbb, 0) || !EVP_marshal_private_key(&cbb, pkey) ||
      !CBB_finish(&cbb, &der, &der_len) || der_len > LONG_MAX) {
    CBB_cleanup(&cbb);
    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_ENCODE_ERROR);
    OPENSSL_free(der);
    return NULL;
  }

  const uint8_t *p = der;
  PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, (long)der_len);
  if (p8 == NULL || p != der + der_len) {
    PKCS8_PRIV_KEY_INFO_free(p8);
    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
    goto err;
  }

  OPENSSL_free(der);
  return p8;

err:
  OPENSSL_free(der);
  return NULL;
}

PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *pkcs8, const char *pass,
                                   int pass_len_in) {
  size_t pass_len;
  if (pass_len_in == -1 && pass != NULL) {
    pass_len = strlen(pass);
  } else {
    pass_len = (size_t)pass_len_in;
  }

  PKCS8_PRIV_KEY_INFO *ret = NULL;
  EVP_PKEY *pkey = NULL;
  uint8_t *in = NULL;

  // Convert the legacy ASN.1 object to a byte string.
  int in_len = i2d_X509_SIG(pkcs8, &in);
  if (in_len < 0) {
    goto err;
  }

  CBS cbs;
  CBS_init(&cbs, in, in_len);
  pkey = PKCS8_parse_encrypted_private_key(&cbs, pass, pass_len);
  if (pkey == NULL || CBS_len(&cbs) != 0) {
    goto err;
  }

  ret = EVP_PKEY2PKCS8(pkey);

err:
  OPENSSL_free(in);
  EVP_PKEY_free(pkey);
  return ret;
}

X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, const char *pass,
                        int pass_len_in, const uint8_t *salt, size_t salt_len,
                        int iterations, PKCS8_PRIV_KEY_INFO *p8inf) {
  size_t pass_len;
  if (pass_len_in == -1 && pass != NULL) {
    pass_len = strlen(pass);
  } else {
    pass_len = (size_t)pass_len_in;
  }

  // Parse out the private key.
  EVP_PKEY *pkey = EVP_PKCS82PKEY(p8inf);
  if (pkey == NULL) {
    return NULL;
  }

  X509_SIG *ret = NULL;
  uint8_t *der = NULL;
  const uint8_t *ptr;
  size_t der_len;
  CBB cbb;
  if (!CBB_init(&cbb, 128) ||
      !PKCS8_marshal_encrypted_private_key(&cbb, pbe_nid, cipher, pass,
                                           pass_len, salt, salt_len, iterations,
                                           pkey) ||
      !CBB_finish(&cbb, &der, &der_len)) {
    CBB_cleanup(&cbb);
    goto err;
  }

  // Convert back to legacy ASN.1 objects.
  ptr = der;
  ret = d2i_X509_SIG(NULL, &ptr, der_len);
  if (ret == NULL || ptr != der + der_len) {
    OPENSSL_PUT_ERROR(PKCS8, ERR_R_INTERNAL_ERROR);
    X509_SIG_free(ret);
    ret = NULL;
  }

err:
  OPENSSL_free(der);
  EVP_PKEY_free(pkey);
  return ret;
}

struct pkcs12_context {
  EVP_PKEY **out_key;
  STACK_OF(X509) *out_certs;
  const char *password;
  size_t password_len;
};

// PKCS12_handle_sequence parses a BER-encoded SEQUENCE of elements in a PKCS#12
// structure.
static int PKCS12_handle_sequence(
    CBS *sequence, struct pkcs12_context *ctx,
    int (*handle_element)(CBS *cbs, struct pkcs12_context *ctx)) {
  uint8_t *storage = NULL;
  CBS in;
  int ret = 0;

  // Although a BER->DER conversion is done at the beginning of |PKCS12_parse|,
  // the ASN.1 data gets wrapped in OCTETSTRINGs and/or encrypted and the
  // conversion cannot see through those wrappings. So each time we step
  // through one we need to convert to DER again.
  if (!CBS_asn1_ber_to_der(sequence, &in, &storage)) {
    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
    return 0;
  }

  CBS child;
  if (!CBS_get_asn1(&in, &child, CBS_ASN1_SEQUENCE) || CBS_len(&in) != 0) {
    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
    goto err;
  }

  while (CBS_len(&child) > 0) {
    CBS element;
    if (!CBS_get_asn1(&child, &element, CBS_ASN1_SEQUENCE)) {
      OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
      goto err;
    }

    if (!handle_element(&element, ctx)) {
      goto err;
    }
  }

  ret = 1;

err:
  OPENSSL_free(storage);
  return ret;
}

// 1.2.840.113549.1.12.10.1.1
static const uint8_t kKeyBag[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
                                  0x01, 0x0c, 0x0a, 0x01, 0x01};

// 1.2.840.113549.1.12.10.1.2
static const uint8_t kPKCS8ShroudedKeyBag[] = {
    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x02};

// 1.2.840.113549.1.12.10.1.3
static const uint8_t kCertBag[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
                                   0x01, 0x0c, 0x0a, 0x01, 0x03};

// 1.2.840.113549.1.9.20
static const uint8_t kFriendlyName[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
                                        0x0d, 0x01, 0x09, 0x14};

// 1.2.840.113549.1.9.21
static const uint8_t kLocalKeyID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
                                      0x0d, 0x01, 0x09, 0x15};

// 1.2.840.113549.1.9.22.1
static const uint8_t kX509Certificate[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
                                           0x0d, 0x01, 0x09, 0x16, 0x01};

// parse_bag_attributes parses the bagAttributes field of a SafeBag structure.
// It sets |*out_friendly_name| to a newly-allocated copy of the friendly name,
// encoded as a UTF-8 string, or NULL if there is none. It returns one on
// success and zero on error.
static int parse_bag_attributes(CBS *attrs, uint8_t **out_friendly_name,
                                size_t *out_friendly_name_len) {
  *out_friendly_name = NULL;
  *out_friendly_name_len = 0;

  // See https://tools.ietf.org/html/rfc7292#section-4.2.
  while (CBS_len(attrs) != 0) {
    CBS attr, oid, values;
    if (!CBS_get_asn1(attrs, &attr, CBS_ASN1_SEQUENCE) ||
        !CBS_get_asn1(&attr, &oid, CBS_ASN1_OBJECT) ||
        !CBS_get_asn1(&attr, &values, CBS_ASN1_SET) || CBS_len(&attr) != 0) {
      OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
      goto err;
    }
    if (CBS_mem_equal(&oid, kFriendlyName, sizeof(kFriendlyName))) {
      // See https://tools.ietf.org/html/rfc2985, section 5.5.1.
      CBS value;
      if (*out_friendly_name != NULL ||
          !CBS_get_asn1(&values, &value, CBS_ASN1_BMPSTRING) ||
          CBS_len(&values) != 0 || CBS_len(&value) == 0) {
        OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
        goto err;
      }
      // Convert the friendly name to UTF-8.
      CBB cbb;
      if (!CBB_init(&cbb, CBS_len(&value))) {
        goto err;
      }
      while (CBS_len(&value) != 0) {
        uint32_t c;
        if (!CBS_get_ucs2_be(&value, &c) || !CBB_add_utf8(&cbb, c)) {
          OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_INVALID_CHARACTERS);
          CBB_cleanup(&cbb);
          goto err;
        }
      }
      if (!CBB_finish(&cbb, out_friendly_name, out_friendly_name_len)) {
        CBB_cleanup(&cbb);
        goto err;
      }
    }
  }

  return 1;

err:
  OPENSSL_free(*out_friendly_name);
  *out_friendly_name = NULL;
  *out_friendly_name_len = 0;
  return 0;
}

// PKCS12_handle_safe_bag parses a single SafeBag element in a PKCS#12
// structure.
static int PKCS12_handle_safe_bag(CBS *safe_bag, struct pkcs12_context *ctx) {
  CBS bag_id, wrapped_value, bag_attrs;
  if (!CBS_get_asn1(safe_bag, &bag_id, CBS_ASN1_OBJECT) ||
      !CBS_get_asn1(safe_bag, &wrapped_value,
                    CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) {
    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
    return 0;
  }
  if (CBS_len(safe_bag) == 0) {
    CBS_init(&bag_attrs, NULL, 0);
  } else if (!CBS_get_asn1(safe_bag, &bag_attrs, CBS_ASN1_SET) ||
             CBS_len(safe_bag) != 0) {
    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
    return 0;
  }

  const int is_key_bag = CBS_mem_equal(&bag_id, kKeyBag, sizeof(kKeyBag));
  const int is_shrouded_key_bag = CBS_mem_equal(&bag_id, kPKCS8ShroudedKeyBag,
                                                sizeof(kPKCS8ShroudedKeyBag));
  if (is_key_bag || is_shrouded_key_bag) {
    // See RFC 7292, section 4.2.1 and 4.2.2.
    if (*ctx->out_key) {
      OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_MULTIPLE_PRIVATE_KEYS_IN_PKCS12);
      return 0;
    }

    EVP_PKEY *pkey =
        is_key_bag ? EVP_parse_private_key(&wrapped_value)
                   : PKCS8_parse_encrypted_private_key(
                         &wrapped_value, ctx->password, ctx->password_len);
    if (pkey == NULL) {
      return 0;
    }

    if (CBS_len(&wrapped_value) != 0) {
      OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
      EVP_PKEY_free(pkey);
      return 0;
    }

    *ctx->out_key = pkey;
    return 1;
  }

  if (CBS_mem_equal(&bag_id, kCertBag, sizeof(kCertBag))) {
    // See RFC 7292, section 4.2.3.
    CBS cert_bag, cert_type, wrapped_cert, cert;
    if (!CBS_get_asn1(&wrapped_value, &cert_bag, CBS_ASN1_SEQUENCE) ||
        !CBS_get_asn1(&cert_bag, &cert_type, CBS_ASN1_OBJECT) ||
        !CBS_get_asn1(&cert_bag, &wrapped_cert,
                      CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
        !CBS_get_asn1(&wrapped_cert, &cert, CBS_ASN1_OCTETSTRING)) {
      OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
      return 0;
    }

    // Skip unknown certificate types.
    if (!CBS_mem_equal(&cert_type, kX509Certificate,
                       sizeof(kX509Certificate))) {
      return 1;
    }

    if (CBS_len(&cert) > LONG_MAX) {
      OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
      return 0;
    }

    const uint8_t *inp = CBS_data(&cert);
    X509 *x509 = d2i_X509(NULL, &inp, (long)CBS_len(&cert));
    if (!x509) {
      OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
      return 0;
    }

    if (inp != CBS_data(&cert) + CBS_len(&cert)) {
      OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
      X509_free(x509);
      return 0;
    }

    uint8_t *friendly_name;
    size_t friendly_name_len;
    if (!parse_bag_attributes(&bag_attrs, &friendly_name, &friendly_name_len)) {
      X509_free(x509);
      return 0;
    }
    int ok = friendly_name_len == 0 ||
             X509_alias_set1(x509, friendly_name, friendly_name_len);
    OPENSSL_free(friendly_name);
    if (!ok || 0 == sk_X509_push(ctx->out_certs, x509)) {
      X509_free(x509);
      return 0;
    }

    return 1;
  }

  // Unknown element type - ignore it.
  return 1;
}

// 1.2.840.113549.1.7.1
static const uint8_t kPKCS7Data[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
                                     0x0d, 0x01, 0x07, 0x01};

// 1.2.840.113549.1.7.6
static const uint8_t kPKCS7EncryptedData[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
                                              0x0d, 0x01, 0x07, 0x06};

// PKCS12_handle_content_info parses a single PKCS#7 ContentInfo element in a
// PKCS#12 structure.
static int PKCS12_handle_content_info(CBS *content_info,
                                      struct pkcs12_context *ctx) {
  CBS content_type, wrapped_contents, contents;
  int ret = 0;
  uint8_t *storage = NULL;

  if (!CBS_get_asn1(content_info, &content_type, CBS_ASN1_OBJECT) ||
      !CBS_get_asn1(content_info, &wrapped_contents,
                    CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
      CBS_len(content_info) != 0) {
    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
    goto err;
  }

  if (CBS_mem_equal(&content_type, kPKCS7EncryptedData,
                    sizeof(kPKCS7EncryptedData))) {
    // See https://tools.ietf.org/html/rfc2315#section-13.
    //
    // PKCS#7 encrypted data inside a PKCS#12 structure is generally an
    // encrypted certificate bag and it's generally encrypted with 40-bit
    // RC2-CBC.
    CBS version_bytes, eci, contents_type, ai, encrypted_contents;
    uint8_t *out;
    size_t out_len;

    if (!CBS_get_asn1(&wrapped_contents, &contents, CBS_ASN1_SEQUENCE) ||
        !CBS_get_asn1(&contents, &version_bytes, CBS_ASN1_INTEGER) ||
        // EncryptedContentInfo, see
        // https://tools.ietf.org/html/rfc2315#section-10.1
        !CBS_get_asn1(&contents, &eci, CBS_ASN1_SEQUENCE) ||
        !CBS_get_asn1(&eci, &contents_type, CBS_ASN1_OBJECT) ||
        // AlgorithmIdentifier, see
        // https://tools.ietf.org/html/rfc5280#section-4.1.1.2
        !CBS_get_asn1(&eci, &ai, CBS_ASN1_SEQUENCE) ||
        !CBS_get_asn1_implicit_string(&eci, &encrypted_contents, &storage,
                                      CBS_ASN1_CONTEXT_SPECIFIC | 0,
                                      CBS_ASN1_OCTETSTRING)) {
      OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
      goto err;
    }

    if (!CBS_mem_equal(&contents_type, kPKCS7Data, sizeof(kPKCS7Data))) {
      OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
      goto err;
    }

    if (!pkcs8_pbe_decrypt(&out, &out_len, &ai, ctx->password,
                           ctx->password_len, CBS_data(&encrypted_contents),
                           CBS_len(&encrypted_contents))) {
      goto err;
    }

    CBS safe_contents;
    CBS_init(&safe_contents, out, out_len);
    ret = PKCS12_handle_sequence(&safe_contents, ctx, PKCS12_handle_safe_bag);
    OPENSSL_free(out);
  } else if (CBS_mem_equal(&content_type, kPKCS7Data, sizeof(kPKCS7Data))) {
    CBS octet_string_contents;

    if (!CBS_get_asn1(&wrapped_contents, &octet_string_contents,
                      CBS_ASN1_OCTETSTRING)) {
      OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
      goto err;
    }

    ret = PKCS12_handle_sequence(&octet_string_contents, ctx,
                                 PKCS12_handle_safe_bag);
  } else {
    // Unknown element type - ignore it.
    ret = 1;
  }

err:
  OPENSSL_free(storage);
  return ret;
}

static int pkcs12_check_mac(int *out_mac_ok, const char *password,
                            size_t password_len, const CBS *salt,
                            uint32_t iterations, const EVP_MD *md,
                            const CBS *authsafes, const CBS *expected_mac) {
  int ret = 0;
  uint8_t hmac_key[EVP_MAX_MD_SIZE];
  if (!pkcs12_key_gen(password, password_len, CBS_data(salt), CBS_len(salt),
                      PKCS12_MAC_ID, iterations, EVP_MD_size(md), hmac_key,
                      md)) {
    goto err;
  }

  uint8_t hmac[EVP_MAX_MD_SIZE];
  unsigned hmac_len;
  if (NULL == HMAC(md, hmac_key, EVP_MD_size(md), CBS_data(authsafes),
                   CBS_len(authsafes), hmac, &hmac_len)) {
    goto err;
  }

  *out_mac_ok = CBS_mem_equal(expected_mac, hmac, hmac_len);
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
  *out_mac_ok = 1;
#endif
  ret = 1;

err:
  OPENSSL_cleanse(hmac_key, sizeof(hmac_key));
  return ret;
}


int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs,
                             CBS *ber_in, const char *password) {
  uint8_t *storage = NULL;
  CBS in, pfx, mac_data, authsafe, content_type, wrapped_authsafes, authsafes;
  uint64_t version;
  int ret = 0;
  struct pkcs12_context ctx;
  const size_t original_out_certs_len = sk_X509_num(out_certs);

  // The input may be in BER format.
  if (!CBS_asn1_ber_to_der(ber_in, &in, &storage)) {
    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
    return 0;
  }

  *out_key = NULL;
  OPENSSL_memset(&ctx, 0, sizeof(ctx));

  // See ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1.pdf, section
  // four.
  if (!CBS_get_asn1(&in, &pfx, CBS_ASN1_SEQUENCE) || CBS_len(&in) != 0 ||
      !CBS_get_asn1_uint64(&pfx, &version)) {
    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
    goto err;
  }

  if (version < 3) {
    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_VERSION);
    goto err;
  }

  if (!CBS_get_asn1(&pfx, &authsafe, CBS_ASN1_SEQUENCE)) {
    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
    goto err;
  }

  if (CBS_len(&pfx) == 0) {
    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_MISSING_MAC);
    goto err;
  }

  if (!CBS_get_asn1(&pfx, &mac_data, CBS_ASN1_SEQUENCE)) {
    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
    goto err;
  }

  // authsafe is a PKCS#7 ContentInfo. See
  // https://tools.ietf.org/html/rfc2315#section-7.
  if (!CBS_get_asn1(&authsafe, &content_type, CBS_ASN1_OBJECT) ||
      !CBS_get_asn1(&authsafe, &wrapped_authsafes,
                    CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) {
    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
    goto err;
  }

  // The content type can either be data or signedData. The latter indicates
  // that it's signed by a public key, which isn't supported.
  if (!CBS_mem_equal(&content_type, kPKCS7Data, sizeof(kPKCS7Data))) {
    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED);
    goto err;
  }

  if (!CBS_get_asn1(&wrapped_authsafes, &authsafes, CBS_ASN1_OCTETSTRING)) {
    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
    goto err;
  }

  ctx.out_key = out_key;
  ctx.out_certs = out_certs;
  ctx.password = password;
  ctx.password_len = password != NULL ? strlen(password) : 0;

  // Verify the MAC.
  {
    CBS mac, salt, expected_mac;
    if (!CBS_get_asn1(&mac_data, &mac, CBS_ASN1_SEQUENCE)) {
      OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
      goto err;
    }

    const EVP_MD *md = EVP_parse_digest_algorithm(&mac);
    if (md == NULL) {
      goto err;
    }

    if (!CBS_get_asn1(&mac, &expected_mac, CBS_ASN1_OCTETSTRING) ||
        !CBS_get_asn1(&mac_data, &salt, CBS_ASN1_OCTETSTRING)) {
      OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
      goto err;
    }

    // The iteration count is optional and the default is one.
    uint32_t iterations = 1;
    if (CBS_len(&mac_data) > 0) {
      uint64_t iterations_u64;
      if (!CBS_get_asn1_uint64(&mac_data, &iterations_u64) ||
          !pkcs12_iterations_acceptable(iterations_u64)) {
        OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
        goto err;
      }
      iterations = (uint32_t)iterations_u64;
    }

    int mac_ok;
    if (!pkcs12_check_mac(&mac_ok, ctx.password, ctx.password_len, &salt,
                          iterations, md, &authsafes, &expected_mac)) {
      goto err;
    }
    if (!mac_ok && ctx.password_len == 0) {
      // PKCS#12 encodes passwords as NUL-terminated UCS-2, so the empty
      // password is encoded as {0, 0}. Some implementations use the empty byte
      // array for "no password". OpenSSL considers a non-NULL password as {0,
      // 0} and a NULL password as {}. It then, in high-level PKCS#12 parsing
      // code, tries both options. We match this behavior.
      ctx.password = ctx.password != NULL ? NULL : "";
      if (!pkcs12_check_mac(&mac_ok, ctx.password, ctx.password_len, &salt,
                            iterations, md, &authsafes, &expected_mac)) {
        goto err;
      }
    }
    if (!mac_ok) {
      OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_INCORRECT_PASSWORD);
      goto err;
    }
  }

  // authsafes contains a series of PKCS#7 ContentInfos.
  if (!PKCS12_handle_sequence(&authsafes, &ctx, PKCS12_handle_content_info)) {
    goto err;
  }

  ret = 1;

err:
  OPENSSL_free(storage);
  if (!ret) {
    EVP_PKEY_free(*out_key);
    *out_key = NULL;
    while (sk_X509_num(out_certs) > original_out_certs_len) {
      X509 *x509 = sk_X509_pop(out_certs);
      X509_free(x509);
    }
  }

  return ret;
}

void PKCS12_PBE_add(void) {}

struct pkcs12_st {
  uint8_t *ber_bytes;
  size_t ber_len;
};

PKCS12 *d2i_PKCS12(PKCS12 **out_p12, const uint8_t **ber_bytes,
                   size_t ber_len) {
  PKCS12 *p12 = reinterpret_cast<PKCS12 *>(OPENSSL_malloc(sizeof(PKCS12)));
  if (!p12) {
    return NULL;
  }

  p12->ber_bytes =
      reinterpret_cast<uint8_t *>(OPENSSL_memdup(*ber_bytes, ber_len));
  if (!p12->ber_bytes) {
    OPENSSL_free(p12);
    return NULL;
  }

  p12->ber_len = ber_len;
  *ber_bytes += ber_len;

  if (out_p12) {
    PKCS12_free(*out_p12);
    *out_p12 = p12;
  }

  return p12;
}

PKCS12 *d2i_PKCS12_bio(BIO *bio, PKCS12 **out_p12) {
  size_t used = 0;
  BUF_MEM *buf;
  const uint8_t *dummy;
  static const size_t kMaxSize = 256 * 1024;
  PKCS12 *ret = NULL;

  buf = BUF_MEM_new();
  if (buf == NULL) {
    return NULL;
  }
  if (BUF_MEM_grow(buf, 8192) == 0) {
    goto out;
  }

  for (;;) {
    size_t max_read = buf->length - used;
    int n = BIO_read(bio, &buf->data[used],
                     max_read > INT_MAX ? INT_MAX : (int)max_read);
    if (n < 0) {
      if (used == 0) {
        goto out;
      }
      // Workaround a bug in node.js. It uses a memory BIO for this in the wrong
      // mode.
      n = 0;
    }

    if (n == 0) {
      break;
    }
    used += n;

    if (used < buf->length) {
      continue;
    }

    if (buf->length > kMaxSize || BUF_MEM_grow(buf, buf->length * 2) == 0) {
      goto out;
    }
  }

  dummy = (uint8_t *)buf->data;
  ret = d2i_PKCS12(out_p12, &dummy, used);

out:
  BUF_MEM_free(buf);
  return ret;
}

PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **out_p12) {
  BIO *bio;
  PKCS12 *ret;

  bio = BIO_new_fp(fp, 0 /* don't take ownership */);
  if (!bio) {
    return NULL;
  }

  ret = d2i_PKCS12_bio(bio, out_p12);
  BIO_free(bio);
  return ret;
}

int i2d_PKCS12(const PKCS12 *p12, uint8_t **out) {
  if (p12->ber_len > INT_MAX) {
    OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW);
    return -1;
  }

  if (out == NULL) {
    return (int)p12->ber_len;
  }

  if (*out == NULL) {
    *out = reinterpret_cast<uint8_t *>(
        OPENSSL_memdup(p12->ber_bytes, p12->ber_len));
    if (*out == NULL) {
      return -1;
    }
  } else {
    OPENSSL_memcpy(*out, p12->ber_bytes, p12->ber_len);
    *out += p12->ber_len;
  }
  return (int)p12->ber_len;
}

int i2d_PKCS12_bio(BIO *bio, const PKCS12 *p12) {
  return BIO_write_all(bio, p12->ber_bytes, p12->ber_len);
}

int i2d_PKCS12_fp(FILE *fp, const PKCS12 *p12) {
  BIO *bio = BIO_new_fp(fp, 0 /* don't take ownership */);
  if (bio == NULL) {
    return 0;
  }

  int ret = i2d_PKCS12_bio(bio, p12);
  BIO_free(bio);
  return ret;
}

int PKCS12_parse(const PKCS12 *p12, const char *password, EVP_PKEY **out_pkey,
                 X509 **out_cert, STACK_OF(X509) **out_ca_certs) {
  CBS ber_bytes;
  STACK_OF(X509) *ca_certs = NULL;
  char ca_certs_alloced = 0;

  if (out_ca_certs != NULL && *out_ca_certs != NULL) {
    ca_certs = *out_ca_certs;
  }

  if (!ca_certs) {
    ca_certs = sk_X509_new_null();
    if (ca_certs == NULL) {
      return 0;
    }
    ca_certs_alloced = 1;
  }

  CBS_init(&ber_bytes, p12->ber_bytes, p12->ber_len);
  if (!PKCS12_get_key_and_certs(out_pkey, ca_certs, &ber_bytes, password)) {
    if (ca_certs_alloced) {
      sk_X509_free(ca_certs);
    }
    return 0;
  }

  // OpenSSL selects the last certificate which matches the private key as
  // |out_cert|.
  *out_cert = NULL;
  size_t num_certs = sk_X509_num(ca_certs);
  if (*out_pkey != NULL && num_certs > 0) {
    for (size_t i = num_certs - 1; i < num_certs; i--) {
      X509 *cert = sk_X509_value(ca_certs, i);
      if (X509_check_private_key(cert, *out_pkey)) {
        *out_cert = cert;
        sk_X509_delete(ca_certs, i);
        break;
      }
      ERR_clear_error();
    }
  }

  if (out_ca_certs) {
    *out_ca_certs = ca_certs;
  } else {
    sk_X509_pop_free(ca_certs, X509_free);
  }

  return 1;
}

int PKCS12_verify_mac(const PKCS12 *p12, const char *password,
                      int password_len) {
  if (password == NULL) {
    if (password_len != 0) {
      return 0;
    }
  } else if (password_len != -1 &&
             (password[password_len] != 0 ||
              OPENSSL_memchr(password, 0, password_len) != NULL)) {
    return 0;
  }

  EVP_PKEY *pkey = NULL;
  X509 *cert = NULL;
  if (!PKCS12_parse(p12, password, &pkey, &cert, NULL)) {
    ERR_clear_error();
    return 0;
  }

  EVP_PKEY_free(pkey);
  X509_free(cert);

  return 1;
}

// add_bag_attributes adds the bagAttributes field of a SafeBag structure,
// containing the specified friendlyName and localKeyId attributes.
static int add_bag_attributes(CBB *bag, const char *name, size_t name_len,
                              const uint8_t *key_id, size_t key_id_len) {
  if (name == NULL && key_id_len == 0) {
    return 1;  // Omit the OPTIONAL SET.
  }
  // See https://tools.ietf.org/html/rfc7292#section-4.2.
  CBB attrs, attr, oid, values, value;
  if (!CBB_add_asn1(bag, &attrs, CBS_ASN1_SET)) {
    return 0;
  }
  if (name_len != 0) {
    // See https://tools.ietf.org/html/rfc2985, section 5.5.1.
    if (!CBB_add_asn1(&attrs, &attr, CBS_ASN1_SEQUENCE) ||
        !CBB_add_asn1(&attr, &oid, CBS_ASN1_OBJECT) ||
        !CBB_add_bytes(&oid, kFriendlyName, sizeof(kFriendlyName)) ||
        !CBB_add_asn1(&attr, &values, CBS_ASN1_SET) ||
        !CBB_add_asn1(&values, &value, CBS_ASN1_BMPSTRING)) {
      return 0;
    }
    // Convert the friendly name to a BMPString.
    CBS name_cbs;
    CBS_init(&name_cbs, (const uint8_t *)name, name_len);
    while (CBS_len(&name_cbs) != 0) {
      uint32_t c;
      if (!CBS_get_utf8(&name_cbs, &c) || !CBB_add_ucs2_be(&value, c)) {
        OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_INVALID_CHARACTERS);
        return 0;
      }
    }
  }
  if (key_id_len != 0) {
    // See https://tools.ietf.org/html/rfc2985, section 5.5.2.
    if (!CBB_add_asn1(&attrs, &attr, CBS_ASN1_SEQUENCE) ||
        !CBB_add_asn1(&attr, &oid, CBS_ASN1_OBJECT) ||
        !CBB_add_bytes(&oid, kLocalKeyID, sizeof(kLocalKeyID)) ||
        !CBB_add_asn1(&attr, &values, CBS_ASN1_SET) ||
        !CBB_add_asn1(&values, &value, CBS_ASN1_OCTETSTRING) ||
        !CBB_add_bytes(&value, key_id, key_id_len)) {
      return 0;
    }
  }
  return CBB_flush_asn1_set_of(&attrs) && CBB_flush(bag);
}

static int add_cert_bag(CBB *cbb, X509 *cert, const char *name,
                        const uint8_t *key_id, size_t key_id_len) {
  CBB bag, bag_oid, bag_contents, cert_bag, cert_type, wrapped_cert, cert_value;
  if (  // See https://tools.ietf.org/html/rfc7292#section-4.2.
      !CBB_add_asn1(cbb, &bag, CBS_ASN1_SEQUENCE) ||
      !CBB_add_asn1(&bag, &bag_oid, CBS_ASN1_OBJECT) ||
      !CBB_add_bytes(&bag_oid, kCertBag, sizeof(kCertBag)) ||
      !CBB_add_asn1(&bag, &bag_contents,
                    CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) ||
      // See https://tools.ietf.org/html/rfc7292#section-4.2.3.
      !CBB_add_asn1(&bag_contents, &cert_bag, CBS_ASN1_SEQUENCE) ||
      !CBB_add_asn1(&cert_bag, &cert_type, CBS_ASN1_OBJECT) ||
      !CBB_add_bytes(&cert_type, kX509Certificate, sizeof(kX509Certificate)) ||
      !CBB_add_asn1(&cert_bag, &wrapped_cert,
                    CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) ||
      !CBB_add_asn1(&wrapped_cert, &cert_value, CBS_ASN1_OCTETSTRING)) {
    return 0;
  }
  uint8_t *buf;
  int len = i2d_X509(cert, NULL);

  int int_name_len = 0;
  const char *cert_name = (const char *)X509_alias_get0(cert, &int_name_len);
  size_t name_len = int_name_len;
  if (name) {
    if (name_len != 0) {
      OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_AMBIGUOUS_FRIENDLY_NAME);
      return 0;
    }
    name_len = strlen(name);
  } else {
    name = cert_name;
  }

  if (len < 0 || !CBB_add_space(&cert_value, &buf, (size_t)len) ||
      i2d_X509(cert, &buf) < 0 ||
      !add_bag_attributes(&bag, name, name_len, key_id, key_id_len) ||
      !CBB_flush(cbb)) {
    return 0;
  }
  return 1;
}

static int add_cert_safe_contents(CBB *cbb, X509 *cert,
                                  const STACK_OF(X509) *chain, const char *name,
                                  const uint8_t *key_id, size_t key_id_len) {
  CBB safe_contents;
  if (!CBB_add_asn1(cbb, &safe_contents, CBS_ASN1_SEQUENCE) ||
      (cert != NULL &&
       !add_cert_bag(&safe_contents, cert, name, key_id, key_id_len))) {
    return 0;
  }

  for (size_t i = 0; i < sk_X509_num(chain); i++) {
    // Only the leaf certificate gets attributes.
    if (!add_cert_bag(&safe_contents, sk_X509_value(chain, i), NULL, NULL, 0)) {
      return 0;
    }
  }

  return CBB_flush(cbb);
}

// add_encrypted_data encrypts |in| with |pbe_nid| and |pbe_cipher|, writing the
// result to |out|. It returns one on success and zero on error. |pbe_nid| and
// |pbe_cipher| are interpreted as in |PKCS8_encrypt|.
static int add_encrypted_data(CBB *out, int pbe_nid,
                              const EVP_CIPHER *pbe_cipher,
                              const char *password, size_t password_len,
                              uint32_t iterations, const uint8_t *in,
                              size_t in_len) {
  uint8_t salt[PKCS5_SALT_LEN];
  if (!RAND_bytes(salt, sizeof(salt))) {
    return 0;
  }

  bssl::ScopedEVP_CIPHER_CTX ctx;
  CBB content_info, type, wrapper, encrypted_data, encrypted_content_info,
      inner_type, encrypted_content;
  if (  // Add the ContentInfo wrapping.
      !CBB_add_asn1(out, &content_info, CBS_ASN1_SEQUENCE) ||
      !CBB_add_asn1(&content_info, &type, CBS_ASN1_OBJECT) ||
      !CBB_add_bytes(&type, kPKCS7EncryptedData, sizeof(kPKCS7EncryptedData)) ||
      !CBB_add_asn1(&content_info, &wrapper,
                    CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) ||
      // See https://tools.ietf.org/html/rfc2315#section-13.
      !CBB_add_asn1(&wrapper, &encrypted_data, CBS_ASN1_SEQUENCE) ||
      !CBB_add_asn1_uint64(&encrypted_data, 0 /* version */) ||
      // See https://tools.ietf.org/html/rfc2315#section-10.1.
      !CBB_add_asn1(&encrypted_data, &encrypted_content_info,
                    CBS_ASN1_SEQUENCE) ||
      !CBB_add_asn1(&encrypted_content_info, &inner_type, CBS_ASN1_OBJECT) ||
      !CBB_add_bytes(&inner_type, kPKCS7Data, sizeof(kPKCS7Data)) ||
      // Set up encryption and fill in contentEncryptionAlgorithm.
      !pkcs12_pbe_encrypt_init(&encrypted_content_info, ctx.get(), pbe_nid,
                               pbe_cipher, iterations, password, password_len,
                               salt, sizeof(salt)) ||
      // Note this tag is primitive. It is an implicitly-tagged OCTET_STRING, so
      // it inherits the inner tag's constructed bit.
      !CBB_add_asn1(&encrypted_content_info, &encrypted_content,
                    CBS_ASN1_CONTEXT_SPECIFIC | 0)) {
    return 0;
  }

  size_t max_out = in_len + EVP_CIPHER_CTX_block_size(ctx.get());
  if (max_out < in_len) {
    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_TOO_LONG);
    return 0;
  }

  uint8_t *ptr;
  int n1, n2;
  if (!CBB_reserve(&encrypted_content, &ptr, max_out) ||
      !EVP_CipherUpdate(ctx.get(), ptr, &n1, in, in_len) ||
      !EVP_CipherFinal_ex(ctx.get(), ptr + n1, &n2) ||
      !CBB_did_write(&encrypted_content, n1 + n2) || !CBB_flush(out)) {
    return 0;
  }

  return 1;
}

PKCS12 *PKCS12_create(const char *password, const char *name,
                      const EVP_PKEY *pkey, X509 *cert,
                      const STACK_OF(X509) *chain, int key_nid, int cert_nid,
                      int iterations, int mac_iterations, int key_type) {
  // TODO(crbug.com/396434682): Improve these defaults.
  if (key_nid == 0) {
    key_nid = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
  }
  if (cert_nid == 0) {
    cert_nid = NID_pbe_WithSHA1And40BitRC2_CBC;
  }
  if (iterations == 0) {
    iterations = PKCS12_DEFAULT_ITER;
  }
  if (mac_iterations == 0) {
    mac_iterations = 1;
  }
  if (  // In OpenSSL, this specifies a non-standard Microsoft key usage
        // extension which we do not currently support.
      key_type != 0 ||
      // In OpenSSL, -1 here means to omit the MAC, which we do not
      // currently support. Omitting it is also invalid for a password-based
      // PKCS#12 file.
      mac_iterations < 0 ||
      // Don't encode empty objects.
      (pkey == NULL && cert == NULL && sk_X509_num(chain) == 0)) {
    OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_OPTIONS);
    return 0;
  }

  // PKCS#12 is a very confusing recursive data format, built out of another
  // recursive data format. Section 5.1 of RFC 7292 describes the encoding
  // algorithm, but there is no clear overview. A quick summary:
  //
  // PKCS#7 defines a ContentInfo structure, which is a overgeneralized typed
  // combinator structure for applying cryptography. We care about two types. A
  // data ContentInfo contains an OCTET STRING and is a leaf node of the
  // combinator tree. An encrypted-data ContentInfo contains encryption
  // parameters (key derivation and encryption) and wraps another ContentInfo,
  // usually data.
  //
  // A PKCS#12 file is a PFX structure (section 4), which contains a single data
  // ContentInfo and a MAC over it. This root ContentInfo is the
  // AuthenticatedSafe and its payload is a SEQUENCE of other ContentInfos, so
  // that different parts of the PKCS#12 file can by differently protected.
  //
  // Each ContentInfo in the AuthenticatedSafe, after undoing all the PKCS#7
  // combinators, has SafeContents payload. A SafeContents is a SEQUENCE of
  // SafeBag. SafeBag is PKCS#12's typed structure, with subtypes such as KeyBag
  // and CertBag. Confusingly, there is a SafeContents bag type which itself
  // recursively contains more SafeBags, but we do not implement this. Bags also
  // can have attributes.
  //
  // The grouping of SafeBags into intermediate ContentInfos does not appear to
  // be significant, except that all SafeBags sharing a ContentInfo have the
  // same level of protection. Additionally, while keys may be encrypted by
  // placing a KeyBag in an encrypted-data ContentInfo, PKCS#12 also defines a
  // key-specific encryption container, PKCS8ShroudedKeyBag, which is used
  // instead.

  // Note that |password| may be NULL to specify no password, rather than the
  // empty string. They are encoded differently in PKCS#12. (One is the empty
  // byte array and the other is NUL-terminated UCS-2.)
  size_t password_len = password != NULL ? strlen(password) : 0;

  uint8_t key_id[EVP_MAX_MD_SIZE];
  unsigned key_id_len = 0;
  if (cert != NULL && pkey != NULL) {
    if (!X509_check_private_key(cert, pkey) ||
        // Matching OpenSSL, use the SHA-1 hash of the certificate as the local
        // key ID. Some PKCS#12 consumers require one to connect the private key
        // and certificate.
        !X509_digest(cert, EVP_sha1(), key_id, &key_id_len)) {
      return 0;
    }
  }

  // See https://tools.ietf.org/html/rfc7292#section-4.
  PKCS12 *ret = NULL;
  CBB cbb, pfx, auth_safe, auth_safe_oid, auth_safe_wrapper, auth_safe_data,
      content_infos;
  uint8_t mac_key[EVP_MAX_MD_SIZE];
  if (!CBB_init(&cbb, 0) || !CBB_add_asn1(&cbb, &pfx, CBS_ASN1_SEQUENCE) ||
      !CBB_add_asn1_uint64(&pfx, 3) ||
      // auth_safe is a data ContentInfo.
      !CBB_add_asn1(&pfx, &auth_safe, CBS_ASN1_SEQUENCE) ||
      !CBB_add_asn1(&auth_safe, &auth_safe_oid, CBS_ASN1_OBJECT) ||
      !CBB_add_bytes(&auth_safe_oid, kPKCS7Data, sizeof(kPKCS7Data)) ||
      !CBB_add_asn1(&auth_safe, &auth_safe_wrapper,
                    CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) ||
      !CBB_add_asn1(&auth_safe_wrapper, &auth_safe_data,
                    CBS_ASN1_OCTETSTRING) ||
      // See https://tools.ietf.org/html/rfc7292#section-4.1. |auth_safe|'s
      // contains a SEQUENCE of ContentInfos.
      !CBB_add_asn1(&auth_safe_data, &content_infos, CBS_ASN1_SEQUENCE)) {
    goto err;
  }

  // If there are any certificates, place them in CertBags wrapped in a single
  // encrypted ContentInfo.
  if (cert != NULL || sk_X509_num(chain) > 0) {
    if (cert_nid < 0) {
      // Place the certificates in an unencrypted ContentInfo. This could be
      // more compactly-encoded by reusing the same ContentInfo as the key, but
      // OpenSSL does not do this. We keep them separate for consistency. (Keys,
      // even when encrypted, are always placed in unencrypted ContentInfos.
      // PKCS#12 defines bag-level encryption for keys.)
      CBB content_info, oid, wrapper, data;
      if (!CBB_add_asn1(&content_infos, &content_info, CBS_ASN1_SEQUENCE) ||
          !CBB_add_asn1(&content_info, &oid, CBS_ASN1_OBJECT) ||
          !CBB_add_bytes(&oid, kPKCS7Data, sizeof(kPKCS7Data)) ||
          !CBB_add_asn1(&content_info, &wrapper,
                        CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) ||
          !CBB_add_asn1(&wrapper, &data, CBS_ASN1_OCTETSTRING) ||
          !add_cert_safe_contents(&data, cert, chain, name, key_id,
                                  key_id_len) ||
          !CBB_flush(&content_infos)) {
        goto err;
      }
    } else {
      // This function differs from other OpenSSL functions in how PBES1 and
      // PBES2 schemes are selected. If the NID matches a cipher, treat this as
      // PBES2 instead. Convert to the other convention.
      const EVP_CIPHER *cipher = pkcs5_pbe2_nid_to_cipher(cert_nid);
      if (cipher != nullptr) {
        cert_nid = -1;
      }
      CBB plaintext_cbb;
      int ok =
          CBB_init(&plaintext_cbb, 0) &&
          add_cert_safe_contents(&plaintext_cbb, cert, chain, name, key_id,
                                 key_id_len) &&
          add_encrypted_data(&content_infos, cert_nid, cipher, password,
                             password_len, iterations, CBB_data(&plaintext_cbb),
                             CBB_len(&plaintext_cbb));
      CBB_cleanup(&plaintext_cbb);
      if (!ok) {
        goto err;
      }
    }
  }

  // If there is a key, place it in a single KeyBag or PKCS8ShroudedKeyBag
  // wrapped in an unencrypted ContentInfo. (One could also place it in a KeyBag
  // inside an encrypted ContentInfo, but OpenSSL does not do this and some
  // PKCS#12 consumers do not support KeyBags.)
  if (pkey != NULL) {
    CBB content_info, oid, wrapper, data, safe_contents, bag, bag_oid,
        bag_contents;
    if (  // Add another data ContentInfo.
        !CBB_add_asn1(&content_infos, &content_info, CBS_ASN1_SEQUENCE) ||
        !CBB_add_asn1(&content_info, &oid, CBS_ASN1_OBJECT) ||
        !CBB_add_bytes(&oid, kPKCS7Data, sizeof(kPKCS7Data)) ||
        !CBB_add_asn1(&content_info, &wrapper,
                      CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) ||
        !CBB_add_asn1(&wrapper, &data, CBS_ASN1_OCTETSTRING) ||
        !CBB_add_asn1(&data, &safe_contents, CBS_ASN1_SEQUENCE) ||
        // Add a SafeBag containing a PKCS8ShroudedKeyBag.
        !CBB_add_asn1(&safe_contents, &bag, CBS_ASN1_SEQUENCE) ||
        !CBB_add_asn1(&bag, &bag_oid, CBS_ASN1_OBJECT)) {
      goto err;
    }
    if (key_nid < 0) {
      if (!CBB_add_bytes(&bag_oid, kKeyBag, sizeof(kKeyBag)) ||
          !CBB_add_asn1(&bag, &bag_contents,
                        CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) ||
          !EVP_marshal_private_key(&bag_contents, pkey)) {
        goto err;
      }
    } else {
      // This function differs from other OpenSSL functions in how PBES1 and
      // PBES2 schemes are selected. If the NID matches a cipher, treat this as
      // PBES2 instead. Convert to the other convention.
      const EVP_CIPHER *cipher = pkcs5_pbe2_nid_to_cipher(key_nid);
      if (cipher != nullptr) {
        key_nid = -1;
      }
      if (!CBB_add_bytes(&bag_oid, kPKCS8ShroudedKeyBag,
                         sizeof(kPKCS8ShroudedKeyBag)) ||
          !CBB_add_asn1(&bag, &bag_contents,
                        CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) ||
          !PKCS8_marshal_encrypted_private_key(
              &bag_contents, key_nid, cipher, password, password_len,
              NULL /* generate a random salt */,
              0 /* use default salt length */, iterations, pkey)) {
        goto err;
      }
    }
    size_t name_len = 0;
    if (name) {
      name_len = strlen(name);
    }
    if (!add_bag_attributes(&bag, name, name_len, key_id, key_id_len) ||
        !CBB_flush(&content_infos)) {
      goto err;
    }
  }

  {
    // Compute the MAC. Match OpenSSL in using SHA-1 as the hash function. The
    // MAC covers |auth_safe_data|.
    const EVP_MD *mac_md = EVP_sha1();
    uint8_t mac_salt[PKCS5_SALT_LEN];
    uint8_t mac[EVP_MAX_MD_SIZE];
    unsigned mac_len;
    if (!CBB_flush(&auth_safe_data) ||
        !RAND_bytes(mac_salt, sizeof(mac_salt)) ||
        !pkcs12_key_gen(password, password_len, mac_salt, sizeof(mac_salt),
                        PKCS12_MAC_ID, mac_iterations, EVP_MD_size(mac_md),
                        mac_key, mac_md) ||
        !HMAC(mac_md, mac_key, EVP_MD_size(mac_md), CBB_data(&auth_safe_data),
              CBB_len(&auth_safe_data), mac, &mac_len)) {
      goto err;
    }

    CBB mac_data, digest_info, mac_cbb, mac_salt_cbb;
    if (!CBB_add_asn1(&pfx, &mac_data, CBS_ASN1_SEQUENCE) ||
        !CBB_add_asn1(&mac_data, &digest_info, CBS_ASN1_SEQUENCE) ||
        !EVP_marshal_digest_algorithm(&digest_info, mac_md) ||
        !CBB_add_asn1(&digest_info, &mac_cbb, CBS_ASN1_OCTETSTRING) ||
        !CBB_add_bytes(&mac_cbb, mac, mac_len) ||
        !CBB_add_asn1(&mac_data, &mac_salt_cbb, CBS_ASN1_OCTETSTRING) ||
        !CBB_add_bytes(&mac_salt_cbb, mac_salt, sizeof(mac_salt)) ||
        // The iteration count has a DEFAULT of 1, but RFC 7292 says "The
        // default is for historical reasons and its use is deprecated." Thus we
        // explicitly encode the iteration count, though it is not valid DER.
        !CBB_add_asn1_uint64(&mac_data, mac_iterations)) {
      goto err;
    }

    ret = reinterpret_cast<PKCS12 *>(OPENSSL_malloc(sizeof(PKCS12)));
    if (ret == NULL || !CBB_finish(&cbb, &ret->ber_bytes, &ret->ber_len)) {
      OPENSSL_free(ret);
      ret = NULL;
      goto err;
    }
  }

err:
  OPENSSL_cleanse(mac_key, sizeof(mac_key));
  CBB_cleanup(&cbb);
  return ret;
}

void PKCS12_free(PKCS12 *p12) {
  if (p12 == NULL) {
    return;
  }
  OPENSSL_free(p12->ber_bytes);
  OPENSSL_free(p12);
}
