Add ASN1_buf_print to print a buffer in ASN1_bn_print format.
[openssl.git] / crypto / asn1 / a_object.c
index 44473dc1b38a4be1b13186ef68f2d8aa0009a272..5d3ebd6ca7abc7805040c81dd33e86fd97bb08c2 100644 (file)
@@ -1,4 +1,3 @@
-/* crypto/asn1/a_object.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -139,9 +138,9 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
             }
             if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) {
                 use_bn = 1;
-                if (!bl)
+                if (bl == NULL)
                     bl = BN_new();
-                if (!bl || !BN_set_word(bl, l))
+                if (bl == NULL || !BN_set_word(bl, l))
                     goto err;
             }
             if (use_bn) {
@@ -173,7 +172,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
                     OPENSSL_free(tmp);
                 tmpsize = blsize + 32;
                 tmp = OPENSSL_malloc(tmpsize);
-                if (!tmp)
+                if (tmp == NULL)
                     goto err;
             }
             while (blsize--)
@@ -225,7 +224,7 @@ int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
     i = i2t_ASN1_OBJECT(buf, sizeof buf, a);
     if (i > (int)(sizeof(buf) - 1)) {
         p = OPENSSL_malloc(i + 1);
-        if (!p)
+        if (p == NULL)
             return -1;
         i2t_ASN1_OBJECT(p, i + 1, a);
     }
@@ -271,7 +270,7 @@ ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
 ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
                              long len)
 {
-    ASN1_OBJECT *ret = NULL;
+    ASN1_OBJECT *ret = NULL, tobj;
     const unsigned char *p;
     unsigned char *data;
     int i, length;
@@ -288,6 +287,29 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
     }
     /* Now 0 < len <= INT_MAX, so the cast is safe. */
     length = (int)len;
+    /*
+     * Try to lookup OID in table: these are all valid encodings so if we get
+     * a match we know the OID is valid.
+     */
+    tobj.nid = NID_undef;
+    tobj.data = p;
+    tobj.length = length;
+    tobj.flags = 0;
+    i = OBJ_obj2nid(&tobj);
+    if (i != NID_undef) {
+        /*
+         * Return shared registered OID object: this improves efficiency
+         * because we don't have to return a dynamically allocated OID
+         * and NID lookups can use the cached value.
+         */
+        ret = OBJ_nid2obj(i);
+        if (a) {
+            ASN1_OBJECT_free(*a);
+            *a = ret;
+        }
+        *pp += len;
+        return ret;
+    }
     for (i = 0; i < length; i++, p++) {
         if (*p == 0x80 && (!i || !(p[-1] & 0x80))) {
             ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);