// Copyright 1995-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/asn1.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/span.h>
#include <openssl/x509.h>

#include <limits.h>

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


using namespace bssl;

int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
                   ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey,
                   const EVP_MD *type) {
  if (signature->type != V_ASN1_BIT_STRING) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE);
    return 0;
  }
  ScopedEVP_MD_CTX ctx;
  if (!EVP_DigestSignInit(ctx.get(), nullptr, type, nullptr, pkey)) {
    return 0;
  }
  return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, ctx.get());
}

int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
                       X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
                       void *asn, EVP_MD_CTX *ctx) {
  // Historically, this function called |EVP_MD_CTX_cleanup| on return. Some
  // callers rely on this to avoid memory leaks.
  Cleanup cleanup = [&] { EVP_MD_CTX_cleanup(ctx); };

  // Write out the requested copies of the AlgorithmIdentifier. This may modify
  // |asn|, so we must do it first.
  if ((algor1 != nullptr && !x509_digest_sign_algorithm(ctx, algor1)) ||
      (algor2 != nullptr && !x509_digest_sign_algorithm(ctx, algor2))) {
    return 0;
  }

  uint8_t *in = nullptr;
  int in_len = ASN1_item_i2d(reinterpret_cast<ASN1_VALUE *>(asn), &in, it);
  if (in_len < 0) {
    return 0;
  }
  UniquePtr<uint8_t> free_in(in);

  return x509_sign_to_bit_string(ctx, signature, Span(in, in_len));
}

int bssl::x509_sign_to_bit_string(EVP_MD_CTX *ctx, ASN1_BIT_STRING *out,
                                  Span<const uint8_t> in) {
  if (out->type != V_ASN1_BIT_STRING) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE);
    return 0;
  }

  EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
  size_t sig_len = EVP_PKEY_size(pkey);
  if (sig_len > INT_MAX) {
    // Ensure the signature will fit in |out|.
    OPENSSL_PUT_ERROR(X509, ERR_R_OVERFLOW);
    return 0;
  }
  Array<uint8_t> sig;
  if (!sig.Init(sig_len)) {
    return 0;
  }

  if (!EVP_DigestSign(ctx, sig.data(), &sig_len, in.data(), in.size())) {
    OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB);
    return 0;
  }
  sig.Shrink(sig_len);

  uint8_t *sig_data;
  sig.Release(&sig_data, &sig_len);
  ASN1_STRING_set0(out, sig_data, static_cast<int>(sig_len));
  return static_cast<int>(sig_len);
}
