// Copyright 2025 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/cms.h>

#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/x509.h>

#include "../bytestring/internal.h"
#include "../internal.h"
#include "../mem_internal.h"
#include "../pkcs7/internal.h"


using namespace bssl;

// TODO(davidben): Should we move the core PKCS#7 / CMS implementation into
// crypto/cms instead of crypto/pkcs7? CMS is getting new features while PKCS#7
// is not.
OPENSSL_DECLARE_ERROR_REASON(CMS, CERTIFICATE_HAS_NO_KEYID)

DECLARE_OPAQUE_STRUCT(CMS_SignerInfo_st, CMSSignerInfo)
DECLARE_OPAQUE_STRUCT(CMS_ContentInfo_st, CMSContentInfo)

BSSL_NAMESPACE_BEGIN

class CMSSignerInfo : public CMS_SignerInfo_st {
 public:
  UniquePtr<X509> signcert;
  UniquePtr<EVP_PKEY> pkey;
  const EVP_MD *md = nullptr;
  bool use_key_id = false;
};

class CMSContentInfo : public CMS_ContentInfo_st {
 public:
  static constexpr bool kAllowUniquePtr = true;
  bool has_signer_info = false;
  CMSSignerInfo signer_info;
  Array<uint8_t> der;
};

BSSL_NAMESPACE_END

CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
                          BIO *data, uint32_t flags) {
  // We only support external signatures and do not support embedding
  // certificates in SignedData.
  if ((flags & CMS_DETACHED) == 0 || sk_X509_num(certs) != 0) {
    OPENSSL_PUT_ERROR(CMS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    return nullptr;
  }

  UniquePtr<CMSContentInfo> cms = MakeUnique<CMSContentInfo>();
  if (cms == nullptr) {
    return nullptr;
  }

  if (pkey != nullptr &&
      !CMS_add1_signer(cms.get(), signcert, pkey, /*md=*/nullptr, flags)) {
    return nullptr;
  }

  // We don't actually use streaming mode, but Linux passes |CMS_STREAM| to
  // |CMS_sign| and OpenSSL interprets it as an alias for |CMS_PARTIAL| in this
  // context.
  if ((flags & (CMS_PARTIAL | CMS_STREAM)) == 0 &&
      !CMS_final(cms.get(), data, nullptr, flags)) {
    return nullptr;
  }

  return cms.release();
}

void CMS_ContentInfo_free(CMS_ContentInfo *cms) { Delete(FromOpaque(cms)); }

CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, X509 *signcert,
                                EVP_PKEY *pkey, const EVP_MD *md,
                                uint32_t flags) {
  auto *impl = FromOpaque(cms);
  if (  // Already finalized.
      !impl->der.empty() ||
      // We only support one signer.
      impl->has_signer_info ||
      // We do not support configuring a signer in multiple steps. (In OpenSSL,
      // this is used to configure attributes.
      (flags & CMS_PARTIAL) != 0 ||
      // We do not support embedding certificates in SignedData.
      (flags & CMS_NOCERTS) == 0 ||
      // We do not support attributes in SignedData.
      (flags & CMS_NOATTR) == 0) {
    OPENSSL_PUT_ERROR(CMS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    return nullptr;
  }

  if (signcert == nullptr || pkey == nullptr) {
    OPENSSL_PUT_ERROR(CMS, ERR_R_PASSED_NULL_PARAMETER);
    return nullptr;
  }

  if (!X509_check_private_key(signcert, pkey)) {
    OPENSSL_PUT_ERROR(CMS, CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
    return nullptr;
  }

  // Default to SHA-256.
  if (md == nullptr) {
    md = EVP_sha256();
  }

  // Save information for later.
  impl->has_signer_info = true;
  impl->signer_info.signcert = UpRef(signcert);
  impl->signer_info.pkey = UpRef(pkey);
  impl->signer_info.md = md;
  impl->signer_info.use_key_id = (flags & CMS_USE_KEYID) != 0;
  return &impl->signer_info;
}

int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, uint32_t flags) {
  auto *impl = FromOpaque(cms);
  if (  // Already finalized.
      !impl->der.empty() ||
      // Require a SignerInfo. We do not support signature-less SignedDatas.
      !impl->has_signer_info ||
      // We only support the straightforward passthrough mode, without S/MIME
      // translations.
      (flags & CMS_BINARY) == 0 ||
      // We do not support |dcont|. It is unclear what it does.
      dcont != nullptr) {
    OPENSSL_PUT_ERROR(CMS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    return 0;
  }

  ScopedCBB cbb;
  if (!CBB_init(cbb.get(), 2048) ||
      !pkcs7_add_external_signature(cbb.get(), impl->signer_info.signcert.get(),
                                    impl->signer_info.pkey.get(),
                                    impl->signer_info.md, data,
                                    impl->signer_info.use_key_id) ||
      !CBBFinishArray(cbb.get(), &impl->der)) {
    return 0;
  }

  return 1;
}

int i2d_CMS_bio(BIO *out, CMS_ContentInfo *cms) {
  auto *impl = FromOpaque(cms);
  if (impl->der.empty()) {
    // Not yet finalized.
    OPENSSL_PUT_ERROR(CMS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    return 0;
  }

  return BIO_write_all(out, impl->der.data(), impl->der.size());
}

int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags) {
  // We do not support streaming mode.
  if ((flags & CMS_STREAM) != 0 || in != nullptr) {
    OPENSSL_PUT_ERROR(CMS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    return 0;
  }

  return i2d_CMS_bio(out, cms);
}
