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