/* v3_cpols.c */
/*
 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
 * 1999.
 */
/* ====================================================================
 * Copyright (c) 1999-2004 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).
 *
 */

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

#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/stack.h>
#include <openssl/x509v3.h>

#include "internal.h"

// Certificate policies extension support: this one is a bit complex...

static int i2r_certpol(const X509V3_EXT_METHOD *method, void *ext, BIO *out,
                       int indent);
static void *r2i_certpol(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
                         const char *value);
static void print_qualifiers(BIO *out, const STACK_OF(POLICYQUALINFO) *quals,
                             int indent);
static void print_notice(BIO *out, const USERNOTICE *notice, int indent);
static POLICYINFO *policy_section(X509V3_CTX *ctx,
                                  STACK_OF(CONF_VALUE) *polstrs, int ia5org);
static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
                                      STACK_OF(CONF_VALUE) *unot, int ia5org);
static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos);

const X509V3_EXT_METHOD v3_cpols = {
    NID_certificate_policies,
    0,
    ASN1_ITEM_ref(CERTIFICATEPOLICIES),
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    i2r_certpol,
    r2i_certpol,
    NULL,
};

ASN1_ITEM_TEMPLATE(CERTIFICATEPOLICIES) = ASN1_EX_TEMPLATE_TYPE(
    ASN1_TFLG_SEQUENCE_OF, 0, CERTIFICATEPOLICIES, POLICYINFO)
ASN1_ITEM_TEMPLATE_END(CERTIFICATEPOLICIES)

IMPLEMENT_ASN1_FUNCTIONS(CERTIFICATEPOLICIES)

ASN1_SEQUENCE(POLICYINFO) = {
    ASN1_SIMPLE(POLICYINFO, policyid, ASN1_OBJECT),
    ASN1_SEQUENCE_OF_OPT(POLICYINFO, qualifiers, POLICYQUALINFO),
} ASN1_SEQUENCE_END(POLICYINFO)

IMPLEMENT_ASN1_FUNCTIONS(POLICYINFO)

ASN1_ADB_TEMPLATE(policydefault) = ASN1_SIMPLE(POLICYQUALINFO, d.other,
                                               ASN1_ANY);

ASN1_ADB(POLICYQUALINFO) = {
    ADB_ENTRY(NID_id_qt_cps,
              ASN1_SIMPLE(POLICYQUALINFO, d.cpsuri, ASN1_IA5STRING)),
    ADB_ENTRY(NID_id_qt_unotice,
              ASN1_SIMPLE(POLICYQUALINFO, d.usernotice, USERNOTICE)),
} ASN1_ADB_END(POLICYQUALINFO, 0, pqualid, 0, &policydefault_tt, NULL);

ASN1_SEQUENCE(POLICYQUALINFO) = {
    ASN1_SIMPLE(POLICYQUALINFO, pqualid, ASN1_OBJECT),
    ASN1_ADB_OBJECT(POLICYQUALINFO),
} ASN1_SEQUENCE_END(POLICYQUALINFO)

IMPLEMENT_ASN1_FUNCTIONS(POLICYQUALINFO)

ASN1_SEQUENCE(USERNOTICE) = {
    ASN1_OPT(USERNOTICE, noticeref, NOTICEREF),
    ASN1_OPT(USERNOTICE, exptext, DISPLAYTEXT),
} ASN1_SEQUENCE_END(USERNOTICE)

IMPLEMENT_ASN1_FUNCTIONS(USERNOTICE)

ASN1_SEQUENCE(NOTICEREF) = {
    ASN1_SIMPLE(NOTICEREF, organization, DISPLAYTEXT),
    ASN1_SEQUENCE_OF(NOTICEREF, noticenos, ASN1_INTEGER),
} ASN1_SEQUENCE_END(NOTICEREF)

IMPLEMENT_ASN1_FUNCTIONS(NOTICEREF)

