Implement STACK_OF(ANS1_OBJECT) for extended key usage extension, change the
[openssl.git] / crypto / x509v3 / v3_cpols.c
index 95033f265b28b4d8002eb37c663452980c28b26e..b4d4883545182380e275d258e1f1e7a014509ef3 100644 (file)
 
 #include <stdio.h>
 #include "cryptlib.h"
-#include "conf.h"
-#include "asn1.h"
-#include "asn1_mac.h"
-#include "x509v3.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... */
 
@@ -69,16 +69,18 @@ static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, BIO
 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 *polstrs);
-static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, STACK *unot);
-static STACK *nref_nos(STACK *nos);
+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,
-CERTIFICATEPOLICIES_free,
+(X509V3_EXT_FREE)CERTIFICATEPOLICIES_free,
 (X509V3_EXT_D2I)d2i_CERTIFICATEPOLICIES,
-i2d_CERTIFICATEPOLICIES,
+(X509V3_EXT_I2D)i2d_CERTIFICATEPOLICIES,
 NULL, NULL,
 NULL, NULL,
 (X509V3_EXT_I2R)i2r_certpol,
@@ -87,17 +89,6 @@ NULL
 };
 
 
-/*
- * ASN1err(ASN1_F_POLICYINFO_NEW,ERR_R_MALLOC_FAILURE);
- * ASN1err(ASN1_F_D2I_POLICYINFO,ERR_R_MALLOC_FAILURE);
- * ASN1err(ASN1_F_POLICYQUALINFO_NEW,ERR_R_MALLOC_FAILURE);
- * ASN1err(ASN1_F_D2I_POLICYQUALINFO,ERR_R_MALLOC_FAILURE);
- * ASN1err(ASN1_F_USERNOTICE_NEW,ERR_R_MALLOC_FAILURE);
- * ASN1err(ASN1_F_D2I_USERNOTICE,ERR_R_MALLOC_FAILURE);
- * ASN1err(ASN1_F_NOTICEREF_NEW,ERR_R_MALLOC_FAILURE);
- * ASN1err(ASN1_F_D2I_NOTICEREF,ERR_R_MALLOC_FAILURE);
- */
-
 static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
                X509V3_CTX *ctx, char *value)
 {
@@ -105,21 +96,25 @@ static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
        char *pstr;
        POLICYINFO *pol;
        ASN1_OBJECT *pobj;
-       STACK *vals;
+       STACK_OF(CONF_VALUE) *vals;
        CONF_VALUE *cnf;
-       int i;
+       int i, ia5org;
        pols = sk_POLICYINFO_new_null();
        vals =  X509V3_parse_list(value);
-       for(i = 0; i < sk_num(vals); i++) {
-               cnf = (CONF_VALUE *)sk_value(vals, i);
+       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(*pstr == '@') {
-                       STACK *polsect;
+               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);
@@ -127,7 +122,7 @@ static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
                                X509V3_conf_err(cnf);
                                goto err;
                        }
-                       pol = policy_section(ctx, polsect);
+                       pol = policy_section(ctx, polsect, ia5org);
                        X509V3_section_free(ctx, polsect);
                        if(!pol) goto err;
                } else {
@@ -141,22 +136,23 @@ static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
                }
                sk_POLICYINFO_push(pols, pol);
        }
-       sk_pop_free(vals, X509V3_conf_free);
+       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 *polstrs)
+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_num(polstrs); i++) {
-               cnf = (CONF_VALUE *)sk_value(polstrs, i);
+       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))) {
@@ -177,7 +173,7 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx, STACK *polstrs)
                        if(!ASN1_STRING_set(qual->d.cpsuri, cnf->value,
                                                 strlen(cnf->value))) goto merr;
                } else if(!name_cmp(cnf->name, "userNotice")) {
-                       STACK *unot;
+                       STACK_OF(CONF_VALUE) *unot;
                        if(*cnf->value != '@') {
                                X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_EXPECTED_A_SECTION_NAME);
                                X509V3_conf_err(cnf);
@@ -190,7 +186,7 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx, STACK *polstrs)
                                X509V3_conf_err(cnf);
                                goto err;
                        }
-                       qual = notice_section(ctx, unot);
+                       qual = notice_section(ctx, unot, ia5org);
                        X509V3_section_free(ctx, unot);
                        if(!qual) goto err;
                        if(!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
@@ -219,7 +215,8 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx, STACK *polstrs)
        
 }
 
-static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, STACK *unot)
+static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
+                                       STACK_OF(CONF_VALUE) *unot, int ia5org)
 {
        int i;
        CONF_VALUE *cnf;
@@ -229,8 +226,8 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, STACK *unot)
        qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice);
        if(!(not = USERNOTICE_new())) goto merr;
        qual->d.usernotice = not;
-       for(i = 0; i < sk_num(unot); i++) {
-               cnf = (CONF_VALUE *)sk_value(unot, i);
+       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,
@@ -241,24 +238,25 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, STACK *unot)
                                if(!(nref = NOTICEREF_new())) goto merr;
                                not->noticeref = nref;
                        } else nref = not->noticeref;
-                       nref->organization = ASN1_VISIBLESTRING_new();
+                       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 *nos;
+                       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_num(nos)) {
+                       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_pop_free(nos, X509V3_conf_free);
+                       sk_CONF_VALUE_pop_free(nos, X509V3_conf_free);
                        if(!nref->noticenos) goto err;
                } else {
                        X509V3err(X509V3_F_NOTICE_SECTION,X509V3_R_INVALID_OPTION);
@@ -284,15 +282,15 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, STACK *unot)
        return NULL;
 }
 
-static STACK *nref_nos(STACK *nos)
+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_num(nos); i++) {
-               cnf = (CONF_VALUE *)sk_value(nos, 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;