X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fx509v3%2Fv3_cpols.c;h=8147ea598e35ee9a06b9988666f15bacd49d7a8d;hp=26a5df12e3dd7f09cab6cdab67f7a0af1a2bc824;hb=b196e7d936fb377d9c5b305748ac25ff0e53ef6d;hpb=ba404b5e86a707afe7faca8e22d53eea5e64c8b6 diff --git a/crypto/x509v3/v3_cpols.c b/crypto/x509v3/v3_cpols.c index 26a5df12e3..8147ea598e 100644 --- a/crypto/x509v3/v3_cpols.c +++ b/crypto/x509v3/v3_cpols.c @@ -1,16 +1,17 @@ /* v3_cpols.c */ -/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL - * project 1999. +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * 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. + * 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 @@ -60,596 +61,422 @@ #include "cryptlib.h" #include #include -#include +#include #include +#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 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); + 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, -CERTIFICATEPOLICIES_free, -(X509V3_EXT_D2I)d2i_CERTIFICATEPOLICIES, -i2d_CERTIFICATEPOLICIES, -NULL, NULL, -NULL, NULL, -(X509V3_EXT_I2R)i2r_certpol, -(X509V3_EXT_R2I)r2i_certpol, -NULL + 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) -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; -} +IMPLEMENT_ASN1_FUNCTIONS(CERTIFICATEPOLICIES) -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; - - -} +ASN1_SEQUENCE(POLICYINFO) = { + ASN1_SIMPLE(POLICYINFO, policyid, ASN1_OBJECT), + ASN1_SEQUENCE_OF_OPT(POLICYINFO, qualifiers, POLICYQUALINFO) +} ASN1_SEQUENCE_END(POLICYINFO) -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; -} +IMPLEMENT_ASN1_FUNCTIONS(POLICYINFO) -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; -} +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); -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; -} +ASN1_SEQUENCE(POLICYQUALINFO) = { + ASN1_SIMPLE(POLICYQUALINFO, pqualid, ASN1_OBJECT), + ASN1_ADB_OBJECT(POLICYQUALINFO) +} ASN1_SEQUENCE_END(POLICYQUALINFO) +IMPLEMENT_ASN1_FUNCTIONS(POLICYQUALINFO) -int i2d_CERTIFICATEPOLICIES(STACK_OF(POLICYINFO) *a, unsigned char **pp) -{ +ASN1_SEQUENCE(USERNOTICE) = { + ASN1_OPT(USERNOTICE, noticeref, NOTICEREF), + ASN1_OPT(USERNOTICE, exptext, DISPLAYTEXT) +} ASN1_SEQUENCE_END(USERNOTICE) -return i2d_ASN1_SET_OF_POLICYINFO(a, pp, i2d_POLICYINFO, V_ASN1_SEQUENCE, - V_ASN1_UNIVERSAL, IS_SEQUENCE);} +IMPLEMENT_ASN1_FUNCTIONS(USERNOTICE) -STACK_OF(POLICYINFO) *CERTIFICATEPOLICIES_new(void) -{ - return sk_POLICYINFO_new_null(); -} +ASN1_SEQUENCE(NOTICEREF) = { + ASN1_SIMPLE(NOTICEREF, organization, DISPLAYTEXT), + ASN1_SEQUENCE_OF(NOTICEREF, noticenos, ASN1_INTEGER) +} ASN1_SEQUENCE_END(NOTICEREF) -void CERTIFICATEPOLICIES_free(STACK_OF(POLICYINFO) *a) -{ - sk_POLICYINFO_pop_free(a, POLICYINFO_free); -} +IMPLEMENT_ASN1_FUNCTIONS(NOTICEREF) -STACK_OF(POLICYINFO) *d2i_CERTIFICATEPOLICIES(STACK_OF(POLICYINFO) **a, - unsigned char **pp,long length) +static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *value) { -return d2i_ASN1_SET_OF_POLICYINFO(a, pp, length, d2i_POLICYINFO, - POLICYINFO_free, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); - + 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; + } + if (!sk_POLICYINFO_push(pols, pol)) { + POLICYINFO_free(pol); + X509V3err(X509V3_F_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; } -IMPLEMENT_STACK_OF(POLICYINFO) -IMPLEMENT_ASN1_SET_OF(POLICYINFO) - -int i2d_POLICYINFO(POLICYINFO *a, unsigned char **pp) +static POLICYINFO *policy_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *polstrs, int ia5org) { - 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(); + 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; + if (!(qual->pqualid = OBJ_nid2obj(NID_id_qt_cps))) { + X509V3err(X509V3_F_POLICY_SECTION, ERR_R_INTERNAL_ERROR); + goto err; + } + if (!(qual->d.cpsuri = ASN1_IA5STRING_new())) + goto merr; + 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; - 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) +static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *unot, int ia5org) { - 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); + int i, ret; + CONF_VALUE *cnf; + USERNOTICE *not; + POLICYQUALINFO *qual; + if (!(qual = POLICYQUALINFO_new())) + goto merr; + if (!(qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice))) { + X509V3err(X509V3_F_NOTICE_SECTION, 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")) { + if (!(not->exptext = ASN1_VISIBLESTRING_new())) + 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)) { + 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; } -POLICYINFO *d2i_POLICYINFO(POLICYINFO **a, unsigned char **pp,long length) +static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos) { - 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); + 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; } -void POLICYINFO_free(POLICYINFO *a) +static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, + BIO *out, int indent) { - if (a == NULL) return; - ASN1_OBJECT_free(a->policyid); - sk_POLICYQUALINFO_pop_free(a->qualifiers, POLICYQUALINFO_free); - Free (a); + 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) + 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; - } - } + 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); + 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); } -USERNOTICE *d2i_USERNOTICE(USERNOTICE **a, unsigned char **pp,long length) +void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent) { - 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); + 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, ""); } - -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)