static void *r2i_certpol(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
                         const char *value) {
  STACK_OF(POLICYINFO) *pols = NULL;
  char *pstr;
  POLICYINFO *pol;
  ASN1_OBJECT *pobj;
  STACK_OF(CONF_VALUE) *vals;
  CONF_VALUE *cnf;
  size_t i;
  int ia5org;
  pols = sk_POLICYINFO_new_null();
  if (pols == NULL) {
    OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
    return NULL;
  }
  vals = X509V3_parse_list(value);
  if (vals == NULL) {
    OPENSSL_PUT_ERROR(X509V3, ERR_R_X509V3_LIB);
    goto err;
  }
  ia5org = 0;
  for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
    cnf = sk_CONF_VALUE_value(vals, i);
    if (cnf->value || !cnf->name) {
      OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_POLICY_IDENTIFIER);
      X509V3_conf_err(cnf);
      goto err;
    }
    pstr = cnf->name;
    if (!strcmp(pstr, "ia5org")) {
      ia5org = 1;
      continue;
    } else if (*pstr == '@') {
      STACK_OF(CONF_VALUE) *polsect;
      polsect = X509V3_get_section(ctx, pstr + 1);
      if (!polsect) {
        OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION);

        X509V3_conf_err(cnf);
        goto err;
      }
      pol = policy_section(ctx, polsect, ia5org);
      X509V3_section_free(ctx, polsect);
      if (!pol) {
        goto err;
      }
    } else {
      if (!(pobj = OBJ_txt2obj(cnf->name, 0))) {
        OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
        X509V3_conf_err(cnf);
        goto err;
      }
      pol = POLICYINFO_new();
      if (pol == NULL) {
        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
        ASN1_OBJECT_free(pobj);
        goto err;
      }
      pol->policyid = pobj;
    }
    if (!sk_POLICYINFO_push(pols, pol)) {
      POLICYINFO_free(pol);
      OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
      goto err;
    }
  }
  sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
  return pols;
err:
  sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
  sk_POLICYINFO_pop_free(pols, POLICYINFO_free);
  return NULL;
}

static POLICYINFO *policy_section(X509V3_CTX *ctx,
                                  STACK_OF(CONF_VALUE) *polstrs, int ia5org) {
  size_t i;
  CONF_VALUE *cnf;
  POLICYINFO *pol;
  POLICYQUALINFO *qual;
  if (!(pol = POLICYINFO_new())) {
    goto merr;
  }
  for (i = 0; i < sk_CONF_VALUE_num(polstrs); i++) {
    cnf = sk_CONF_VALUE_value(polstrs, i);
    if (!strcmp(cnf->name, "policyIdentifier")) {
      ASN1_OBJECT *pobj;
      if (!(pobj = OBJ_txt2obj(cnf->value, 0))) {
        OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
        X509V3_conf_err(cnf);
        goto err;
      }
      pol->policyid = pobj;

    } else if (!x509v3_name_cmp(cnf->name, "CPS")) {
      if (!pol->qualifiers) {
        pol->qualifiers = sk_POLICYQUALINFO_new_null();
      }
      if (!(qual = POLICYQUALINFO_new())) {
        goto merr;
      }
      if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) {
        goto merr;
      }
      qual->pqualid = OBJ_nid2obj(NID_id_qt_cps);
      if (qual->pqualid == NULL) {
        OPENSSL_PUT_ERROR(X509V3, ERR_R_INTERNAL_ERROR);
        goto err;
      }
      qual->d.cpsuri = ASN1_IA5STRING_new();
      if (qual->d.cpsuri == NULL) {
        goto err;
      }
      if (!ASN1_STRING_set(qual->d.cpsuri, cnf->value, strlen(cnf->value))) {
        goto merr;
      }
    } else if (!x509v3_name_cmp(cnf->name, "userNotice")) {
      STACK_OF(CONF_VALUE) *unot;
      if (*cnf->value != '@') {
        OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXPECTED_A_SECTION_NAME);
        X509V3_conf_err(cnf);
        goto err;
      }
      unot = X509V3_get_section(ctx, cnf->value + 1);
      if (!unot) {
        OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION);

        X509V3_conf_err(cnf);
        goto err;
      }
      qual = notice_section(ctx, unot, ia5org);
      X509V3_section_free(ctx, unot);
      if (!qual) {
        goto err;
      }
      if (!pol->qualifiers) {
        pol->qualifiers = sk_POLICYQUALINFO_new_null();
      }
      if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) {
        goto merr;
      }
    } else {
      OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION);

      X509V3_conf_err(cnf);
      goto err;
    }
  }
  if (!pol->policyid) {
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_POLICY_IDENTIFIER);
    goto err;
  }

  return pol;

