aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2015-09-17 23:50:13 +0100
committerDr. Stephen Henson <steve@openssl.org>2015-09-19 05:57:19 +0100
commit331bf00bed8c2839466b608e725c8aa5ef54622c (patch)
treef9aaa516a31cbe6dc3070959d6a86c1d2717f9d1 /crypto
parent4fe1cbdff89768c5d1983988ce1022674a438bbb (diff)
downloadopenssl-331bf00bed8c2839466b608e725c8aa5ef54622c.tar.gz
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 <rsalz@openssl.org>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/asn1/a_object.c25
1 files changed, 24 insertions, 1 deletions
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);