xref: /aosp_15_r20/external/boringssl/src/crypto/obj/obj.c (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1*8fb009dcSAndroid Build Coastguard Worker /* Copyright (C) 1995-1998 Eric Young ([email protected])
2*8fb009dcSAndroid Build Coastguard Worker  * All rights reserved.
3*8fb009dcSAndroid Build Coastguard Worker  *
4*8fb009dcSAndroid Build Coastguard Worker  * This package is an SSL implementation written
5*8fb009dcSAndroid Build Coastguard Worker  * by Eric Young ([email protected]).
6*8fb009dcSAndroid Build Coastguard Worker  * The implementation was written so as to conform with Netscapes SSL.
7*8fb009dcSAndroid Build Coastguard Worker  *
8*8fb009dcSAndroid Build Coastguard Worker  * This library is free for commercial and non-commercial use as long as
9*8fb009dcSAndroid Build Coastguard Worker  * the following conditions are aheared to.  The following conditions
10*8fb009dcSAndroid Build Coastguard Worker  * apply to all code found in this distribution, be it the RC4, RSA,
11*8fb009dcSAndroid Build Coastguard Worker  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12*8fb009dcSAndroid Build Coastguard Worker  * included with this distribution is covered by the same copyright terms
13*8fb009dcSAndroid Build Coastguard Worker  * except that the holder is Tim Hudson ([email protected]).
14*8fb009dcSAndroid Build Coastguard Worker  *
15*8fb009dcSAndroid Build Coastguard Worker  * Copyright remains Eric Young's, and as such any Copyright notices in
16*8fb009dcSAndroid Build Coastguard Worker  * the code are not to be removed.
17*8fb009dcSAndroid Build Coastguard Worker  * If this package is used in a product, Eric Young should be given attribution
18*8fb009dcSAndroid Build Coastguard Worker  * as the author of the parts of the library used.
19*8fb009dcSAndroid Build Coastguard Worker  * This can be in the form of a textual message at program startup or
20*8fb009dcSAndroid Build Coastguard Worker  * in documentation (online or textual) provided with the package.
21*8fb009dcSAndroid Build Coastguard Worker  *
22*8fb009dcSAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
23*8fb009dcSAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions
24*8fb009dcSAndroid Build Coastguard Worker  * are met:
25*8fb009dcSAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the copyright
26*8fb009dcSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer.
27*8fb009dcSAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright
28*8fb009dcSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer in the
29*8fb009dcSAndroid Build Coastguard Worker  *    documentation and/or other materials provided with the distribution.
30*8fb009dcSAndroid Build Coastguard Worker  * 3. All advertising materials mentioning features or use of this software
31*8fb009dcSAndroid Build Coastguard Worker  *    must display the following acknowledgement:
32*8fb009dcSAndroid Build Coastguard Worker  *    "This product includes cryptographic software written by
33*8fb009dcSAndroid Build Coastguard Worker  *     Eric Young ([email protected])"
34*8fb009dcSAndroid Build Coastguard Worker  *    The word 'cryptographic' can be left out if the rouines from the library
35*8fb009dcSAndroid Build Coastguard Worker  *    being used are not cryptographic related :-).
36*8fb009dcSAndroid Build Coastguard Worker  * 4. If you include any Windows specific code (or a derivative thereof) from
37*8fb009dcSAndroid Build Coastguard Worker  *    the apps directory (application code) you must include an acknowledgement:
38*8fb009dcSAndroid Build Coastguard Worker  *    "This product includes software written by Tim Hudson ([email protected])"
39*8fb009dcSAndroid Build Coastguard Worker  *
40*8fb009dcSAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41*8fb009dcSAndroid Build Coastguard Worker  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42*8fb009dcSAndroid Build Coastguard Worker  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43*8fb009dcSAndroid Build Coastguard Worker  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44*8fb009dcSAndroid Build Coastguard Worker  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45*8fb009dcSAndroid Build Coastguard Worker  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46*8fb009dcSAndroid Build Coastguard Worker  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47*8fb009dcSAndroid Build Coastguard Worker  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48*8fb009dcSAndroid Build Coastguard Worker  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49*8fb009dcSAndroid Build Coastguard Worker  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50*8fb009dcSAndroid Build Coastguard Worker  * SUCH DAMAGE.
51*8fb009dcSAndroid Build Coastguard Worker  *
52*8fb009dcSAndroid Build Coastguard Worker  * The licence and distribution terms for any publically available version or
53*8fb009dcSAndroid Build Coastguard Worker  * derivative of this code cannot be changed.  i.e. this code cannot simply be
54*8fb009dcSAndroid Build Coastguard Worker  * copied and put under another distribution licence
55*8fb009dcSAndroid Build Coastguard Worker  * [including the GNU Public Licence.] */
56*8fb009dcSAndroid Build Coastguard Worker 
57*8fb009dcSAndroid Build Coastguard Worker #include <openssl/obj.h>
58*8fb009dcSAndroid Build Coastguard Worker 
59*8fb009dcSAndroid Build Coastguard Worker #include <inttypes.h>
60*8fb009dcSAndroid Build Coastguard Worker #include <limits.h>
61*8fb009dcSAndroid Build Coastguard Worker #include <string.h>
62*8fb009dcSAndroid Build Coastguard Worker 
63*8fb009dcSAndroid Build Coastguard Worker #include <openssl/asn1.h>
64*8fb009dcSAndroid Build Coastguard Worker #include <openssl/bytestring.h>
65*8fb009dcSAndroid Build Coastguard Worker #include <openssl/err.h>
66*8fb009dcSAndroid Build Coastguard Worker #include <openssl/lhash.h>
67*8fb009dcSAndroid Build Coastguard Worker #include <openssl/mem.h>
68*8fb009dcSAndroid Build Coastguard Worker #include <openssl/thread.h>
69*8fb009dcSAndroid Build Coastguard Worker 
70*8fb009dcSAndroid Build Coastguard Worker #include "../asn1/internal.h"
71*8fb009dcSAndroid Build Coastguard Worker #include "../internal.h"
72*8fb009dcSAndroid Build Coastguard Worker #include "../lhash/internal.h"
73*8fb009dcSAndroid Build Coastguard Worker 
74*8fb009dcSAndroid Build Coastguard Worker // obj_data.h must be included after the definition of |ASN1_OBJECT|.
75*8fb009dcSAndroid Build Coastguard Worker #include "obj_dat.h"
76*8fb009dcSAndroid Build Coastguard Worker 
77*8fb009dcSAndroid Build Coastguard Worker 
78*8fb009dcSAndroid Build Coastguard Worker DEFINE_LHASH_OF(ASN1_OBJECT)
79*8fb009dcSAndroid Build Coastguard Worker 
80*8fb009dcSAndroid Build Coastguard Worker static CRYPTO_MUTEX global_added_lock = CRYPTO_MUTEX_INIT;
81*8fb009dcSAndroid Build Coastguard Worker // These globals are protected by |global_added_lock|.
82*8fb009dcSAndroid Build Coastguard Worker static LHASH_OF(ASN1_OBJECT) *global_added_by_data = NULL;
83*8fb009dcSAndroid Build Coastguard Worker static LHASH_OF(ASN1_OBJECT) *global_added_by_nid = NULL;
84*8fb009dcSAndroid Build Coastguard Worker static LHASH_OF(ASN1_OBJECT) *global_added_by_short_name = NULL;
85*8fb009dcSAndroid Build Coastguard Worker static LHASH_OF(ASN1_OBJECT) *global_added_by_long_name = NULL;
86*8fb009dcSAndroid Build Coastguard Worker 
87*8fb009dcSAndroid Build Coastguard Worker static CRYPTO_MUTEX global_next_nid_lock = CRYPTO_MUTEX_INIT;
88*8fb009dcSAndroid Build Coastguard Worker static unsigned global_next_nid = NUM_NID;
89*8fb009dcSAndroid Build Coastguard Worker 
obj_next_nid(void)90*8fb009dcSAndroid Build Coastguard Worker static int obj_next_nid(void) {
91*8fb009dcSAndroid Build Coastguard Worker   CRYPTO_MUTEX_lock_write(&global_next_nid_lock);
92*8fb009dcSAndroid Build Coastguard Worker   int ret = global_next_nid++;
93*8fb009dcSAndroid Build Coastguard Worker   CRYPTO_MUTEX_unlock_write(&global_next_nid_lock);
94*8fb009dcSAndroid Build Coastguard Worker   return ret;
95*8fb009dcSAndroid Build Coastguard Worker }
96*8fb009dcSAndroid Build Coastguard Worker 
OBJ_dup(const ASN1_OBJECT * o)97*8fb009dcSAndroid Build Coastguard Worker ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) {
98*8fb009dcSAndroid Build Coastguard Worker   ASN1_OBJECT *r;
99*8fb009dcSAndroid Build Coastguard Worker   unsigned char *data = NULL;
100*8fb009dcSAndroid Build Coastguard Worker   char *sn = NULL, *ln = NULL;
101*8fb009dcSAndroid Build Coastguard Worker 
102*8fb009dcSAndroid Build Coastguard Worker   if (o == NULL) {
103*8fb009dcSAndroid Build Coastguard Worker     return NULL;
104*8fb009dcSAndroid Build Coastguard Worker   }
105*8fb009dcSAndroid Build Coastguard Worker 
106*8fb009dcSAndroid Build Coastguard Worker   if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC)) {
107*8fb009dcSAndroid Build Coastguard Worker     // TODO(fork): this is a little dangerous.
108*8fb009dcSAndroid Build Coastguard Worker     return (ASN1_OBJECT *)o;
109*8fb009dcSAndroid Build Coastguard Worker   }
110*8fb009dcSAndroid Build Coastguard Worker 
111*8fb009dcSAndroid Build Coastguard Worker   r = ASN1_OBJECT_new();
112*8fb009dcSAndroid Build Coastguard Worker   if (r == NULL) {
113*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(OBJ, ERR_R_ASN1_LIB);
114*8fb009dcSAndroid Build Coastguard Worker     return NULL;
115*8fb009dcSAndroid Build Coastguard Worker   }
116*8fb009dcSAndroid Build Coastguard Worker   r->ln = r->sn = NULL;
117*8fb009dcSAndroid Build Coastguard Worker 
118*8fb009dcSAndroid Build Coastguard Worker   // once data is attached to an object, it remains const
119*8fb009dcSAndroid Build Coastguard Worker   r->data = OPENSSL_memdup(o->data, o->length);
120*8fb009dcSAndroid Build Coastguard Worker   if (o->length != 0 && r->data == NULL) {
121*8fb009dcSAndroid Build Coastguard Worker     goto err;
122*8fb009dcSAndroid Build Coastguard Worker   }
123*8fb009dcSAndroid Build Coastguard Worker 
124*8fb009dcSAndroid Build Coastguard Worker   r->length = o->length;
125*8fb009dcSAndroid Build Coastguard Worker   r->nid = o->nid;
126*8fb009dcSAndroid Build Coastguard Worker 
127*8fb009dcSAndroid Build Coastguard Worker   if (o->ln != NULL) {
128*8fb009dcSAndroid Build Coastguard Worker     ln = OPENSSL_strdup(o->ln);
129*8fb009dcSAndroid Build Coastguard Worker     if (ln == NULL) {
130*8fb009dcSAndroid Build Coastguard Worker       goto err;
131*8fb009dcSAndroid Build Coastguard Worker     }
132*8fb009dcSAndroid Build Coastguard Worker   }
133*8fb009dcSAndroid Build Coastguard Worker 
134*8fb009dcSAndroid Build Coastguard Worker   if (o->sn != NULL) {
135*8fb009dcSAndroid Build Coastguard Worker     sn = OPENSSL_strdup(o->sn);
136*8fb009dcSAndroid Build Coastguard Worker     if (sn == NULL) {
137*8fb009dcSAndroid Build Coastguard Worker       goto err;
138*8fb009dcSAndroid Build Coastguard Worker     }
139*8fb009dcSAndroid Build Coastguard Worker   }
140*8fb009dcSAndroid Build Coastguard Worker 
141*8fb009dcSAndroid Build Coastguard Worker   r->sn = sn;
142*8fb009dcSAndroid Build Coastguard Worker   r->ln = ln;
143*8fb009dcSAndroid Build Coastguard Worker 
144*8fb009dcSAndroid Build Coastguard Worker   r->flags =
145*8fb009dcSAndroid Build Coastguard Worker       o->flags | (ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
146*8fb009dcSAndroid Build Coastguard Worker                   ASN1_OBJECT_FLAG_DYNAMIC_DATA);
147*8fb009dcSAndroid Build Coastguard Worker   return r;
148*8fb009dcSAndroid Build Coastguard Worker 
149*8fb009dcSAndroid Build Coastguard Worker err:
150*8fb009dcSAndroid Build Coastguard Worker   OPENSSL_free(ln);
151*8fb009dcSAndroid Build Coastguard Worker   OPENSSL_free(sn);
152*8fb009dcSAndroid Build Coastguard Worker   OPENSSL_free(data);
153*8fb009dcSAndroid Build Coastguard Worker   OPENSSL_free(r);
154*8fb009dcSAndroid Build Coastguard Worker   return NULL;
155*8fb009dcSAndroid Build Coastguard Worker }
156*8fb009dcSAndroid Build Coastguard Worker 
OBJ_cmp(const ASN1_OBJECT * a,const ASN1_OBJECT * b)157*8fb009dcSAndroid Build Coastguard Worker int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b) {
158*8fb009dcSAndroid Build Coastguard Worker   if (a->length < b->length) {
159*8fb009dcSAndroid Build Coastguard Worker     return -1;
160*8fb009dcSAndroid Build Coastguard Worker   } else if (a->length > b->length) {
161*8fb009dcSAndroid Build Coastguard Worker     return 1;
162*8fb009dcSAndroid Build Coastguard Worker   }
163*8fb009dcSAndroid Build Coastguard Worker   return OPENSSL_memcmp(a->data, b->data, a->length);
164*8fb009dcSAndroid Build Coastguard Worker }
165*8fb009dcSAndroid Build Coastguard Worker 
OBJ_get0_data(const ASN1_OBJECT * obj)166*8fb009dcSAndroid Build Coastguard Worker const uint8_t *OBJ_get0_data(const ASN1_OBJECT *obj) {
167*8fb009dcSAndroid Build Coastguard Worker   if (obj == NULL) {
168*8fb009dcSAndroid Build Coastguard Worker     return NULL;
169*8fb009dcSAndroid Build Coastguard Worker   }
170*8fb009dcSAndroid Build Coastguard Worker 
171*8fb009dcSAndroid Build Coastguard Worker   return obj->data;
172*8fb009dcSAndroid Build Coastguard Worker }
173*8fb009dcSAndroid Build Coastguard Worker 
OBJ_length(const ASN1_OBJECT * obj)174*8fb009dcSAndroid Build Coastguard Worker size_t OBJ_length(const ASN1_OBJECT *obj) {
175*8fb009dcSAndroid Build Coastguard Worker   if (obj == NULL || obj->length < 0) {
176*8fb009dcSAndroid Build Coastguard Worker     return 0;
177*8fb009dcSAndroid Build Coastguard Worker   }
178*8fb009dcSAndroid Build Coastguard Worker 
179*8fb009dcSAndroid Build Coastguard Worker   return (size_t)obj->length;
180*8fb009dcSAndroid Build Coastguard Worker }
181*8fb009dcSAndroid Build Coastguard Worker 
get_builtin_object(int nid)182*8fb009dcSAndroid Build Coastguard Worker static const ASN1_OBJECT *get_builtin_object(int nid) {
183*8fb009dcSAndroid Build Coastguard Worker   // |NID_undef| is stored separately, so all the indices are off by one. The
184*8fb009dcSAndroid Build Coastguard Worker   // caller of this function must have a valid built-in, non-undef NID.
185*8fb009dcSAndroid Build Coastguard Worker   BSSL_CHECK(nid > 0 && nid < NUM_NID);
186*8fb009dcSAndroid Build Coastguard Worker   return &kObjects[nid - 1];
187*8fb009dcSAndroid Build Coastguard Worker }
188*8fb009dcSAndroid Build Coastguard Worker 
189*8fb009dcSAndroid Build Coastguard Worker // obj_cmp is called to search the kNIDsInOIDOrder array. The |key| argument is
190*8fb009dcSAndroid Build Coastguard Worker // an |ASN1_OBJECT|* that we're looking for and |element| is a pointer to an
191*8fb009dcSAndroid Build Coastguard Worker // unsigned int in the array.
obj_cmp(const void * key,const void * element)192*8fb009dcSAndroid Build Coastguard Worker static int obj_cmp(const void *key, const void *element) {
193*8fb009dcSAndroid Build Coastguard Worker   uint16_t nid = *((const uint16_t *)element);
194*8fb009dcSAndroid Build Coastguard Worker   return OBJ_cmp(key, get_builtin_object(nid));
195*8fb009dcSAndroid Build Coastguard Worker }
196*8fb009dcSAndroid Build Coastguard Worker 
OBJ_obj2nid(const ASN1_OBJECT * obj)197*8fb009dcSAndroid Build Coastguard Worker int OBJ_obj2nid(const ASN1_OBJECT *obj) {
198*8fb009dcSAndroid Build Coastguard Worker   if (obj == NULL) {
199*8fb009dcSAndroid Build Coastguard Worker     return NID_undef;
200*8fb009dcSAndroid Build Coastguard Worker   }
201*8fb009dcSAndroid Build Coastguard Worker 
202*8fb009dcSAndroid Build Coastguard Worker   if (obj->nid != 0) {
203*8fb009dcSAndroid Build Coastguard Worker     return obj->nid;
204*8fb009dcSAndroid Build Coastguard Worker   }
205*8fb009dcSAndroid Build Coastguard Worker 
206*8fb009dcSAndroid Build Coastguard Worker   CRYPTO_MUTEX_lock_read(&global_added_lock);
207*8fb009dcSAndroid Build Coastguard Worker   if (global_added_by_data != NULL) {
208*8fb009dcSAndroid Build Coastguard Worker     ASN1_OBJECT *match;
209*8fb009dcSAndroid Build Coastguard Worker 
210*8fb009dcSAndroid Build Coastguard Worker     match = lh_ASN1_OBJECT_retrieve(global_added_by_data, obj);
211*8fb009dcSAndroid Build Coastguard Worker     if (match != NULL) {
212*8fb009dcSAndroid Build Coastguard Worker       CRYPTO_MUTEX_unlock_read(&global_added_lock);
213*8fb009dcSAndroid Build Coastguard Worker       return match->nid;
214*8fb009dcSAndroid Build Coastguard Worker     }
215*8fb009dcSAndroid Build Coastguard Worker   }
216*8fb009dcSAndroid Build Coastguard Worker   CRYPTO_MUTEX_unlock_read(&global_added_lock);
217*8fb009dcSAndroid Build Coastguard Worker 
218*8fb009dcSAndroid Build Coastguard Worker   const uint16_t *nid_ptr =
219*8fb009dcSAndroid Build Coastguard Worker       bsearch(obj, kNIDsInOIDOrder, OPENSSL_ARRAY_SIZE(kNIDsInOIDOrder),
220*8fb009dcSAndroid Build Coastguard Worker               sizeof(kNIDsInOIDOrder[0]), obj_cmp);
221*8fb009dcSAndroid Build Coastguard Worker   if (nid_ptr == NULL) {
222*8fb009dcSAndroid Build Coastguard Worker     return NID_undef;
223*8fb009dcSAndroid Build Coastguard Worker   }
224*8fb009dcSAndroid Build Coastguard Worker 
225*8fb009dcSAndroid Build Coastguard Worker   return get_builtin_object(*nid_ptr)->nid;
226*8fb009dcSAndroid Build Coastguard Worker }
227*8fb009dcSAndroid Build Coastguard Worker 
OBJ_cbs2nid(const CBS * cbs)228*8fb009dcSAndroid Build Coastguard Worker int OBJ_cbs2nid(const CBS *cbs) {
229*8fb009dcSAndroid Build Coastguard Worker   if (CBS_len(cbs) > INT_MAX) {
230*8fb009dcSAndroid Build Coastguard Worker     return NID_undef;
231*8fb009dcSAndroid Build Coastguard Worker   }
232*8fb009dcSAndroid Build Coastguard Worker 
233*8fb009dcSAndroid Build Coastguard Worker   ASN1_OBJECT obj;
234*8fb009dcSAndroid Build Coastguard Worker   OPENSSL_memset(&obj, 0, sizeof(obj));
235*8fb009dcSAndroid Build Coastguard Worker   obj.data = CBS_data(cbs);
236*8fb009dcSAndroid Build Coastguard Worker   obj.length = (int)CBS_len(cbs);
237*8fb009dcSAndroid Build Coastguard Worker 
238*8fb009dcSAndroid Build Coastguard Worker   return OBJ_obj2nid(&obj);
239*8fb009dcSAndroid Build Coastguard Worker }
240*8fb009dcSAndroid Build Coastguard Worker 
241*8fb009dcSAndroid Build Coastguard Worker // short_name_cmp is called to search the kNIDsInShortNameOrder array. The
242*8fb009dcSAndroid Build Coastguard Worker // |key| argument is name that we're looking for and |element| is a pointer to
243*8fb009dcSAndroid Build Coastguard Worker // an unsigned int in the array.
short_name_cmp(const void * key,const void * element)244*8fb009dcSAndroid Build Coastguard Worker static int short_name_cmp(const void *key, const void *element) {
245*8fb009dcSAndroid Build Coastguard Worker   const char *name = (const char *)key;
246*8fb009dcSAndroid Build Coastguard Worker   uint16_t nid = *((const uint16_t *)element);
247*8fb009dcSAndroid Build Coastguard Worker 
248*8fb009dcSAndroid Build Coastguard Worker   return strcmp(name, get_builtin_object(nid)->sn);
249*8fb009dcSAndroid Build Coastguard Worker }
250*8fb009dcSAndroid Build Coastguard Worker 
OBJ_sn2nid(const char * short_name)251*8fb009dcSAndroid Build Coastguard Worker int OBJ_sn2nid(const char *short_name) {
252*8fb009dcSAndroid Build Coastguard Worker   CRYPTO_MUTEX_lock_read(&global_added_lock);
253*8fb009dcSAndroid Build Coastguard Worker   if (global_added_by_short_name != NULL) {
254*8fb009dcSAndroid Build Coastguard Worker     ASN1_OBJECT *match, template;
255*8fb009dcSAndroid Build Coastguard Worker 
256*8fb009dcSAndroid Build Coastguard Worker     template.sn = short_name;
257*8fb009dcSAndroid Build Coastguard Worker     match = lh_ASN1_OBJECT_retrieve(global_added_by_short_name, &template);
258*8fb009dcSAndroid Build Coastguard Worker     if (match != NULL) {
259*8fb009dcSAndroid Build Coastguard Worker       CRYPTO_MUTEX_unlock_read(&global_added_lock);
260*8fb009dcSAndroid Build Coastguard Worker       return match->nid;
261*8fb009dcSAndroid Build Coastguard Worker     }
262*8fb009dcSAndroid Build Coastguard Worker   }
263*8fb009dcSAndroid Build Coastguard Worker   CRYPTO_MUTEX_unlock_read(&global_added_lock);
264*8fb009dcSAndroid Build Coastguard Worker 
265*8fb009dcSAndroid Build Coastguard Worker   const uint16_t *nid_ptr =
266*8fb009dcSAndroid Build Coastguard Worker       bsearch(short_name, kNIDsInShortNameOrder,
267*8fb009dcSAndroid Build Coastguard Worker               OPENSSL_ARRAY_SIZE(kNIDsInShortNameOrder),
268*8fb009dcSAndroid Build Coastguard Worker               sizeof(kNIDsInShortNameOrder[0]), short_name_cmp);
269*8fb009dcSAndroid Build Coastguard Worker   if (nid_ptr == NULL) {
270*8fb009dcSAndroid Build Coastguard Worker     return NID_undef;
271*8fb009dcSAndroid Build Coastguard Worker   }
272*8fb009dcSAndroid Build Coastguard Worker 
273*8fb009dcSAndroid Build Coastguard Worker   return get_builtin_object(*nid_ptr)->nid;
274*8fb009dcSAndroid Build Coastguard Worker }
275*8fb009dcSAndroid Build Coastguard Worker 
276*8fb009dcSAndroid Build Coastguard Worker // long_name_cmp is called to search the kNIDsInLongNameOrder array. The
277*8fb009dcSAndroid Build Coastguard Worker // |key| argument is name that we're looking for and |element| is a pointer to
278*8fb009dcSAndroid Build Coastguard Worker // an unsigned int in the array.
long_name_cmp(const void * key,const void * element)279*8fb009dcSAndroid Build Coastguard Worker static int long_name_cmp(const void *key, const void *element) {
280*8fb009dcSAndroid Build Coastguard Worker   const char *name = (const char *)key;
281*8fb009dcSAndroid Build Coastguard Worker   uint16_t nid = *((const uint16_t *)element);
282*8fb009dcSAndroid Build Coastguard Worker 
283*8fb009dcSAndroid Build Coastguard Worker   return strcmp(name, get_builtin_object(nid)->ln);
284*8fb009dcSAndroid Build Coastguard Worker }
285*8fb009dcSAndroid Build Coastguard Worker 
OBJ_ln2nid(const char * long_name)286*8fb009dcSAndroid Build Coastguard Worker int OBJ_ln2nid(const char *long_name) {
287*8fb009dcSAndroid Build Coastguard Worker   CRYPTO_MUTEX_lock_read(&global_added_lock);
288*8fb009dcSAndroid Build Coastguard Worker   if (global_added_by_long_name != NULL) {
289*8fb009dcSAndroid Build Coastguard Worker     ASN1_OBJECT *match, template;
290*8fb009dcSAndroid Build Coastguard Worker 
291*8fb009dcSAndroid Build Coastguard Worker     template.ln = long_name;
292*8fb009dcSAndroid Build Coastguard Worker     match = lh_ASN1_OBJECT_retrieve(global_added_by_long_name, &template);
293*8fb009dcSAndroid Build Coastguard Worker     if (match != NULL) {
294*8fb009dcSAndroid Build Coastguard Worker       CRYPTO_MUTEX_unlock_read(&global_added_lock);
295*8fb009dcSAndroid Build Coastguard Worker       return match->nid;
296*8fb009dcSAndroid Build Coastguard Worker     }
297*8fb009dcSAndroid Build Coastguard Worker   }
298*8fb009dcSAndroid Build Coastguard Worker   CRYPTO_MUTEX_unlock_read(&global_added_lock);
299*8fb009dcSAndroid Build Coastguard Worker 
300*8fb009dcSAndroid Build Coastguard Worker   const uint16_t *nid_ptr = bsearch(
301*8fb009dcSAndroid Build Coastguard Worker       long_name, kNIDsInLongNameOrder, OPENSSL_ARRAY_SIZE(kNIDsInLongNameOrder),
302*8fb009dcSAndroid Build Coastguard Worker       sizeof(kNIDsInLongNameOrder[0]), long_name_cmp);
303*8fb009dcSAndroid Build Coastguard Worker   if (nid_ptr == NULL) {
304*8fb009dcSAndroid Build Coastguard Worker     return NID_undef;
305*8fb009dcSAndroid Build Coastguard Worker   }
306*8fb009dcSAndroid Build Coastguard Worker 
307*8fb009dcSAndroid Build Coastguard Worker   return get_builtin_object(*nid_ptr)->nid;
308*8fb009dcSAndroid Build Coastguard Worker }
309*8fb009dcSAndroid Build Coastguard Worker 
OBJ_txt2nid(const char * s)310*8fb009dcSAndroid Build Coastguard Worker int OBJ_txt2nid(const char *s) {
311*8fb009dcSAndroid Build Coastguard Worker   ASN1_OBJECT *obj;
312*8fb009dcSAndroid Build Coastguard Worker   int nid;
313*8fb009dcSAndroid Build Coastguard Worker 
314*8fb009dcSAndroid Build Coastguard Worker   obj = OBJ_txt2obj(s, 0 /* search names */);
315*8fb009dcSAndroid Build Coastguard Worker   nid = OBJ_obj2nid(obj);
316*8fb009dcSAndroid Build Coastguard Worker   ASN1_OBJECT_free(obj);
317*8fb009dcSAndroid Build Coastguard Worker   return nid;
318*8fb009dcSAndroid Build Coastguard Worker }
319*8fb009dcSAndroid Build Coastguard Worker 
OBJ_nid2cbb(CBB * out,int nid)320*8fb009dcSAndroid Build Coastguard Worker OPENSSL_EXPORT int OBJ_nid2cbb(CBB *out, int nid) {
321*8fb009dcSAndroid Build Coastguard Worker   const ASN1_OBJECT *obj = OBJ_nid2obj(nid);
322*8fb009dcSAndroid Build Coastguard Worker   CBB oid;
323*8fb009dcSAndroid Build Coastguard Worker 
324*8fb009dcSAndroid Build Coastguard Worker   if (obj == NULL ||
325*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_asn1(out, &oid, CBS_ASN1_OBJECT) ||
326*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_bytes(&oid, obj->data, obj->length) ||
327*8fb009dcSAndroid Build Coastguard Worker       !CBB_flush(out)) {
328*8fb009dcSAndroid Build Coastguard Worker     return 0;
329*8fb009dcSAndroid Build Coastguard Worker   }
330*8fb009dcSAndroid Build Coastguard Worker 
331*8fb009dcSAndroid Build Coastguard Worker   return 1;
332*8fb009dcSAndroid Build Coastguard Worker }
333*8fb009dcSAndroid Build Coastguard Worker 
OBJ_get_undef(void)334*8fb009dcSAndroid Build Coastguard Worker const ASN1_OBJECT *OBJ_get_undef(void) {
335*8fb009dcSAndroid Build Coastguard Worker   static const ASN1_OBJECT kUndef = {
336*8fb009dcSAndroid Build Coastguard Worker       /*sn=*/SN_undef,
337*8fb009dcSAndroid Build Coastguard Worker       /*ln=*/LN_undef,
338*8fb009dcSAndroid Build Coastguard Worker       /*nid=*/NID_undef,
339*8fb009dcSAndroid Build Coastguard Worker       /*length=*/0,
340*8fb009dcSAndroid Build Coastguard Worker       /*data=*/NULL,
341*8fb009dcSAndroid Build Coastguard Worker       /*flags=*/0,
342*8fb009dcSAndroid Build Coastguard Worker   };
343*8fb009dcSAndroid Build Coastguard Worker   return &kUndef;
344*8fb009dcSAndroid Build Coastguard Worker }
345*8fb009dcSAndroid Build Coastguard Worker 
OBJ_nid2obj(int nid)346*8fb009dcSAndroid Build Coastguard Worker ASN1_OBJECT *OBJ_nid2obj(int nid) {
347*8fb009dcSAndroid Build Coastguard Worker   if (nid == NID_undef) {
348*8fb009dcSAndroid Build Coastguard Worker     return (ASN1_OBJECT *)OBJ_get_undef();
349*8fb009dcSAndroid Build Coastguard Worker   }
350*8fb009dcSAndroid Build Coastguard Worker 
351*8fb009dcSAndroid Build Coastguard Worker   if (nid > 0 && nid < NUM_NID) {
352*8fb009dcSAndroid Build Coastguard Worker     const ASN1_OBJECT *obj = get_builtin_object(nid);
353*8fb009dcSAndroid Build Coastguard Worker     if (nid != NID_undef && obj->nid == NID_undef) {
354*8fb009dcSAndroid Build Coastguard Worker       goto err;
355*8fb009dcSAndroid Build Coastguard Worker     }
356*8fb009dcSAndroid Build Coastguard Worker     return (ASN1_OBJECT *)obj;
357*8fb009dcSAndroid Build Coastguard Worker   }
358*8fb009dcSAndroid Build Coastguard Worker 
359*8fb009dcSAndroid Build Coastguard Worker   CRYPTO_MUTEX_lock_read(&global_added_lock);
360*8fb009dcSAndroid Build Coastguard Worker   if (global_added_by_nid != NULL) {
361*8fb009dcSAndroid Build Coastguard Worker     ASN1_OBJECT *match, template;
362*8fb009dcSAndroid Build Coastguard Worker 
363*8fb009dcSAndroid Build Coastguard Worker     template.nid = nid;
364*8fb009dcSAndroid Build Coastguard Worker     match = lh_ASN1_OBJECT_retrieve(global_added_by_nid, &template);
365*8fb009dcSAndroid Build Coastguard Worker     if (match != NULL) {
366*8fb009dcSAndroid Build Coastguard Worker       CRYPTO_MUTEX_unlock_read(&global_added_lock);
367*8fb009dcSAndroid Build Coastguard Worker       return match;
368*8fb009dcSAndroid Build Coastguard Worker     }
369*8fb009dcSAndroid Build Coastguard Worker   }
370*8fb009dcSAndroid Build Coastguard Worker   CRYPTO_MUTEX_unlock_read(&global_added_lock);
371*8fb009dcSAndroid Build Coastguard Worker 
372*8fb009dcSAndroid Build Coastguard Worker err:
373*8fb009dcSAndroid Build Coastguard Worker   OPENSSL_PUT_ERROR(OBJ, OBJ_R_UNKNOWN_NID);
374*8fb009dcSAndroid Build Coastguard Worker   return NULL;
375*8fb009dcSAndroid Build Coastguard Worker }
376*8fb009dcSAndroid Build Coastguard Worker 
OBJ_nid2sn(int nid)377*8fb009dcSAndroid Build Coastguard Worker const char *OBJ_nid2sn(int nid) {
378*8fb009dcSAndroid Build Coastguard Worker   const ASN1_OBJECT *obj = OBJ_nid2obj(nid);
379*8fb009dcSAndroid Build Coastguard Worker   if (obj == NULL) {
380*8fb009dcSAndroid Build Coastguard Worker     return NULL;
381*8fb009dcSAndroid Build Coastguard Worker   }
382*8fb009dcSAndroid Build Coastguard Worker 
383*8fb009dcSAndroid Build Coastguard Worker   return obj->sn;
384*8fb009dcSAndroid Build Coastguard Worker }
385*8fb009dcSAndroid Build Coastguard Worker 
OBJ_nid2ln(int nid)386*8fb009dcSAndroid Build Coastguard Worker const char *OBJ_nid2ln(int nid) {
387*8fb009dcSAndroid Build Coastguard Worker   const ASN1_OBJECT *obj = OBJ_nid2obj(nid);
388*8fb009dcSAndroid Build Coastguard Worker   if (obj == NULL) {
389*8fb009dcSAndroid Build Coastguard Worker     return NULL;
390*8fb009dcSAndroid Build Coastguard Worker   }
391*8fb009dcSAndroid Build Coastguard Worker 
392*8fb009dcSAndroid Build Coastguard Worker   return obj->ln;
393*8fb009dcSAndroid Build Coastguard Worker }
394*8fb009dcSAndroid Build Coastguard Worker 
create_object_with_text_oid(int (* get_nid)(void),const char * oid,const char * short_name,const char * long_name)395*8fb009dcSAndroid Build Coastguard Worker static ASN1_OBJECT *create_object_with_text_oid(int (*get_nid)(void),
396*8fb009dcSAndroid Build Coastguard Worker                                                 const char *oid,
397*8fb009dcSAndroid Build Coastguard Worker                                                 const char *short_name,
398*8fb009dcSAndroid Build Coastguard Worker                                                 const char *long_name) {
399*8fb009dcSAndroid Build Coastguard Worker   uint8_t *buf;
400*8fb009dcSAndroid Build Coastguard Worker   size_t len;
401*8fb009dcSAndroid Build Coastguard Worker   CBB cbb;
402*8fb009dcSAndroid Build Coastguard Worker   if (!CBB_init(&cbb, 32) ||
403*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_asn1_oid_from_text(&cbb, oid, strlen(oid)) ||
404*8fb009dcSAndroid Build Coastguard Worker       !CBB_finish(&cbb, &buf, &len)) {
405*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(OBJ, OBJ_R_INVALID_OID_STRING);
406*8fb009dcSAndroid Build Coastguard Worker     CBB_cleanup(&cbb);
407*8fb009dcSAndroid Build Coastguard Worker     return NULL;
408*8fb009dcSAndroid Build Coastguard Worker   }
409*8fb009dcSAndroid Build Coastguard Worker 
410*8fb009dcSAndroid Build Coastguard Worker   ASN1_OBJECT *ret = ASN1_OBJECT_create(get_nid ? get_nid() : NID_undef, buf,
411*8fb009dcSAndroid Build Coastguard Worker                                         len, short_name, long_name);
412*8fb009dcSAndroid Build Coastguard Worker   OPENSSL_free(buf);
413*8fb009dcSAndroid Build Coastguard Worker   return ret;
414*8fb009dcSAndroid Build Coastguard Worker }
415*8fb009dcSAndroid Build Coastguard Worker 
OBJ_txt2obj(const char * s,int dont_search_names)416*8fb009dcSAndroid Build Coastguard Worker ASN1_OBJECT *OBJ_txt2obj(const char *s, int dont_search_names) {
417*8fb009dcSAndroid Build Coastguard Worker   if (!dont_search_names) {
418*8fb009dcSAndroid Build Coastguard Worker     int nid = OBJ_sn2nid(s);
419*8fb009dcSAndroid Build Coastguard Worker     if (nid == NID_undef) {
420*8fb009dcSAndroid Build Coastguard Worker       nid = OBJ_ln2nid(s);
421*8fb009dcSAndroid Build Coastguard Worker     }
422*8fb009dcSAndroid Build Coastguard Worker 
423*8fb009dcSAndroid Build Coastguard Worker     if (nid != NID_undef) {
424*8fb009dcSAndroid Build Coastguard Worker       return OBJ_nid2obj(nid);
425*8fb009dcSAndroid Build Coastguard Worker     }
426*8fb009dcSAndroid Build Coastguard Worker   }
427*8fb009dcSAndroid Build Coastguard Worker 
428*8fb009dcSAndroid Build Coastguard Worker   return create_object_with_text_oid(NULL, s, NULL, NULL);
429*8fb009dcSAndroid Build Coastguard Worker }
430*8fb009dcSAndroid Build Coastguard Worker 
strlcpy_int(char * dst,const char * src,int dst_size)431*8fb009dcSAndroid Build Coastguard Worker static int strlcpy_int(char *dst, const char *src, int dst_size) {
432*8fb009dcSAndroid Build Coastguard Worker   size_t ret = OPENSSL_strlcpy(dst, src, dst_size < 0 ? 0 : (size_t)dst_size);
433*8fb009dcSAndroid Build Coastguard Worker   if (ret > INT_MAX) {
434*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(OBJ, ERR_R_OVERFLOW);
435*8fb009dcSAndroid Build Coastguard Worker     return -1;
436*8fb009dcSAndroid Build Coastguard Worker   }
437*8fb009dcSAndroid Build Coastguard Worker   return (int)ret;
438*8fb009dcSAndroid Build Coastguard Worker }
439*8fb009dcSAndroid Build Coastguard Worker 
OBJ_obj2txt(char * out,int out_len,const ASN1_OBJECT * obj,int always_return_oid)440*8fb009dcSAndroid Build Coastguard Worker int OBJ_obj2txt(char *out, int out_len, const ASN1_OBJECT *obj,
441*8fb009dcSAndroid Build Coastguard Worker                 int always_return_oid) {
442*8fb009dcSAndroid Build Coastguard Worker   // Python depends on the empty OID successfully encoding as the empty
443*8fb009dcSAndroid Build Coastguard Worker   // string.
444*8fb009dcSAndroid Build Coastguard Worker   if (obj == NULL || obj->length == 0) {
445*8fb009dcSAndroid Build Coastguard Worker     return strlcpy_int(out, "", out_len);
446*8fb009dcSAndroid Build Coastguard Worker   }
447*8fb009dcSAndroid Build Coastguard Worker 
448*8fb009dcSAndroid Build Coastguard Worker   if (!always_return_oid) {
449*8fb009dcSAndroid Build Coastguard Worker     int nid = OBJ_obj2nid(obj);
450*8fb009dcSAndroid Build Coastguard Worker     if (nid != NID_undef) {
451*8fb009dcSAndroid Build Coastguard Worker       const char *name = OBJ_nid2ln(nid);
452*8fb009dcSAndroid Build Coastguard Worker       if (name == NULL) {
453*8fb009dcSAndroid Build Coastguard Worker         name = OBJ_nid2sn(nid);
454*8fb009dcSAndroid Build Coastguard Worker       }
455*8fb009dcSAndroid Build Coastguard Worker       if (name != NULL) {
456*8fb009dcSAndroid Build Coastguard Worker         return strlcpy_int(out, name, out_len);
457*8fb009dcSAndroid Build Coastguard Worker       }
458*8fb009dcSAndroid Build Coastguard Worker     }
459*8fb009dcSAndroid Build Coastguard Worker   }
460*8fb009dcSAndroid Build Coastguard Worker 
461*8fb009dcSAndroid Build Coastguard Worker   CBS cbs;
462*8fb009dcSAndroid Build Coastguard Worker   CBS_init(&cbs, obj->data, obj->length);
463*8fb009dcSAndroid Build Coastguard Worker   char *txt = CBS_asn1_oid_to_text(&cbs);
464*8fb009dcSAndroid Build Coastguard Worker   if (txt == NULL) {
465*8fb009dcSAndroid Build Coastguard Worker     if (out_len > 0) {
466*8fb009dcSAndroid Build Coastguard Worker       out[0] = '\0';
467*8fb009dcSAndroid Build Coastguard Worker     }
468*8fb009dcSAndroid Build Coastguard Worker     return -1;
469*8fb009dcSAndroid Build Coastguard Worker   }
470*8fb009dcSAndroid Build Coastguard Worker 
471*8fb009dcSAndroid Build Coastguard Worker   int ret = strlcpy_int(out, txt, out_len);
472*8fb009dcSAndroid Build Coastguard Worker   OPENSSL_free(txt);
473*8fb009dcSAndroid Build Coastguard Worker   return ret;
474*8fb009dcSAndroid Build Coastguard Worker }
475*8fb009dcSAndroid Build Coastguard Worker 
hash_nid(const ASN1_OBJECT * obj)476*8fb009dcSAndroid Build Coastguard Worker static uint32_t hash_nid(const ASN1_OBJECT *obj) {
477*8fb009dcSAndroid Build Coastguard Worker   return obj->nid;
478*8fb009dcSAndroid Build Coastguard Worker }
479*8fb009dcSAndroid Build Coastguard Worker 
cmp_nid(const ASN1_OBJECT * a,const ASN1_OBJECT * b)480*8fb009dcSAndroid Build Coastguard Worker static int cmp_nid(const ASN1_OBJECT *a, const ASN1_OBJECT *b) {
481*8fb009dcSAndroid Build Coastguard Worker   return a->nid - b->nid;
482*8fb009dcSAndroid Build Coastguard Worker }
483*8fb009dcSAndroid Build Coastguard Worker 
hash_data(const ASN1_OBJECT * obj)484*8fb009dcSAndroid Build Coastguard Worker static uint32_t hash_data(const ASN1_OBJECT *obj) {
485*8fb009dcSAndroid Build Coastguard Worker   return OPENSSL_hash32(obj->data, obj->length);
486*8fb009dcSAndroid Build Coastguard Worker }
487*8fb009dcSAndroid Build Coastguard Worker 
hash_short_name(const ASN1_OBJECT * obj)488*8fb009dcSAndroid Build Coastguard Worker static uint32_t hash_short_name(const ASN1_OBJECT *obj) {
489*8fb009dcSAndroid Build Coastguard Worker   return OPENSSL_strhash(obj->sn);
490*8fb009dcSAndroid Build Coastguard Worker }
491*8fb009dcSAndroid Build Coastguard Worker 
cmp_short_name(const ASN1_OBJECT * a,const ASN1_OBJECT * b)492*8fb009dcSAndroid Build Coastguard Worker static int cmp_short_name(const ASN1_OBJECT *a, const ASN1_OBJECT *b) {
493*8fb009dcSAndroid Build Coastguard Worker   return strcmp(a->sn, b->sn);
494*8fb009dcSAndroid Build Coastguard Worker }
495*8fb009dcSAndroid Build Coastguard Worker 
hash_long_name(const ASN1_OBJECT * obj)496*8fb009dcSAndroid Build Coastguard Worker static uint32_t hash_long_name(const ASN1_OBJECT *obj) {
497*8fb009dcSAndroid Build Coastguard Worker   return OPENSSL_strhash(obj->ln);
498*8fb009dcSAndroid Build Coastguard Worker }
499*8fb009dcSAndroid Build Coastguard Worker 
cmp_long_name(const ASN1_OBJECT * a,const ASN1_OBJECT * b)500*8fb009dcSAndroid Build Coastguard Worker static int cmp_long_name(const ASN1_OBJECT *a, const ASN1_OBJECT *b) {
501*8fb009dcSAndroid Build Coastguard Worker   return strcmp(a->ln, b->ln);
502*8fb009dcSAndroid Build Coastguard Worker }
503*8fb009dcSAndroid Build Coastguard Worker 
504*8fb009dcSAndroid Build Coastguard Worker // obj_add_object inserts |obj| into the various global hashes for run-time
505*8fb009dcSAndroid Build Coastguard Worker // added objects. It returns one on success or zero otherwise.
obj_add_object(ASN1_OBJECT * obj)506*8fb009dcSAndroid Build Coastguard Worker static int obj_add_object(ASN1_OBJECT *obj) {
507*8fb009dcSAndroid Build Coastguard Worker   obj->flags &= ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
508*8fb009dcSAndroid Build Coastguard Worker                   ASN1_OBJECT_FLAG_DYNAMIC_DATA);
509*8fb009dcSAndroid Build Coastguard Worker 
510*8fb009dcSAndroid Build Coastguard Worker   CRYPTO_MUTEX_lock_write(&global_added_lock);
511*8fb009dcSAndroid Build Coastguard Worker   if (global_added_by_nid == NULL) {
512*8fb009dcSAndroid Build Coastguard Worker     global_added_by_nid = lh_ASN1_OBJECT_new(hash_nid, cmp_nid);
513*8fb009dcSAndroid Build Coastguard Worker   }
514*8fb009dcSAndroid Build Coastguard Worker   if (global_added_by_data == NULL) {
515*8fb009dcSAndroid Build Coastguard Worker     global_added_by_data = lh_ASN1_OBJECT_new(hash_data, OBJ_cmp);
516*8fb009dcSAndroid Build Coastguard Worker   }
517*8fb009dcSAndroid Build Coastguard Worker   if (global_added_by_short_name == NULL) {
518*8fb009dcSAndroid Build Coastguard Worker     global_added_by_short_name =
519*8fb009dcSAndroid Build Coastguard Worker         lh_ASN1_OBJECT_new(hash_short_name, cmp_short_name);
520*8fb009dcSAndroid Build Coastguard Worker   }
521*8fb009dcSAndroid Build Coastguard Worker   if (global_added_by_long_name == NULL) {
522*8fb009dcSAndroid Build Coastguard Worker     global_added_by_long_name = lh_ASN1_OBJECT_new(hash_long_name, cmp_long_name);
523*8fb009dcSAndroid Build Coastguard Worker   }
524*8fb009dcSAndroid Build Coastguard Worker 
525*8fb009dcSAndroid Build Coastguard Worker   int ok = 0;
526*8fb009dcSAndroid Build Coastguard Worker   if (global_added_by_nid == NULL ||
527*8fb009dcSAndroid Build Coastguard Worker       global_added_by_data == NULL ||
528*8fb009dcSAndroid Build Coastguard Worker       global_added_by_short_name == NULL ||
529*8fb009dcSAndroid Build Coastguard Worker       global_added_by_long_name == NULL) {
530*8fb009dcSAndroid Build Coastguard Worker     goto err;
531*8fb009dcSAndroid Build Coastguard Worker   }
532*8fb009dcSAndroid Build Coastguard Worker 
533*8fb009dcSAndroid Build Coastguard Worker   // We don't pay attention to |old_object| (which contains any previous object
534*8fb009dcSAndroid Build Coastguard Worker   // that was evicted from the hashes) because we don't have a reference count
535*8fb009dcSAndroid Build Coastguard Worker   // on ASN1_OBJECT values. Also, we should never have duplicates nids and so
536*8fb009dcSAndroid Build Coastguard Worker   // should always have objects in |global_added_by_nid|.
537*8fb009dcSAndroid Build Coastguard Worker   ASN1_OBJECT *old_object;
538*8fb009dcSAndroid Build Coastguard Worker   ok = lh_ASN1_OBJECT_insert(global_added_by_nid, &old_object, obj);
539*8fb009dcSAndroid Build Coastguard Worker   if (obj->length != 0 && obj->data != NULL) {
540*8fb009dcSAndroid Build Coastguard Worker     ok &= lh_ASN1_OBJECT_insert(global_added_by_data, &old_object, obj);
541*8fb009dcSAndroid Build Coastguard Worker   }
542*8fb009dcSAndroid Build Coastguard Worker   if (obj->sn != NULL) {
543*8fb009dcSAndroid Build Coastguard Worker     ok &= lh_ASN1_OBJECT_insert(global_added_by_short_name, &old_object, obj);
544*8fb009dcSAndroid Build Coastguard Worker   }
545*8fb009dcSAndroid Build Coastguard Worker   if (obj->ln != NULL) {
546*8fb009dcSAndroid Build Coastguard Worker     ok &= lh_ASN1_OBJECT_insert(global_added_by_long_name, &old_object, obj);
547*8fb009dcSAndroid Build Coastguard Worker   }
548*8fb009dcSAndroid Build Coastguard Worker 
549*8fb009dcSAndroid Build Coastguard Worker err:
550*8fb009dcSAndroid Build Coastguard Worker   CRYPTO_MUTEX_unlock_write(&global_added_lock);
551*8fb009dcSAndroid Build Coastguard Worker   return ok;
552*8fb009dcSAndroid Build Coastguard Worker }
553*8fb009dcSAndroid Build Coastguard Worker 
OBJ_create(const char * oid,const char * short_name,const char * long_name)554*8fb009dcSAndroid Build Coastguard Worker int OBJ_create(const char *oid, const char *short_name, const char *long_name) {
555*8fb009dcSAndroid Build Coastguard Worker   ASN1_OBJECT *op =
556*8fb009dcSAndroid Build Coastguard Worker       create_object_with_text_oid(obj_next_nid, oid, short_name, long_name);
557*8fb009dcSAndroid Build Coastguard Worker   if (op == NULL ||
558*8fb009dcSAndroid Build Coastguard Worker       !obj_add_object(op)) {
559*8fb009dcSAndroid Build Coastguard Worker     return NID_undef;
560*8fb009dcSAndroid Build Coastguard Worker   }
561*8fb009dcSAndroid Build Coastguard Worker   return op->nid;
562*8fb009dcSAndroid Build Coastguard Worker }
563*8fb009dcSAndroid Build Coastguard Worker 
OBJ_cleanup(void)564*8fb009dcSAndroid Build Coastguard Worker void OBJ_cleanup(void) {}
565