Allow setting of all fields in CRLDP. Few cosmetic changes to output.
authorDr. Stephen Henson <steve@openssl.org>
Mon, 25 Jul 2005 18:42:29 +0000 (18:42 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Mon, 25 Jul 2005 18:42:29 +0000 (18:42 +0000)
CHANGES
crypto/x509v3/v3_crld.c
crypto/x509v3/v3err.c
crypto/x509v3/x509v3.h

diff --git a/CHANGES b/CHANGES
index 206c0dc..c97da1e 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -5,7 +5,8 @@
  Changes between 0.9.8 and 0.9.9  [xx XXX xxxx]
 
   *) Modify CRL distribution points extension code to print out previously
-     unsupported fields.
+     unsupported fields. Enhance extension setting code to allow setting of
+     all fields.
      [Steve Henson]
 
   *) Add print only support for Issuing Distribution Point CRL extension.
index 2dd6932..bdb3dd5 100644 (file)
 #include <openssl/asn1t.h>
 #include <openssl/x509v3.h>
 
-static STACK_OF(DIST_POINT) *v2i_crld(X509V3_EXT_METHOD *method,
+static void *v2i_crld(X509V3_EXT_METHOD *method,
                                X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
 static int i2r_crldp(X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
                                                                int indent);
 
-X509V3_EXT_METHOD v3_crld = {
-NID_crl_distribution_points, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(CRL_DIST_POINTS),
-0,0,0,0,
-0,0,
-0,
-(X509V3_EXT_V2I)v2i_crld,
-i2r_crldp,0,
-NULL
+X509V3_EXT_METHOD v3_crld =
+       {
+       NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
+       0,0,0,0,
+       0,0,
+       0,
+       v2i_crld,
+       i2r_crldp,0,
+       NULL
+       };
+
+static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx, char *sect)
+       {
+       STACK_OF(CONF_VALUE) *gnsect;
+       STACK_OF(GENERAL_NAME) *gens;
+       if (*sect == '@')
+               gnsect = X509V3_get_section(ctx, sect + 1);
+       else
+               gnsect = X509V3_parse_list(sect);
+       if (!gnsect)
+               {
+               X509V3err(X509V3_F_GNAMES_FROM_SECTNAME,
+                                               X509V3_R_SECTION_NOT_FOUND);
+               return NULL;
+               }
+       gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect);
+       if (*sect == '@')
+               X509V3_section_free(ctx, gnsect);
+       else
+               sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free);
+       return gens;
+       }
+
+static int get_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx,
+                                                       CONF_VALUE *cnf)
+       {
+       STACK_OF(GENERAL_NAME) *fnm = NULL;
+       STACK_OF(X509_NAME_ENTRY) *rnm = NULL;
+       if (!strncmp(cnf->name, "fullname", 9))
+               {
+               fnm = gnames_from_sectname(ctx, cnf->value);
+               if (!fnm)
+                       goto err;
+               }
+       else if (!strcmp(cnf->name, "relativename"))
+               {
+               int ret;
+               STACK_OF(CONF_VALUE) *dnsect;
+               X509_NAME *nm;
+               nm = X509_NAME_new();
+               if (!nm)
+                       return -1;
+               dnsect = X509V3_get_section(ctx, cnf->value);
+               if (!dnsect)
+                       {
+                       X509V3err(X509V3_F_GET_DIST_POINT_NAME,
+                                               X509V3_R_SECTION_NOT_FOUND);
+                       return -1;
+                       }
+               ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC);
+               X509V3_section_free(ctx, dnsect);
+               rnm = nm->entries;
+               nm->entries = NULL;
+               X509_NAME_free(nm);
+               if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0)
+                       goto err;
+               /* Since its a name fragment can't have more than one
+                * RDNSequence
+                */
+               if (sk_X509_NAME_ENTRY_value(rnm,
+                               sk_X509_NAME_ENTRY_num(rnm) - 1)->set)
+                       {
+                       X509V3err(X509V3_F_GET_DIST_POINT_NAME,
+                                               X509V3_R_INVAID_MULTIPLE_RDNS);
+                       goto err;
+                       }
+               }
+       else
+               return 0;
+
+       if (*pdp)
+               {
+               X509V3err(X509V3_F_GET_DIST_POINT_NAME,
+                                               X509V3_R_DISTPOINT_ALREADY_SET);
+               goto err;
+               }
+
+       *pdp = DIST_POINT_NAME_new();
+       if (!*pdp)
+               goto err;
+       if (fnm)
+               {
+               (*pdp)->type = 0;
+               (*pdp)->name.fullname = fnm;
+               }
+       else
+               {
+               (*pdp)->type = 1;
+               (*pdp)->name.relativename = rnm;
+               }
+
+       return 1;
+               
+       err:
+       if (fnm)
+               sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free);
+       if (rnm)
+               sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free);
+       return -1;
+       }
+
+
+static const BIT_STRING_BITNAME reason_flags[] = {
+{1, "Key Compromise", "keyCompromise"},
+{2, "CA Compromise", "CACompromise"},
+{3, "Affiliation Changed", "affiliationChanged"},
+{4, "Superseded", "superseded"},
+{5, "Cessation Of Operation", "cessationOfOperation"},
+{6, "Certificate Hold", "certificateHold"},
+{7, "Privilege Withdrawn", "privilegeWithdrawn"},
+{8, "AA Compromise", "AACompromise"},
+{-1, NULL, NULL}
 };
 
