Make preprocessor error into real preprocessor error
[openssl.git] / crypto / asn1 / asn1_gen.c
index 0e1cc08894f0cb3b19cdead37aa0da6730b407ef..5f01b8dac14022f1459f859bbd4a22b76fa23a78 100644 (file)
@@ -57,7 +57,7 @@
  *
  */
 
-#include "cryptlib.h"
+#include "internal/cryptlib.h"
 #include <openssl/asn1.h>
 #include <openssl/x509v3.h>
 
@@ -74,6 +74,8 @@
 #define ASN1_GEN_STR(str,val)   {str, sizeof(str) - 1, val}
 
 #define ASN1_FLAG_EXP_MAX       20
+/* Maximum number of nested sequences */
+#define ASN1_GEN_SEQ_MAX_DEPTH  50
 
 /* Input formats */
 
@@ -110,13 +112,16 @@ typedef struct {
     int exp_count;
 } tag_exp_arg;
 
+static ASN1_TYPE *generate_v3(char *str, X509V3_CTX *cnf, int depth,
+                              int *perr);
 static int bitstr_cb(const char *elem, int len, void *bitstr);
 static int asn1_cb(const char *elem, int len, void *bitstr);
 static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class,
                       int exp_constructed, int exp_pad, int imp_ok);
 static int parse_tagging(const char *vstart, int vlen, int *ptag,
                          int *pclass);
-static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf);
+static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf,
+                             int depth, int *perr);
 static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype);
 static int asn1_str2tag(const char *tagstr, int len);
 
@@ -132,6 +137,16 @@ ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf)
 }
 
 ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
+{
+    int err = 0;
+    ASN1_TYPE *ret = generate_v3(str, cnf, 0, &err);
+    if (err)
+        ASN1err(ASN1_F_ASN1_GENERATE_V3, err);
+    return ret;
+}
+
+static ASN1_TYPE *generate_v3(char *str, X509V3_CTX *cnf, int depth,
+                              int *perr)
 {
     ASN1_TYPE *ret;
     tag_exp_arg asn1_tags;
@@ -144,7 +159,7 @@ ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
     unsigned char *p;
     const unsigned char *cp;
     int cpy_len;
-    long hdr_len;
+    long hdr_len = 0;
     int hdr_constructed = 0, hdr_tag, hdr_class;
     int r;
 
@@ -152,17 +167,22 @@ ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
     asn1_tags.imp_class = -1;
     asn1_tags.format = ASN1_GEN_FORMAT_ASCII;
     asn1_tags.exp_count = 0;
-    if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0)
+    if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0) {
+        *perr = ASN1_R_UNKNOWN_TAG;
         return NULL;
+    }
 
     if ((asn1_tags.utype == V_ASN1_SEQUENCE)
         || (asn1_tags.utype == V_ASN1_SET)) {
         if (!cnf) {
-            ASN1err(ASN1_F_ASN1_GENERATE_V3,
-                    ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
+            *perr = ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG;
             return NULL;
         }
-        ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf);
+        if (depth >= ASN1_GEN_SEQ_MAX_DEPTH) {
+            *perr = ASN1_R_ILLEGAL_NESTED_TAGGING;
+            return NULL;
+        }
+        ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf, depth, perr);
     } else
         ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype);
 
@@ -260,10 +280,8 @@ ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
     ret = d2i_ASN1_TYPE(NULL, &cp, len);
 
  err:
-    if (orig_der)
-        OPENSSL_free(orig_der);
-    if (new_der)
-        OPENSSL_free(new_der);
+    OPENSSL_free(orig_der);
+    OPENSSL_free(new_der);
 
     return ret;
 
@@ -280,7 +298,7 @@ static int asn1_cb(const char *elem, int len, void *bitstr)
     int tmp_tag, tmp_class;
 
     if (elem == NULL)
-        return 0;
+        return -1;
 
     for (i = 0, p = elem; i < len; p++, i++) {
         /* Look for the ':' in name value pairs */
@@ -353,17 +371,17 @@ static int asn1_cb(const char *elem, int len, void *bitstr)
         break;
 
     case ASN1_GEN_FLAG_FORMAT:
-        if(!vstart) {
+        if (!vstart) {
             ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_FORMAT);
             return -1;
         }
-        if (!strncmp(vstart, "ASCII", 5))
+        if (strncmp(vstart, "ASCII", 5) == 0)
             arg->format = ASN1_GEN_FORMAT_ASCII;
-        else if (!strncmp(vstart, "UTF8", 4))
+        else if (strncmp(vstart, "UTF8", 4) == 0)
             arg->format = ASN1_GEN_FORMAT_UTF8;
-        else if (!strncmp(vstart, "HEX", 3))
+        else if (strncmp(vstart, "HEX", 3) == 0)
             arg->format = ASN1_GEN_FORMAT_HEX;
-        else if (!strncmp(vstart, "BITLIST", 7))
+        else if (strncmp(vstart, "BITLIST", 7) == 0)
             arg->format = ASN1_GEN_FORMAT_BITLIST;
         else {
             ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_FORMAT);
@@ -434,7 +452,8 @@ static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass)
 
 /* Handle multiple types: SET and SEQUENCE */
 
