/* 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 "cryptlib.h"
#include <openssl/conf.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.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;
	int i, ia5org;
	pols = sk_POLICYINFO_new_null();
	if (pols == NULL) {
		X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE);
		return NULL;
	}
	vals =  X509V3_parse_list(value);
	if (vals == NULL) {
		X509V3err(X509V3_F_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 ) {
			X509V3err(X509V3_F_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) {
				X509V3err(X509V3_F_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))) {
				X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_OBJECT_IDENTIFIER);
				X509V3_conf_err(cnf);
				goto err;
			}
			pol = POLICYINFO_new();
			pol->policyid = pobj;
		}
		sk_POLICYINFO_push(pols, pol);
	}
	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)
{
	int 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))) {
				X509V3err(X509V3_F_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;
			qual->pqualid = 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 != '@') {
				X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_EXPECTED_A_SECTION_NAME);
				X509V3_conf_err(cnf);
				goto err;
			}
			unot = X509V3_get_section(ctx, cnf->value + 1);
			if(!unot) {
				X509V3err(X509V3_F_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 {
			X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_INVALID_OPTION);

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

	return pol;

	merr:
	X509V3err(X509V3_F_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)
{
	int i, ret;
	CONF_VALUE *cnf;
	USERNOTICE *not;
	POLICYQUALINFO *qual;
	if(!(qual = POLICYQUALINFO_new())) goto merr;
	qual->pqualid = 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)) {
				X509V3err(X509V3_F_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 {
			X509V3err(X509V3_F_NOTICE_SECTION,X509V3_R_INVALID_OPTION);
			X509V3_conf_err(cnf);
			goto err;
		}
	}

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

	return qual;

	merr:
	X509V3err(X509V3_F_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;

	int 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))) {
			X509V3err(X509V3_F_NREF_NOS,X509V3_R_INVALID_NUMBER);
			goto err;
		}
		if(!sk_ASN1_INTEGER_push(nnums, aint)) goto merr;
	}
	return 1;

	merr:
	X509V3err(X509V3_F_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)
{
	int 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;
	int 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)
{
	int 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, "");
	}
	
