summaryrefslogtreecommitdiff
path: root/src/crypto/obj/obj.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto/obj/obj.c')
-rw-r--r--src/crypto/obj/obj.c52
1 files changed, 36 insertions, 16 deletions
diff --git a/src/crypto/obj/obj.c b/src/crypto/obj/obj.c
index 9be37305..41064247 100644
--- a/src/crypto/obj/obj.c
+++ b/src/crypto/obj/obj.c
@@ -115,16 +115,12 @@ ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) {
}
r->ln = r->sn = NULL;
- data = OPENSSL_malloc(o->length);
- if (data == NULL) {
+ // once data is attached to an object, it remains const
+ r->data = OPENSSL_memdup(o->data, o->length);
+ if (o->length != 0 && r->data == NULL) {
goto err;
}
- if (o->data != NULL) {
- OPENSSL_memcpy(data, o->data, o->length);
- }
- // once data is attached to an object, it remains const
- r->data = data;
r->length = o->length;
r->nid = o->nid;
@@ -183,12 +179,19 @@ size_t OBJ_length(const ASN1_OBJECT *obj) {
return (size_t)obj->length;
}
+static const ASN1_OBJECT *get_builtin_object(int nid) {
+ // |NID_undef| is stored separately, so all the indices are off by one. The
+ // caller of this function must have a valid built-in, non-undef NID.
+ BSSL_CHECK(nid > 0 && nid < NUM_NID);
+ return &kObjects[nid - 1];
+}
+
// obj_cmp is called to search the kNIDsInOIDOrder array. The |key| argument is
// an |ASN1_OBJECT|* that we're looking for and |element| is a pointer to an
// unsigned int in the array.
static int obj_cmp(const void *key, const void *element) {
uint16_t nid = *((const uint16_t *)element);
- return OBJ_cmp(key, &kObjects[nid]);
+ return OBJ_cmp(key, get_builtin_object(nid));
}
int OBJ_obj2nid(const ASN1_OBJECT *obj) {
@@ -219,7 +222,7 @@ int OBJ_obj2nid(const ASN1_OBJECT *obj) {
return NID_undef;
}
- return kObjects[*nid_ptr].nid;
+ return get_builtin_object(*nid_ptr)->nid;
}
int OBJ_cbs2nid(const CBS *cbs) {
@@ -242,7 +245,7 @@ static int short_name_cmp(const void *key, const void *element) {
const char *name = (const char *)key;
uint16_t nid = *((const uint16_t *)element);
- return strcmp(name, kObjects[nid].sn);
+ return strcmp(name, get_builtin_object(nid)->sn);
}
int OBJ_sn2nid(const char *short_name) {
@@ -267,7 +270,7 @@ int OBJ_sn2nid(const char *short_name) {
return NID_undef;
}
- return kObjects[*nid_ptr].nid;
+ return get_builtin_object(*nid_ptr)->nid;
}
// long_name_cmp is called to search the kNIDsInLongNameOrder array. The
@@ -277,7 +280,7 @@ static int long_name_cmp(const void *key, const void *element) {
const char *name = (const char *)key;
uint16_t nid = *((const uint16_t *)element);
- return strcmp(name, kObjects[nid].ln);
+ return strcmp(name, get_builtin_object(nid)->ln);
}
int OBJ_ln2nid(const char *long_name) {
@@ -301,7 +304,7 @@ int OBJ_ln2nid(const char *long_name) {
return NID_undef;
}
- return kObjects[*nid_ptr].nid;
+ return get_builtin_object(*nid_ptr)->nid;
}
int OBJ_txt2nid(const char *s) {
@@ -328,12 +331,29 @@ OPENSSL_EXPORT int OBJ_nid2cbb(CBB *out, int nid) {
return 1;
}
+const ASN1_OBJECT *OBJ_get_undef(void) {
+ static const ASN1_OBJECT kUndef = {
+ /*sn=*/SN_undef,
+ /*ln=*/LN_undef,
+ /*nid=*/NID_undef,
+ /*length=*/0,
+ /*data=*/NULL,
+ /*flags=*/0,
+ };
+ return &kUndef;
+}
+
ASN1_OBJECT *OBJ_nid2obj(int nid) {
- if (nid >= 0 && nid < NUM_NID) {
- if (nid != NID_undef && kObjects[nid].nid == NID_undef) {
+ if (nid == NID_undef) {
+ return (ASN1_OBJECT *)OBJ_get_undef();
+ }
+
+ if (nid > 0 && nid < NUM_NID) {
+ const ASN1_OBJECT *obj = get_builtin_object(nid);
+ if (nid != NID_undef && obj->nid == NID_undef) {
goto err;
}
- return (ASN1_OBJECT *)&kObjects[nid];
+ return (ASN1_OBJECT *)obj;
}
CRYPTO_MUTEX_lock_read(&global_added_lock);