xref: /freebsd/crypto/openssl/crypto/objects/obj_dat.c (revision f25b8c9fb4f58cf61adb47d7570abe7caa6d385d)
1 /*
2  * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #include <stdio.h>
11 #include "crypto/ctype.h"
12 #include <limits.h>
13 #include "internal/cryptlib.h"
14 #include "internal/thread_once.h"
15 #include "internal/tsan_assist.h"
16 #include <openssl/lhash.h>
17 #include <openssl/asn1.h>
18 #include "crypto/objects.h"
19 #include <openssl/bn.h>
20 #include "crypto/asn1.h"
21 #include "obj_local.h"
22 
23 /* obj_dat.h is generated from objects.txt and obj_mac.{num,h} by obj_dat.pl */
24 #include "obj_dat.h"
25 
26 DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
27 DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
28 DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
29 
30 #define ADDED_DATA 0
31 #define ADDED_SNAME 1
32 #define ADDED_LNAME 2
33 #define ADDED_NID 3
34 
35 struct added_obj_st {
36     int type;
37     ASN1_OBJECT *obj;
38 };
39 
40 static LHASH_OF(ADDED_OBJ) *added = NULL;
41 static CRYPTO_RWLOCK *ossl_obj_lock = NULL;
42 #ifdef TSAN_REQUIRES_LOCKING
43 static CRYPTO_RWLOCK *ossl_obj_nid_lock = NULL;
44 #endif
45 
46 static CRYPTO_ONCE ossl_obj_lock_init = CRYPTO_ONCE_STATIC_INIT;
47 
48 static ossl_inline void objs_free_locks(void)
49 {
50     CRYPTO_THREAD_lock_free(ossl_obj_lock);
51     ossl_obj_lock = NULL;
52 #ifdef TSAN_REQUIRES_LOCKING
53     CRYPTO_THREAD_lock_free(ossl_obj_nid_lock);
54     ossl_obj_nid_lock = NULL;
55 #endif
56 }
57 
58 DEFINE_RUN_ONCE_STATIC(obj_lock_initialise)
59 {
60     ossl_obj_lock = CRYPTO_THREAD_lock_new();
61     if (ossl_obj_lock == NULL)
62         return 0;
63 
64 #ifdef TSAN_REQUIRES_LOCKING
65     ossl_obj_nid_lock = CRYPTO_THREAD_lock_new();
66     if (ossl_obj_nid_lock == NULL) {
67         objs_free_locks();
68         return 0;
69     }
70 #endif
71     return 1;
72 }
73 
74 static ossl_inline int ossl_init_added_lock(void)
75 {
76 #ifndef OPENSSL_NO_AUTOLOAD_CONFIG
77     /* Make sure we've loaded config before checking for any "added" objects */
78     OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
79 #endif
80     return RUN_ONCE(&ossl_obj_lock_init, obj_lock_initialise);
81 }
82 
83 static ossl_inline int ossl_obj_write_lock(int lock)
84 {
85     if (!lock)
86         return 1;
87     if (!ossl_init_added_lock())
88         return 0;
89     return CRYPTO_THREAD_write_lock(ossl_obj_lock);
90 }
91 
92 static ossl_inline int ossl_obj_read_lock(int lock)
93 {
94     if (!lock)
95         return 1;
96     if (!ossl_init_added_lock())
97         return 0;
98     return CRYPTO_THREAD_read_lock(ossl_obj_lock);
99 }
100 
101 static ossl_inline void ossl_obj_unlock(int lock)
102 {
103     if (lock)
104         CRYPTO_THREAD_unlock(ossl_obj_lock);
105 }
106 
107 static int sn_cmp(const ASN1_OBJECT *const *a, const unsigned int *b)
108 {
109     return strcmp((*a)->sn, nid_objs[*b].sn);
110 }
111 
112 IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
113 
114 static int ln_cmp(const ASN1_OBJECT *const *a, const unsigned int *b)
115 {
116     return strcmp((*a)->ln, nid_objs[*b].ln);
117 }
118 
119 IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
120 
121 static unsigned long added_obj_hash(const ADDED_OBJ *ca)
122 {
123     const ASN1_OBJECT *a;
124     int i;
125     unsigned long ret = 0;
126     unsigned char *p;
127 
128     a = ca->obj;
129     switch (ca->type) {
130     case ADDED_DATA:
131         ret = (unsigned long)a->length << 20UL;
132         p = (unsigned char *)a->data;
133         for (i = 0; i < a->length; i++)
134             ret ^= p[i] << ((i * 3) % 24);
135         break;
136     case ADDED_SNAME:
137         ret = OPENSSL_LH_strhash(a->sn);
138         break;
139     case ADDED_LNAME:
140         ret = OPENSSL_LH_strhash(a->ln);
141         break;
142     case ADDED_NID:
143         ret = a->nid;
144         break;
145     default:
146         /* abort(); */
147         return 0;
148     }
149     ret &= 0x3fffffffL;
150     ret |= ((unsigned long)ca->type) << 30L;
151     return ret;
152 }
153 
154 static int added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb)
155 {
156     ASN1_OBJECT *a, *b;
157     int i;
158 
159     i = ca->type - cb->type;
160     if (i)
161         return i;
162     a = ca->obj;
163     b = cb->obj;
164     switch (ca->type) {
165     case ADDED_DATA:
166         i = (a->length - b->length);
167         if (i)
168             return i;
169         return memcmp(a->data, b->data, (size_t)a->length);
170     case ADDED_SNAME:
171         if (a->sn == NULL)
172             return -1;
173         else if (b->sn == NULL)
174             return 1;
175         else
176             return strcmp(a->sn, b->sn);
177     case ADDED_LNAME:
178         if (a->ln == NULL)
179             return -1;
180         else if (b->ln == NULL)
181             return 1;
182         else
183             return strcmp(a->ln, b->ln);
184     case ADDED_NID:
185         return a->nid - b->nid;
186     default:
187         /* abort(); */
188         return 0;
189     }
190 }
191 
192 static void cleanup1_doall(ADDED_OBJ *a)
193 {
194     a->obj->nid = 0;
195     a->obj->flags |= ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | ASN1_OBJECT_FLAG_DYNAMIC_DATA;
196 }
197 
198 static void cleanup2_doall(ADDED_OBJ *a)
199 {
200     a->obj->nid++;
201 }
202 
203 static void cleanup3_doall(ADDED_OBJ *a)
204 {
205     if (--a->obj->nid == 0)
206         ASN1_OBJECT_free(a->obj);
207     OPENSSL_free(a);
208 }
209 
210 void ossl_obj_cleanup_int(void)
211 {
212     if (added != NULL) {
213         lh_ADDED_OBJ_set_down_load(added, 0);
214         lh_ADDED_OBJ_doall(added, cleanup1_doall); /* zero counters */
215         lh_ADDED_OBJ_doall(added, cleanup2_doall); /* set counters */
216         lh_ADDED_OBJ_doall(added, cleanup3_doall); /* free objects */
217         lh_ADDED_OBJ_free(added);
218         added = NULL;
219     }
220     objs_free_locks();
221 }
222 
223 /*
224  * Requires that the ossl_obj_lock be held
225  * if TSAN_REQUIRES_LOCKING defined
226  */
227 static int obj_new_nid_unlocked(int num)
228 {
229     static TSAN_QUALIFIER int new_nid = NUM_NID;
230 #ifdef TSAN_REQUIRES_LOCKING
231     int i;
232 
233     i = new_nid;
234     new_nid += num;
235 
236     return i;
237 #else
238     return tsan_add(&new_nid, num);
239 #endif
240 }
241 
242 int OBJ_new_nid(int num)
243 {
244 #ifdef TSAN_REQUIRES_LOCKING
245     int i;
246 
247     if (!ossl_obj_write_lock(1)) {
248         ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
249         return NID_undef;
250     }
251 
252     i = obj_new_nid_unlocked(num);
253 
254     ossl_obj_unlock(1);
255 
256     return i;
257 #else
258     return obj_new_nid_unlocked(num);
259 #endif
260 }
261 
262 static int ossl_obj_add_object(const ASN1_OBJECT *obj, int lock)
263 {
264     ASN1_OBJECT *o = NULL;
265     ADDED_OBJ *ao[4] = { NULL, NULL, NULL, NULL }, *aop[4];
266     int i;
267 
268     if ((o = OBJ_dup(obj)) == NULL)
269         return NID_undef;
270     if ((ao[ADDED_NID] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL
271         || (o->length != 0
272             && obj->data != NULL
273             && (ao[ADDED_DATA] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL)
274         || (o->sn != NULL
275             && (ao[ADDED_SNAME] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL)
276         || (o->ln != NULL
277             && (ao[ADDED_LNAME] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL))
278         goto err2;
279 
280     if (!ossl_obj_write_lock(lock)) {
281         ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
282         goto err2;
283     }
284     if (added == NULL) {
285         added = lh_ADDED_OBJ_new(added_obj_hash, added_obj_cmp);
286         if (added == NULL) {
287             ERR_raise(ERR_LIB_OBJ, ERR_R_CRYPTO_LIB);
288             goto err;
289         }
290     }
291 
292     for (i = ADDED_DATA; i <= ADDED_NID; i++) {
293         if (ao[i] != NULL) {
294             ao[i]->type = i;
295             ao[i]->obj = o;
296             aop[i] = lh_ADDED_OBJ_retrieve(added, ao[i]);
297             if (aop[i] != NULL)
298                 aop[i]->type = -1;
299             (void)lh_ADDED_OBJ_insert(added, ao[i]);
300             if (lh_ADDED_OBJ_error(added)) {
301                 if (aop[i] != NULL)
302                     aop[i]->type = i;
303                 while (i-- > ADDED_DATA) {
304                     lh_ADDED_OBJ_delete(added, ao[i]);
305                     if (aop[i] != NULL)
306                         aop[i]->type = i;
307                 }
308                 ERR_raise(ERR_LIB_OBJ, ERR_R_CRYPTO_LIB);
309                 goto err;
310             }
311         }
312     }
313     o->flags &= ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | ASN1_OBJECT_FLAG_DYNAMIC_DATA);
314 
315     ossl_obj_unlock(lock);
316     return o->nid;
317 
318 err:
319     ossl_obj_unlock(lock);
320 err2:
321     for (i = ADDED_DATA; i <= ADDED_NID; i++)
322         OPENSSL_free(ao[i]);
323     ASN1_OBJECT_free(o);
324     return NID_undef;
325 }
326 
327 ASN1_OBJECT *OBJ_nid2obj(int n)
328 {
329     ADDED_OBJ ad, *adp = NULL;
330     ASN1_OBJECT ob;
331 
332     if (n == NID_undef
333         || (n > 0 && n < NUM_NID && nid_objs[n].nid != NID_undef))
334         return (ASN1_OBJECT *)&(nid_objs[n]);
335 
336     ad.type = ADDED_NID;
337     ad.obj = &ob;
338     ob.nid = n;
339     if (!ossl_obj_read_lock(1)) {
340         ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_READ_LOCK);
341         return NULL;
342     }
343     if (added != NULL)
344         adp = lh_ADDED_OBJ_retrieve(added, &ad);
345     ossl_obj_unlock(1);
346     if (adp != NULL)
347         return adp->obj;
348 
349     ERR_raise(ERR_LIB_OBJ, OBJ_R_UNKNOWN_NID);
350     return NULL;
351 }
352 
353 const char *OBJ_nid2sn(int n)
354 {
355     ASN1_OBJECT *ob = OBJ_nid2obj(n);
356 
357     return ob == NULL ? NULL : ob->sn;
358 }
359 
360 const char *OBJ_nid2ln(int n)
361 {
362     ASN1_OBJECT *ob = OBJ_nid2obj(n);
363 
364     return ob == NULL ? NULL : ob->ln;
365 }
366 
367 static int obj_cmp(const ASN1_OBJECT *const *ap, const unsigned int *bp)
368 {
369     int j;
370     const ASN1_OBJECT *a = *ap;
371     const ASN1_OBJECT *b = &nid_objs[*bp];
372 
373     j = (a->length - b->length);
374     if (j)
375         return j;
376     if (a->length == 0)
377         return 0;
378     return memcmp(a->data, b->data, a->length);
379 }
380 
381 IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
382 
383 static int ossl_obj_obj2nid(const ASN1_OBJECT *a, const int lock)
384 {
385     int nid = NID_undef;
386     const unsigned int *op;
387     ADDED_OBJ ad, *adp;
388 
389     if (a == NULL)
390         return NID_undef;
391     if (a->nid != NID_undef)
392         return a->nid;
393     if (a->length == 0)
394         return NID_undef;
395 
396     op = OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ);
397     if (op != NULL)
398         return nid_objs[*op].nid;
399     if (!ossl_obj_read_lock(lock)) {
400         ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_READ_LOCK);
401         return NID_undef;
402     }
403     if (added != NULL) {
404         ad.type = ADDED_DATA;
405         ad.obj = (ASN1_OBJECT *)a; /* casting away const is harmless here */
406         adp = lh_ADDED_OBJ_retrieve(added, &ad);
407         if (adp != NULL)
408             nid = adp->obj->nid;
409     }
410     ossl_obj_unlock(lock);
411     return nid;
412 }
413 
414 /*
415  * Convert an object name into an ASN1_OBJECT if "noname" is not set then
416  * search for short and long names first. This will convert the "dotted" form
417  * into an object: unlike OBJ_txt2nid it can be used with any objects, not
418  * just registered ones.
419  */
420 ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name)
421 {
422     int nid = NID_undef;
423     ASN1_OBJECT *op = NULL;
424     unsigned char *buf;
425     unsigned char *p;
426     const unsigned char *cp;
427     int i, j;
428 
429     if (!no_name) {
430         if ((nid = OBJ_sn2nid(s)) != NID_undef
431             || (nid = OBJ_ln2nid(s)) != NID_undef) {
432             return OBJ_nid2obj(nid);
433         }
434         if (!ossl_isdigit(*s)) {
435             ERR_raise(ERR_LIB_OBJ, OBJ_R_UNKNOWN_OBJECT_NAME);
436             return NULL;
437         }
438     }
439 
440     /* Work out size of content octets */
441     i = a2d_ASN1_OBJECT(NULL, 0, s, -1);
442     if (i <= 0)
443         return NULL;
444 
445     /* Work out total size */
446     j = ASN1_object_size(0, i, V_ASN1_OBJECT);
447     if (j < 0)
448         return NULL;
449 
450     if ((buf = OPENSSL_malloc(j)) == NULL)
451         return NULL;
452 
453     p = buf;
454     /* Write out tag+length */
455     ASN1_put_object(&p, 0, i, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
456     /* Write out contents */
457     a2d_ASN1_OBJECT(p, i, s, -1);
458 
459     cp = buf;
460     op = d2i_ASN1_OBJECT(NULL, &cp, j);
461     OPENSSL_free(buf);
462     return op;
463 }
464 
465 int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
466 {
467     int i, n = 0, len, nid, first, use_bn;
468     BIGNUM *bl;
469     unsigned long l;
470     const unsigned char *p;
471     char tbuf[DECIMAL_SIZE(i) + DECIMAL_SIZE(l) + 2];
472     const char *s;
473 
474     /* Ensure that, at every state, |buf| is NUL-terminated. */
475     if (buf != NULL && buf_len > 0)
476         buf[0] = '\0';
477 
478     if (a == NULL || a->data == NULL)
479         return 0;
480 
481     if (!no_name && (nid = OBJ_obj2nid(a)) != NID_undef) {
482         s = OBJ_nid2ln(nid);
483         if (s == NULL)
484             s = OBJ_nid2sn(nid);
485         if (s != NULL) {
486             if (buf != NULL)
487                 OPENSSL_strlcpy(buf, s, buf_len);
488             return (int)strlen(s);
489         }
490     }
491 
492     len = a->length;
493     p = a->data;
494 
495     first = 1;
496     bl = NULL;
497 
498     /*
499      * RFC 2578 (STD 58) says this about OBJECT IDENTIFIERs:
500      *
501      * > 3.5. OBJECT IDENTIFIER values
502      * >
503      * > An OBJECT IDENTIFIER value is an ordered list of non-negative
504      * > numbers. For the SMIv2, each number in the list is referred to as a
505      * > sub-identifier, there are at most 128 sub-identifiers in a value,
506      * > and each sub-identifier has a maximum value of 2^32-1 (4294967295
507      * > decimal).
508      *
509      * So a legitimate OID according to this RFC is at most (32 * 128 / 7),
510      * i.e. 586 bytes long.
511      *
512      * Ref: https://datatracker.ietf.org/doc/html/rfc2578#section-3.5
513      */
514     if (len > 586)
515         goto err;
516 
517     while (len > 0) {
518         l = 0;
519         use_bn = 0;
520         for (;;) {
521             unsigned char c = *p++;
522 
523             len--;
524             if (len == 0 && (c & 0x80) != 0)
525                 goto err;
526             if (use_bn) {
527                 if (!BN_add_word(bl, c & 0x7f))
528                     goto err;
529             } else {
530                 l |= c & 0x7f;
531             }
532             if ((c & 0x80) == 0)
533                 break;
534             if (!use_bn && l > (ULONG_MAX >> 7L)) {
535                 if (bl == NULL && (bl = BN_new()) == NULL)
536                     goto err;
537                 if (!BN_set_word(bl, l))
538                     goto err;
539                 use_bn = 1;
540             }
541             if (use_bn) {
542                 if (!BN_lshift(bl, bl, 7))
543                     goto err;
544             } else {
545                 l <<= 7L;
546             }
547         }
548 
549         if (first) {
550             first = 0;
551             if (l >= 80) {
552                 i = 2;
553                 if (use_bn) {
554                     if (!BN_sub_word(bl, 80))
555                         goto err;
556                 } else {
557                     l -= 80;
558                 }
559             } else {
560                 i = (int)(l / 40);
561                 l -= (long)(i * 40);
562             }
563             if (buf != NULL && buf_len > 1) {
564                 *buf++ = i + '0';
565                 *buf = '\0';
566                 buf_len--;
567             }
568             n++;
569         }
570 
571         if (use_bn) {
572             char *bndec;
573             bndec = BN_bn2dec(bl);
574             if (!bndec)
575                 goto err;
576             i = strlen(bndec);
577             if (buf != NULL) {
578                 if (buf_len > 1) {
579                     *buf++ = '.';
580                     *buf = '\0';
581                     buf_len--;
582                 }
583                 OPENSSL_strlcpy(buf, bndec, buf_len);
584                 if (i > buf_len) {
585                     buf += buf_len;
586                     buf_len = 0;
587                 } else {
588                     buf += i;
589                     buf_len -= i;
590                 }
591             }
592             n++;
593             n += i;
594             OPENSSL_free(bndec);
595         } else {
596             BIO_snprintf(tbuf, sizeof(tbuf), ".%lu", l);
597             i = strlen(tbuf);
598             if (buf && buf_len > 0) {
599                 OPENSSL_strlcpy(buf, tbuf, buf_len);
600                 if (i > buf_len) {
601                     buf += buf_len;
602                     buf_len = 0;
603                 } else {
604                     buf += i;
605                     buf_len -= i;
606                 }
607             }
608             n += i;
609             l = 0;
610         }
611     }
612 
613     BN_free(bl);
614     return n;
615 
616 err:
617     BN_free(bl);
618     return -1;
619 }
620 
621 int OBJ_txt2nid(const char *s)
622 {
623     ASN1_OBJECT *obj = OBJ_txt2obj(s, 0);
624     int nid = NID_undef;
625 
626     if (obj != NULL) {
627         nid = OBJ_obj2nid(obj);
628         ASN1_OBJECT_free(obj);
629     }
630     return nid;
631 }
632 
633 int OBJ_ln2nid(const char *s)
634 {
635     ASN1_OBJECT o;
636     const ASN1_OBJECT *oo = &o;
637     ADDED_OBJ ad, *adp;
638     const unsigned int *op;
639     int nid = NID_undef;
640 
641     o.ln = s;
642     op = OBJ_bsearch_ln(&oo, ln_objs, NUM_LN);
643     if (op != NULL)
644         return nid_objs[*op].nid;
645     if (!ossl_obj_read_lock(1)) {
646         ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_READ_LOCK);
647         return NID_undef;
648     }
649     if (added != NULL) {
650         ad.type = ADDED_LNAME;
651         ad.obj = &o;
652         adp = lh_ADDED_OBJ_retrieve(added, &ad);
653         if (adp != NULL)
654             nid = adp->obj->nid;
655     }
656     ossl_obj_unlock(1);
657     return nid;
658 }
659 
660 int OBJ_sn2nid(const char *s)
661 {
662     ASN1_OBJECT o;
663     const ASN1_OBJECT *oo = &o;
664     ADDED_OBJ ad, *adp;
665     const unsigned int *op;
666     int nid = NID_undef;
667 
668     o.sn = s;
669     op = OBJ_bsearch_sn(&oo, sn_objs, NUM_SN);
670     if (op != NULL)
671         return nid_objs[*op].nid;
672     if (!ossl_obj_read_lock(1)) {
673         ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_READ_LOCK);
674         return NID_undef;
675     }
676     if (added != NULL) {
677         ad.type = ADDED_SNAME;
678         ad.obj = &o;
679         adp = lh_ADDED_OBJ_retrieve(added, &ad);
680         if (adp != NULL)
681             nid = adp->obj->nid;
682     }
683     ossl_obj_unlock(1);
684     return nid;
685 }
686 
687 const void *OBJ_bsearch_(const void *key, const void *base, int num, int size,
688     int (*cmp)(const void *, const void *))
689 {
690     return OBJ_bsearch_ex_(key, base, num, size, cmp, 0);
691 }
692 
693 const void *OBJ_bsearch_ex_(const void *key, const void *base, int num,
694     int size,
695     int (*cmp)(const void *, const void *),
696     int flags)
697 {
698     const char *p = ossl_bsearch(key, base, num, size, cmp, flags);
699 
700 #ifdef CHARSET_EBCDIC
701     /*
702      * THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and I
703      * don't have perl (yet), we revert to a *LINEAR* search when the object
704      * wasn't found in the binary search.
705      */
706     if (p == NULL) {
707         const char *base_ = base;
708         int l, h, i = 0, c = 0;
709         char *p1;
710 
711         for (i = 0; i < num; ++i) {
712             p1 = &(base_[i * size]);
713             c = (*cmp)(key, p1);
714             if (c == 0
715                 || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)))
716                 return p1;
717         }
718     }
719 #endif
720     return p;
721 }
722 
723 /*
724  * Parse a BIO sink to create some extra oid's objects.
725  * Line format:<OID:isdigit or '.']><isspace><SN><isspace><LN>
726  */
727 int OBJ_create_objects(BIO *in)
728 {
729     char buf[512];
730     int i, num = 0;
731     char *o, *s, *l = NULL;
732 
733     for (;;) {
734         s = o = NULL;
735         i = BIO_gets(in, buf, 512);
736         if (i <= 0)
737             return num;
738         buf[i - 1] = '\0';
739         if (!ossl_isalnum(buf[0]))
740             return num;
741         o = s = buf;
742         while (ossl_isdigit(*s) || *s == '.')
743             s++;
744         if (*s != '\0') {
745             *(s++) = '\0';
746             while (ossl_isspace(*s))
747                 s++;
748             if (*s == '\0') {
749                 s = NULL;
750             } else {
751                 l = s;
752                 while (*l != '\0' && !ossl_isspace(*l))
753                     l++;
754                 if (*l != '\0') {
755                     *(l++) = '\0';
756                     while (ossl_isspace(*l))
757                         l++;
758                     if (*l == '\0') {
759                         l = NULL;
760                     }
761                 } else {
762                     l = NULL;
763                 }
764             }
765         } else {
766             s = NULL;
767         }
768         if (*o == '\0')
769             return num;
770         if (!OBJ_create(o, s, l))
771             return num;
772         num++;
773     }
774 }
775 
776 int OBJ_create(const char *oid, const char *sn, const char *ln)
777 {
778     ASN1_OBJECT *tmpoid = NULL;
779     int ok = 0;
780 
781     /* With no arguments at all, nothing can be done */
782     if (oid == NULL && sn == NULL && ln == NULL) {
783         ERR_raise(ERR_LIB_OBJ, ERR_R_PASSED_INVALID_ARGUMENT);
784         return 0;
785     }
786 
787     /* Check to see if short or long name already present */
788     if ((sn != NULL && OBJ_sn2nid(sn) != NID_undef)
789         || (ln != NULL && OBJ_ln2nid(ln) != NID_undef)) {
790         ERR_raise(ERR_LIB_OBJ, OBJ_R_OID_EXISTS);
791         return 0;
792     }
793 
794     if (oid != NULL) {
795         /* Convert numerical OID string to an ASN1_OBJECT structure */
796         tmpoid = OBJ_txt2obj(oid, 1);
797         if (tmpoid == NULL)
798             return 0;
799     } else {
800         /* Create a no-OID ASN1_OBJECT */
801         tmpoid = ASN1_OBJECT_new();
802         if (tmpoid == NULL) {
803             ERR_raise(ERR_LIB_OBJ, ERR_R_ASN1_LIB);
804             return 0;
805         }
806     }
807 
808     if (!ossl_obj_write_lock(1)) {
809         ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
810         ASN1_OBJECT_free(tmpoid);
811         return 0;
812     }
813 
814     /* If NID is not NID_undef then object already exists */
815     if (oid != NULL
816         && ossl_obj_obj2nid(tmpoid, 0) != NID_undef) {
817         ERR_raise(ERR_LIB_OBJ, OBJ_R_OID_EXISTS);
818         goto err;
819     }
820 
821     tmpoid->nid = obj_new_nid_unlocked(1);
822 
823     if (tmpoid->nid == NID_undef)
824         goto err;
825 
826     tmpoid->sn = (char *)sn;
827     tmpoid->ln = (char *)ln;
828 
829     ok = ossl_obj_add_object(tmpoid, 0);
830 
831     tmpoid->sn = NULL;
832     tmpoid->ln = NULL;
833 
834 err:
835     ossl_obj_unlock(1);
836     ASN1_OBJECT_free(tmpoid);
837     return ok;
838 }
839 
840 size_t OBJ_length(const ASN1_OBJECT *obj)
841 {
842     if (obj == NULL)
843         return 0;
844     return obj->length;
845 }
846 
847 const unsigned char *OBJ_get0_data(const ASN1_OBJECT *obj)
848 {
849     if (obj == NULL)
850         return NULL;
851     return obj->data;
852 }
853 
854 int OBJ_add_object(const ASN1_OBJECT *obj)
855 {
856     return ossl_obj_add_object(obj, 1);
857 }
858 
859 int OBJ_obj2nid(const ASN1_OBJECT *a)
860 {
861     return ossl_obj_obj2nid(a, 1);
862 }
863