// Copyright 2017 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 <openssl/pkcs7.h>

#include <assert.h>
#include <limits.h>

#include <openssl/asn1.h>
#include <openssl/bytestring.h>
#include <openssl/cms.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/pem.h>
#include <openssl/pool.h>
#include <openssl/stack.h>
#include <openssl/x509.h>

#include "../asn1/internal.h"
#include "../internal.h"
#include "../mem_internal.h"
#include "../x509/internal.h"
#include "internal.h"


using namespace bssl;

int PKCS7_get_certificates(STACK_OF(X509) *out_certs, CBS *cbs) {
  int ret = 0;
  const size_t initial_certs_len = sk_X509_num(out_certs);
  STACK_OF(CRYPTO_BUFFER) *raw = sk_CRYPTO_BUFFER_new_null();
  if (raw == nullptr || !PKCS7_get_raw_certificates(raw, cbs, nullptr)) {
    goto err;
  }

  for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(raw); i++) {
    CRYPTO_BUFFER *buf = sk_CRYPTO_BUFFER_value(raw, i);
    X509 *x509 = X509_parse_from_buffer(buf);
    if (x509 == nullptr || !sk_X509_push(out_certs, x509)) {
      X509_free(x509);
      goto err;
    }
  }

  ret = 1;

err:
  sk_CRYPTO_BUFFER_pop_free(raw, CRYPTO_BUFFER_free);
  if (!ret) {
    while (sk_X509_num(out_certs) != initial_certs_len) {
      X509 *x509 = sk_X509_pop(out_certs);
      X509_free(x509);
    }
  }

  return ret;
}

