Fix ASN1_TYPE bug.
authorDr. Stephen Henson <steve@openssl.org>
Thu, 21 Sep 2000 18:57:00 +0000 (18:57 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Thu, 21 Sep 2000 18:57:00 +0000 (18:57 +0000)
CHANGES
crypto/asn1/a_type.c
crypto/asn1/asn1.h

diff --git a/CHANGES b/CHANGES
index 786ab50..7645d6f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,18 @@
 
  Changes between 0.9.5a and 0.9.6  [xx XXX 2000]
 
+  *) Fix for a nasty bug in ASN1_TYPE handling. ASN1_TYPE is used for
+     a general "ANY" type, as such it should be able to decode anything
+     including tagged types. However it didn't check the class so it would
+     wrongly interpret tagged types in the same way as their universal
+     counterpart and unknown types were just rejected. Changed so that the
+     tagged and unknown types are handled in the same way as a SEQUENCE:
+     that is the encoding is stored intact. There is also a new type
+     "V_ASN1_OTHER" which is used when the class is not universal, in this
+     case we have no idea what the actual type is so we just lump them all
+     together.
+     [Steve Henson]
+
   *) On VMS, stdout may very well lead to a file that is written to
      in a record-oriented fashion.  That means that every write() will
      write a separate record, which will be read separately by the
index 3620e60..cf71602 100644 (file)
@@ -123,6 +123,8 @@ int i2d_ASN1_TYPE(ASN1_TYPE *a, unsigned char **pp)
                break;
        case V_ASN1_SET:
        case V_ASN1_SEQUENCE:
+       case V_ASN1_OTHER:
+       default:
                if (a->value.set == NULL)
                        r=0;
                else
@@ -159,6 +161,8 @@ ASN1_TYPE *d2i_ASN1_TYPE(ASN1_TYPE **a, unsigned char **pp, long length)
 
        inf=ASN1_get_object(&q,&len,&tag,&xclass,length);
        if (inf & 0x80) goto err;
+       /* If not universal tag we've no idea what it is */
+       if(xclass != V_ASN1_UNIVERSAL) tag = V_ASN1_OTHER;
        
        ASN1_TYPE_component_free(ret);
 
@@ -245,6 +249,8 @@ ASN1_TYPE *d2i_ASN1_TYPE(ASN1_TYPE **a, unsigned char **pp, long length)
                break;
        case V_ASN1_SET:
        case V_ASN1_SEQUENCE:
+       case V_ASN1_OTHER:
+       default:
                /* Sets and sequences are left complete */
                if ((ret->value.set=ASN1_STRING_new()) == NULL) goto err;
                ret->value.set->type=tag;
@@ -252,9 +258,6 @@ ASN1_TYPE *d2i_ASN1_TYPE(ASN1_TYPE **a, unsigned char **pp, long length)
                if (!ASN1_STRING_set(ret->value.set,p,(int)len)) goto err;
                p+=len;
                break;
-       default:
-               ASN1err(ASN1_F_D2I_ASN1_TYPE,ASN1_R_BAD_TYPE);
-               goto err;
                }
 
        ret->type=tag;
@@ -333,10 +336,9 @@ static void ASN1_TYPE_component_free(ASN1_TYPE *a)
                case V_ASN1_UNIVERSALSTRING:
                case V_ASN1_BMPSTRING:
                case V_ASN1_UTF8STRING:
-                       ASN1_STRING_free((ASN1_STRING *)a->value.ptr);
-                       break;
+               case V_ASN1_OTHER:
                default:
-                       /* MEMORY LEAK */
+                       ASN1_STRING_free((ASN1_STRING *)a->value.ptr);
                        break;
                        }
                a->type=0;
index 3346377..6f956b1 100644 (file)
@@ -83,6 +83,7 @@ extern "C" {
 #define V_ASN1_PRIMATIVE_TAG           0x1f
 
 #define V_ASN1_APP_CHOOSE              -2      /* let the recipient choose */
+#define V_ASN1_OTHER                   -3      /* used in ASN1_TYPE */
 
 #define V_ASN1_NEG                     0x100   /* negative flag */