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