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