/* 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 <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 "pcy_int.h"

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

static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, BIO *out, int indent);
static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *value);
static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, int indent);
static void print_notice(BIO *out, 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,
(X509V3_EXT_I2R)i2r_certpol,
(X509V3_EXT_R2I)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 STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
		X509V3_CTX *ctx, 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, r2i_certpol, ERR_R_MALLOC_FAILURE);
		return NULL;
	}
	vals =  X509V3_parse_list(value);
	if (vals == NULL) {
		OPENSSL_PUT_ERROR(X509V3, r2i_certpol, 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, r2i_certpol, 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, r2i_certpol, 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, r2i_certpol, X509V3_R_INVALID_OBJECT_IDENTIFIER);
				X509V3_conf_err(cnf);
				goto err;
			}
			pol = POLICYINFO_new();
			pol->policyid = pobj;
		}
		if (!sk_POLICYINFO_push(pols, pol)){
			POLICYINFO_free(pol);
			OPENSSL_PUT_ERROR(X509V3, r2i_certpol, 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, policy_section, X509V3_R_INVALID_OBJECT_IDENTIFIER);
				X509V3_conf_err(cnf);
				goto err;
			}
			pol->policyid = pobj;

		} else if(!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;
                        /* TODO(fork): const correctness */
			qual->pqualid = (ASN1_OBJECT*) OBJ_nid2obj(NID_id_qt_cps);
			qual->d.cpsuri = M_ASN1_IA5STRING_new();
			if(!ASN1_STRING_set(qual->d.cpsuri, cnf->value,
						 strlen(cnf->value))) goto merr;
		} else if(!name_cmp(cnf->name, "userNotice")) {
			STACK_OF(CONF_VALUE) *unot;
			if(*cnf->value != '@') {
				OPENSSL_PUT_ERROR(X509V3, policy_section, 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, policy_section, 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, policy_section, X509V3_R_INVALID_OPTION);

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

	return pol;

	merr:
	OPENSSL_PUT_ERROR(X509V3, policy_section, 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;
        /* TODO(fork): const correctness */
	qual->pqualid = (ASN1_OBJECT *) OBJ_nid2obj(NID_id_qt_unotice);
	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 = M_ASN1_VISIBLESTRING_new();
			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, notice_section, 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, notice_section, X509V3_R_INVALID_OPTION);
			X509V3_conf_err(cnf);
			goto err;
		}
	}

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

	return qual;

	merr:
	OPENSSL_PUT_ERROR(X509V3, notice_section, 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, nref_nos, X509V3_R_INVALID_NUMBER);
			goto err;
		}
		if(!sk_ASN1_INTEGER_push(nnums, aint)) goto merr;
	}
	return 1;

	merr:
	OPENSSL_PUT_ERROR(X509V3, nref_nos, ERR_R_MALLOC_FAILURE);

	err:
	sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free);
	return 0;
}


static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol,
		BIO *out, int indent)
{
	size_t i;
	POLICYINFO *pinfo;
	/* First print out the policy OIDs */
	for(i = 0; i < sk_POLICYINFO_num(pol); i++) {
		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, STACK_OF(POLICYQUALINFO) *quals,
		int indent)
{
	POLICYQUALINFO *qualinfo;
	size_t i;
	for(i = 0; i < sk_POLICYQUALINFO_num(quals); i++) {
		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->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, USERNOTICE *notice, int indent)
{
	size_t i;
	if(notice->noticeref) {
		NOTICEREF *ref;
		ref = notice->noticeref;
		BIO_printf(out, "%*sOrganization: %s\n", indent, "",
						 ref->organization->data);
		BIO_printf(out, "%*sNumber%s: ", indent, "",
			   sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : "");
		for(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, ", ");
			tmp = i2s_ASN1_INTEGER(NULL, num);
			BIO_puts(out, tmp);
			OPENSSL_free(tmp);
		}
		BIO_puts(out, "\n");
	}
	if(notice->exptext)
		BIO_printf(out, "%*sExplicit Text: %s\n", indent, "",
							 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, "");
	}
