/* v3_cpols.c */
/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
 * project 1999.
 */
/* ====================================================================
 * Copyright (c) 1999 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/asn1_mac.h>
#include <openssl/x509v3.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 STACK *nref_nos(STACK_OF(CONF_VALUE) *nos);

X509V3_EXT_METHOD v3_cpols = {
NID_certificate_policies, 0,
(X509V3_EXT_NEW)CERTIFICATEPOLICIES_new,
(X509V3_EXT_FREE)CERTIFICATEPOLICIES_free,
(X509V3_EXT_D2I)d2i_CERTIFICATEPOLICIES,
(X509V3_EXT_I2D)i2d_CERTIFICATEPOLICIES,
NULL, NULL,
NULL, NULL,
(X509V3_EXT_I2R)i2r_certpol,
(X509V3_EXT_R2I)r2i_certpol,
NULL
};


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();
	vals =  X509V3_parse_list(value);
	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_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 = 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(!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;
	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 = 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 = ASN1_IA5STRING_new();
			else nref->organization = ASN1_VISIBLESTRING_new();
			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;
			}
			nref->noticenos = nref_nos(nos);
			sk_CONF_VALUE_pop_free(nos, X509V3_conf_free);
			if(!nref->noticenos) 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 STACK *nref_nos(STACK_OF(CONF_VALUE) *nos)
{
	STACK *nnums;
	CONF_VALUE *cnf;
	ASN1_INTEGER *aint;
	int i;
	if(!(nnums = sk_new_null())) goto merr;
	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_push(nnums, (char *)aint)) goto merr;
	}
	return nnums;

	merr:
	X509V3err(X509V3_F_NOTICE_SECTION,ERR_R_MALLOC_FAILURE);

	err:
	sk_pop_free(nnums, ASN1_STRING_free);
	return NULL;
}


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


int i2d_CERTIFICATEPOLICIES(STACK_OF(POLICYINFO) *a, unsigned char **pp)
{

return i2d_ASN1_SET_OF_POLICYINFO(a, pp, i2d_POLICYINFO, V_ASN1_SEQUENCE,
                                                 V_ASN1_UNIVERSAL, IS_SEQUENCE);}

STACK_OF(POLICYINFO) *CERTIFICATEPOLICIES_new(void)
{
	return sk_POLICYINFO_new_null();
}

void CERTIFICATEPOLICIES_free(STACK_OF(POLICYINFO) *a)
{
	sk_POLICYINFO_pop_free(a, POLICYINFO_free);
}

STACK_OF(POLICYINFO) *d2i_CERTIFICATEPOLICIES(STACK_OF(POLICYINFO) **a,
		unsigned char **pp,long length)
{
return d2i_ASN1_SET_OF_POLICYINFO(a, pp, length, d2i_POLICYINFO,
                         POLICYINFO_free, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);

}

IMPLEMENT_STACK_OF(POLICYINFO)
IMPLEMENT_ASN1_SET_OF(POLICYINFO)

int i2d_POLICYINFO(POLICYINFO *a, unsigned char **pp)
{
	M_ASN1_I2D_vars(a);

	M_ASN1_I2D_len (a->policyid, i2d_ASN1_OBJECT);
	M_ASN1_I2D_len_SEQUENCE_type(POLICYQUALINFO, a->qualifiers,
							 i2d_POLICYQUALINFO);

	M_ASN1_I2D_seq_total();

	M_ASN1_I2D_put (a->policyid, i2d_ASN1_OBJECT);
	M_ASN1_I2D_put_SEQUENCE_type(POLICYQUALINFO, a->qualifiers,
							 i2d_POLICYQUALINFO);

	M_ASN1_I2D_finish();
}

POLICYINFO *POLICYINFO_new(void)
{
	POLICYINFO *ret=NULL;
	ASN1_CTX c;
	M_ASN1_New_Malloc(ret, POLICYINFO);
	ret->policyid = NULL;
	ret->qualifiers = NULL;
	return (ret);
	M_ASN1_New_Error(ASN1_F_POLICYINFO_NEW);
}

POLICYINFO *d2i_POLICYINFO(POLICYINFO **a, unsigned char **pp,long length)
{
	M_ASN1_D2I_vars(a,POLICYINFO *,POLICYINFO_new);
	M_ASN1_D2I_Init();
	M_ASN1_D2I_start_sequence();
	M_ASN1_D2I_get(ret->policyid, d2i_ASN1_OBJECT);
	if(!M_ASN1_D2I_end_sequence()) {
		M_ASN1_D2I_get_seq_type (POLICYQUALINFO, ret->qualifiers,
				 d2i_POLICYQUALINFO, POLICYQUALINFO_free);
	}
	M_ASN1_D2I_Finish(a, POLICYINFO_free, ASN1_F_D2I_POLICYINFO);
}

void POLICYINFO_free(POLICYINFO *a)
{
	if (a == NULL) return;
	ASN1_OBJECT_free(a->policyid);
	sk_POLICYQUALINFO_pop_free(a->qualifiers, POLICYQUALINFO_free);
	Free (a);
}

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_num(ref->noticenos) > 1) ? "s" : "");
		for(i = 0; i < sk_num(ref->noticenos); i++) {
			ASN1_INTEGER *num;
			char *tmp;
			num = (ASN1_INTEGER *)sk_value(ref->noticenos, i);
			if(i) BIO_puts(out, ", ");
			tmp = i2s_ASN1_INTEGER(NULL, num);
			BIO_puts(out, tmp);
			Free(tmp);
		}
		BIO_puts(out, "\n");
	}
	if(notice->exptext)
		BIO_printf(out, "%*sExplicit Text: %s\n", indent, "",
							 notice->exptext->data);
}
		
	

int i2d_POLICYQUALINFO(POLICYQUALINFO *a, unsigned char **pp)
{
	M_ASN1_I2D_vars(a);

	M_ASN1_I2D_len (a->pqualid, i2d_ASN1_OBJECT);
	switch(OBJ_obj2nid(a->pqualid)) {
		case NID_id_qt_cps:
		M_ASN1_I2D_len(a->d.cpsuri, i2d_ASN1_IA5STRING);
		break;

		case NID_id_qt_unotice:
		M_ASN1_I2D_len(a->d.usernotice, i2d_USERNOTICE);
		break;

		default:
		M_ASN1_I2D_len(a->d.other, i2d_ASN1_TYPE);
		break;
	}

	M_ASN1_I2D_seq_total();

	M_ASN1_I2D_put (a->pqualid, i2d_ASN1_OBJECT);
	switch(OBJ_obj2nid(a->pqualid)) {
		case NID_id_qt_cps:
		M_ASN1_I2D_put(a->d.cpsuri, i2d_ASN1_IA5STRING);
		break;

		case NID_id_qt_unotice:
		M_ASN1_I2D_put(a->d.usernotice, i2d_USERNOTICE);
		break;

		default:
		M_ASN1_I2D_put(a->d.other, i2d_ASN1_TYPE);
		break;
	}

	M_ASN1_I2D_finish();
}

POLICYQUALINFO *POLICYQUALINFO_new(void)
{
	POLICYQUALINFO *ret=NULL;
	ASN1_CTX c;
	M_ASN1_New_Malloc(ret, POLICYQUALINFO);
	ret->pqualid = NULL;
	ret->d.other = NULL;
	return (ret);
	M_ASN1_New_Error(ASN1_F_POLICYQUALINFO_NEW);
}

POLICYQUALINFO *d2i_POLICYQUALINFO(POLICYQUALINFO **a, unsigned char **pp,
		long length)
{
	M_ASN1_D2I_vars(a,POLICYQUALINFO *,POLICYQUALINFO_new);
	M_ASN1_D2I_Init();
	M_ASN1_D2I_start_sequence();
	M_ASN1_D2I_get (ret->pqualid, d2i_ASN1_OBJECT);
	switch(OBJ_obj2nid(ret->pqualid)) {
		case NID_id_qt_cps:
		M_ASN1_D2I_get(ret->d.cpsuri, d2i_ASN1_IA5STRING);
		break;

		case NID_id_qt_unotice:
		M_ASN1_D2I_get(ret->d.usernotice, d2i_USERNOTICE);
		break;

		default:
		M_ASN1_D2I_get(ret->d.other, d2i_ASN1_TYPE);
		break;
	}
	M_ASN1_D2I_Finish(a, POLICYQUALINFO_free, ASN1_F_D2I_POLICYQUALINFO);
}

void POLICYQUALINFO_free(POLICYQUALINFO *a)
{
	if (a == NULL) return;
	switch(OBJ_obj2nid(a->pqualid)) {
		case NID_id_qt_cps:
		ASN1_IA5STRING_free(a->d.cpsuri);
		break;

		case NID_id_qt_unotice:
		USERNOTICE_free(a->d.usernotice);
		break;

		default:
		ASN1_TYPE_free(a->d.other);
		break;
	}
	
	ASN1_OBJECT_free(a->pqualid);
	Free (a);
}

int i2d_USERNOTICE(USERNOTICE *a, unsigned char **pp)
{
	M_ASN1_I2D_vars(a);

	M_ASN1_I2D_len (a->noticeref, i2d_NOTICEREF);
	M_ASN1_I2D_len (a->exptext, i2d_DISPLAYTEXT);

	M_ASN1_I2D_seq_total();

	M_ASN1_I2D_put (a->noticeref, i2d_NOTICEREF);
	M_ASN1_I2D_put (a->exptext, i2d_DISPLAYTEXT);

	M_ASN1_I2D_finish();
}

USERNOTICE *USERNOTICE_new(void)
{
	USERNOTICE *ret=NULL;
	ASN1_CTX c;
	M_ASN1_New_Malloc(ret, USERNOTICE);
	ret->noticeref = NULL;
	ret->exptext = NULL;
	return (ret);
	M_ASN1_New_Error(ASN1_F_USERNOTICE_NEW);
}

USERNOTICE *d2i_USERNOTICE(USERNOTICE **a, unsigned char **pp,long length)
{
	M_ASN1_D2I_vars(a,USERNOTICE *,USERNOTICE_new);
	M_ASN1_D2I_Init();
	M_ASN1_D2I_start_sequence();
	M_ASN1_D2I_get_opt(ret->noticeref, d2i_NOTICEREF, V_ASN1_SEQUENCE);
	if (!M_ASN1_D2I_end_sequence()) {
		M_ASN1_D2I_get(ret->exptext, d2i_DISPLAYTEXT);
	}
	M_ASN1_D2I_Finish(a, USERNOTICE_free, ASN1_F_D2I_USERNOTICE);
}

void USERNOTICE_free(USERNOTICE *a)
{
	if (a == NULL) return;
	NOTICEREF_free(a->noticeref);
	DISPLAYTEXT_free(a->exptext);
	Free (a);
}

int i2d_NOTICEREF(NOTICEREF *a, unsigned char **pp)
{
	M_ASN1_I2D_vars(a);

	M_ASN1_I2D_len (a->organization, i2d_DISPLAYTEXT);
	M_ASN1_I2D_len_SEQUENCE(a->noticenos, i2d_ASN1_INTEGER);

	M_ASN1_I2D_seq_total();

	M_ASN1_I2D_put (a->organization, i2d_DISPLAYTEXT);
	M_ASN1_I2D_put_SEQUENCE(a->noticenos, i2d_ASN1_INTEGER);

	M_ASN1_I2D_finish();
}

NOTICEREF *NOTICEREF_new(void)
{
	NOTICEREF *ret=NULL;
	ASN1_CTX c;
	M_ASN1_New_Malloc(ret, NOTICEREF);
	ret->organization = NULL;
	ret->noticenos = NULL;
	return (ret);
	M_ASN1_New_Error(ASN1_F_NOTICEREF_NEW);
}

NOTICEREF *d2i_NOTICEREF(NOTICEREF **a, unsigned char **pp,long length)
{
	M_ASN1_D2I_vars(a,NOTICEREF *,NOTICEREF_new);
	M_ASN1_D2I_Init();
	M_ASN1_D2I_start_sequence();
	/* This is to cope with some broken encodings that use IA5STRING for
         * the organization field
	 */
	M_ASN1_D2I_get_opt(ret->organization, d2i_ASN1_IA5STRING,
							 V_ASN1_IA5STRING);
	if(!ret->organization) {
		 M_ASN1_D2I_get(ret->organization, d2i_DISPLAYTEXT);
	}
	M_ASN1_D2I_get_seq(ret->noticenos, d2i_ASN1_INTEGER, ASN1_STRING_free);
	M_ASN1_D2I_Finish(a, NOTICEREF_free, ASN1_F_D2I_NOTICEREF);
}

void NOTICEREF_free(NOTICEREF *a)
{
	if (a == NULL) return;
	DISPLAYTEXT_free(a->organization);
	sk_pop_free(a->noticenos, ASN1_STRING_free);
	Free (a);
}

IMPLEMENT_STACK_OF(POLICYQUALINFO)
IMPLEMENT_ASN1_SET_OF(POLICYQUALINFO)
