1/* 2 * Copyright (c) 2011-12 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 25 * All rights reserved. 26 * 27 * This package is an SSL implementation written 28 * by Eric Young (eay@cryptsoft.com). 29 * The implementation was written so as to conform with Netscapes SSL. 30 * 31 * This library is free for commercial and non-commercial use as long as 32 * the following conditions are aheared to. The following conditions 33 * apply to all code found in this distribution, be it the RC4, RSA, 34 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 35 * included with this distribution is covered by the same copyright terms 36 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 37 * 38 * Copyright remains Eric Young's, and as such any Copyright notices in 39 * the code are not to be removed. 40 * If this package is used in a product, Eric Young should be given attribution 41 * as the author of the parts of the library used. 42 * This can be in the form of a textual message at program startup or 43 * in documentation (online or textual) provided with the package. 44 * 45 * Redistribution and use in source and binary forms, with or without 46 * modification, are permitted provided that the following conditions 47 * are met: 48 * 1. Redistributions of source code must retain the copyright 49 * notice, this list of conditions and the following disclaimer. 50 * 2. Redistributions in binary form must reproduce the above copyright 51 * notice, this list of conditions and the following disclaimer in the 52 * documentation and/or other materials provided with the distribution. 53 * 3. All advertising materials mentioning features or use of this software 54 * must display the following acknowledgement: 55 * "This product includes cryptographic software written by 56 * Eric Young (eay@cryptsoft.com)" 57 * The word 'cryptographic' can be left out if the rouines from the library 58 * being used are not cryptographic related :-). 59 * 4. If you include any Windows specific code (or a derivative thereof) from 60 * the apps directory (application code) you must include an acknowledgement: 61 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 62 * 63 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 64 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 65 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 66 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 67 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 68 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 69 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 70 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 71 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 72 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 73 * SUCH DAMAGE. 74 * 75 * The licence and distribution terms for any publically available version or 76 * derivative of this code cannot be changed. i.e. this code cannot simply be 77 * copied and put under another distribution licence 78 * [including the GNU Public Licence.] 79 */ 80 81#include "ossl-config.h" 82 83#include <ctype.h> 84#include <limits.h> 85#include <stdio.h> 86#include <stdlib.h> 87#include <string.h> 88#include <time.h> 89 90/* #include "ossl-asn1.h" */ 91#include "ossl-lhash.h" 92#include "ossl-objects.h" 93#include "ossl-buffer.h" 94#include "ossl-obj-dat.h" 95#include "ossl-bn.h" 96 97static ASN1_OBJECT * 98ASN1_OBJECT_new(void) 99{ 100 ASN1_OBJECT *ret; 101 102 ret = (ASN1_OBJECT *)malloc(sizeof(ASN1_OBJECT)); 103 if (NULL == ret) { 104 /* ASN1err(ASN1_F_ASN1_OBJECT_NEW,ERR_R_MALLOC_FAILURE); */ 105 return (NULL); 106 } 107 ret->length = 0; 108 ret->data = NULL; 109 ret->nid = 0; 110 ret->sn = NULL; 111 ret->ln = NULL; 112 ret->flags = ASN1_OBJECT_FLAG_DYNAMIC; 113 114 return (ret); 115} 116 117 118static void 119ASN1_OBJECT_free(ASN1_OBJECT *a) 120{ 121 if (a == NULL) { 122 return; 123 } 124 if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) { 125 if (a->sn != NULL) { 126 free((void *)a->sn); 127 } 128 if (a->ln != NULL) { 129 free((void *)a->ln); 130 } 131 a->sn = a->ln = NULL; 132 } 133 if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) { 134 if (a->data != NULL) { 135 free(a->data); 136 } 137 a->data = NULL; 138 a->length = 0; 139 } 140 if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC) { 141 free(a); 142 } 143} 144 145 146static ASN1_OBJECT * 147ASN1_OBJECT_create(int nid, unsigned char *data, int len, 148 const char *sn, const char *ln) 149{ 150 ASN1_OBJECT o; 151 152 o.sn = sn; 153 o.ln = ln; 154 o.data = data; 155 o.nid = nid; 156 o.length = len; 157 o.flags = ASN1_OBJECT_FLAG_DYNAMIC|ASN1_OBJECT_FLAG_DYNAMIC_STRINGS| 158 ASN1_OBJECT_FLAG_DYNAMIC_DATA; 159 160 return (OBJ_dup(&o)); 161} 162 163 164static int 165a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) 166{ 167 int i, first, len = 0, c, use_bn; 168 char ftmp[24], *tmp = ftmp; 169 int tmpsize = sizeof ftmp; 170 const char *p; 171 unsigned long l; 172 BIGNUM *bl = NULL; 173 174 if (num == 0) { 175 return (0); 176 } else if (num == -1) { 177 num = strlen(buf); 178 } 179 180 p = buf; 181 c = *(p++); 182 num--; 183 if ((c >= '0') && (c <= '2')) { 184 first = c-'0'; 185 } else { 186 /* ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_FIRST_NUM_TOO_LARGE); */ 187 goto err; 188 } 189 190 if (num <= 0) { 191 /* ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_MISSING_SECOND_NUMBER); */ 192 goto err; 193 } 194 c = *(p++); 195 num--; 196 for ( ; ; ) { 197 if (num <= 0) { 198 break; 199 } 200 if ((c != '.') && (c != ' ')) { 201 /* ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_SEPARATOR); */ 202 goto err; 203 } 204 l = 0; 205 use_bn = 0; 206 for ( ; ; ) { 207 if (num <= 0) { 208 break; 209 } 210 num--; 211 c = *(p++); 212 if ((c == ' ') || (c == '.')) { 213 break; 214 } 215 if ((c < '0') || (c > '9')) { 216 /* ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_DIGIT); */ 217 goto err; 218 } 219 if (!use_bn && (l > (ULONG_MAX / 10L))) { 220 use_bn = 1; 221 if (!bl) { 222 bl = BN_new(); 223 } 224 if (!bl || !BN_set_word(bl, l)) { 225 goto err; 226 } 227 } 228 if (use_bn) { 229 if (!BN_mul_word(bl, 10L) || 230 !BN_add_word(bl, c-'0')) { 231 goto err; 232 } 233 } else{ 234 l = l*10L+(long)(c-'0'); 235 } 236 } 237 if (len == 0) { 238 if ((first < 2) && (l >= 40)) { 239 /* ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_SECOND_NUMBER_TOO_LARGE); */ 240 goto err; 241 } 242 if (use_bn) { 243 if (!BN_add_word(bl, first * 40)) { 244 goto err; 245 } 246 } else{ 247 l += (long)first*40; 248 } 249 } 250 i = 0; 251 if (use_bn) { 252 int blsize; 253 blsize = BN_num_bits(bl); 254 blsize = (blsize + 6)/7; 255 if (blsize > tmpsize) { 256 if (tmp != ftmp) { 257 free(tmp); 258 } 259 tmpsize = blsize + 32; 260 tmp = malloc(tmpsize); 261 if (!tmp) { 262 goto err; 263 } 264 } 265 while (blsize--) { 266 tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L); 267 } 268 } else { 269 for ( ; ; ) { 270 tmp[i++] = (unsigned char)l & 0x7f; 271 l >>= 7L; 272 if (l == 0L) { 273 break; 274 } 275 } 276 } 277 if (out != NULL) { 278 if (len+i > olen) { 279 /* ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_BUFFER_TOO_SMALL); */ 280 goto err; 281 } 282 while (--i > 0) { 283 out[len++] = tmp[i]|0x80; 284 } 285 out[len++] = tmp[0]; 286 } else{ 287 len += i; 288 } 289 } 290 if (tmp != ftmp) { 291 free(tmp); 292 } 293 if (bl) { 294 BN_free(bl); 295 } 296 return (len); 297 298err: 299 if (tmp != ftmp) { 300 free(tmp); 301 } 302 if (bl) { 303 BN_free(bl); 304 } 305 return (0); 306} 307 308 309ASN1_OBJECT * 310OBJ_dup(const ASN1_OBJECT *o) 311{ 312 ASN1_OBJECT *r; 313 int i; 314 char *ln = NULL; 315 316 if (o == NULL) { 317 return (NULL); 318 } 319 if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC)) { 320 return ((ASN1_OBJECT *)o); /* XXX: ugh! Why? What kind of 321 * duplication is this??? */ 322 } 323 r = ASN1_OBJECT_new(); 324 if (r == NULL) { 325 /* OBJerr(OBJ_F_OBJ_DUP,ERR_R_ASN1_LIB); */ 326 return (NULL); 327 } 328 r->data = malloc(o->length); 329 if (r->data == NULL) { 330 goto err; 331 } 332 if (o->data != NULL) { 333 memcpy(r->data, o->data, o->length); 334 } 335 r->length = o->length; 336 r->nid = o->nid; 337 r->ln = r->sn = NULL; 338 if (o->ln != NULL) { 339 i = strlen(o->ln)+1; 340 r->ln = ln = malloc(i); 341 if (r->ln == NULL) { 342 goto err; 343 } 344 memcpy(ln, o->ln, i); 345 } 346 347 if (o->sn != NULL) { 348 char *s; 349 350 i = strlen(o->sn)+1; 351 r->sn = s = malloc(i); 352 if (r->sn == NULL) { 353 goto err; 354 } 355 memcpy(s, o->sn, i); 356 } 357 r->flags = o->flags|(ASN1_OBJECT_FLAG_DYNAMIC| 358 ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|ASN1_OBJECT_FLAG_DYNAMIC_DATA); 359 return (r); 360 361err: 362 /* OBJerr(OBJ_F_OBJ_DUP,ERR_R_MALLOC_FAILURE); */ 363 if (r != NULL) { 364 if (ln != NULL) { 365 free(ln); 366 } 367 if (r->data != NULL) { 368 free(r->data); 369 } 370 free(r); 371 } 372 return (NULL); 373} 374 375 376int 377OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b) 378{ 379 int ret; 380 381 ret = (a->length-b->length); 382 if (ret) { 383 return (ret); 384 } 385 return (memcmp(a->data, b->data, a->length)); 386} 387 388 389static int sn_cmp(const void *a, const void *b); 390static int ln_cmp(const void *a, const void *b); 391static int obj_cmp(const void *a, const void *b); 392 393#define ADDED_DATA 0 394#define ADDED_SNAME 1 395#define ADDED_LNAME 2 396#define ADDED_NID 3 397 398typedef struct added_obj_st { 399 int type; 400 ASN1_OBJECT * obj; 401} ADDED_OBJ; 402 403static int new_nid = NUM_NID; 404static LHASH *added = NULL; 405 406static int 407sn_cmp(const void *a, const void *b) 408{ 409 const ASN1_OBJECT *const *ap = a, *const *bp = b; 410 411 return (strcmp((*ap)->sn, (*bp)->sn)); 412} 413 414 415static int 416ln_cmp(const void *a, const void *b) 417{ 418 const ASN1_OBJECT *const *ap = a, *const *bp = b; 419 420 return (strcmp((*ap)->ln, (*bp)->ln)); 421} 422 423 424/* static unsigned long add_hash(ADDED_OBJ *ca) */ 425static unsigned long 426add_hash(const void *ca_void) 427{ 428 const ASN1_OBJECT *a; 429 int i; 430 unsigned long ret = 0; 431 unsigned char *p; 432 const ADDED_OBJ *ca = (const ADDED_OBJ *)ca_void; 433 434 a = ca->obj; 435 switch (ca->type) { 436 case ADDED_DATA: 437 ret = a->length<<20L; 438 p = (unsigned char *)a->data; 439 for (i = 0; i < a->length; i++) { 440 ret ^= p[i]<<((i*3)%24); 441 } 442 break; 443 444 case ADDED_SNAME: 445 ret = lh_strhash(a->sn); 446 break; 447 448 case ADDED_LNAME: 449 ret = lh_strhash(a->ln); 450 break; 451 452 case ADDED_NID: 453 ret = a->nid; 454 break; 455 456 default: 457 /* abort(); */ 458 return (0); 459 } 460 ret &= 0x3fffffffL; 461 ret |= ca->type<<30L; 462 return (ret); 463} 464 465 466/* static int add_cmp(ADDED_OBJ *ca, ADDED_OBJ *cb) */ 467static int 468add_cmp(const void *ca_void, const void *cb_void) 469{ 470 ASN1_OBJECT *a, *b; 471 int i; 472 const ADDED_OBJ *ca = (const ADDED_OBJ *)ca_void; 473 const ADDED_OBJ *cb = (const ADDED_OBJ *)cb_void; 474 475 i = ca->type-cb->type; 476 if (i) { 477 return (i); 478 } 479 a = ca->obj; 480 b = cb->obj; 481 switch (ca->type) { 482 case ADDED_DATA: 483 i = (a->length - b->length); 484 if (i) { 485 return (i); 486 } 487 return (memcmp(a->data, b->data, (size_t)a->length)); 488 489 case ADDED_SNAME: 490 if (a->sn == NULL) { 491 return (-1); 492 } else if (b->sn == NULL) { 493 return (1); 494 } else { 495 return (strcmp(a->sn, b->sn)); 496 } 497 498 case ADDED_LNAME: 499 if (a->ln == NULL) { 500 return (-1); 501 } else if (b->ln == NULL) { 502 return (1); 503 } else { 504 return (strcmp(a->ln, b->ln)); 505 } 506 507 case ADDED_NID: 508 return (a->nid-b->nid); 509 510 default: 511 /* abort(); */ 512 return (0); 513 } 514} 515 516 517static int 518init_added(void) 519{ 520 if (added != NULL) { 521 return (1); 522 } 523 added = lh_new(add_hash, add_cmp); 524 return (added != NULL); 525} 526 527 528#if 0 529static void 530cleanup1(ADDED_OBJ *a) 531{ 532 a->obj->nid = 0; 533 a->obj->flags |= ASN1_OBJECT_FLAG_DYNAMIC| 534 ASN1_OBJECT_FLAG_DYNAMIC_STRINGS| 535 ASN1_OBJECT_FLAG_DYNAMIC_DATA; 536} 537 538 539static void 540cleanup2(ADDED_OBJ *a) 541{ 542 a->obj->nid++; 543} 544 545 546static void 547cleanup3(ADDED_OBJ *a) 548{ 549 if (--a->obj->nid == 0) { 550 ASN1_OBJECT_free(a->obj); 551 } 552 free(a); 553} 554 555 556static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ *) 557static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ *) 558static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ *) 559 560void 561OBJ_cleanup(void) 562{ 563 if (added == NULL) { 564 return; 565 } 566 added->down_load = 0; 567 lh_doall(added, LHASH_DOALL_FN(cleanup1)); /* zero counters */ 568 lh_doall(added, LHASH_DOALL_FN(cleanup2)); /* set counters */ 569 lh_doall(added, LHASH_DOALL_FN(cleanup3)); /* free objects */ 570 lh_free(added); 571 added = NULL; 572} 573 574 575#endif 576 577int 578OBJ_new_nid(int num) 579{ 580 int i; 581 582 i = new_nid; 583 new_nid += num; 584 return (i); 585} 586 587 588int 589OBJ_add_object(const ASN1_OBJECT *obj) 590{ 591 ASN1_OBJECT *o; 592 ADDED_OBJ *ao[4] = { NULL, NULL, NULL, NULL }, *aop; 593 int i; 594 595 if (added == NULL) { 596 if (!init_added()) { 597 return (0); 598 } 599 } 600 if ((o = OBJ_dup(obj)) == NULL) { 601 goto err; 602 } 603 if (!(ao[ADDED_NID] = (ADDED_OBJ *)malloc(sizeof(ADDED_OBJ)))) { 604 goto err2; 605 } 606 if ((o->length != 0) && (obj->data != NULL)) { 607 if (!(ao[ADDED_DATA] = (ADDED_OBJ *)malloc(sizeof(ADDED_OBJ)))) { 608 goto err2; 609 } 610 } 611 if (o->sn != NULL) { 612 if (!(ao[ADDED_SNAME] = (ADDED_OBJ *)malloc(sizeof(ADDED_OBJ)))) { 613 goto err2; 614 } 615 } 616 if (o->ln != NULL) { 617 if (!(ao[ADDED_LNAME] = (ADDED_OBJ *)malloc(sizeof(ADDED_OBJ)))) { 618 goto err2; 619 } 620 } 621 622 for (i = ADDED_DATA; i <= ADDED_NID; i++) { 623 if (ao[i] != NULL) { 624 ao[i]->type = i; 625 ao[i]->obj = o; 626 aop = (ADDED_OBJ *)lh_insert(added, ao[i]); 627 /* memory leak, buit should not normally matter */ 628 if (aop != NULL) { 629 free(aop); 630 } 631 } 632 } 633 o->flags &= ~(ASN1_OBJECT_FLAG_DYNAMIC|ASN1_OBJECT_FLAG_DYNAMIC_STRINGS| 634 ASN1_OBJECT_FLAG_DYNAMIC_DATA); 635 636 return (o->nid); 637 638err2: 639 /* OBJerr(OBJ_F_OBJ_ADD_OBJECT,ERR_R_MALLOC_FAILURE); */ 640err: 641 for (i = ADDED_DATA; i <= ADDED_NID; i++) { 642 if (ao[i] != NULL) { 643 free(ao[i]); 644 } 645 } 646 if (o != NULL) { 647 free(o); 648 } 649 return (NID_undef); 650} 651 652 653ASN1_OBJECT * 654OBJ_nid2obj(int n) 655{ 656 ADDED_OBJ ad, *adp; 657 ASN1_OBJECT ob; 658 659 if ((n >= 0) && (n < NUM_NID)) { 660 if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { 661 /* OBJerr(OBJ_F_OBJ_NID2OBJ,OBJ_R_UNKNOWN_NID); */ 662 return (NULL); 663 } 664 return ((ASN1_OBJECT *)&(nid_objs[n])); 665 } else if (added == NULL) { 666 return (NULL); 667 } else{ 668 ad.type = ADDED_NID; 669 ad.obj = &ob; 670 ob.nid = n; 671 adp = (ADDED_OBJ *)lh_retrieve(added, &ad); 672 if (adp != NULL) { 673 return (adp->obj); 674 } else{ 675 /* OBJerr(OBJ_F_OBJ_NID2OBJ,OBJ_R_UNKNOWN_NID); */ 676 return (NULL); 677 } 678 } 679} 680 681 682const char * 683OBJ_nid2sn(int n) 684{ 685 ADDED_OBJ ad, *adp; 686 ASN1_OBJECT ob; 687 688 if ((n >= 0) && (n < NUM_NID)) { 689 if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { 690 /* OBJerr(OBJ_F_OBJ_NID2SN,OBJ_R_UNKNOWN_NID); */ 691 return (NULL); 692 } 693 return (nid_objs[n].sn); 694 } else if (added == NULL) { 695 return (NULL); 696 } else{ 697 ad.type = ADDED_NID; 698 ad.obj = &ob; 699 ob.nid = n; 700 adp = (ADDED_OBJ *)lh_retrieve(added, &ad); 701 if (adp != NULL) { 702 return (adp->obj->sn); 703 } else{ 704 /* OBJerr(OBJ_F_OBJ_NID2SN,OBJ_R_UNKNOWN_NID); */ 705 return (NULL); 706 } 707 } 708} 709 710 711const char * 712OBJ_nid2ln(int n) 713{ 714 ADDED_OBJ ad, *adp; 715 ASN1_OBJECT ob; 716 717 if ((n >= 0) && (n < NUM_NID)) { 718 if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { 719 /* OBJerr(OBJ_F_OBJ_NID2LN,OBJ_R_UNKNOWN_NID); */ 720 return (NULL); 721 } 722 return (nid_objs[n].ln); 723 } else if (added == NULL) { 724 return (NULL); 725 } else{ 726 ad.type = ADDED_NID; 727 ad.obj = &ob; 728 ob.nid = n; 729 adp = (ADDED_OBJ *)lh_retrieve(added, &ad); 730 if (adp != NULL) { 731 return (adp->obj->ln); 732 } else{ 733 /* OBJerr(OBJ_F_OBJ_NID2LN,OBJ_R_UNKNOWN_NID); */ 734 return (NULL); 735 } 736 } 737} 738 739 740int 741OBJ_obj2nid(const ASN1_OBJECT *a) 742{ 743 ASN1_OBJECT **op; 744 ADDED_OBJ ad, *adp; 745 746 if (a == NULL) { 747 return (NID_undef); 748 } 749 if (a->nid != 0) { 750 return (a->nid); 751 } 752 753 if (added != NULL) { 754 ad.type = ADDED_DATA; 755 ad.obj = (ASN1_OBJECT *)a; /* XXX: ugly but harmless */ 756 adp = (ADDED_OBJ *)lh_retrieve(added, &ad); 757 if (adp != NULL) { 758 return (adp->obj->nid); 759 } 760 } 761 op = (ASN1_OBJECT **)OBJ_bsearch((const char *)&a, (const char *)obj_objs, 762 NUM_OBJ, sizeof(ASN1_OBJECT *), obj_cmp); 763 if (op == NULL) { 764 return (NID_undef); 765 } 766 return ((*op)->nid); 767} 768 769 770#if 0 771 772/* Convert an object name into an ASN1_OBJECT 773 * if "noname" is not set then search for short and long names first. 774 * This will convert the "dotted" form into an object: unlike OBJ_txt2nid 775 * it can be used with any objects, not just registered ones. 776 */ 777ASN1_OBJECT * 778OBJ_txt2obj(const char *s, int no_name) 779{ 780 int nid = NID_undef; 781 ASN1_OBJECT *op = NULL; 782 unsigned char *buf; 783 unsigned char *p; 784 const unsigned char *cp; 785 int i, j; 786 787 if (!no_name) { 788 if (((nid = OBJ_sn2nid(s)) != NID_undef) || 789 ((nid = OBJ_ln2nid(s)) != NID_undef)) { 790 return (OBJ_nid2obj(nid)); 791 } 792 } 793 794 /* Work out size of content octets */ 795 i = a2d_ASN1_OBJECT(NULL, 0, s, -1); 796 if (i <= 0) { 797 /* Don't clear the error */ 798 /*ERR_clear_error();*/ 799 return (NULL); 800 } 801 /* Work out total size */ 802 j = ASN1_object_size(0, i, V_ASN1_OBJECT); 803 804 if ((buf = (unsigned char *)malloc(j)) == NULL) { 805 return (NULL); 806 } 807 808 p = buf; 809 /* Write out tag+length */ 810 ASN1_put_object(&p, 0, i, V_ASN1_OBJECT, V_ASN1_UNIVERSAL); 811 /* Write out contents */ 812 a2d_ASN1_OBJECT(p, i, s, -1); 813 814 cp = buf; 815 op = d2i_ASN1_OBJECT(NULL, &cp, j); 816 free(buf); 817 return (op); 818} 819 820 821#ifndef DECIMAL_SIZE 822#define DECIMAL_SIZE(type) ((sizeof(type)*8+2)/3+1) 823#endif 824 825int 826OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) 827{ 828 int i, n = 0, len, nid, first, use_bn; 829 BIGNUM *bl; 830 unsigned long l; 831 unsigned char *p; 832 char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2]; 833 834 if ((a == NULL) || (a->data == NULL)) { 835 buf[0] = '\0'; 836 return (0); 837 } 838 839 840 if (!no_name && ((nid = OBJ_obj2nid(a)) != NID_undef)) { 841 const char *s; 842 s = OBJ_nid2ln(nid); 843 if (s == NULL) { 844 s = OBJ_nid2sn(nid); 845 } 846 if (s) { 847 if (buf) { 848 BUF_strlcpy(buf, s, buf_len); 849 } 850 n = strlen(s); 851 return (n); 852 } 853 } 854 855 856 len = a->length; 857 p = a->data; 858 859 first = 1; 860 bl = NULL; 861 862 while (len > 0) { 863 l = 0; 864 use_bn = 0; 865 for ( ; ; ) { 866 unsigned char c = *p++; 867 len--; 868 if ((len == 0) && (c & 0x80)) { 869 goto err; 870 } 871 if (use_bn) { 872 if (!BN_add_word(bl, c & 0x7f)) { 873 goto err; 874 } 875 } else{ 876 l |= c & 0x7f; 877 } 878 if (!(c & 0x80)) { 879 break; 880 } 881 if (!use_bn && (l > (ULONG_MAX >> 7L))) { 882 if (!bl && !(bl = BN_new())) { 883 goto err; 884 } 885 if (!BN_set_word(bl, l)) { 886 goto err; 887 } 888 use_bn = 1; 889 } 890 if (use_bn) { 891 if (!BN_lshift(bl, bl, 7)) { 892 goto err; 893 } 894 } else{ 895 l <<= 7L; 896 } 897 } 898 899 if (first) { 900 first = 0; 901 if (l >= 80) { 902 i = 2; 903 if (use_bn) { 904 if (!BN_sub_word(bl, 80)) { 905 goto err; 906 } 907 } else{ 908 l -= 80; 909 } 910 } else { 911 i = (int)(l/40); 912 l -= (long)(i*40); 913 } 914 if (buf && (buf_len > 0)) { 915 *buf++ = i + '0'; 916 buf_len--; 917 } 918 n++; 919 } 920 921 if (use_bn) { 922 char *bndec; 923 bndec = BN_bn2dec(bl); 924 if (!bndec) { 925 goto err; 926 } 927 i = strlen(bndec); 928 if (buf) { 929 if (buf_len > 0) { 930 *buf++ = '.'; 931 buf_len--; 932 } 933 BUF_strlcpy(buf, bndec, buf_len); 934 if (i > buf_len) { 935 buf += buf_len; 936 buf_len = 0; 937 } else { 938 buf += i; 939 buf_len -= i; 940 } 941 } 942 n++; 943 n += i; 944 free(bndec); 945 } else { 946 BIO_snprintf(tbuf, sizeof tbuf, ".%lu", l); 947 i = strlen(tbuf); 948 if (buf && (buf_len > 0)) { 949 BUF_strlcpy(buf, tbuf, buf_len); 950 if (i > buf_len) { 951 buf += buf_len; 952 buf_len = 0; 953 } else { 954 buf += i; 955 buf_len -= i; 956 } 957 } 958 n += i; 959 l = 0; 960 } 961 } 962 963 if (bl) { 964 BN_free(bl); 965 } 966 return (n); 967 968err: 969 if (bl) { 970 BN_free(bl); 971 } 972 return (-1); 973} 974 975 976int 977OBJ_txt2nid(const char *s) 978{ 979 ASN1_OBJECT *obj; 980 int nid; 981 982 obj = OBJ_txt2obj(s, 0); 983 nid = OBJ_obj2nid(obj); 984 ASN1_OBJECT_free(obj); 985 return (nid); 986} 987 988 989#endif /* #if 0 */ 990 991int 992OBJ_ln2nid(const char *s) 993{ 994 ASN1_OBJECT o, *oo = &o, **op; 995 ADDED_OBJ ad, *adp; 996 997 o.ln = s; 998 if (added != NULL) { 999 ad.type = ADDED_LNAME; 1000 ad.obj = &o; 1001 adp = (ADDED_OBJ *)lh_retrieve(added, &ad); 1002 if (adp != NULL) { 1003 return (adp->obj->nid); 1004 } 1005 } 1006 op = (ASN1_OBJECT **)OBJ_bsearch((char *)&oo, (char *)ln_objs, NUM_LN, 1007 sizeof(ASN1_OBJECT *), ln_cmp); 1008 if (op == NULL) { 1009 return (NID_undef); 1010 } 1011 return ((*op)->nid); 1012} 1013 1014 1015int 1016OBJ_sn2nid(const char *s) 1017{ 1018 ASN1_OBJECT o, *oo = &o, **op; 1019 ADDED_OBJ ad, *adp; 1020 1021 o.sn = s; 1022 if (added != NULL) { 1023 ad.type = ADDED_SNAME; 1024 ad.obj = &o; 1025 adp = (ADDED_OBJ *)lh_retrieve(added, &ad); 1026 if (adp != NULL) { 1027 return (adp->obj->nid); 1028 } 1029 } 1030 op = (ASN1_OBJECT **)OBJ_bsearch((char *)&oo, (char *)sn_objs, NUM_SN, 1031 sizeof(ASN1_OBJECT *), sn_cmp); 1032 if (op == NULL) { 1033 return (NID_undef); 1034 } 1035 return ((*op)->nid); 1036} 1037 1038 1039static int 1040obj_cmp(const void *ap, const void *bp) 1041{ 1042 int j; 1043 const ASN1_OBJECT *a = *(ASN1_OBJECT *const *)ap; 1044 const ASN1_OBJECT *b = *(ASN1_OBJECT *const *)bp; 1045 1046 j = (a->length - b->length); 1047 if (j) { 1048 return (j); 1049 } 1050 return (memcmp(a->data, b->data, a->length)); 1051} 1052 1053 1054const char * 1055OBJ_bsearch(const char *key, const char *base, int num, int size, 1056 int (*cmp)(const void *, const void *)) 1057{ 1058 return (OBJ_bsearch_ex(key, base, num, size, cmp, 0)); 1059} 1060 1061 1062const char * 1063OBJ_bsearch_ex(const char *key, const char *base, int num, 1064 int size, int (*cmp)(const void *, const void *), int flags) 1065{ 1066 int l, h, i = 0, c = 0; 1067 const char *p = NULL; 1068 1069 if (num == 0) { 1070 return (NULL); 1071 } 1072 l = 0; 1073 h = num; 1074 while (l < h) { 1075 i = (l+h)/2; 1076 p = &(base[i*size]); 1077 c = (*cmp)(key, p); 1078 if (c < 0) { 1079 h = i; 1080 } else if (c > 0) { 1081 l = i+1; 1082 } else{ 1083 break; 1084 } 1085 } 1086#ifdef CHARSET_EBCDIC 1087 1088/* THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and 1089 * I don't have perl (yet), we revert to a *LINEAR* search 1090 * when the object wasn't found in the binary search. 1091 */ 1092 if (c != 0) { 1093 for (i = 0; i < num; ++i) { 1094 p = &(base[i*size]); 1095 c = (*cmp)(key, p); 1096 if ((c == 0) || ((c < 0) && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH))) { 1097 return (p); 1098 } 1099 } 1100 } 1101#endif 1102 if ((c != 0) && !(flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)) { 1103 p = NULL; 1104 } else if ((c == 0) && (flags & OBJ_BSEARCH_FIRST_VALUE_ON_MATCH)) { 1105 while (i > 0 && (*cmp)(key, &(base[(i-1)*size])) == 0) { 1106 i--; 1107 } 1108 p = &(base[i*size]); 1109 } 1110 return (p); 1111} 1112 1113 1114int 1115OBJ_create_objects(BIO *in) 1116{ 1117 /* MS_STATIC */ 1118 char buf[512]; 1119 int i, num = 0; 1120 char *o, *s, *l = NULL; 1121 1122 for ( ; ; ) { 1123 s = o = NULL; 1124 i = BIO_gets(in, buf, 512); 1125 if (i <= 0) { 1126 return (num); 1127 } 1128 buf[i-1] = '\0'; 1129 if (!isalnum((unsigned char)buf[0])) { 1130 return (num); 1131 } 1132 o = s = buf; 1133 while (isdigit((unsigned char)*s) || (*s == '.')) { 1134 s++; 1135 } 1136 if (*s != '\0') { 1137 *(s++) = '\0'; 1138 while (isspace((unsigned char)*s)) { 1139 s++; 1140 } 1141 if (*s == '\0') { 1142 s = NULL; 1143 } else{ 1144 l = s; 1145 while ((*l != '\0') && !isspace((unsigned char)*l)) { 1146 l++; 1147 } 1148 if (*l != '\0') { 1149 *(l++) = '\0'; 1150 while (isspace((unsigned char)*l)) { 1151 l++; 1152 } 1153 if (*l == '\0') { 1154 l = NULL; 1155 } 1156 } else{ 1157 l = NULL; 1158 } 1159 } 1160 } else{ 1161 s = NULL; 1162 } 1163 if ((o == NULL) || (*o == '\0')) { 1164 return (num); 1165 } 1166 if (!OBJ_create(o, s, l)) { 1167 return (num); 1168 } 1169 num++; 1170 } 1171 return (num); 1172} 1173 1174 1175int 1176OBJ_create(const char *oid, const char *sn, const char *ln) 1177{ 1178 int ok = 0; 1179 ASN1_OBJECT *op = NULL; 1180 unsigned char *buf; 1181 int i; 1182 1183 i = a2d_ASN1_OBJECT(NULL, 0, oid, -1); 1184 if (i <= 0) { 1185 return (0); 1186 } 1187 1188 if ((buf = (unsigned char *)malloc(i)) == NULL) { 1189 /* OBJerr(OBJ_F_OBJ_CREATE,ERR_R_MALLOC_FAILURE); */ 1190 return (0); 1191 } 1192 i = a2d_ASN1_OBJECT(buf, i, oid, -1); 1193 if (i == 0) { 1194 goto err; 1195 } 1196 op = (ASN1_OBJECT *)ASN1_OBJECT_create(OBJ_new_nid(1), buf, i, sn, ln); 1197 if (op == NULL) { 1198 goto err; 1199 } 1200 ok = OBJ_add_object(op); 1201err: 1202 ASN1_OBJECT_free(op); 1203 free(buf); 1204 return (ok); 1205} 1206