Line data Source code
1 : /* crypto/objects/obj_dat.c */
2 : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 : * All rights reserved.
4 : *
5 : * This package is an SSL implementation written
6 : * by Eric Young (eay@cryptsoft.com).
7 : * The implementation was written so as to conform with Netscapes SSL.
8 : *
9 : * This library is free for commercial and non-commercial use as long as
10 : * the following conditions are aheared to. The following conditions
11 : * apply to all code found in this distribution, be it the RC4, RSA,
12 : * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 : * included with this distribution is covered by the same copyright terms
14 : * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 : *
16 : * Copyright remains Eric Young's, and as such any Copyright notices in
17 : * the code are not to be removed.
18 : * If this package is used in a product, Eric Young should be given attribution
19 : * as the author of the parts of the library used.
20 : * This can be in the form of a textual message at program startup or
21 : * in documentation (online or textual) provided with the package.
22 : *
23 : * Redistribution and use in source and binary forms, with or without
24 : * modification, are permitted provided that the following conditions
25 : * are met:
26 : * 1. Redistributions of source code must retain the copyright
27 : * notice, this list of conditions and the following disclaimer.
28 : * 2. Redistributions in binary form must reproduce the above copyright
29 : * notice, this list of conditions and the following disclaimer in the
30 : * documentation and/or other materials provided with the distribution.
31 : * 3. All advertising materials mentioning features or use of this software
32 : * must display the following acknowledgement:
33 : * "This product includes cryptographic software written by
34 : * Eric Young (eay@cryptsoft.com)"
35 : * The word 'cryptographic' can be left out if the rouines from the library
36 : * being used are not cryptographic related :-).
37 : * 4. If you include any Windows specific code (or a derivative thereof) from
38 : * the apps directory (application code) you must include an acknowledgement:
39 : * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 : *
41 : * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 : * SUCH DAMAGE.
52 : *
53 : * The licence and distribution terms for any publically available version or
54 : * derivative of this code cannot be changed. i.e. this code cannot simply be
55 : * copied and put under another distribution licence
56 : * [including the GNU Public Licence.]
57 : */
58 :
59 : #include <stdio.h>
60 : #include <ctype.h>
61 : #include <limits.h>
62 : #include "cryptlib.h"
63 : #include <openssl/lhash.h>
64 : #include <openssl/asn1.h>
65 : #include <openssl/objects.h>
66 : #include <openssl/bn.h>
67 :
68 : /* obj_dat.h is generated from objects.h by obj_dat.pl */
69 : #ifndef OPENSSL_NO_OBJECT
70 : # include "obj_dat.h"
71 : #else
72 : /* You will have to load all the objects needed manually in the application */
73 : # define NUM_NID 0
74 : # define NUM_SN 0
75 : # define NUM_LN 0
76 : # define NUM_OBJ 0
77 : static const unsigned char lvalues[1];
78 : static const ASN1_OBJECT nid_objs[1];
79 : static const unsigned int sn_objs[1];
80 : static const unsigned int ln_objs[1];
81 : static const unsigned int obj_objs[1];
82 : #endif
83 :
84 : DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
85 : DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
86 : DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
87 :
88 : #define ADDED_DATA 0
89 : #define ADDED_SNAME 1
90 : #define ADDED_LNAME 2
91 : #define ADDED_NID 3
92 :
93 : typedef struct added_obj_st {
94 : int type;
95 : ASN1_OBJECT *obj;
96 : } ADDED_OBJ;
97 : DECLARE_LHASH_OF(ADDED_OBJ);
98 :
99 : static int new_nid = NUM_NID;
100 : static LHASH_OF(ADDED_OBJ) *added = NULL;
101 :
102 : static int sn_cmp(const ASN1_OBJECT *const *a, const unsigned int *b)
103 : {
104 0 : return (strcmp((*a)->sn, nid_objs[*b].sn));
105 : }
106 :
107 0 : IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
108 :
109 : static int ln_cmp(const ASN1_OBJECT *const *a, const unsigned int *b)
110 : {
111 0 : return (strcmp((*a)->ln, nid_objs[*b].ln));
112 : }
113 :
114 0 : IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
115 :
116 0 : static unsigned long added_obj_hash(const ADDED_OBJ *ca)
117 : {
118 : const ASN1_OBJECT *a;
119 : int i;
120 : unsigned long ret = 0;
121 : unsigned char *p;
122 :
123 0 : a = ca->obj;
124 0 : switch (ca->type) {
125 : case ADDED_DATA:
126 0 : ret = a->length << 20L;
127 0 : p = (unsigned char *)a->data;
128 0 : for (i = 0; i < a->length; i++)
129 0 : ret ^= p[i] << ((i * 3) % 24);
130 : break;
131 : case ADDED_SNAME:
132 0 : ret = lh_strhash(a->sn);
133 0 : break;
134 : case ADDED_LNAME:
135 0 : ret = lh_strhash(a->ln);
136 0 : break;
137 : case ADDED_NID:
138 0 : ret = a->nid;
139 0 : break;
140 : default:
141 : /* abort(); */
142 : return 0;
143 : }
144 0 : ret &= 0x3fffffffL;
145 0 : ret |= ((unsigned long)ca->type) << 30L;
146 0 : return (ret);
147 : }
148 :
149 0 : static IMPLEMENT_LHASH_HASH_FN(added_obj, ADDED_OBJ)
150 :
151 0 : static int added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb)
152 : {
153 : ASN1_OBJECT *a, *b;
154 : int i;
155 :
156 0 : i = ca->type - cb->type;
157 0 : if (i)
158 : return (i);
159 0 : a = ca->obj;
160 0 : b = cb->obj;
161 0 : switch (ca->type) {
162 : case ADDED_DATA:
163 0 : i = (a->length - b->length);
164 0 : if (i)
165 : return (i);
166 0 : return (memcmp(a->data, b->data, (size_t)a->length));
167 : case ADDED_SNAME:
168 0 : if (a->sn == NULL)
169 : return (-1);
170 0 : else if (b->sn == NULL)
171 : return (1);
172 : else
173 0 : return (strcmp(a->sn, b->sn));
174 : case ADDED_LNAME:
175 0 : if (a->ln == NULL)
176 : return (-1);
177 0 : else if (b->ln == NULL)
178 : return (1);
179 : else
180 0 : return (strcmp(a->ln, b->ln));
181 : case ADDED_NID:
182 0 : return (a->nid - b->nid);
183 : default:
184 : /* abort(); */
185 : return 0;
186 : }
187 : }
188 :
189 0 : static IMPLEMENT_LHASH_COMP_FN(added_obj, ADDED_OBJ)
190 :
191 0 : static int init_added(void)
192 : {
193 0 : if (added != NULL)
194 : return (1);
195 0 : added = lh_ADDED_OBJ_new();
196 0 : return (added != NULL);
197 : }
198 :
199 : static void cleanup1_doall(ADDED_OBJ *a)
200 : {
201 0 : a->obj->nid = 0;
202 0 : a->obj->flags |= ASN1_OBJECT_FLAG_DYNAMIC |
203 : ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | ASN1_OBJECT_FLAG_DYNAMIC_DATA;
204 : }
205 :
206 : static void cleanup2_doall(ADDED_OBJ *a)
207 : {
208 0 : a->obj->nid++;
209 : }
210 :
211 0 : static void cleanup3_doall(ADDED_OBJ *a)
212 : {
213 0 : if (--a->obj->nid == 0)
214 0 : ASN1_OBJECT_free(a->obj);
215 0 : OPENSSL_free(a);
216 0 : }
217 :
218 0 : static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ)
219 0 : static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ)
220 0 : static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ)
221 :
222 : /*
223 : * The purpose of obj_cleanup_defer is to avoid EVP_cleanup() attempting to
224 : * use freed up OIDs. If neccessary the actual freeing up of OIDs is delayed.
225 : */
226 : int obj_cleanup_defer = 0;
227 :
228 17908 : void check_defer(int nid)
229 : {
230 17908 : if (!obj_cleanup_defer && nid >= NUM_NID)
231 0 : obj_cleanup_defer = 1;
232 17908 : }
233 :
234 0 : void OBJ_cleanup(void)
235 : {
236 0 : if (obj_cleanup_defer) {
237 0 : obj_cleanup_defer = 2;
238 0 : return;
239 : }
240 0 : if (added == NULL)
241 : return;
242 0 : lh_ADDED_OBJ_down_load(added) = 0;
243 0 : lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup1)); /* zero counters */
244 0 : lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup2)); /* set counters */
245 0 : lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup3)); /* free objects */
246 0 : lh_ADDED_OBJ_free(added);
247 0 : added = NULL;
248 : }
249 :
250 0 : int OBJ_new_nid(int num)
251 : {
252 : int i;
253 :
254 0 : i = new_nid;
255 0 : new_nid += num;
256 0 : return (i);
257 : }
258 :
259 0 : int OBJ_add_object(const ASN1_OBJECT *obj)
260 : {
261 : ASN1_OBJECT *o;
262 0 : ADDED_OBJ *ao[4] = { NULL, NULL, NULL, NULL }, *aop;
263 : int i;
264 :
265 0 : if (added == NULL)
266 0 : if (!init_added())
267 : return (0);
268 0 : if ((o = OBJ_dup(obj)) == NULL)
269 : goto err;
270 0 : if (!(ao[ADDED_NID] = (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ))))
271 : goto err2;
272 0 : if ((o->length != 0) && (obj->data != NULL))
273 0 : if (!
274 0 : (ao[ADDED_DATA] = (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ))))
275 : goto err2;
276 0 : if (o->sn != NULL)
277 0 : if (!
278 0 : (ao[ADDED_SNAME] =
279 0 : (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ))))
280 : goto err2;
281 0 : if (o->ln != NULL)
282 0 : if (!
283 0 : (ao[ADDED_LNAME] =
284 0 : (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ))))
285 : goto err2;
286 :
287 0 : for (i = ADDED_DATA; i <= ADDED_NID; i++) {
288 0 : if (ao[i] != NULL) {
289 0 : ao[i]->type = i;
290 0 : ao[i]->obj = o;
291 0 : aop = lh_ADDED_OBJ_insert(added, ao[i]);
292 : /* memory leak, buit should not normally matter */
293 0 : if (aop != NULL)
294 0 : OPENSSL_free(aop);
295 : }
296 : }
297 0 : o->flags &=
298 : ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
299 : ASN1_OBJECT_FLAG_DYNAMIC_DATA);
300 :
301 0 : return (o->nid);
302 : err2:
303 0 : OBJerr(OBJ_F_OBJ_ADD_OBJECT, ERR_R_MALLOC_FAILURE);
304 : err:
305 0 : for (i = ADDED_DATA; i <= ADDED_NID; i++)
306 0 : if (ao[i] != NULL)
307 0 : OPENSSL_free(ao[i]);
308 0 : if (o != NULL)
309 0 : OPENSSL_free(o);
310 : return (NID_undef);
311 : }
312 :
313 40106 : ASN1_OBJECT *OBJ_nid2obj(int n)
314 : {
315 : ADDED_OBJ ad, *adp;
316 : ASN1_OBJECT ob;
317 :
318 40106 : if ((n >= 0) && (n < NUM_NID)) {
319 40106 : if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
320 0 : OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID);
321 0 : return (NULL);
322 : }
323 40106 : return ((ASN1_OBJECT *)&(nid_objs[n]));
324 0 : } else if (added == NULL)
325 : return (NULL);
326 : else {
327 0 : ad.type = ADDED_NID;
328 0 : ad.obj = &ob;
329 0 : ob.nid = n;
330 0 : adp = lh_ADDED_OBJ_retrieve(added, &ad);
331 0 : if (adp != NULL)
332 0 : return (adp->obj);
333 : else {
334 0 : OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID);
335 0 : return (NULL);
336 : }
337 : }
338 : }
339 :
340 26247 : const char *OBJ_nid2sn(int n)
341 : {
342 : ADDED_OBJ ad, *adp;
343 : ASN1_OBJECT ob;
344 :
345 26247 : if ((n >= 0) && (n < NUM_NID)) {
346 26247 : if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
347 0 : OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID);
348 0 : return (NULL);
349 : }
350 26247 : return (nid_objs[n].sn);
351 0 : } else if (added == NULL)
352 : return (NULL);
353 : else {
354 0 : ad.type = ADDED_NID;
355 0 : ad.obj = &ob;
356 0 : ob.nid = n;
357 0 : adp = lh_ADDED_OBJ_retrieve(added, &ad);
358 0 : if (adp != NULL)
359 0 : return (adp->obj->sn);
360 : else {
361 0 : OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID);
362 0 : return (NULL);
363 : }
364 : }
365 : }
366 :
367 17908 : const char *OBJ_nid2ln(int n)
368 : {
369 : ADDED_OBJ ad, *adp;
370 : ASN1_OBJECT ob;
371 :
372 17908 : if ((n >= 0) && (n < NUM_NID)) {
373 17908 : if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
374 0 : OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID);
375 0 : return (NULL);
376 : }
377 17908 : return (nid_objs[n].ln);
378 0 : } else if (added == NULL)
379 : return (NULL);
380 : else {
381 0 : ad.type = ADDED_NID;
382 0 : ad.obj = &ob;
383 0 : ob.nid = n;
384 0 : adp = lh_ADDED_OBJ_retrieve(added, &ad);
385 0 : if (adp != NULL)
386 0 : return (adp->obj->ln);
387 : else {
388 0 : OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID);
389 0 : return (NULL);
390 : }
391 : }
392 : }
393 :
394 333406 : static int obj_cmp(const ASN1_OBJECT *const *ap, const unsigned int *bp)
395 : {
396 : int j;
397 333406 : const ASN1_OBJECT *a = *ap;
398 333406 : const ASN1_OBJECT *b = &nid_objs[*bp];
399 :
400 333406 : j = (a->length - b->length);
401 333406 : if (j)
402 : return (j);
403 214129 : if (a->length == 0)
404 : return 0;
405 214129 : return (memcmp(a->data, b->data, a->length));
406 : }
407 :
408 333406 : IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
409 :
410 39269 : int OBJ_obj2nid(const ASN1_OBJECT *a)
411 : {
412 : const unsigned int *op;
413 : ADDED_OBJ ad, *adp;
414 :
415 39269 : if (a == NULL)
416 : return (NID_undef);
417 39269 : if (a->nid != 0)
418 : return (a->nid);
419 :
420 39269 : if (a->length == 0)
421 : return NID_undef;
422 :
423 39269 : if (added != NULL) {
424 0 : ad.type = ADDED_DATA;
425 0 : ad.obj = (ASN1_OBJECT *)a; /* XXX: ugly but harmless */
426 0 : adp = lh_ADDED_OBJ_retrieve(added, &ad);
427 0 : if (adp != NULL)
428 0 : return (adp->obj->nid);
429 : }
430 : op = OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ);
431 39269 : if (op == NULL)
432 : return (NID_undef);
433 39269 : return (nid_objs[*op].nid);
434 : }
435 :
436 : /*
437 : * Convert an object name into an ASN1_OBJECT if "noname" is not set then
438 : * search for short and long names first. This will convert the "dotted" form
439 : * into an object: unlike OBJ_txt2nid it can be used with any objects, not
440 : * just registered ones.
441 : */
442 :
443 0 : ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name)
444 : {
445 : int nid = NID_undef;
446 : ASN1_OBJECT *op = NULL;
447 : unsigned char *buf;
448 : unsigned char *p;
449 : const unsigned char *cp;
450 : int i, j;
451 :
452 0 : if (!no_name) {
453 0 : if (((nid = OBJ_sn2nid(s)) != NID_undef) ||
454 : ((nid = OBJ_ln2nid(s)) != NID_undef))
455 0 : return OBJ_nid2obj(nid);
456 : }
457 :
458 : /* Work out size of content octets */
459 0 : i = a2d_ASN1_OBJECT(NULL, 0, s, -1);
460 0 : if (i <= 0) {
461 : /* Don't clear the error */
462 : /*
463 : * ERR_clear_error();
464 : */
465 : return NULL;
466 : }
467 : /* Work out total size */
468 0 : j = ASN1_object_size(0, i, V_ASN1_OBJECT);
469 :
470 0 : if ((buf = (unsigned char *)OPENSSL_malloc(j)) == NULL)
471 : return NULL;
472 :
473 0 : p = buf;
474 : /* Write out tag+length */
475 0 : ASN1_put_object(&p, 0, i, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
476 : /* Write out contents */
477 0 : a2d_ASN1_OBJECT(p, i, s, -1);
478 :
479 0 : cp = buf;
480 0 : op = d2i_ASN1_OBJECT(NULL, &cp, j);
481 0 : OPENSSL_free(buf);
482 0 : return op;
483 : }
484 :
485 0 : int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
486 : {
487 : int i, n = 0, len, nid, first, use_bn;
488 : BIGNUM *bl;
489 : unsigned long l;
490 : const unsigned char *p;
491 : char tbuf[DECIMAL_SIZE(i) + DECIMAL_SIZE(l) + 2];
492 :
493 : /* Ensure that, at every state, |buf| is NUL-terminated. */
494 0 : if (buf && buf_len > 0)
495 0 : buf[0] = '\0';
496 :
497 0 : if ((a == NULL) || (a->data == NULL))
498 : return (0);
499 :
500 0 : if (!no_name && (nid = OBJ_obj2nid(a)) != NID_undef) {
501 : const char *s;
502 0 : s = OBJ_nid2ln(nid);
503 0 : if (s == NULL)
504 0 : s = OBJ_nid2sn(nid);
505 0 : if (s) {
506 0 : if (buf)
507 0 : BUF_strlcpy(buf, s, buf_len);
508 0 : n = strlen(s);
509 0 : return n;
510 : }
511 : }
512 :
513 0 : len = a->length;
514 0 : p = a->data;
515 :
516 : first = 1;
517 : bl = NULL;
518 :
519 0 : while (len > 0) {
520 : l = 0;
521 : use_bn = 0;
522 : for (;;) {
523 0 : unsigned char c = *p++;
524 0 : len--;
525 0 : if ((len == 0) && (c & 0x80))
526 : goto err;
527 0 : if (use_bn) {
528 0 : if (!BN_add_word(bl, c & 0x7f))
529 : goto err;
530 : } else
531 0 : l |= c & 0x7f;
532 0 : if (!(c & 0x80))
533 : break;
534 0 : if (!use_bn && (l > (ULONG_MAX >> 7L))) {
535 0 : if (!bl && !(bl = BN_new()))
536 : goto err;
537 0 : if (!BN_set_word(bl, l))
538 : goto err;
539 : use_bn = 1;
540 : }
541 0 : if (use_bn) {
542 0 : if (!BN_lshift(bl, bl, 7))
543 : goto err;
544 : } else
545 0 : l <<= 7L;
546 : }
547 :
548 0 : if (first) {
549 : first = 0;
550 0 : if (l >= 80) {
551 : i = 2;
552 0 : if (use_bn) {
553 0 : if (!BN_sub_word(bl, 80))
554 : goto err;
555 : } else
556 0 : l -= 80;
557 : } else {
558 0 : i = (int)(l / 40);
559 0 : l -= (long)(i * 40);
560 : }
561 0 : if (buf && (buf_len > 1)) {
562 0 : *buf++ = i + '0';
563 0 : *buf = '\0';
564 0 : buf_len--;
565 : }
566 0 : n++;
567 : }
568 :
569 0 : if (use_bn) {
570 : char *bndec;
571 0 : bndec = BN_bn2dec(bl);
572 0 : if (!bndec)
573 : goto err;
574 0 : i = strlen(bndec);
575 0 : if (buf) {
576 0 : if (buf_len > 1) {
577 0 : *buf++ = '.';
578 0 : *buf = '\0';
579 0 : buf_len--;
580 : }
581 0 : BUF_strlcpy(buf, bndec, buf_len);
582 0 : if (i > buf_len) {
583 0 : buf += buf_len;
584 : buf_len = 0;
585 : } else {
586 0 : buf += i;
587 0 : buf_len -= i;
588 : }
589 : }
590 0 : n++;
591 0 : n += i;
592 0 : OPENSSL_free(bndec);
593 : } else {
594 0 : BIO_snprintf(tbuf, sizeof tbuf, ".%lu", l);
595 0 : i = strlen(tbuf);
596 0 : if (buf && (buf_len > 0)) {
597 0 : BUF_strlcpy(buf, tbuf, buf_len);
598 0 : if (i > buf_len) {
599 0 : buf += buf_len;
600 : buf_len = 0;
601 : } else {
602 0 : buf += i;
603 0 : buf_len -= i;
604 : }
605 : }
606 0 : n += i;
607 : l = 0;
608 : }
609 : }
610 :
611 0 : if (bl)
612 0 : BN_free(bl);
613 0 : return n;
614 :
615 : err:
616 0 : if (bl)
617 0 : BN_free(bl);
618 : return -1;
619 : }
620 :
621 0 : int OBJ_txt2nid(const char *s)
622 : {
623 : ASN1_OBJECT *obj;
624 : int nid;
625 0 : obj = OBJ_txt2obj(s, 0);
626 0 : nid = OBJ_obj2nid(obj);
627 0 : ASN1_OBJECT_free(obj);
628 0 : return nid;
629 : }
630 :
631 0 : int OBJ_ln2nid(const char *s)
632 : {
633 : ASN1_OBJECT o;
634 0 : const ASN1_OBJECT *oo = &o;
635 : ADDED_OBJ ad, *adp;
636 : const unsigned int *op;
637 :
638 0 : o.ln = s;
639 0 : if (added != NULL) {
640 0 : ad.type = ADDED_LNAME;
641 0 : ad.obj = &o;
642 0 : adp = lh_ADDED_OBJ_retrieve(added, &ad);
643 0 : if (adp != NULL)
644 0 : return (adp->obj->nid);
645 : }
646 : op = OBJ_bsearch_ln(&oo, ln_objs, NUM_LN);
647 0 : if (op == NULL)
648 : return (NID_undef);
649 0 : return (nid_objs[*op].nid);
650 : }
651 :
652 0 : int OBJ_sn2nid(const char *s)
653 : {
654 : ASN1_OBJECT o;
655 0 : const ASN1_OBJECT *oo = &o;
656 : ADDED_OBJ ad, *adp;
657 : const unsigned int *op;
658 :
659 0 : o.sn = s;
660 0 : if (added != NULL) {
661 0 : ad.type = ADDED_SNAME;
662 0 : ad.obj = &o;
663 0 : adp = lh_ADDED_OBJ_retrieve(added, &ad);
664 0 : if (adp != NULL)
665 0 : return (adp->obj->nid);
666 : }
667 : op = OBJ_bsearch_sn(&oo, sn_objs, NUM_SN);
668 0 : if (op == NULL)
669 : return (NID_undef);
670 0 : return (nid_objs[*op].nid);
671 : }
672 :
673 26358 : const void *OBJ_bsearch_(const void *key, const void *base, int num, int size,
674 : int (*cmp) (const void *, const void *))
675 : {
676 65627 : return OBJ_bsearch_ex_(key, base, num, size, cmp, 0);
677 : }
678 :
679 67911 : const void *OBJ_bsearch_ex_(const void *key, const void *base_, int num,
680 : int size,
681 : int (*cmp) (const void *, const void *),
682 : int flags)
683 : {
684 : const char *base = base_;
685 : int l, h, i = 0, c = 0;
686 : const char *p = NULL;
687 :
688 67911 : if (num == 0)
689 : return (NULL);
690 : l = 0;
691 : h = num;
692 435678 : while (l < h) {
693 434932 : i = (l + h) / 2;
694 434932 : p = &(base[i * size]);
695 434932 : c = (*cmp) (key, p);
696 434932 : if (c < 0)
697 : h = i;
698 209107 : else if (c > 0)
699 143486 : l = i + 1;
700 : else
701 : break;
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 (c != 0) {
710 : for (i = 0; i < num; ++i) {
711 : p = &(base[i * size]);
712 : c = (*cmp) (key, p);
713 : if (c == 0 || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)))
714 : return p;
715 : }
716 : }
717 : #endif
718 66367 : if (c != 0 && !(flags & OBJ_BSEARCH_VALUE_ON_NOMATCH))
719 : p = NULL;
720 65621 : else if (c == 0 && (flags & OBJ_BSEARCH_FIRST_VALUE_ON_MATCH)) {
721 740 : while (i > 0 && (*cmp) (key, &(base[(i - 1) * size])) == 0)
722 : i--;
723 740 : p = &(base[i * size]);
724 : }
725 66367 : return (p);
726 : }
727 :
728 0 : int OBJ_create_objects(BIO *in)
729 : {
730 : MS_STATIC char buf[512];
731 : int i, num = 0;
732 : char *o, *s, *l = NULL;
733 :
734 : for (;;) {
735 : s = o = NULL;
736 0 : i = BIO_gets(in, buf, 512);
737 0 : if (i <= 0)
738 : return (num);
739 0 : buf[i - 1] = '\0';
740 0 : if (!isalnum((unsigned char)buf[0]))
741 : return (num);
742 : o = s = buf;
743 0 : while (isdigit((unsigned char)*s) || (*s == '.'))
744 0 : s++;
745 0 : if (*s != '\0') {
746 0 : *(s++) = '\0';
747 0 : while (isspace((unsigned char)*s))
748 0 : s++;
749 0 : if (*s == '\0')
750 : s = NULL;
751 : else {
752 : l = s;
753 0 : while ((*l != '\0') && !isspace((unsigned char)*l))
754 0 : l++;
755 0 : if (*l != '\0') {
756 0 : *(l++) = '\0';
757 0 : while (isspace((unsigned char)*l))
758 0 : l++;
759 0 : if (*l == '\0')
760 : l = NULL;
761 : } else
762 : l = NULL;
763 : }
764 : } else
765 : s = NULL;
766 0 : if ((o == NULL) || (*o == '\0'))
767 : return (num);
768 0 : if (!OBJ_create(o, s, l))
769 : return (num);
770 0 : num++;
771 0 : }
772 : /* return(num); */
773 : }
774 :
775 0 : int OBJ_create(const char *oid, const char *sn, const char *ln)
776 : {
777 : int ok = 0;
778 : ASN1_OBJECT *op = NULL;
779 : unsigned char *buf;
780 : int i;
781 :
782 0 : i = a2d_ASN1_OBJECT(NULL, 0, oid, -1);
783 0 : if (i <= 0)
784 : return (0);
785 :
786 0 : if ((buf = (unsigned char *)OPENSSL_malloc(i)) == NULL) {
787 0 : OBJerr(OBJ_F_OBJ_CREATE, ERR_R_MALLOC_FAILURE);
788 0 : return (0);
789 : }
790 0 : i = a2d_ASN1_OBJECT(buf, i, oid, -1);
791 0 : if (i == 0)
792 : goto err;
793 0 : op = (ASN1_OBJECT *)ASN1_OBJECT_create(OBJ_new_nid(1), buf, i, sn, ln);
794 0 : if (op == NULL)
795 : goto err;
796 0 : ok = OBJ_add_object(op);
797 : err:
798 0 : ASN1_OBJECT_free(op);
799 0 : OPENSSL_free(buf);
800 0 : return (ok);
801 : }
|