int PKCS7_get_CRLs(STACK_OF(X509_CRL) *out_crls, CBS *cbs) {
  CBS signed_data, crls;
  uint8_t *der_bytes = nullptr;
  int ret = 0, has_crls;
  const size_t initial_crls_len = sk_X509_CRL_num(out_crls);

  // See https://tools.ietf.org/html/rfc2315#section-9.1
  if (!pkcs7_parse_header(&der_bytes, &signed_data, cbs) ||
      // Even if only CRLs are included, there may be an empty certificates
      // block. OpenSSL does this, for example.
      !CBS_get_optional_asn1(
          &signed_data, nullptr, nullptr,
          CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
      !CBS_get_optional_asn1(
          &signed_data, &crls, &has_crls,
          CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1)) {
    goto err;
  }

  if (!has_crls) {
    CBS_init(&crls, nullptr, 0);
  }

  while (CBS_len(&crls) > 0) {
    CBS crl_data;
    X509_CRL *crl;
    const uint8_t *inp;

    if (!CBS_get_asn1_element(&crls, &crl_data, CBS_ASN1_SEQUENCE)) {
      goto err;
    }

    if (CBS_len(&crl_data) > LONG_MAX) {
      goto err;
    }
    inp = CBS_data(&crl_data);
    crl = d2i_X509_CRL(nullptr, &inp, (long)CBS_len(&crl_data));
    if (!crl) {
      goto err;
    }

    assert(inp == CBS_data(&crl_data) + CBS_len(&crl_data));

    if (sk_X509_CRL_push(out_crls, crl) == 0) {
      X509_CRL_free(crl);
      goto err;
    }
  }

  ret = 1;

err:
  OPENSSL_free(der_bytes);

  if (!ret) {
    while (sk_X509_CRL_num(out_crls) != initial_crls_len) {
      X509_CRL_free(sk_X509_CRL_pop(out_crls));
    }
  }

  return ret;
}

int PKCS7_get_PEM_certificates(STACK_OF(X509) *out_certs, BIO *pem_bio) {
  uint8_t *data;
  long len;
  int ret;

  // Even though we pass PEM_STRING_PKCS7 as the expected PEM type here, PEM
  // internally will actually allow several other values too, including
  // "CERTIFICATE".
  if (!PEM_bytes_read_bio(&data, &len, nullptr /* PEM type output */,
                          PEM_STRING_PKCS7, pem_bio,
                          nullptr /* password callback */,
                          nullptr /* password callback argument */)) {
    return 0;
  }

  CBS cbs;
  CBS_init(&cbs, data, len);
  ret = PKCS7_get_certificates(out_certs, &cbs);
  OPENSSL_free(data);
  return ret;
}

int PKCS7_get_PEM_CRLs(STACK_OF(X509_CRL) *out_crls, BIO *pem_bio) {
  uint8_t *data;
  long len;
  int ret;

  // Even though we pass PEM_STRING_PKCS7 as the expected PEM type here, PEM
  // internally will actually allow several other values too, including
  // "CERTIFICATE".
  if (!PEM_bytes_read_bio(&data, &len, nullptr /* PEM type output */,
                          PEM_STRING_PKCS7, pem_bio,
                          nullptr /* password callback */,
                          nullptr /* password callback argument */)) {
    return 0;
  }

  CBS cbs;
  CBS_init(&cbs, data, len);
  ret = PKCS7_get_CRLs(out_crls, &cbs);
  OPENSSL_free(data);
  return ret;
}

static int pkcs7_bundle_certificates_cb(CBB *out, void *arg) {
  auto *certs = static_cast<const STACK_OF(X509) *>(arg);
  size_t i;
  CBB certificates;

  // See https://tools.ietf.org/html/rfc2315#section-9.1
  if (!CBB_add_asn1(out, &certificates,
                    CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) {
    return 0;
  }

  for (i = 0; i < sk_X509_num(certs); i++) {
    X509 *x509 = sk_X509_value(certs, i);
    uint8_t *buf;
    int len = i2d_X509(x509, nullptr);

    if (len < 0 || !CBB_add_space(&certificates, &buf, len) ||
        i2d_X509(x509, &buf) < 0) {
      return 0;
    }
  }

  // |certificates| is a implicitly-tagged SET OF.
  return CBB_flush_asn1_set_of(&certificates) && CBB_flush(out);
}

int PKCS7_bundle_certificates(CBB *out, const STACK_OF(X509) *certs) {
  return pkcs7_add_signed_data(
      out, /*signed_data_version=*/1,
      /*digest_algos_cb=*/nullptr, pkcs7_bundle_certificates_cb,
      /*signer_infos_cb=*/nullptr, const_cast<STACK_OF(X509) *>(certs));
}

static int pkcs7_bundle_crls_cb(CBB *out, void *arg) {
  auto *crls = static_cast<const STACK_OF(X509_CRL) *>(arg);
  size_t i;
  CBB crl_data;

  // See https://tools.ietf.org/html/rfc2315#section-9.1
  if (!CBB_add_asn1(out, &crl_data,
                    CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1)) {
    return 0;
  }

  for (i = 0; i < sk_X509_CRL_num(crls); i++) {
    X509_CRL *crl = sk_X509_CRL_value(crls, i);
    uint8_t *buf;
    int len = i2d_X509_CRL(crl, nullptr);

    if (len < 0 || !CBB_add_space(&crl_data, &buf, len) ||
        i2d_X509_CRL(crl, &buf) < 0) {
      return 0;
    }
  }

  // |crl_data| is a implicitly-tagged SET OF.
  return CBB_flush_asn1_set_of(&crl_data) && CBB_flush(out);
}

int PKCS7_bundle_CRLs(CBB *out, const STACK_OF(X509_CRL) *crls) {
  return pkcs7_add_signed_data(
      out, /*signed_data_version=*/1,
      /*digest_algos_cb=*/nullptr, pkcs7_bundle_crls_cb,
      /*signer_infos_cb=*/nullptr, const_cast<STACK_OF(X509_CRL) *>(crls));
}

static PKCS7 *pkcs7_new(CBS *cbs) {
  CBS copy = *cbs, copy2 = *cbs;
  PKCS7 *ret = NewZeroed<PKCS7>();
  if (ret == nullptr) {
    return nullptr;
  }
  ret->type = OBJ_nid2obj(NID_pkcs7_signed);
  ret->d.sign = New<PKCS7_SIGNED>();
  if (ret->d.sign == nullptr) {
    goto err;
  }
  ret->d.sign->cert = sk_X509_new_null();
  ret->d.sign->crl = sk_X509_CRL_new_null();
  if (ret->d.sign->cert == nullptr || ret->d.sign->crl == nullptr ||
      !PKCS7_get_certificates(ret->d.sign->cert, &copy) ||
      !PKCS7_get_CRLs(ret->d.sign->crl, cbs)) {
    goto err;
  }

  if (sk_X509_num(ret->d.sign->cert) == 0) {
    sk_X509_free(ret->d.sign->cert);
    ret->d.sign->cert = nullptr;
  }

  if (sk_X509_CRL_num(ret->d.sign->crl) == 0) {
    sk_X509_CRL_free(ret->d.sign->crl);
    ret->d.sign->crl = nullptr;
  }

  ret->ber_len = CBS_len(&copy2) - CBS_len(cbs);
  ret->ber_bytes = reinterpret_cast<uint8_t *>(
      OPENSSL_memdup(CBS_data(&copy2), ret->ber_len));
  if (ret->ber_bytes == nullptr) {
    goto err;
  }

  return ret;

err:
  PKCS7_free(ret);
  return nullptr;
}

PKCS7 *d2i_PKCS7(PKCS7 **out, const uint8_t **inp, size_t len) {
  CBS cbs;
  CBS_init(&cbs, *inp, len);
  PKCS7 *ret = pkcs7_new(&cbs);
  if (ret == nullptr) {
    return nullptr;
  }
  *inp = CBS_data(&cbs);
  if (out != nullptr) {
    PKCS7_free(*out);
    *out = ret;
  }
  return ret;
}

PKCS7 *d2i_PKCS7_bio(BIO *bio, PKCS7 **out) {
  // Use a generous bound, to allow for PKCS#7 files containing large root sets.
  static const size_t kMaxSize = 4 * 1024 * 1024;
  uint8_t *data;
  size_t len;
  if (!BIO_read_asn1(bio, &data, &len, kMaxSize)) {
    return nullptr;
  }

  CBS cbs;
  CBS_init(&cbs, data, len);
  PKCS7 *ret = pkcs7_new(&cbs);
  OPENSSL_free(data);
  if (out != nullptr && ret != nullptr) {
    PKCS7_free(*out);
    *out = ret;
  }
  return ret;
}

int i2d_PKCS7(const PKCS7 *p7, uint8_t **out) {
  if (p7->ber_len > INT_MAX) {
    OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW);
    return -1;
  }

  if (out == nullptr) {
    return (int)p7->ber_len;
  }

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

int i2d_PKCS7_bio(BIO *bio, const PKCS7 *p7) {
  return BIO_write_all(bio, p7->ber_bytes, p7->ber_len);
}

void PKCS7_free(PKCS7 *p7) {
  if (p7 == nullptr) {
    return;
  }

  OPENSSL_free(p7->ber_bytes);
  ASN1_OBJECT_free(p7->type);
  // We only supported signed data.
  if (p7->d.sign != nullptr) {
    sk_X509_pop_free(p7->d.sign->cert, X509_free);
    sk_X509_CRL_pop_free(p7->d.sign->crl, X509_CRL_free);
    Delete(p7->d.sign);
  }
  Delete(p7);
}

// We only support signed data, so these getters are no-ops.
int PKCS7_type_is_data(const PKCS7 *p7) { return 0; }
int PKCS7_type_is_digest(const PKCS7 *p7) { return 0; }
int PKCS7_type_is_encrypted(const PKCS7 *p7) { return 0; }
int PKCS7_type_is_enveloped(const PKCS7 *p7) { return 0; }
int PKCS7_type_is_signed(const PKCS7 *p7) { return 1; }
int PKCS7_type_is_signedAndEnveloped(const PKCS7 *p7) { return 0; }

static bool digest_sign_update(EVP_MD_CTX *ctx, BIO *data) {
  for (;;) {
    uint8_t buf[4096];
    const int n = BIO_read(data, buf, sizeof(buf));
    if (n == 0) {
      return true;
    } else if (n < 0 || !EVP_DigestSignUpdate(ctx, buf, n)) {
      return false;
    }
  }
}

namespace {
struct signer_info_data {
  X509 *sign_cert = nullptr;
  ScopedEVP_MD_CTX sign_ctx;
  bool use_key_id = false;
};
}  // namespace

static int write_signer_digest_algos(CBB *digest_algos_set, void *arg) {
  auto *si_data = static_cast<struct signer_info_data *>(arg);
  // https://www.rfc-editor.org/rfc/rfc5754.html#section-2
  // "Implementations MUST generate SHA2 AlgorithmIdentifiers with absent
  //  parameters."
  return EVP_marshal_digest_algorithm_no_params(
      digest_algos_set, EVP_MD_CTX_get0_md(si_data->sign_ctx.get()));
}

// write_signer_info writes the SignerInfo structure from
// https://www.rfc-editor.org/rfc/rfc2315.html#section-9.2 and
// https://www.rfc-editor.org/rfc/rfc5652.html#section-5.3 to |out|. It returns
// one on success or zero on error.
static int write_signer_info(CBB *out, void *arg) {
  auto *si_data = static_cast<struct signer_info_data *>(arg);

  uint64_t version = si_data->use_key_id ? 3u : 1u;
  CBB seq, child, signing_algo, null, signature;
  if (!CBB_add_asn1(out, &seq, CBS_ASN1_SEQUENCE) ||
      !CBB_add_asn1_uint64(&seq, version)) {
    return 0;
  }

  // Output the SignerIdentifier.
  if (si_data->use_key_id) {
    const ASN1_OCTET_STRING *skid =
        X509_get0_subject_key_id(si_data->sign_cert);
    if (skid == nullptr) {
      OPENSSL_PUT_ERROR(CMS, CMS_R_CERTIFICATE_HAS_NO_KEYID);
      return 0;
    }
    // subjectKeyIdentifier is implicitly-tagged.
    if (!CBB_add_asn1_element(&seq, CBS_ASN1_CONTEXT_SPECIFIC | 0,
                              ASN1_STRING_get0_data(skid),
                              ASN1_STRING_length(skid))) {
      return 0;
    }
  } else {
    if (!CBB_add_asn1(&seq, &child, CBS_ASN1_SEQUENCE) ||
        !x509_marshal_name(&child, X509_get_subject_name(si_data->sign_cert)) ||
        !asn1_marshal_integer(&child,
                              X509_get0_serialNumber(si_data->sign_cert),
                              /*tag=*/0)) {
      return 0;
    }
  }

  // Output the digest and signature algorithm. This cannot use X.509 signature
  // algorithms because CMS incorrectly decomposes signature algorithms into a
  // combination of digesting and "encrypting" the digest, then uses the plain
  // rsaEncryption OID instead of the hash-specific RSA OIDs. For now, we only
  // support RSA.
  EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(si_data->sign_ctx->pctx);
  if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) {
    OPENSSL_PUT_ERROR(PKCS7, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    return 0;
  }
  if (!EVP_marshal_digest_algorithm_no_params(
          &seq, EVP_MD_CTX_get0_md(si_data->sign_ctx.get())) ||
      !CBB_add_asn1(&seq, &signing_algo, CBS_ASN1_SEQUENCE) ||
      !OBJ_nid2cbb(&signing_algo, NID_rsaEncryption) ||
      !CBB_add_asn1(&signing_algo, &null, CBS_ASN1_NULL)) {
    return 0;
  }

  // Output the signature.
  uint8_t *ptr;
  size_t sig_len;
  if (!EVP_DigestSignFinal(si_data->sign_ctx.get(), nullptr, &sig_len) ||
      !CBB_add_asn1(&seq, &signature, CBS_ASN1_OCTETSTRING) ||
      !CBB_reserve(&signature, &ptr, sig_len) ||
      !EVP_DigestSignFinal(si_data->sign_ctx.get(), ptr, &sig_len) ||
      !CBB_did_write(&signature, sig_len) ||  //
      !CBB_flush(out)) {
    return 0;
  }

  return 1;
}

int bssl::pkcs7_add_external_signature(CBB *out, X509 *sign_cert, EVP_PKEY *key,
                                       const EVP_MD *md, BIO *data,
                                       bool use_key_id) {
  signer_info_data si_data;
  si_data.use_key_id = use_key_id;
  si_data.sign_cert = sign_cert;

  // Set up the signature.
  if (!EVP_DigestSignInit(si_data.sign_ctx.get(), nullptr, md, nullptr, key) ||
      !digest_sign_update(si_data.sign_ctx.get(), data)) {
    return 0;
  }

  // See RFC 5652, Section 5.1. When no certificates are present, the version
  // comes from the highest SignerInfo version, which will be 3 (CMS) for a key
  // ID, and 1 (CMS or PKCS#7) for issuer and serial.
  uint64_t signed_data_version = use_key_id ? 3u : 1u;
  return pkcs7_add_signed_data(
      out, signed_data_version, write_signer_digest_algos,
      /*cert_crl_cb=*/nullptr, write_signer_info, &si_data);
}

PKCS7 *PKCS7_sign(X509 *sign_cert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
                  BIO *data, int flags) {
  ScopedCBB cbb;
  if (!CBB_init(cbb.get(), 2048)) {
    return nullptr;
  }

  if (sign_cert == nullptr && pkey == nullptr && flags == PKCS7_DETACHED) {
    // Caller just wants to bundle certificates.
    if (!PKCS7_bundle_certificates(cbb.get(), certs)) {
      return nullptr;
    }
  } else if (sign_cert != nullptr && pkey != nullptr && certs == nullptr &&
             data != nullptr &&
             flags == (PKCS7_NOATTR | PKCS7_BINARY | PKCS7_NOCERTS |
                       PKCS7_DETACHED)) {
    // In OpenSSL, this API signs with some default hash. That default has been
    // SHA-256 since 2015.
    if (!pkcs7_add_external_signature(cbb.get(), sign_cert, pkey, EVP_sha256(),
                                      data, /*use_key_id=*/false)) {
      return nullptr;
    }
  } else {
    OPENSSL_PUT_ERROR(PKCS7, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    return nullptr;
  }

  CBS cbs;
  CBS_init(&cbs, CBB_data(cbb.get()), CBB_len(cbb.get()));
  return pkcs7_new(&cbs);
}
