From 331bf00bed8c2839466b608e725c8aa5ef54622c Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Thu, 17 Sep 2015 23:50:13 +0100 Subject: [PATCH] Return shared OIDs when decoding. When an OID is decoded see if it exists in the registered OID table and if so return the shared OID instead of dynamically allocating an ASN1_OBJECT. Reviewed-by: Rich Salz --- crypto/asn1/a_object.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/crypto/asn1/a_object.c b/crypto/asn1/a_object.c index 44473dc1b3..80b5055978 100644 --- a/crypto/asn1/a_object.c +++ b/crypto/asn1/a_object.c @@ -271,7 +271,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 +288,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); -- 2.34.1