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