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