-static STACK_OF(DIST_POINT) *v2i_crld(X509V3_EXT_METHOD *method,
+static int set_reasons(ASN1_BIT_STRING **preas, char *value)
+       {
+       STACK_OF(CONF_VALUE) *rsk = NULL;
+       const BIT_STRING_BITNAME *pbn;
+       const char *bnam;
+       int i, ret = 0;
+       rsk = X509V3_parse_list(value);
+       if (!rsk)
+               return 0;
+       if (*preas)
+               return 0;
+       for (i = 0; i < sk_CONF_VALUE_num(rsk); i++)
+               {
+               bnam = sk_CONF_VALUE_value(rsk, i)->name;
+               if (!*preas)
+                       {
+                       *preas = ASN1_BIT_STRING_new();
+                       if (!*preas)
+                               goto err;
+                       }
+               for (pbn = reason_flags; pbn->lname; pbn++)
+                       {
+                       if (!strcmp(pbn->sname, bnam))
+                               {
+                               if (!ASN1_BIT_STRING_set_bit(*preas,
+                                                       pbn->bitnum, 1))
+                                       goto err;
+                               break;
+                               }
+                       }
+               if (!pbn->lname)
+                       goto err;
+               }
+       ret = 1;
+
+       err:
+       sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free);
+       return ret;
+       }
+
+static int print_reasons(BIO *out, const char *rname,
+                       ASN1_BIT_STRING *rflags, int indent)
+       {
+       int first = 1;
+       const BIT_STRING_BITNAME *pbn;
+       BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, "");
+       for (pbn = reason_flags; pbn->lname; pbn++)
+               {
+               if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum))
+                       {
+                       if (first)
+                               first = 0;
+                       else
+                               BIO_puts(out, ", ");
+                       BIO_puts(out, pbn->lname);
+                       }
+               }
+       if (first)
+               BIO_puts(out, "<EMPTY>\n");
+       else
+               BIO_puts(out, "\n");
+       return 1;
+       }
+
+static DIST_POINT *crldp_from_section(X509V3_CTX *ctx,
+                                               STACK_OF(CONF_VALUE) *nval)
+       {
+       int i;
+       CONF_VALUE *cnf;
+       DIST_POINT *point = NULL;
+       point = DIST_POINT_new();
+       if (!point)
+               goto err;
+       for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
+               {
+               int ret;
+               cnf = sk_CONF_VALUE_value(nval, i);
+               ret = get_dist_point_name(&point->distpoint, ctx, cnf);
+               if (ret > 0)
+                       continue;
+               if (ret < 0)
+                       goto err;
+               if (!strcmp(cnf->name, "reasons"))
+                       {
+                       if (!set_reasons(&point->reasons, cnf->value))
+                               goto err;
+                       }
+               else if (!strcmp(cnf->name, "CRLissuer"))
+                       {
+                       point->CRLissuer =
+                               gnames_from_sectname(ctx, cnf->value);
+                       if (!point->CRLissuer)
+                               goto err;
+                       }
+               }
+
+       return point;
+                       
+
+       err:
+       if (point)
+               DIST_POINT_free(point);
+       return NULL;
+       }
+
+static void *v2i_crld(X509V3_EXT_METHOD *method,
                                X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
-{
+       {
        STACK_OF(DIST_POINT) *crld = NULL;
        GENERAL_NAMES *gens = NULL;
        GENERAL_NAME *gen = NULL;
@@ -90,19 +309,44 @@ static STACK_OF(DIST_POINT) *v2i_crld(X509V3_EXT_METHOD *method,
        for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
                DIST_POINT *point;
                cnf = sk_CONF_VALUE_value(nval, i);
-               if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) goto err; 
-               if(!(gens = GENERAL_NAMES_new())) goto merr;
-               if(!sk_GENERAL_NAME_push(gens, gen)) goto merr;
-               gen = NULL;
-               if(!(point = DIST_POINT_new())) goto merr;
-               if(!sk_DIST_POINT_push(crld, point)) {
-                       DIST_POINT_free(point);
-                       goto merr;
-               }
-               if(!(point->distpoint = DIST_POINT_NAME_new())) goto merr;
-               point->distpoint->name.fullname = gens;
-               point->distpoint->type = 0;
-               gens = NULL;
+               if (!cnf->value && cnf->name[0] == '@')
+                       {
+                       STACK_OF(CONF_VALUE) *dpsect;
+                       dpsect = X509V3_get_section(ctx, cnf->name + 1);
+                       if (!dpsect)
+                               goto err;
+                       point = crldp_from_section(ctx, dpsect);
+                       X509V3_section_free(ctx, dpsect);
+                       if (!point)
+                               goto err;
+                       if(!sk_DIST_POINT_push(crld, point))
+                               {
+                               DIST_POINT_free(point);
+                               goto merr;
+                               }
+                       }
+               else
+                       {
+                       if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
+                               goto err; 
+                       if(!(gens = GENERAL_NAMES_new()))
+                               goto merr;
+                       if(!sk_GENERAL_NAME_push(gens, gen))
+                               goto merr;
+                       gen = NULL;
+                       if(!(point = DIST_POINT_new()))
+                               goto merr;
+                       if(!sk_DIST_POINT_push(crld, point))
+                               {
+                               DIST_POINT_free(point);
+                               goto merr;
+                               }
+                       if(!(point->distpoint = DIST_POINT_NAME_new()))
+                               goto merr;
+                       point->distpoint->name.fullname = gens;
+                       point->distpoint->type = 0;
+                       gens = NULL;
+                       }
        }
        return crld;
 
@@ -163,42 +407,6 @@ X509V3_EXT_METHOD v3_idp =
        NULL
        };
 
-static const BIT_STRING_BITNAME reason_flags[] = {
-{1, "Key Compromise", "keyCompromise"},
-{2, "CA Compromise", "CACompromise"},
-{3, "Affiliation Changed", "affiliationChanged"},
-{4, "Superseded", "superseded"},
-{5, "Cessation Of Operation", "cessationOfOperation"},
-{6, "Certificate Hold", "certificateHold"},
-{7, "Privilege Withdrawn", "privilegeWithdrawn"},
-{8, "AA Compromise", "AACompromise"},
-{-1, NULL, NULL}
-};
-
-static int print_reasons(BIO *out, const char *rname,
-                       ASN1_BIT_STRING *rflags, int indent)
-       {
-       int first = 1;
-       const BIT_STRING_BITNAME *pbn;
-       BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, "");
-       for (pbn = reason_flags; pbn->lname; pbn++)
-               {
-               if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum))
-                       {
-                       if (first)
-                               first = 0;
-                       else
-                               BIO_puts(out, ", ");
-                       BIO_puts(out, pbn->lname);
-                       }
-               }
-       if (first)
-               BIO_puts(out, "<EMPTY>\n");
-       else
-               BIO_puts(out, "\n");
-       return 1;
-       }
-
 static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent)
        {
        int i;
@@ -216,7 +424,7 @@ static int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent)
        if (dpn->type == 0)
                {
                BIO_printf(out, "%*sFull Name:\n", indent, "");
-               print_gens(out, dpn->name.fullname, indent + 2);
+               print_gens(out, dpn->name.fullname, indent);
                }
        else
                {
@@ -262,16 +470,17 @@ static int i2r_crldp(X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
        int i;
        for(i = 0; i < sk_DIST_POINT_num(crld); i++)
                {
+               BIO_puts(out, "\n");
                point = sk_DIST_POINT_value(crld, i);
                if(point->distpoint)
-                       print_distpoint(out, point->distpoint, indent + 2);
+                       print_distpoint(out, point->distpoint, indent);
                if(point->reasons) 
                        print_reasons(out, "Reasons", point->reasons,
-                                                               indent + 2);
+                                                               indent);
                if(point->CRLissuer)
                        {
                        BIO_printf(out, "%*sCRL Issuer:\n", indent, "");
-                       print_gens(out, point->CRLissuer, indent + 2);
+                       print_gens(out, point->CRLissuer, indent);
                        }
                }
        return 1;
index e96bd62..1d9d6c2 100644 (file)
@@ -77,6 +77,8 @@ static ERR_STRING_DATA X509V3_str_functs[]=
 {ERR_FUNC(X509V3_F_DO_EXT_I2D),        "DO_EXT_I2D"},
 {ERR_FUNC(X509V3_F_DO_EXT_NCONF),      "DO_EXT_NCONF"},
 {ERR_FUNC(X509V3_F_DO_I2V_NAME_CONSTRAINTS),   "DO_I2V_NAME_CONSTRAINTS"},
+{ERR_FUNC(X509V3_F_GET_DIST_POINT_NAME),       "GET_DIST_POINT_NAME"},
+{ERR_FUNC(X509V3_F_GNAMES_FROM_SECTNAME),      "GNAMES_FROM_SECTNAME"},
 {ERR_FUNC(X509V3_F_HEX_TO_STRING),     "hex_to_string"},
 {ERR_FUNC(X509V3_F_I2S_ASN1_ENUMERATED),       "i2s_ASN1_ENUMERATED"},
 {ERR_FUNC(X509V3_F_I2S_ASN1_IA5STRING),        "I2S_ASN1_IA5STRING"},
@@ -136,6 +138,7 @@ static ERR_STRING_DATA X509V3_str_reasons[]=
 {ERR_REASON(X509V3_R_BN_DEC2BN_ERROR)    ,"bn dec2bn error"},
 {ERR_REASON(X509V3_R_BN_TO_ASN1_INTEGER_ERROR),"bn to asn1 integer error"},
 {ERR_REASON(X509V3_R_DIRNAME_ERROR)      ,"dirname error"},
+{ERR_REASON(X509V3_R_DISTPOINT_ALREADY_SET),"distpoint already set"},
 {ERR_REASON(X509V3_R_DUPLICATE_ZONE_ID)  ,"duplicate zone id"},
 {ERR_REASON(X509V3_R_ERROR_CONVERTING_ZONE),"error converting zone"},
 {ERR_REASON(X509V3_R_ERROR_CREATING_EXTENSION),"error creating extension"},
@@ -149,6 +152,7 @@ static ERR_STRING_DATA X509V3_str_reasons[]=
 {ERR_REASON(X509V3_R_ILLEGAL_EMPTY_EXTENSION),"illegal empty extension"},
 {ERR_REASON(X509V3_R_ILLEGAL_HEX_DIGIT)  ,"illegal hex digit"},
 {ERR_REASON(X509V3_R_INCORRECT_POLICY_SYNTAX_TAG),"incorrect policy syntax tag"},
+{ERR_REASON(X509V3_R_INVAID_MULTIPLE_RDNS),"invaid multiple rdns"},
 {ERR_REASON(X509V3_R_INVALID_BOOLEAN_STRING),"invalid boolean string"},
 {ERR_REASON(X509V3_R_INVALID_EXTENSION_STRING),"invalid extension string"},
 {ERR_REASON(X509V3_R_INVALID_NAME)       ,"invalid name"},
index c6533d4..3d4f741 100644 (file)
@@ -650,6 +650,8 @@ void ERR_load_X509V3_strings(void);
 #define X509V3_F_DO_EXT_I2D                             135
 #define X509V3_F_DO_EXT_NCONF                           151
 #define X509V3_F_DO_I2V_NAME_CONSTRAINTS                148
+#define X509V3_F_GET_DIST_POINT_NAME                    155
+#define X509V3_F_GNAMES_FROM_SECTNAME                   156
 #define X509V3_F_HEX_TO_STRING                          111
 #define X509V3_F_I2S_ASN1_ENUMERATED                    121
 #define X509V3_F_I2S_ASN1_IA5STRING                     149
@@ -706,6 +708,7 @@ void ERR_load_X509V3_strings(void);
 #define X509V3_R_BN_DEC2BN_ERROR                        100
 #define X509V3_R_BN_TO_ASN1_INTEGER_ERROR               101
 #define X509V3_R_DIRNAME_ERROR                          149
+#define X509V3_R_DISTPOINT_ALREADY_SET                  160
 #define X509V3_R_DUPLICATE_ZONE_ID                      133
 #define X509V3_R_ERROR_CONVERTING_ZONE                  131
 #define X509V3_R_ERROR_CREATING_EXTENSION               144
@@ -719,6 +722,7 @@ void ERR_load_X509V3_strings(void);
 #define X509V3_R_ILLEGAL_EMPTY_EXTENSION                151
 #define X509V3_R_ILLEGAL_HEX_DIGIT                      113
 #define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG            152
+#define X509V3_R_INVAID_MULTIPLE_RDNS                   161
 #define X509V3_R_INVALID_BOOLEAN_STRING                         104
 #define X509V3_R_INVALID_EXTENSION_STRING               105
 #define X509V3_R_INVALID_NAME                           106