/* v3_conf.c */
/*
 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
 * 1999.
 */
/* ====================================================================
 * Copyright (c) 1999-2002 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com). */

// extension creation utilities

#include <ctype.h>
#include <stdio.h>
#include <string.h>

#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>

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

static int v3_check_critical(const char **value);
static int v3_check_generic(const char **value);
static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
                                    int crit, const char *value);
static X509_EXTENSION *v3_generic_extension(const char *ext, const char *value,
                                            int crit, int type,
                                            X509V3_CTX *ctx);
static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
                                  int crit, void *ext_struc);
static unsigned char *generic_asn1(const char *value, X509V3_CTX *ctx,
                                   long *ext_len);
// CONF *conf:  Config file
// char *name:  Name
// char *value:  Value
X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name,
                                 const char *value) {
  int crit;
  int ext_type;
  X509_EXTENSION *ret;
  crit = v3_check_critical(&value);
  if ((ext_type = v3_check_generic(&value))) {
    return v3_generic_extension(name, value, crit, ext_type, ctx);
  }
  ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value);
  if (!ret) {
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_IN_EXTENSION);
    ERR_add_error_data(4, "name=", name, ", value=", value);
  }
  return ret;
}

// CONF *conf:  Config file
// char *value:  Value
X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
                                     const char *value) {
  int crit;
  int ext_type;
  crit = v3_check_critical(&value);
  if ((ext_type = v3_check_generic(&value))) {
    return v3_generic_extension(OBJ_nid2sn(ext_nid), value, crit, ext_type,
                                ctx);
  }
  return do_ext_nconf(conf, ctx, ext_nid, crit, value);
}

// CONF *conf:  Config file
// char *value:  Value
static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
                                    int crit, const char *value) {
  const X509V3_EXT_METHOD *method;
  X509_EXTENSION *ext;
  STACK_OF(CONF_VALUE) *nval;
  void *ext_struc;
  if (ext_nid == NID_undef) {
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION_NAME);
    return NULL;
  }
  if (!(method = X509V3_EXT_get_nid(ext_nid))) {
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION);
    return NULL;
  }
  // Now get internal extension representation based on type
  if (method->v2i) {
    if (*value == '@') {
      nval = NCONF_get_section(conf, value + 1);
    } else {
      nval = X509V3_parse_list(value);
    }
    if (nval == NULL || sk_CONF_VALUE_num(nval) <= 0) {
      OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_EXTENSION_STRING);
      ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", value);
      if (*value != '@') {
        sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
      }
      return NULL;
    }
    ext_struc = method->v2i(method, ctx, nval);
    if (*value != '@') {
      sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
    }
    if (!ext_struc) {
      return NULL;
    }
  } else if (method->s2i) {
    if (!(ext_struc = method->s2i(method, ctx, value))) {
      return NULL;
    }
  } else if (method->r2i) {
    if (!ctx->db || !ctx->db_meth) {
      OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_CONFIG_DATABASE);
      return NULL;
    }
    if (!(ext_struc = method->r2i(method, ctx, value))) {
      return NULL;
    }
  } else {
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
    ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid));
    return NULL;
  }

  ext = do_ext_i2d(method, ext_nid, crit, ext_struc);
  if (method->it) {
    ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it));
  } else {
    method->ext_free(ext_struc);
  }
  return ext;
}

static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
                                  int crit, void *ext_struc) {
  unsigned char *ext_der;
  int ext_len;
  ASN1_OCTET_STRING *ext_oct;
  X509_EXTENSION *ext;
  // Convert internal representation to DER
  if (method->it) {
    ext_der = NULL;
    ext_len = ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it));
    if (ext_len < 0) {
      goto merr;
    }
  } else {
    unsigned char *p;
    ext_len = method->i2d(ext_struc, NULL);
    if (!(ext_der = OPENSSL_malloc(ext_len))) {
      goto merr;
    }
    p = ext_der;
    method->i2d(ext_struc, &p);
  }
  if (!(ext_oct = ASN1_OCTET_STRING_new())) {
    goto merr;
  }
  ext_oct->data = ext_der;
  ext_oct->length = ext_len;

  ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct);
  if (!ext) {
    goto merr;
  }
  ASN1_OCTET_STRING_free(ext_oct);

  return ext;

merr:
  OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
  return NULL;
}

// Given an internal structure, nid and critical flag create an extension

X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc) {
  const X509V3_EXT_METHOD *method;
  if (!(method = X509V3_EXT_get_nid(ext_nid))) {
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION);
    return NULL;
  }
  return do_ext_i2d(method, ext_nid, crit, ext_struc);
}

// Check the extension string for critical flag
static int v3_check_critical(const char **value) {
  const char *p = *value;
  if ((strlen(p) < 9) || strncmp(p, "critical,", 9)) {
    return 0;
  }
  p += 9;
  while (isspace((unsigned char)*p)) {
    p++;
  }
  *value = p;
  return 1;
}

// Check extension string for generic extension and return the type
static int v3_check_generic(const char **value) {
  int gen_type = 0;
  const char *p = *value;
  if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4)) {
    p += 4;
    gen_type = 1;
  } else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5)) {
    p += 5;
    gen_type = 2;
  } else {
    return 0;
  }

  while (isspace((unsigned char)*p)) {
    p++;
  }
  *value = p;
  return gen_type;
}