-static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
+static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf,
+                             int depth, int *perr)
 {
     ASN1_TYPE *ret = NULL;
     STACK_OF(ASN1_TYPE) *sk = NULL;
@@ -453,7 +472,8 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
             goto bad;
         for (i = 0; i < sk_CONF_VALUE_num(sect); i++) {
             ASN1_TYPE *typ =
-                ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf);
+                generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf,
+                            depth + 1, perr);
             if (!typ)
                 goto bad;
             if (!sk_ASN1_TYPE_push(sk, typ))
@@ -472,15 +492,12 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
 
     if (derlen < 0)
         goto bad;
-
-    if (!(ret = ASN1_TYPE_new()))
+    if ((ret = ASN1_TYPE_new()) == NULL)
         goto bad;
-
-    if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype)))
+    if ((ret->value.asn1_string = ASN1_STRING_type_new(utype)) == NULL)
         goto bad;
 
     ret->type = utype;
-
     ret->value.asn1_string->data = der;
     ret->value.asn1_string->length = derlen;
 
@@ -488,13 +505,10 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
 
  bad:
 
-    if (der)
-        OPENSSL_free(der);
+    OPENSSL_free(der);
 
-    if (sk)
-        sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
-    if (sect)
-        X509V3_section_free(cnf, sect);
+    sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
+    X509V3_section_free(cnf, sect);
 
     return ret;
 }
@@ -603,8 +617,8 @@ static int asn1_str2tag(const char *tagstr, int len)
         len = strlen(tagstr);
 
     tntmp = tnst;
-    for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++) {
-        if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len))
+    for (i = 0; i < OSSL_NELEM(tnst); i++, tntmp++) {
+        if ((len == tntmp->len) && (strncmp(tntmp->strnam, tagstr, len) == 0))
             return tntmp->tag;
     }
 
@@ -614,15 +628,12 @@ static int asn1_str2tag(const char *tagstr, int len)
 static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
 {
     ASN1_TYPE *atmp = NULL;
-
     CONF_VALUE vtmp;
-
     unsigned char *rdata;
     long rdlen;
-
     int no_unused = 1;
 
-    if (!(atmp = ASN1_TYPE_new())) {
+    if ((atmp = ASN1_TYPE_new()) == NULL) {
         ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
         return NULL;
     }
@@ -659,7 +670,8 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
             ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT);
             goto bad_form;
         }
-        if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str))) {
+        if ((atmp->value.integer
+                    = s2i_ASN1_INTEGER(NULL, (char *)str)) == NULL) {
             ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER);
             goto bad_str;
         }
@@ -670,7 +682,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
             ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT);
             goto bad_form;
         }
-        if (!(atmp->value.object = OBJ_txt2obj(str, 0))) {
+        if ((atmp->value.object = OBJ_txt2obj(str, 0)) == NULL) {
             ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT);
             goto bad_str;
         }
@@ -682,7 +694,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
             ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT);
             goto bad_form;
         }
-        if (!(atmp->value.asn1_string = ASN1_STRING_new())) {
+        if ((atmp->value.asn1_string = ASN1_STRING_new()) == NULL) {
             ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
             goto bad_str;
         }
@@ -707,7 +719,6 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
     case V_ASN1_UNIVERSALSTRING:
     case V_ASN1_GENERALSTRING:
     case V_ASN1_NUMERICSTRING:
-
         if (format == ASN1_GEN_FORMAT_ASCII)
             format = MBSTRING_ASC;
         else if (format == ASN1_GEN_FORMAT_UTF8)
@@ -726,25 +737,20 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
         break;
 
     case V_ASN1_BIT_STRING:
-
     case V_ASN1_OCTET_STRING:
-
-        if (!(atmp->value.asn1_string = ASN1_STRING_new())) {
+        if ((atmp->value.asn1_string = ASN1_STRING_new()) == NULL) {
             ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
             goto bad_form;
         }
 
         if (format == ASN1_GEN_FORMAT_HEX) {
-
-            if (!(rdata = string_to_hex((char *)str, &rdlen))) {
+            if ((rdata = string_to_hex((char *)str, &rdlen)) == NULL) {
                 ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX);
                 goto bad_str;
             }
-
             atmp->value.asn1_string->data = rdata;
             atmp->value.asn1_string->length = rdlen;
             atmp->value.asn1_string->type = utype;
-
         } else if (format == ASN1_GEN_FORMAT_ASCII)
             ASN1_STRING_set(atmp->value.asn1_string, str, -1);
         else if ((format == ASN1_GEN_FORMAT_BITLIST)
@@ -812,7 +818,7 @@ static int mask_cb(const char *elem, int len, void *arg)
     int tag;
     if (elem == NULL)
         return 0;
-    if (len == 3 && !strncmp(elem, "DIR", 3)) {
+    if ((len == 3) && (strncmp(elem, "DIR", 3) == 0)) {
         *pmask |= B_ASN1_DIRECTORYSTRING;
         return 1;
     }