merr:
  OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);

err:
  POLICYINFO_free(pol);
  return NULL;
}

static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
                                      STACK_OF(CONF_VALUE) *unot, int ia5org) {
  size_t i;
  int ret;
  CONF_VALUE *cnf;
  USERNOTICE * not ;
  POLICYQUALINFO *qual;
  if (!(qual = POLICYQUALINFO_new())) {
    goto merr;
  }
  qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice);
  if (qual->pqualid == NULL) {
    OPENSSL_PUT_ERROR(X509V3, ERR_R_INTERNAL_ERROR);
    goto err;
  }
  if (!(not = USERNOTICE_new())) {
    goto merr;
  }
  qual->d.usernotice = not ;
  for (i = 0; i < sk_CONF_VALUE_num(unot); i++) {
    cnf = sk_CONF_VALUE_value(unot, i);
    if (!strcmp(cnf->name, "explicitText")) {
      not ->exptext = ASN1_VISIBLESTRING_new();
      if (not ->exptext == NULL) {
        goto merr;
      }
      if (!ASN1_STRING_set(not ->exptext, cnf->value, strlen(cnf->value))) {
        goto merr;
      }
    } else if (!strcmp(cnf->name, "organization")) {
      NOTICEREF *nref;
      if (!not ->noticeref) {
        if (!(nref = NOTICEREF_new())) {
          goto merr;
        }
        not ->noticeref = nref;
      } else {
        nref = not ->noticeref;
      }
      if (ia5org) {
        nref->organization->type = V_ASN1_IA5STRING;
      } else {
        nref->organization->type = V_ASN1_VISIBLESTRING;
      }
      if (!ASN1_STRING_set(nref->organization, cnf->value,
                           strlen(cnf->value))) {
        goto merr;
      }
    } else if (!strcmp(cnf->name, "noticeNumbers")) {
      NOTICEREF *nref;
      STACK_OF(CONF_VALUE) *nos;
      if (!not ->noticeref) {
        if (!(nref = NOTICEREF_new())) {
          goto merr;
        }
        not ->noticeref = nref;
      } else {
        nref = not ->noticeref;
      }
      nos = X509V3_parse_list(cnf->value);
      if (!nos || !sk_CONF_VALUE_num(nos)) {
        OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NUMBERS);
        X509V3_conf_err(cnf);
        goto err;
      }
      ret = nref_nos(nref->noticenos, nos);
      sk_CONF_VALUE_pop_free(nos, X509V3_conf_free);
      if (!ret) {
        goto err;
      }
    } else {
      OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION);
      X509V3_conf_err(cnf);
      goto err;
    }
  }

  if (not ->noticeref &&
      (!not ->noticeref->noticenos || !not ->noticeref->organization)) {
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_NEED_ORGANIZATION_AND_NUMBERS);
    goto err;
  }

  return qual;

merr:
  OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);

err:
  POLICYQUALINFO_free(qual);
  return NULL;
}