// Create a generic extension: for now just handle DER type
static X509_EXTENSION *v3_generic_extension(const char *ext, const char *value,
                                            int crit, int gen_type,
                                            X509V3_CTX *ctx) {
  unsigned char *ext_der = NULL;
  long ext_len = 0;
  ASN1_OBJECT *obj = NULL;
  ASN1_OCTET_STRING *oct = NULL;
  X509_EXTENSION *extension = NULL;
  if (!(obj = OBJ_txt2obj(ext, 0))) {
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_NAME_ERROR);
    ERR_add_error_data(2, "name=", ext);
    goto err;
  }

  if (gen_type == 1) {
    ext_der = x509v3_hex_to_bytes(value, &ext_len);
  } else if (gen_type == 2) {
    ext_der = generic_asn1(value, ctx, &ext_len);
  }

  if (ext_der == NULL) {
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_VALUE_ERROR);
    ERR_add_error_data(2, "value=", value);
    goto err;
  }

  if (!(oct = ASN1_OCTET_STRING_new())) {
    OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  oct->data = ext_der;
  oct->length = ext_len;
  ext_der = NULL;

  extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct);

err:
  ASN1_OBJECT_free(obj);
  ASN1_OCTET_STRING_free(oct);
  if (ext_der) {
    OPENSSL_free(ext_der);
  }
  return extension;
}

static unsigned char *generic_asn1(const char *value, X509V3_CTX *ctx,
                                   long *ext_len) {
  ASN1_TYPE *typ;
  unsigned char *ext_der = NULL;
  typ = ASN1_generate_v3(value, ctx);
  if (typ == NULL) {
    return NULL;
  }
  *ext_len = i2d_ASN1_TYPE(typ, &ext_der);
  ASN1_TYPE_free(typ);
  return ext_der;
}

// This is the main function: add a bunch of extensions based on a config
// file section to an extension STACK.

int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section,
                            STACK_OF(X509_EXTENSION) **sk) {
  X509_EXTENSION *ext;
  STACK_OF(CONF_VALUE) *nval;
  CONF_VALUE *val;
  size_t i;
  if (!(nval = NCONF_get_section(conf, section))) {
    return 0;
  }
  for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
    val = sk_CONF_VALUE_value(nval, i);
    if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value))) {
      return 0;
    }
    if (sk) {
      X509v3_add_ext(sk, ext, -1);
    }
    X509_EXTENSION_free(ext);
  }
  return 1;
}

// Convenience functions to add extensions to a certificate, CRL and request

int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section,
                         X509 *cert) {
  STACK_OF(X509_EXTENSION) **sk = NULL;
  if (cert) {
    sk = &cert->cert_info->extensions;
  }
  return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
}

// Same as above but for a CRL

int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section,
                             X509_CRL *crl) {
  STACK_OF(X509_EXTENSION) **sk = NULL;
  if (crl) {
    sk = &crl->crl->extensions;
  }
  return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
}

// Add extensions to certificate request

int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section,
                             X509_REQ *req) {
  STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL;
  int i;
  if (req) {
    sk = &extlist;
  }
  i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
  if (!i || !sk) {
    return i;
  }
  i = X509_REQ_add_extensions(req, extlist);
  sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free);
  return i;
}

// Config database functions

char *X509V3_get_string(X509V3_CTX *ctx, const char *name,
                        const char *section) {
  if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string) {
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_OPERATION_NOT_DEFINED);
    return NULL;
  }
  if (ctx->db_meth->get_string) {
    return ctx->db_meth->get_string(ctx->db, name, section);
  }
  return NULL;
}

STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, const char *section) {
  if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section) {
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_OPERATION_NOT_DEFINED);
    return NULL;
  }
  if (ctx->db_meth->get_section) {
    return ctx->db_meth->get_section(ctx->db, section);
  }
  return NULL;
}

void X509V3_string_free(X509V3_CTX *ctx, char *str) {
  if (!str) {
    return;
  }
  if (ctx->db_meth->free_string) {
    ctx->db_meth->free_string(ctx->db, str);
  }
}

void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section) {
  if (!section) {
    return;
  }
  if (ctx->db_meth->free_section) {
    ctx->db_meth->free_section(ctx->db, section);
  }
}

static char *nconf_get_string(void *db, const char *section,
                              const char *value) {
  // TODO(fork): This returns a non-const pointer because |X509V3_CONF_METHOD|
  // allows |get_string| to return caller-owned pointers, provided they're
  // freed by |free_string|. |nconf_method| leaves |free_string| NULL, and
  // there are no other implementations of |X509V3_CONF_METHOD|, so this can
  // be simplified if we make it private.
  return (char *)NCONF_get_string(db, section, value);
}

static STACK_OF(CONF_VALUE) *nconf_get_section(void *db, const char *section) {
  return NCONF_get_section(db, section);
}

static const X509V3_CONF_METHOD nconf_method = {nconf_get_string,
                                                nconf_get_section, NULL, NULL};

void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf) {
  ctx->db_meth = &nconf_method;
  ctx->db = conf;
}

void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req,
                    X509_CRL *crl, int flags) {
  ctx->issuer_cert = issuer;
  ctx->subject_cert = subj;
  ctx->crl = crl;
  ctx->subject_req = req;
  ctx->flags = flags;
}
