New config module for string tables. This can be used to add new
[openssl.git] / crypto / asn1 / asn1_gen.c
index a0f7e452f68580eee4af60608555680188f3f90f..7c2c337a1a6670807521c8ddc35a113e4f3b0726 100644 (file)
@@ -145,7 +145,7 @@ ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
        unsigned char *p;
        const unsigned char *cp;
        int cpy_len;
-       size_t hdr_len;
+       long hdr_len;
        int hdr_constructed = 0, hdr_tag, hdr_class;
        int r;
 
@@ -227,6 +227,8 @@ ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
        /* Allocate buffer for new encoding */
 
        new_der = OPENSSL_malloc(len);
+       if (!new_der)
+               goto err;
 
        /* Generate tagged encoding */
 
@@ -245,8 +247,14 @@ ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
        /* If IMPLICIT, output tag */
 
        if (asn1_tags.imp_tag != -1)
+               {
+               if (asn1_tags.imp_class == V_ASN1_UNIVERSAL 
+                   && (asn1_tags.imp_tag == V_ASN1_SEQUENCE
+                    || asn1_tags.imp_tag == V_ASN1_SET) )
+                       hdr_constructed = V_ASN1_CONSTRUCTED;
                ASN1_put_object(&p, hdr_constructed, hdr_len,
                                        asn1_tags.imp_tag, asn1_tags.imp_class);
+               }
 
        /* Copy across original encoding */
        memcpy(p, cpy_start, cpy_len);
@@ -446,6 +454,8 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
        int derlen;
        int i;
        sk = sk_ASN1_TYPE_new_null();
+       if (!sk)
+               goto bad;
        if (section)
                {
                if (!cnf)
@@ -458,7 +468,8 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
                        ASN1_TYPE *typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf);
                        if (!typ)
                                goto bad;
-                       sk_ASN1_TYPE_push(sk, typ);
+                       if (!sk_ASN1_TYPE_push(sk, typ))
+                               goto bad;
                        }
                }
 
@@ -469,6 +480,9 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
        else
                derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der);
 
+       if (derlen < 0)
+               goto bad;
+
        if (!(ret = ASN1_TYPE_new()))
                goto bad;
 
@@ -838,3 +852,27 @@ static int bitstr_cb(const char *elem, int len, void *bitstr)
        return 1;
        }
 
+static int mask_cb(const char *elem, int len, void *arg)
+       {
+       unsigned long *pmask = arg, tmpmask;
+       int tag;
+       if (len == 3 && !strncmp(elem, "DIR", 3))
+               {
+               *pmask |= B_ASN1_DIRECTORYSTRING;
+               return 1;
+               }
+       tag = asn1_str2tag(elem, len);
+       if (!tag || (tag & ASN1_GEN_FLAG))
+               return 0;
+       tmpmask = ASN1_tag2bit(tag);
+       if (!tmpmask)
+               return 0;
+       *pmask |= tmpmask;
+       return 1;
+       }
+
+int ASN1_str2mask(const char *str, unsigned long *pmask)
+       {
+       *pmask = 0;
+       return CONF_parse_list(str, '|', 1, mask_cb, pmask);
+       }