static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos) {
  CONF_VALUE *cnf;
  ASN1_INTEGER *aint;

  size_t i;

  for (i = 0; i < sk_CONF_VALUE_num(nos); i++) {
    cnf = sk_CONF_VALUE_value(nos, i);
    if (!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) {
      OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NUMBER);
      goto err;
    }
    if (!sk_ASN1_INTEGER_push(nnums, aint)) {
      goto merr;
    }
  }
  return 1;

merr:
  ASN1_INTEGER_free(aint);
  OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);

err:
  return 0;
}

static int i2r_certpol(const X509V3_EXT_METHOD *method, void *ext, BIO *out,
                       int indent) {
  const STACK_OF(POLICYINFO) *pol = ext;
  // First print out the policy OIDs
  for (size_t i = 0; i < sk_POLICYINFO_num(pol); i++) {
    const POLICYINFO *pinfo = sk_POLICYINFO_value(pol, i);
    BIO_printf(out, "%*sPolicy: ", indent, "");
    i2a_ASN1_OBJECT(out, pinfo->policyid);
    BIO_puts(out, "\n");
    if (pinfo->qualifiers) {
      print_qualifiers(out, pinfo->qualifiers, indent + 2);
    }
  }
  return 1;
}

static void print_qualifiers(BIO *out, const STACK_OF(POLICYQUALINFO) *quals,
                             int indent) {
  for (size_t i = 0; i < sk_POLICYQUALINFO_num(quals); i++) {
    const POLICYQUALINFO *qualinfo = sk_POLICYQUALINFO_value(quals, i);
    switch (OBJ_obj2nid(qualinfo->pqualid)) {
      case NID_id_qt_cps:
        BIO_printf(out, "%*sCPS: %.*s\n", indent, "",
                   qualinfo->d.cpsuri->length, qualinfo->d.cpsuri->data);
        break;

      case NID_id_qt_unotice:
        BIO_printf(out, "%*sUser Notice:\n", indent, "");
        print_notice(out, qualinfo->d.usernotice, indent + 2);
        break;

      default:
        BIO_printf(out, "%*sUnknown Qualifier: ", indent + 2, "");

        i2a_ASN1_OBJECT(out, qualinfo->pqualid);
        BIO_puts(out, "\n");
        break;
    }
  }
}

static void print_notice(BIO *out, const USERNOTICE *notice, int indent) {
  if (notice->noticeref) {
    NOTICEREF *ref;
    ref = notice->noticeref;
    BIO_printf(out, "%*sOrganization: %.*s\n", indent, "",
               ref->organization->length, ref->organization->data);
    BIO_printf(out, "%*sNumber%s: ", indent, "",
               sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : "");
    for (size_t i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) {
      ASN1_INTEGER *num;
      char *tmp;
      num = sk_ASN1_INTEGER_value(ref->noticenos, i);
      if (i) {
        BIO_puts(out, ", ");
      }
      if (num == NULL) {
        BIO_puts(out, "(null)");
      } else {
        tmp = i2s_ASN1_INTEGER(NULL, num);
        if (tmp == NULL) {
          return;
        }
        BIO_puts(out, tmp);
        OPENSSL_free(tmp);
      }
    }
    BIO_puts(out, "\n");
  }
  if (notice->exptext) {
    BIO_printf(out, "%*sExplicit Text: %.*s\n", indent, "",
               notice->exptext->length, notice->exptext->data);
  }
}

void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent) {
  const X509_POLICY_DATA *dat = node->data;

  BIO_printf(out, "%*sPolicy: ", indent, "");

  i2a_ASN1_OBJECT(out, dat->valid_policy);
  BIO_puts(out, "\n");
  BIO_printf(out, "%*s%s\n", indent + 2, "",
             node_data_critical(dat) ? "Critical" : "Non Critical");
  if (dat->qualifier_set) {
    print_qualifiers(out, dat->qualifier_set, indent + 2);
  } else {
    BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, "");
  }
}
