Suppport for CRL distribution points extension. Also document some of
[openssl.git] / crypto / x509v3 / v3_cpols.c
index c934004..95033f2 100644 (file)
@@ -70,6 +70,8 @@ static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, X509V3_CTX *
 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);
 
 X509V3_EXT_METHOD v3_cpols = {
 NID_certificate_policies, 0,
@@ -96,10 +98,8 @@ NULL
  * ASN1err(ASN1_F_D2I_NOTICEREF,ERR_R_MALLOC_FAILURE);
  */
 
-static STACK_OF(POLICYINFO) *r2i_certpol(method, ctx, value)
-X509V3_EXT_METHOD *method;
-X509V3_CTX *ctx;
-char *value;
+static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
+               X509V3_CTX *ctx, char *value)
 {
        STACK_OF(POLICYINFO) *pols = NULL;
        char *pstr;
@@ -148,24 +148,170 @@ char *value;
        return NULL;
 }
 
-static POLICYINFO *policy_section(ctx, polstrs)
-X509V3_CTX *ctx;
-STACK *polstrs;
+static POLICYINFO *policy_section(X509V3_CTX *ctx, STACK *polstrs)
 {
        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);
+               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 *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);
+                       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 *unot)
+{
+       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_num(unot); i++) {
+               cnf = (CONF_VALUE *)sk_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;
+                       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;
+                       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)) {
+                               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);
+                       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 *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);
+               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(method, pol, out, indent)
-X509V3_EXT_METHOD *method;
-STACK_OF(POLICYINFO) *pol;
-BIO *out;
-int indent;
+static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol,
+               BIO *out, int indent)
 {
        int i;
        POLICYINFO *pinfo;
@@ -182,29 +328,24 @@ int indent;
 }
 
 
-int i2d_CERTIFICATEPOLICIES(a, pp)
-STACK_OF(POLICYINFO) *a;
-unsigned char **pp;
+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()
+STACK_OF(POLICYINFO) *CERTIFICATEPOLICIES_new(void)
 {
        return sk_POLICYINFO_new_null();
 }
 
-void CERTIFICATEPOLICIES_free(a)
-STACK_OF(POLICYINFO) *a;
+void CERTIFICATEPOLICIES_free(STACK_OF(POLICYINFO) *a)
 {
        sk_POLICYINFO_pop_free(a, POLICYINFO_free);
 }
 
-STACK_OF(POLICYINFO) *d2i_CERTIFICATEPOLICIES(a,pp,length)
-STACK_OF(POLICYINFO) **a;
-unsigned char **pp;
-long length;
+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);
@@ -214,9 +355,7 @@ return d2i_ASN1_SET_OF_POLICYINFO(a, pp, length, d2i_POLICYINFO,
 IMPLEMENT_STACK_OF(POLICYINFO)
 IMPLEMENT_ASN1_SET_OF(POLICYINFO)
 
-int i2d_POLICYINFO(a,pp)
-POLICYINFO *a;
-unsigned char **pp;
+int i2d_POLICYINFO(POLICYINFO *a, unsigned char **pp)
 {
        M_ASN1_I2D_vars(a);
 
@@ -233,7 +372,7 @@ unsigned char **pp;
        M_ASN1_I2D_finish();
 }
 
-POLICYINFO *POLICYINFO_new()
+POLICYINFO *POLICYINFO_new(void)
 {
        POLICYINFO *ret=NULL;
        ASN1_CTX c;
@@ -244,10 +383,7 @@ POLICYINFO *POLICYINFO_new()
        M_ASN1_New_Error(ASN1_F_POLICYINFO_NEW);
 }
 
-POLICYINFO *d2i_POLICYINFO(a,pp,length)
-POLICYINFO **a;
-unsigned char **pp;
-long length;
+POLICYINFO *d2i_POLICYINFO(POLICYINFO **a, unsigned char **pp,long length)
 {
        M_ASN1_D2I_vars(a,POLICYINFO *,POLICYINFO_new);
        M_ASN1_D2I_Init();
@@ -260,8 +396,7 @@ long length;
        M_ASN1_D2I_Finish(a, POLICYINFO_free, ASN1_F_D2I_POLICYINFO);
 }
 
-void POLICYINFO_free(a)
-POLICYINFO *a;
+void POLICYINFO_free(POLICYINFO *a)
 {
        if (a == NULL) return;
        ASN1_OBJECT_free(a->policyid);
@@ -269,10 +404,8 @@ POLICYINFO *a;
        Free (a);
 }
 
-static void print_qualifiers(out, quals, indent)
-BIO *out;
-STACK_OF(POLICYQUALINFO) *quals;
-int indent;
+static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals,
+               int indent)
 {
        POLICYQUALINFO *qualinfo;
        int i;
@@ -301,10 +434,7 @@ int indent;
        }
 }
 
