1 /* 2 * Copyright 1995-2018 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 "internal/ctype.h" 12 #include <limits.h> 13 #include "internal/cryptlib.h" 14 #include <openssl/lhash.h> 15 #include <openssl/asn1.h> 16 #include "internal/objects.h" 17 #include <openssl/bn.h> 18 #include "internal/asn1_int.h" 19 #include "obj_lcl.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 return NULL; 233 else { 234 ad.type = ADDED_NID; 235 ad.obj = &ob; 236 ob.nid = n; 237 adp = lh_ADDED_OBJ_retrieve(added, &ad); 238 if (adp != NULL) 239 return adp->obj; 240 else { 241 OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID); 242 return NULL; 243 } 244 } 245 } 246 247 const char *OBJ_nid2sn(int n) 248 { 249 ADDED_OBJ ad, *adp; 250 ASN1_OBJECT ob; 251 252 if ((n >= 0) && (n < NUM_NID)) { 253 if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { 254 OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID); 255 return NULL; 256 } 257 return nid_objs[n].sn; 258 } else if (added == NULL) 259 return NULL; 260 else { 261 ad.type = ADDED_NID; 262 ad.obj = &ob; 263 ob.nid = n; 264 adp = lh_ADDED_OBJ_retrieve(added, &ad); 265 if (adp != NULL) 266 return adp->obj->sn; 267 else { 268 OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID); 269 return NULL; 270 } 271 } 272 } 273 274 const char *OBJ_nid2ln(int n) 275 { 276 ADDED_OBJ ad, *adp; 277 ASN1_OBJECT ob; 278 279 if ((n >= 0) && (n < NUM_NID)) { 280 if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { 281 OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID); 282 return NULL; 283 } 284 return nid_objs[n].ln; 285 } else if (added == NULL) 286 return NULL; 287 else { 288 ad.type = ADDED_NID; 289 ad.obj = &ob; 290 ob.nid = n; 291 adp = lh_ADDED_OBJ_retrieve(added, &ad); 292 if (adp != NULL) 293 return adp->obj->ln; 294 else { 295 OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID); 296 return NULL; 297 } 298 } 299 } 300 301 static int obj_cmp(const ASN1_OBJECT *const *ap, const unsigned int *bp) 302 { 303 int j; 304 const ASN1_OBJECT *a = *ap; 305 const ASN1_OBJECT *b = &nid_objs[*bp]; 306 307 j = (a->length - b->length); 308 if (j) 309 return j; 310 if (a->length == 0) 311 return 0; 312 return memcmp(a->data, b->data, a->length); 313 } 314 315 IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj); 316 317 int OBJ_obj2nid(const ASN1_OBJECT *a) 318 { 319 const unsigned int *op; 320 ADDED_OBJ ad, *adp; 321 322 if (a == NULL) 323 return NID_undef; 324 if (a->nid != 0) 325 return a->nid; 326 327 if (a->length == 0) 328 return NID_undef; 329 330 if (added != NULL) { 331 ad.type = ADDED_DATA; 332 ad.obj = (ASN1_OBJECT *)a; /* XXX: ugly but harmless */ 333 adp = lh_ADDED_OBJ_retrieve(added, &ad); 334 if (adp != NULL) 335 return adp->obj->nid; 336 } 337 op = OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ); 338 if (op == NULL) 339 return NID_undef; 340 return nid_objs[*op].nid; 341 } 342 343 /* 344 * Convert an object name into an ASN1_OBJECT if "noname" is not set then 345 * search for short and long names first. This will convert the "dotted" form 346 * into an object: unlike OBJ_txt2nid it can be used with any objects, not 347 * just registered ones. 348 */ 349 350 ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name) 351 { 352 int nid = NID_undef; 353 ASN1_OBJECT *op; 354 unsigned char *buf; 355 unsigned char *p; 356 const unsigned char *cp; 357 int i, j; 358 359 if (!no_name) { 360 if (((nid = OBJ_sn2nid(s)) != NID_undef) || 361 ((nid = OBJ_ln2nid(s)) != NID_undef)) 362 return OBJ_nid2obj(nid); 363 } 364 365 /* Work out size of content octets */ 366 i = a2d_ASN1_OBJECT(NULL, 0, s, -1); 367 if (i <= 0) { 368 /* Don't clear the error */ 369 /* 370 * ERR_clear_error(); 371 */ 372 return NULL; 373 } 374 /* Work out total size */ 375 j = ASN1_object_size(0, i, V_ASN1_OBJECT); 376 if (j < 0) 377 return NULL; 378 379 if ((buf = OPENSSL_malloc(j)) == NULL) { 380 OBJerr(OBJ_F_OBJ_TXT2OBJ, ERR_R_MALLOC_FAILURE); 381 return NULL; 382 } 383 384 p = buf; 385 /* Write out tag+length */ 386 ASN1_put_object(&p, 0, i, V_ASN1_OBJECT, V_ASN1_UNIVERSAL); 387 /* Write out contents */ 388 a2d_ASN1_OBJECT(p, i, s, -1); 389 390 cp = buf; 391 op = d2i_ASN1_OBJECT(NULL, &cp, j); 392 OPENSSL_free(buf); 393 return op; 394 } 395 396 int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) 397 { 398 int i, n = 0, len, nid, first, use_bn; 399 BIGNUM *bl; 400 unsigned long l; 401 const unsigned char *p; 402 char tbuf[DECIMAL_SIZE(i) + DECIMAL_SIZE(l) + 2]; 403 404 /* Ensure that, at every state, |buf| is NUL-terminated. */ 405 if (buf && buf_len > 0) 406 buf[0] = '\0'; 407 408 if ((a == NULL) || (a->data == NULL)) 409 return 0; 410 411 if (!no_name && (nid = OBJ_obj2nid(a)) != NID_undef) { 412 const char *s; 413 s = OBJ_nid2ln(nid); 414 if (s == NULL) 415 s = OBJ_nid2sn(nid); 416 if (s) { 417 if (buf) 418 OPENSSL_strlcpy(buf, s, buf_len); 419 n = strlen(s); 420 return n; 421 } 422 } 423 424 len = a->length; 425 p = a->data; 426 427 first = 1; 428 bl = NULL; 429 430 while (len > 0) { 431 l = 0; 432 use_bn = 0; 433 for (;;) { 434 unsigned char c = *p++; 435 len--; 436 if ((len == 0) && (c & 0x80)) 437 goto err; 438 if (use_bn) { 439 if (!BN_add_word(bl, c & 0x7f)) 440 goto err; 441 } else 442 l |= c & 0x7f; 443 if (!(c & 0x80)) 444 break; 445 if (!use_bn && (l > (ULONG_MAX >> 7L))) { 446 if (bl == NULL && (bl = BN_new()) == NULL) 447 goto err; 448 if (!BN_set_word(bl, l)) 449 goto err; 450 use_bn = 1; 451 } 452 if (use_bn) { 453 if (!BN_lshift(bl, bl, 7)) 454 goto err; 455 } else 456 l <<= 7L; 457 } 458 459 if (first) { 460 first = 0; 461 if (l >= 80) { 462 i = 2; 463 if (use_bn) { 464 if (!BN_sub_word(bl, 80)) 465 goto err; 466 } else 467 l -= 80; 468 } else { 469 i = (int)(l / 40); 470 l -= (long)(i * 40); 471 } 472 if (buf && (buf_len > 1)) { 473 *buf++ = i + '0'; 474 *buf = '\0'; 475 buf_len--; 476 } 477 n++; 478 } 479 480 if (use_bn) { 481 char *bndec; 482 bndec = BN_bn2dec(bl); 483 if (!bndec) 484 goto err; 485 i = strlen(bndec); 486 if (buf) { 487 if (buf_len > 1) { 488 *buf++ = '.'; 489 *buf = '\0'; 490 buf_len--; 491 } 492 OPENSSL_strlcpy(buf, bndec, buf_len); 493 if (i > buf_len) { 494 buf += buf_len; 495 buf_len = 0; 496 } else { 497 buf += i; 498 buf_len -= i; 499 } 500 } 501 n++; 502 n += i; 503 OPENSSL_free(bndec); 504 } else { 505 BIO_snprintf(tbuf, sizeof(tbuf), ".%lu", l); 506 i = strlen(tbuf); 507 if (buf && (buf_len > 0)) { 508 OPENSSL_strlcpy(buf, tbuf, buf_len); 509 if (i > buf_len) { 510 buf += buf_len; 511 buf_len = 0; 512 } else { 513 buf += i; 514 buf_len -= i; 515 } 516 } 517 n += i; 518 l = 0; 519 } 520 } 521 522 BN_free(bl); 523 return n; 524 525 err: 526 BN_free(bl); 527 return -1; 528 } 529 530 int OBJ_txt2nid(const char *s) 531 { 532 ASN1_OBJECT *obj; 533 int nid; 534 obj = OBJ_txt2obj(s, 0); 535 nid = OBJ_obj2nid(obj); 536 ASN1_OBJECT_free(obj); 537 return nid; 538 } 539 540 int OBJ_ln2nid(const char *s) 541 { 542 ASN1_OBJECT o; 543 const ASN1_OBJECT *oo = &o; 544 ADDED_OBJ ad, *adp; 545 const unsigned int *op; 546 547 o.ln = s; 548 if (added != NULL) { 549 ad.type = ADDED_LNAME; 550 ad.obj = &o; 551 adp = lh_ADDED_OBJ_retrieve(added, &ad); 552 if (adp != NULL) 553 return adp->obj->nid; 554 } 555 op = OBJ_bsearch_ln(&oo, ln_objs, NUM_LN); 556 if (op == NULL) 557 return NID_undef; 558 return nid_objs[*op].nid; 559 } 560 561 int OBJ_sn2nid(const char *s) 562 { 563 ASN1_OBJECT o; 564 const ASN1_OBJECT *oo = &o; 565 ADDED_OBJ ad, *adp; 566 const unsigned int *op; 567 568 o.sn = s; 569 if (added != NULL) { 570 ad.type = ADDED_SNAME; 571 ad.obj = &o; 572 adp = lh_ADDED_OBJ_retrieve(added, &ad); 573 if (adp != NULL) 574 return adp->obj->nid; 575 } 576 op = OBJ_bsearch_sn(&oo, sn_objs, NUM_SN); 577 if (op == NULL) 578 return NID_undef; 579 return nid_objs[*op].nid; 580 } 581 582 const void *OBJ_bsearch_(const void *key, const void *base, int num, int size, 583 int (*cmp) (const void *, const void *)) 584 { 585 return OBJ_bsearch_ex_(key, base, num, size, cmp, 0); 586 } 587 588 const void *OBJ_bsearch_ex_(const void *key, const void *base_, int num, 589 int size, 590 int (*cmp) (const void *, const void *), 591 int flags) 592 { 593 const char *base = base_; 594 int l, h, i = 0, c = 0; 595 const char *p = NULL; 596 597 if (num == 0) 598 return NULL; 599 l = 0; 600 h = num; 601 while (l < h) { 602 i = (l + h) / 2; 603 p = &(base[i * size]); 604 c = (*cmp) (key, p); 605 if (c < 0) 606 h = i; 607 else if (c > 0) 608 l = i + 1; 609 else 610 break; 611 } 612 #ifdef CHARSET_EBCDIC 613 /* 614 * THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and I 615 * don't have perl (yet), we revert to a *LINEAR* search when the object 616 * wasn't found in the binary search. 617 */ 618 if (c != 0) { 619 for (i = 0; i < num; ++i) { 620 p = &(base[i * size]); 621 c = (*cmp) (key, p); 622 if (c == 0 || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH))) 623 return p; 624 } 625 } 626 #endif 627 if (c != 0 && !(flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)) 628 p = NULL; 629 else if (c == 0 && (flags & OBJ_BSEARCH_FIRST_VALUE_ON_MATCH)) { 630 while (i > 0 && (*cmp) (key, &(base[(i - 1) * size])) == 0) 631 i--; 632 p = &(base[i * size]); 633 } 634 return p; 635 } 636 637 /* 638 * Parse a BIO sink to create some extra oid's objects. 639 * Line format:<OID:isdigit or '.']><isspace><SN><isspace><LN> 640 */ 641 int OBJ_create_objects(BIO *in) 642 { 643 char buf[512]; 644 int i, num = 0; 645 char *o, *s, *l = NULL; 646 647 for (;;) { 648 s = o = NULL; 649 i = BIO_gets(in, buf, 512); 650 if (i <= 0) 651 return num; 652 buf[i - 1] = '\0'; 653 if (!ossl_isalnum(buf[0])) 654 return num; 655 o = s = buf; 656 while (ossl_isdigit(*s) || *s == '.') 657 s++; 658 if (*s != '\0') { 659 *(s++) = '\0'; 660 while (ossl_isspace(*s)) 661 s++; 662 if (*s == '\0') { 663 s = NULL; 664 } else { 665 l = s; 666 while (*l != '\0' && !ossl_isspace(*l)) 667 l++; 668 if (*l != '\0') { 669 *(l++) = '\0'; 670 while (ossl_isspace(*l)) 671 l++; 672 if (*l == '\0') { 673 l = NULL; 674 } 675 } else { 676 l = NULL; 677 } 678 } 679 } else { 680 s = NULL; 681 } 682 if (*o == '\0') 683 return num; 684 if (!OBJ_create(o, s, l)) 685 return num; 686 num++; 687 } 688 } 689 690 int OBJ_create(const char *oid, const char *sn, const char *ln) 691 { 692 ASN1_OBJECT *tmpoid = NULL; 693 int ok = 0; 694 695 /* Check to see if short or long name already present */ 696 if ((sn != NULL && OBJ_sn2nid(sn) != NID_undef) 697 || (ln != NULL && OBJ_ln2nid(ln) != NID_undef)) { 698 OBJerr(OBJ_F_OBJ_CREATE, OBJ_R_OID_EXISTS); 699 return 0; 700 } 701 702 /* Convert numerical OID string to an ASN1_OBJECT structure */ 703 tmpoid = OBJ_txt2obj(oid, 1); 704 if (tmpoid == NULL) 705 return 0; 706 707 /* If NID is not NID_undef then object already exists */ 708 if (OBJ_obj2nid(tmpoid) != NID_undef) { 709 OBJerr(OBJ_F_OBJ_CREATE, OBJ_R_OID_EXISTS); 710 goto err; 711 } 712 713 tmpoid->nid = OBJ_new_nid(1); 714 tmpoid->sn = (char *)sn; 715 tmpoid->ln = (char *)ln; 716 717 ok = OBJ_add_object(tmpoid); 718 719 tmpoid->sn = NULL; 720 tmpoid->ln = NULL; 721 722 err: 723 ASN1_OBJECT_free(tmpoid); 724 return ok; 725 } 726 727 size_t OBJ_length(const ASN1_OBJECT *obj) 728 { 729 if (obj == NULL) 730 return 0; 731 return obj->length; 732 } 733 734 const unsigned char *OBJ_get0_data(const ASN1_OBJECT *obj) 735 { 736 if (obj == NULL) 737 return NULL; 738 return obj->data; 739 } 740