Updates from 1.0.0-stable.
[openssl.git] / crypto / x509v3 / v3_alt.c
index ad6cb08e2065a2a0049cc882c1784f55b3b642f4..f7c7874cac942bb0e40befcea16182546afbf8f2 100644 (file)
@@ -1,5 +1,5 @@
 /* v3_alt.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project.
  */
 /* ====================================================================
@@ -68,7 +68,7 @@ static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens);
 static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx);
 static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx);
 
-X509V3_EXT_METHOD v3_alt[] = {
+const X509V3_EXT_METHOD v3_alt[] = {
 { NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
 0,0,0,0,
 0,0,
@@ -82,6 +82,12 @@ NULL, NULL, NULL},
 (X509V3_EXT_I2V)i2v_GENERAL_NAMES,
 (X509V3_EXT_V2I)v2i_issuer_alt,
 NULL, NULL, NULL},
+
+{ NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES),
+0,0,0,0,
+0,0,
+(X509V3_EXT_I2V)i2v_GENERAL_NAMES,
+NULL, NULL, NULL, NULL},
 };
 
 STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
@@ -137,13 +143,15 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
                case GEN_IPADD:
                p = gen->d.ip->data;
                if(gen->d.ip->length == 4)
-                       sprintf(oline, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+                       BIO_snprintf(oline, sizeof oline,
+                                    "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
                else if(gen->d.ip->length == 16)
                        {
                        oline[0] = 0;
                        for (i = 0; i < 8; i++)
                                {
-                               sprintf(htmp, "%X", p[0] << 8 | p[1]);
+                               BIO_snprintf(htmp, sizeof htmp,
+                                            "%X", p[0] << 8 | p[1]);
                                p += 2;
                                strcat(oline, htmp);
                                if (i != 7)
@@ -239,7 +247,7 @@ static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
        CONF_VALUE *cnf;
        int i;
        if(!(gens = sk_GENERAL_NAME_new_null())) {
-               X509V3err(X509V3_F_V2I_GENERAL_NAMES,ERR_R_MALLOC_FAILURE);
+               X509V3err(X509V3_F_V2I_ISSUER_ALT,ERR_R_MALLOC_FAILURE);
                return NULL;
        }
        for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
@@ -304,7 +312,7 @@ static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
        CONF_VALUE *cnf;
        int i;
        if(!(gens = sk_GENERAL_NAME_new_null())) {
-               X509V3err(X509V3_F_V2I_GENERAL_NAMES,ERR_R_MALLOC_FAILURE);
+               X509V3err(X509V3_F_V2I_SUBJECT_ALT,ERR_R_MALLOC_FAILURE);
                return NULL;
        }
        for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
@@ -339,7 +347,8 @@ static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
        X509_NAME_ENTRY *ne;
        GENERAL_NAME *gen = NULL;
        int i;
-       if(ctx->flags == CTX_TEST) return 1;
+       if(ctx != NULL && ctx->flags == CTX_TEST)
+               return 1;
        if(!ctx || (!ctx->subject_cert && !ctx->subject_req)) {
                X509V3err(X509V3_F_COPY_EMAIL,X509V3_R_NO_SUBJECT_DETAILS);
                goto err;
@@ -357,6 +366,7 @@ static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
                 if (move_p)
                         {
                         X509_NAME_delete_entry(nm, i);
+                       X509_NAME_ENTRY_free(ne);
                         i--;
                         }
                if(!email || !(gen = GENERAL_NAME_new())) {
@@ -383,8 +393,8 @@ static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
        
 }
 
-GENERAL_NAMES *v2i_GENERAL_NAMES(X509V3_EXT_METHOD *method,
-                               X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
+                                X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
 {
        GENERAL_NAME *gen;
        GENERAL_NAMES *gens = NULL;
@@ -405,28 +415,22 @@ GENERAL_NAMES *v2i_GENERAL_NAMES(X509V3_EXT_METHOD *method,
        return NULL;
 }
 
-GENERAL_NAME *v2i_GENERAL_NAME(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
-                                                        CONF_VALUE *cnf)
+GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+                              CONF_VALUE *cnf)
        {
        return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0);
        }
 
-GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
-                               X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
-                                                CONF_VALUE *cnf, int is_nc)
+GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
+                              const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+                              int gen_type, char *value, int is_nc)
        {
        char is_string = 0;
-       int type;
        GENERAL_NAME *gen = NULL;
 
-       char *name, *value;
-
-       name = cnf->name;
-       value = cnf->value;
-
        if(!value)
                {
-               X509V3err(X509V3_F_V2I_GENERAL_NAME,X509V3_R_MISSING_VALUE);
+               X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_MISSING_VALUE);
                return NULL;
                }
 
@@ -437,74 +441,60 @@ GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
                gen = GENERAL_NAME_new();
                if(gen == NULL)
                        {
-                       X509V3err(X509V3_F_V2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE);
+                       X509V3err(X509V3_F_A2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE);
                        return NULL;
                        }
                }
 
-       if(!name_cmp(name, "email"))
-               {
-               is_string = 1;
-               type = GEN_EMAIL;
-               }
-       else if(!name_cmp(name, "URI"))
-               {
-               is_string = 1;
-               type = GEN_URI;
-               }
-       else if(!name_cmp(name, "DNS"))
+       switch (gen_type)
                {
+               case GEN_URI:
+               case GEN_EMAIL:
+               case GEN_DNS:
                is_string = 1;
-               type = GEN_DNS;
-               }
-       else if(!name_cmp(name, "RID"))
+               break;
+               
+               case GEN_RID:
                {
                ASN1_OBJECT *obj;
                if(!(obj = OBJ_txt2obj(value,0)))
                        {
-                       X509V3err(X509V3_F_V2I_GENERAL_NAME,X509V3_R_BAD_OBJECT);
+                       X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_BAD_OBJECT);
                        ERR_add_error_data(2, "value=", value);
                        goto err;
                        }
                gen->d.rid = obj;
-               type = GEN_RID;
                }
-       else if(!name_cmp(name, "IP"))
-               {
+
+               case GEN_IPADD:
                if (is_nc)
                        gen->d.ip = a2i_IPADDRESS_NC(value);
                else
                        gen->d.ip = a2i_IPADDRESS(value);
                if(gen->d.ip == NULL)
                        {
-                       X509V3err(X509V3_F_V2I_GENERAL_NAME,X509V3_R_BAD_IP_ADDRESS);
+                       X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_BAD_IP_ADDRESS);
                        ERR_add_error_data(2, "value=", value);
                        goto err;
                        }
-               type = GEN_IPADD;
-               }
-       else if(!name_cmp(name, "dirName"))
-               {
-               type = GEN_DIRNAME;
+               break;
+
+               case GEN_DIRNAME:
                if (!do_dirname(gen, value, ctx))
                        {
-                       X509V3err(X509V3_F_V2I_GENERAL_NAME,X509V3_R_DIRNAME_ERROR);
+                       X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_DIRNAME_ERROR);
                        goto err;
                        }
-               }
-       else if(!name_cmp(name, "otherName"))
-               {
+               break;
+
+               case GEN_OTHERNAME:
                if (!do_othername(gen, value, ctx))
                        {
-                       X509V3err(X509V3_F_V2I_GENERAL_NAME,X509V3_R_OTHERNAME_ERROR);
+                       X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_OTHERNAME_ERROR);
                        goto err;
                        }
-               type = GEN_OTHERNAME;
-               }
-       else
-               {
-               X509V3err(X509V3_F_V2I_GENERAL_NAME,X509V3_R_UNSUPPORTED_OPTION);
-               ERR_add_error_data(2, "name=", name);
+               default:
+               X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_UNSUPPORTED_TYPE);
                goto err;
                }
 
@@ -514,20 +504,63 @@ GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
                              !ASN1_STRING_set(gen->d.ia5, (unsigned char*)value,
                                               strlen(value)))
                        {
-                       X509V3err(X509V3_F_V2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE);
+                       X509V3err(X509V3_F_A2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE);
                        goto err;
                        }
                }
 
-       gen->type = type;
+       gen->type = gen_type;
 
        return gen;
 
        err:
-       GENERAL_NAME_free(gen);
+       if (!out)
+               GENERAL_NAME_free(gen);
        return NULL;
        }
 
+GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
+                                 const X509V3_EXT_METHOD *method,
+                                 X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc)
+       {
+       int type;
+
+       char *name, *value;
+
+       name = cnf->name;
+       value = cnf->value;
+
+       if(!value)
+               {
+               X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_MISSING_VALUE);
+               return NULL;
+               }
+
+       if(!name_cmp(name, "email"))
+               type = GEN_EMAIL;
+       else if(!name_cmp(name, "URI"))
+               type = GEN_URI;
+       else if(!name_cmp(name, "DNS"))
+               type = GEN_DNS;
+       else if(!name_cmp(name, "RID"))
+               type = GEN_RID;
+       else if(!name_cmp(name, "IP"))
+               type = GEN_IPADD;
+       else if(!name_cmp(name, "dirName"))
+               type = GEN_DIRNAME;
+       else if(!name_cmp(name, "otherName"))
+               type = GEN_OTHERNAME;
+       else
+               {
+               X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_UNSUPPORTED_OPTION);
+               ERR_add_error_data(2, "name=", name);
+               return NULL;
+               }
+
+       return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
+
+       }
+
 static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
        {
        char *objtmp = NULL, *p;
@@ -573,6 +606,7 @@ static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
        if (!ret)
                X509_NAME_free(nm);
        gen->d.dirn = nm;
+       X509V3_section_free(ctx, sk);
                
        return ret;
        }