// 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/x509.h>

#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/digest.h>
#include <openssl/obj.h>

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


ASN1_SEQUENCE(X509_ALGOR) = {
    ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT),
    ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY),
} ASN1_SEQUENCE_END(X509_ALGOR)

IMPLEMENT_ASN1_FUNCTIONS_const(X509_ALGOR)

X509_ALGOR *X509_ALGOR_dup(const X509_ALGOR *alg) {
  bssl::UniquePtr<X509_ALGOR> copy(X509_ALGOR_new());
  if (copy == nullptr || !X509_ALGOR_copy(copy.get(), alg)) {
    return nullptr;
  }
  return copy.release();
}

int X509_ALGOR_copy(X509_ALGOR *dst, const X509_ALGOR *src) {
  bssl::UniquePtr<ASN1_OBJECT> algorithm(OBJ_dup(src->algorithm));
  if (algorithm == nullptr) {
    return 0;
  }
  bssl::UniquePtr<ASN1_TYPE> parameter;
  if (src->parameter != nullptr) {
    parameter.reset(ASN1_TYPE_new());
    if (parameter == nullptr ||
        !ASN1_TYPE_set1(parameter.get(), src->parameter->type,
                        asn1_type_value_as_pointer(src->parameter))) {
      return 0;
    }
  }
  ASN1_OBJECT_free(dst->algorithm);
  dst->algorithm = algorithm.release();
  ASN1_TYPE_free(dst->parameter);
  dst->parameter = parameter.release();
  return 1;
}

int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval) {
  if (!alg) {
    return 0;
  }
  if (ptype != V_ASN1_UNDEF) {
    if (alg->parameter == NULL) {
      alg->parameter = ASN1_TYPE_new();
    }
    if (alg->parameter == NULL) {
      return 0;
    }
  }
  if (alg) {
    ASN1_OBJECT_free(alg->algorithm);
    alg->algorithm = aobj;
  }
  if (ptype == 0) {
    return 1;
  }
  if (ptype == V_ASN1_UNDEF) {
    if (alg->parameter) {
      ASN1_TYPE_free(alg->parameter);
      alg->parameter = NULL;
    }
  } else {
    ASN1_TYPE_set(alg->parameter, ptype, pval);
  }
  return 1;
}

void X509_ALGOR_get0(const ASN1_OBJECT **out_obj, int *out_param_type,
                     const void **out_param_value, const X509_ALGOR *alg) {
  if (out_obj != NULL) {
    *out_obj = alg->algorithm;
  }
  if (out_param_type != NULL) {
    int type = V_ASN1_UNDEF;
    const void *value = NULL;
    if (alg->parameter != NULL) {
      type = alg->parameter->type;
      value = asn1_type_value_as_pointer(alg->parameter);
    }
    *out_param_type = type;
    if (out_param_value != NULL) {
      *out_param_value = value;
    }
  }
}

// Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD

int X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md) {
  int param_type;

  if (EVP_MD_flags(md) & EVP_MD_FLAG_DIGALGID_ABSENT) {
    param_type = V_ASN1_UNDEF;
  } else {
    param_type = V_ASN1_NULL;
  }

  return X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
}

// X509_ALGOR_cmp returns 0 if |a| and |b| are equal and non-zero otherwise.
int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b) {
  int rv;
  rv = OBJ_cmp(a->algorithm, b->algorithm);
  if (rv) {
    return rv;
  }
  if (!a->parameter && !b->parameter) {
    return 0;
  }
  return ASN1_TYPE_cmp(a->parameter, b->parameter);
}

int x509_marshal_algorithm(CBB *out, const X509_ALGOR *in) {
  uint8_t *ptr;
  int len = i2d_X509_ALGOR(in, NULL);
  return len > 0 &&  //
         CBB_add_space(out, &ptr, static_cast<size_t>(len)) &&
         i2d_X509_ALGOR(in, &ptr) == len;
}