-static void print_notice(out, notice, indent)
-BIO *out;
-USERNOTICE *notice;
-int indent;
+static void print_notice(BIO *out, USERNOTICE *notice, int indent)
 {
        int i;
        if(notice->noticeref) {
@@ -326,15 +456,13 @@ int indent;
                BIO_puts(out, "\n");
        }
        if(notice->exptext)
-               BIO_printf(out, "%*sNotice Reference: %s\n", indent, "",
+               BIO_printf(out, "%*sExplicit Text: %s\n", indent, "",
                                                         notice->exptext->data);
 }
                
        
 
-int i2d_POLICYQUALINFO(a,pp)
-POLICYQUALINFO *a;
-unsigned char **pp;
+int i2d_POLICYQUALINFO(POLICYQUALINFO *a, unsigned char **pp)
 {
        M_ASN1_I2D_vars(a);
 
@@ -373,7 +501,7 @@ unsigned char **pp;
        M_ASN1_I2D_finish();
 }
 
-POLICYQUALINFO *POLICYQUALINFO_new()
+POLICYQUALINFO *POLICYQUALINFO_new(void)
 {
        POLICYQUALINFO *ret=NULL;
        ASN1_CTX c;
@@ -384,10 +512,8 @@ POLICYQUALINFO *POLICYQUALINFO_new()
        M_ASN1_New_Error(ASN1_F_POLICYQUALINFO_NEW);
 }
 
-POLICYQUALINFO *d2i_POLICYQUALINFO(a,pp,length)
-POLICYQUALINFO **a;
-unsigned char **pp;
-long length;
+POLICYQUALINFO *d2i_POLICYQUALINFO(POLICYQUALINFO **a, unsigned char **pp,
+               long length)
 {
        M_ASN1_D2I_vars(a,POLICYQUALINFO *,POLICYQUALINFO_new);
        M_ASN1_D2I_Init();
@@ -409,8 +535,7 @@ long length;
        M_ASN1_D2I_Finish(a, POLICYQUALINFO_free, ASN1_F_D2I_POLICYQUALINFO);
 }
 
-void POLICYQUALINFO_free(a)
-POLICYQUALINFO *a;
+void POLICYQUALINFO_free(POLICYQUALINFO *a)
 {
        if (a == NULL) return;
        switch(OBJ_obj2nid(a->pqualid)) {
@@ -431,9 +556,7 @@ POLICYQUALINFO *a;
        Free (a);
 }
 
-int i2d_USERNOTICE(a,pp)
-USERNOTICE *a;
-unsigned char **pp;
+int i2d_USERNOTICE(USERNOTICE *a, unsigned char **pp)
 {
        M_ASN1_I2D_vars(a);
 
@@ -448,7 +571,7 @@ unsigned char **pp;
        M_ASN1_I2D_finish();
 }
 
-USERNOTICE *USERNOTICE_new()
+USERNOTICE *USERNOTICE_new(void)
 {
        USERNOTICE *ret=NULL;
        ASN1_CTX c;
@@ -459,10 +582,7 @@ USERNOTICE *USERNOTICE_new()
        M_ASN1_New_Error(ASN1_F_USERNOTICE_NEW);
 }
 
-USERNOTICE *d2i_USERNOTICE(a,pp,length)
-USERNOTICE **a;
-unsigned char **pp;
-long length;
+USERNOTICE *d2i_USERNOTICE(USERNOTICE **a, unsigned char **pp,long length)
 {
        M_ASN1_D2I_vars(a,USERNOTICE *,USERNOTICE_new);
        M_ASN1_D2I_Init();
@@ -474,8 +594,7 @@ long length;
        M_ASN1_D2I_Finish(a, USERNOTICE_free, ASN1_F_D2I_USERNOTICE);
 }
 
-void USERNOTICE_free(a)
-USERNOTICE *a;
+void USERNOTICE_free(USERNOTICE *a)
 {
        if (a == NULL) return;
        NOTICEREF_free(a->noticeref);
@@ -483,9 +602,7 @@ USERNOTICE *a;
        Free (a);
 }
 
-int i2d_NOTICEREF(a,pp)
-NOTICEREF *a;
-unsigned char **pp;
+int i2d_NOTICEREF(NOTICEREF *a, unsigned char **pp)
 {
        M_ASN1_I2D_vars(a);
 
@@ -500,7 +617,7 @@ unsigned char **pp;
        M_ASN1_I2D_finish();
 }
 
-NOTICEREF *NOTICEREF_new()
+NOTICEREF *NOTICEREF_new(void)
 {
        NOTICEREF *ret=NULL;
        ASN1_CTX c;
@@ -511,10 +628,7 @@ NOTICEREF *NOTICEREF_new()
        M_ASN1_New_Error(ASN1_F_NOTICEREF_NEW);
 }
 
-NOTICEREF *d2i_NOTICEREF(a,pp,length)
-NOTICEREF **a;
-unsigned char **pp;
-long length;
+NOTICEREF *d2i_NOTICEREF(NOTICEREF **a, unsigned char **pp,long length)
 {
        M_ASN1_D2I_vars(a,NOTICEREF *,NOTICEREF_new);
        M_ASN1_D2I_Init();
@@ -531,8 +645,7 @@ long length;
        M_ASN1_D2I_Finish(a, NOTICEREF_free, ASN1_F_D2I_NOTICEREF);
 }
 
-void NOTICEREF_free(a)
-NOTICEREF *a;
+void NOTICEREF_free(NOTICEREF *a)
 {
        if (a == NULL) return;
        DISPLAYTEXT_free(a->organization);