// 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)
IMPLEMENT_ASN1_DUP_FUNCTION_const(X509_ALGOR)

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;
}
