VirtualBox

source: vbox/trunk/src/libs/openssl-3.1.4/crypto/objects/obj_dat.c@ 102863

Last change on this file since 102863 was 102863, checked in by vboxsync, 13 months ago

openssl-3.1.4: Applied and adjusted our OpenSSL changes to 3.1.3. bugref:10577

File size: 20.6 KB
Line 
1/*
2 * Copyright 1995-2023 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.h by obj_dat.pl */
24#include "obj_dat.h"
25
26/*
27 * If we don't have suitable TSAN support, we'll use a lock for generation of
28 * new NIDs. This will be slower of course.
29 */
30#ifndef tsan_ld_acq
31# define OBJ_USE_LOCK_FOR_NEW_NID
32#endif
33
34DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
35DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
36DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
37
38#define ADDED_DATA 0
39#define ADDED_SNAME 1
40#define ADDED_LNAME 2
41#define ADDED_NID 3
42
43struct added_obj_st {
44 int type;
45 ASN1_OBJECT *obj;
46};
47
48static LHASH_OF(ADDED_OBJ) *added = NULL;
49static CRYPTO_RWLOCK *ossl_obj_lock = NULL;
50#ifdef OBJ_USE_LOCK_FOR_NEW_NID
51static CRYPTO_RWLOCK *ossl_obj_nid_lock = NULL;
52#endif
53
54static CRYPTO_ONCE ossl_obj_lock_init = CRYPTO_ONCE_STATIC_INIT;
55
56static ossl_inline void objs_free_locks(void)
57{
58 CRYPTO_THREAD_lock_free(ossl_obj_lock);
59 ossl_obj_lock = NULL;
60#ifdef OBJ_USE_LOCK_FOR_NEW_NID
61 CRYPTO_THREAD_lock_free(ossl_obj_nid_lock);
62 ossl_obj_nid_lock = NULL;
63#endif
64}
65
66DEFINE_RUN_ONCE_STATIC(obj_lock_initialise)
67{
68 ossl_obj_lock = CRYPTO_THREAD_lock_new();
69 if (ossl_obj_lock == NULL)
70 return 0;
71
72#ifdef OBJ_USE_LOCK_FOR_NEW_NID
73 ossl_obj_nid_lock = CRYPTO_THREAD_lock_new();
74 if (ossl_obj_nid_lock == NULL) {
75 objs_free_locks();
76 return 0;
77 }
78#endif
79 return 1;
80}
81
82static ossl_inline int ossl_init_added_lock(void)
83{
84#ifndef OPENSSL_NO_AUTOLOAD_CONFIG
85 /* Make sure we've loaded config before checking for any "added" objects */
86 OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
87#endif
88 return RUN_ONCE(&ossl_obj_lock_init, obj_lock_initialise);
89}
90
91static ossl_inline int ossl_obj_write_lock(int lock)
92{
93 if (!lock)
94 return 1;
95 if (!ossl_init_added_lock())
96 return 0;
97 return CRYPTO_THREAD_write_lock(ossl_obj_lock);
98}
99
100static ossl_inline int ossl_obj_read_lock(int lock)
101{
102 if (!lock)
103 return 1;
104 if (!ossl_init_added_lock())
105 return 0;
106 return CRYPTO_THREAD_read_lock(ossl_obj_lock);
107}
108
109static ossl_inline void ossl_obj_unlock(int lock)
110{
111 if (lock)
112 CRYPTO_THREAD_unlock(ossl_obj_lock);
113}
114
115static int sn_cmp(const ASN1_OBJECT *const *a, const unsigned int *b)
116{
117 return strcmp((*a)->sn, nid_objs[*b].sn);
118}
119
120IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
121
122static int ln_cmp(const ASN1_OBJECT *const *a, const unsigned int *b)
123{
124 return strcmp((*a)->ln, nid_objs[*b].ln);
125}
126
127IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
128
129static unsigned long added_obj_hash(const ADDED_OBJ *ca)
130{
131 const ASN1_OBJECT *a;
132 int i;
133 unsigned long ret = 0;
134 unsigned char *p;
135
136 a = ca->obj;
137 switch (ca->type) {
138 case ADDED_DATA:
139 ret = a->length << 20L;
140 p = (unsigned char *)a->data;
141 for (i = 0; i < a->length; i++)
142 ret ^= p[i] << ((i * 3) % 24);
143 break;
144 case ADDED_SNAME:
145 ret = OPENSSL_LH_strhash(a->sn);
146 break;
147 case ADDED_LNAME:
148 ret = OPENSSL_LH_strhash(a->ln);
149 break;
150 case ADDED_NID:
151 ret = a->nid;
152 break;
153 default:
154 /* abort(); */
155 return 0;
156 }
157 ret &= 0x3fffffffL;
158 ret |= ((unsigned long)ca->type) << 30L;
159 return ret;
160}
161
162static int added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb)
163{
164 ASN1_OBJECT *a, *b;
165 int i;
166
167 i = ca->type - cb->type;
168 if (i)
169 return i;
170 a = ca->obj;
171 b = cb->obj;
172 switch (ca->type) {
173 case ADDED_DATA:
174 i = (a->length - b->length);
175 if (i)
176 return i;
177 return memcmp(a->data, b->data, (size_t)a->length);
178 case ADDED_SNAME:
179 if (a->sn == NULL)
180 return -1;
181 else if (b->sn == NULL)
182 return 1;
183 else
184 return strcmp(a->sn, b->sn);
185 case ADDED_LNAME:
186 if (a->ln == NULL)
187 return -1;
188 else if (b->ln == NULL)
189 return 1;
190 else
191 return strcmp(a->ln, b->ln);
192 case ADDED_NID:
193 return a->nid - b->nid;
194 default:
195 /* abort(); */
196 return 0;
197 }
198}
199
200static void cleanup1_doall(ADDED_OBJ *a)
201{
202 a->obj->nid = 0;
203 a->obj->flags |= ASN1_OBJECT_FLAG_DYNAMIC |
204 ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | ASN1_OBJECT_FLAG_DYNAMIC_DATA;
205}
206
207static void cleanup2_doall(ADDED_OBJ *a)
208{
209 a->obj->nid++;
210}
211
212static void cleanup3_doall(ADDED_OBJ *a)
213{
214 if (--a->obj->nid == 0)
215 ASN1_OBJECT_free(a->obj);
216 OPENSSL_free(a);
217}
218
219void ossl_obj_cleanup_int(void)
220{
221 if (added != NULL) {
222 lh_ADDED_OBJ_set_down_load(added, 0);
223 lh_ADDED_OBJ_doall(added, cleanup1_doall); /* zero counters */
224 lh_ADDED_OBJ_doall(added, cleanup2_doall); /* set counters */
225 lh_ADDED_OBJ_doall(added, cleanup3_doall); /* free objects */
226 lh_ADDED_OBJ_free(added);
227 added = NULL;
228 }
229 objs_free_locks();
230}
231
232/*
233 * Requires that the ossl_obj_lock be held
234 * if TSAN_REQUIRES_LOCKING defined
235 */
236static int obj_new_nid_unlocked(int num)
237{
238#ifdef OBJ_USE_LOCK_FOR_NEW_NID
239 static int new_nid = NUM_NID;
240 int i;
241
242 i = new_nid;
243 new_nid += num;
244
245 return i;
246#else
247 static TSAN_QUALIFIER int new_nid = NUM_NID;
248
249 return tsan_add(&new_nid, num);
250#endif
251}
252
253int OBJ_new_nid(int num)
254{
255#ifdef TSAN_REQUIRES_LOCKING
256 int i;
257
258 if (!ossl_obj_write_lock(1)) {
259 ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
260 return NID_undef;
261 }
262
263 i = obj_new_nid_unlocked(num);
264
265 ossl_obj_unlock(1);
266
267 return i;
268#else
269 return obj_new_nid_unlocked(num);
270#endif
271}
272
273static int ossl_obj_add_object(const ASN1_OBJECT *obj, int lock)
274{
275 ASN1_OBJECT *o = NULL;
276 ADDED_OBJ *ao[4] = { NULL, NULL, NULL, NULL }, *aop;
277 int i;
278
279 if ((o = OBJ_dup(obj)) == NULL)
280 return NID_undef;
281 if ((ao[ADDED_NID] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL
282 || (o->length != 0
283 && obj->data != NULL
284 && (ao[ADDED_DATA] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL)
285 || (o->sn != NULL
286 && (ao[ADDED_SNAME] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL)
287 || (o->ln != NULL
288 && (ao[ADDED_LNAME] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL)) {
289 ERR_raise(ERR_LIB_OBJ, ERR_R_MALLOC_FAILURE);
290 goto err2;
291 }
292
293 if (!ossl_obj_write_lock(lock)) {
294 ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
295 goto err2;
296 }
297 if (added == NULL) {
298 added = lh_ADDED_OBJ_new(added_obj_hash, added_obj_cmp);
299 if (added == NULL) {
300 ERR_raise(ERR_LIB_OBJ, ERR_R_MALLOC_FAILURE);
301 goto err;
302 }
303 }
304
305 for (i = ADDED_DATA; i <= ADDED_NID; i++) {
306 if (ao[i] != NULL) {
307 ao[i]->type = i;
308 ao[i]->obj = o;
309 aop = lh_ADDED_OBJ_insert(added, ao[i]);
310 /* memory leak, but should not normally matter */
311 OPENSSL_free(aop);
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
330ASN1_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
356const char *OBJ_nid2sn(int n)
357{
358 ASN1_OBJECT *ob = OBJ_nid2obj(n);
359
360 return ob == NULL ? NULL : ob->sn;
361}
362
363const char *OBJ_nid2ln(int n)
364{
365 ASN1_OBJECT *ob = OBJ_nid2obj(n);
366
367 return ob == NULL ? NULL : ob->ln;
368}
369
370static 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
384IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
385
386static 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 */
423ASN1_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 ERR_raise(ERR_LIB_OBJ, ERR_R_MALLOC_FAILURE);
455 return NULL;
456 }
457
458 p = buf;
459 /* Write out tag+length */
460 ASN1_put_object(&p, 0, i, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
461 /* Write out contents */
462 a2d_ASN1_OBJECT(p, i, s, -1);
463
464 cp = buf;
465 op = d2i_ASN1_OBJECT(NULL, &cp, j);
466 OPENSSL_free(buf);
467 return op;
468}
469
470int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
471{
472 int i, n = 0, len, nid, first, use_bn;
473 BIGNUM *bl;
474 unsigned long l;
475 const unsigned char *p;
476 char tbuf[DECIMAL_SIZE(i) + DECIMAL_SIZE(l) + 2];
477 const char *s;
478
479 /* Ensure that, at every state, |buf| is NUL-terminated. */
480 if (buf != NULL && buf_len > 0)
481 buf[0] = '\0';
482
483 if (a == NULL || a->data == NULL)
484 return 0;
485
486 if (!no_name && (nid = OBJ_obj2nid(a)) != NID_undef) {
487 s = OBJ_nid2ln(nid);
488 if (s == NULL)
489 s = OBJ_nid2sn(nid);
490 if (s != NULL) {
491 if (buf != NULL)
492 OPENSSL_strlcpy(buf, s, buf_len);
493 return (int)strlen(s);
494 }
495 }
496
497 len = a->length;
498 p = a->data;
499
500 first = 1;
501 bl = NULL;
502
503 /*
504 * RFC 2578 (STD 58) says this about OBJECT IDENTIFIERs:
505 *
506 * > 3.5. OBJECT IDENTIFIER values
507 * >
508 * > An OBJECT IDENTIFIER value is an ordered list of non-negative
509 * > numbers. For the SMIv2, each number in the list is referred to as a
510 * > sub-identifier, there are at most 128 sub-identifiers in a value,
511 * > and each sub-identifier has a maximum value of 2^32-1 (4294967295
512 * > decimal).
513 *
514 * So a legitimate OID according to this RFC is at most (32 * 128 / 7),
515 * i.e. 586 bytes long.
516 *
517 * Ref: https://datatracker.ietf.org/doc/html/rfc2578#section-3.5
518 */
519 if (len > 586)
520 goto err;
521
522 while (len > 0) {
523 l = 0;
524 use_bn = 0;
525 for (;;) {
526 unsigned char c = *p++;
527 len--;
528 if ((len == 0) && (c & 0x80))
529 goto err;
530 if (use_bn) {
531 if (!BN_add_word(bl, c & 0x7f))
532 goto err;
533 } else
534 l |= c & 0x7f;
535 if (!(c & 0x80))
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 if (first) {
552 first = 0;
553 if (l >= 80) {
554 i = 2;
555 if (use_bn) {
556 if (!BN_sub_word(bl, 80))
557 goto err;
558 } else
559 l -= 80;
560 } else {
561 i = (int)(l / 40);
562 l -= (long)(i * 40);
563 }
564 if (buf && (buf_len > 1)) {
565 *buf++ = i + '0';
566 *buf = '\0';
567 buf_len--;
568 }
569 n++;
570 }
571
572 if (use_bn) {
573 char *bndec;
574 bndec = BN_bn2dec(bl);
575 if (!bndec)
576 goto err;
577 i = strlen(bndec);
578 if (buf) {
579 if (buf_len > 1) {
580 *buf++ = '.';
581 *buf = '\0';
582 buf_len--;
583 }
584 OPENSSL_strlcpy(buf, bndec, buf_len);
585 if (i > buf_len) {
586 buf += buf_len;
587 buf_len = 0;
588 } else {
589 buf += i;
590 buf_len -= i;
591 }
592 }
593 n++;
594 n += i;
595 OPENSSL_free(bndec);
596 } else {
597 BIO_snprintf(tbuf, sizeof(tbuf), ".%lu", l);
598 i = strlen(tbuf);
599 if (buf && (buf_len > 0)) {
600 OPENSSL_strlcpy(buf, tbuf, buf_len);
601 if (i > buf_len) {
602 buf += buf_len;
603 buf_len = 0;
604 } else {
605 buf += i;
606 buf_len -= i;
607 }
608 }
609 n += i;
610 l = 0;
611 }
612 }
613
614 BN_free(bl);
615 return n;
616
617 err:
618 BN_free(bl);
619 return -1;
620}
621
622int OBJ_txt2nid(const char *s)
623{
624 ASN1_OBJECT *obj = OBJ_txt2obj(s, 0);
625 int nid = NID_undef;
626
627 if (obj != NULL) {
628 nid = OBJ_obj2nid(obj);
629 ASN1_OBJECT_free(obj);
630 }
631 return nid;
632}
633
634int OBJ_ln2nid(const char *s)
635{
636 ASN1_OBJECT o;
637 const ASN1_OBJECT *oo = &o;
638 ADDED_OBJ ad, *adp;
639 const unsigned int *op;
640 int nid = NID_undef;
641
642 o.ln = s;
643 op = OBJ_bsearch_ln(&oo, ln_objs, NUM_LN);
644 if (op != NULL)
645 return nid_objs[*op].nid;
646 if (!ossl_obj_read_lock(1)) {
647 ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_READ_LOCK);
648 return NID_undef;
649 }
650 if (added != NULL) {
651 ad.type = ADDED_LNAME;
652 ad.obj = &o;
653 adp = lh_ADDED_OBJ_retrieve(added, &ad);
654 if (adp != NULL)
655 nid = adp->obj->nid;
656 }
657 ossl_obj_unlock(1);
658 return nid;
659}
660
661int OBJ_sn2nid(const char *s)
662{
663 ASN1_OBJECT o;
664 const ASN1_OBJECT *oo = &o;
665 ADDED_OBJ ad, *adp;
666 const unsigned int *op;
667 int nid = NID_undef;
668
669 o.sn = s;
670 op = OBJ_bsearch_sn(&oo, sn_objs, NUM_SN);
671 if (op != NULL)
672 return nid_objs[*op].nid;
673 if (!ossl_obj_read_lock(1)) {
674 ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_READ_LOCK);
675 return NID_undef;
676 }
677 if (added != NULL) {
678 ad.type = ADDED_SNAME;
679 ad.obj = &o;
680 adp = lh_ADDED_OBJ_retrieve(added, &ad);
681 if (adp != NULL)
682 nid = adp->obj->nid;
683 }
684 ossl_obj_unlock(1);
685 return nid;
686}
687
688const void *OBJ_bsearch_(const void *key, const void *base, int num, int size,
689 int (*cmp) (const void *, const void *))
690{
691 return OBJ_bsearch_ex_(key, base, num, size, cmp, 0);
692}
693
694const void *OBJ_bsearch_ex_(const void *key, const void *base, int num,
695 int size,
696 int (*cmp) (const void *, const void *),
697 int flags)
698{
699 const char *p = ossl_bsearch(key, base, num, size, cmp, flags);
700
701#ifdef CHARSET_EBCDIC
702 /*
703 * THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and I
704 * don't have perl (yet), we revert to a *LINEAR* search when the object
705 * wasn't found in the binary search.
706 */
707 if (p == NULL) {
708 const char *base_ = base;
709 int l, h, i = 0, c = 0;
710 char *p1;
711
712 for (i = 0; i < num; ++i) {
713 p1 = &(base_[i * size]);
714 c = (*cmp) (key, p1);
715 if (c == 0
716 || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)))
717 return p1;
718 }
719 }
720#endif
721 return p;
722}
723
724/*
725 * Parse a BIO sink to create some extra oid's objects.
726 * Line format:<OID:isdigit or '.']><isspace><SN><isspace><LN>
727 */
728int OBJ_create_objects(BIO *in)
729{
730 char buf[512];
731 int i, num = 0;
732 char *o, *s, *l = NULL;
733
734 for (;;) {
735 s = o = NULL;
736 i = BIO_gets(in, buf, 512);
737 if (i <= 0)
738 return num;
739 buf[i - 1] = '\0';
740 if (!ossl_isalnum(buf[0]))
741 return num;
742 o = s = buf;
743 while (ossl_isdigit(*s) || *s == '.')
744 s++;
745 if (*s != '\0') {
746 *(s++) = '\0';
747 while (ossl_isspace(*s))
748 s++;
749 if (*s == '\0') {
750 s = NULL;
751 } else {
752 l = s;
753 while (*l != '\0' && !ossl_isspace(*l))
754 l++;
755 if (*l != '\0') {
756 *(l++) = '\0';
757 while (ossl_isspace(*l))
758 l++;
759 if (*l == '\0') {
760 l = NULL;
761 }
762 } else {
763 l = NULL;
764 }
765 }
766 } else {
767 s = NULL;
768 }
769 if (*o == '\0')
770 return num;
771 if (!OBJ_create(o, s, l))
772 return num;
773 num++;
774 }
775}
776
777int OBJ_create(const char *oid, const char *sn, const char *ln)
778{
779 ASN1_OBJECT *tmpoid = NULL;
780 int ok = 0;
781
782 /* Check to see if short or long name already present */
783 if ((sn != NULL && OBJ_sn2nid(sn) != NID_undef)
784 || (ln != NULL && OBJ_ln2nid(ln) != NID_undef)) {
785 ERR_raise(ERR_LIB_OBJ, OBJ_R_OID_EXISTS);
786 return 0;
787 }
788
789 /* Convert numerical OID string to an ASN1_OBJECT structure */
790 tmpoid = OBJ_txt2obj(oid, 1);
791 if (tmpoid == NULL)
792 return 0;
793
794 if (!ossl_obj_write_lock(1)) {
795 ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
796 ASN1_OBJECT_free(tmpoid);
797 return 0;
798 }
799
800 /* If NID is not NID_undef then object already exists */
801 if (ossl_obj_obj2nid(tmpoid, 0) != NID_undef) {
802 ERR_raise(ERR_LIB_OBJ, OBJ_R_OID_EXISTS);
803 goto err;
804 }
805
806 tmpoid->nid = obj_new_nid_unlocked(1);
807
808 if (tmpoid->nid == NID_undef)
809 goto err;
810
811 tmpoid->sn = (char *)sn;
812 tmpoid->ln = (char *)ln;
813
814 ok = ossl_obj_add_object(tmpoid, 0);
815
816 tmpoid->sn = NULL;
817 tmpoid->ln = NULL;
818
819 err:
820 ossl_obj_unlock(1);
821 ASN1_OBJECT_free(tmpoid);
822 return ok;
823}
824
825size_t OBJ_length(const ASN1_OBJECT *obj)
826{
827 if (obj == NULL)
828 return 0;
829 return obj->length;
830}
831
832const unsigned char *OBJ_get0_data(const ASN1_OBJECT *obj)
833{
834 if (obj == NULL)
835 return NULL;
836 return obj->data;
837}
838
839int OBJ_add_object(const ASN1_OBJECT *obj)
840{
841 return ossl_obj_add_object(obj, 1);
842}
843
844int OBJ_obj2nid(const ASN1_OBJECT *a)
845{
846 return ossl_obj_obj2nid(a, 1);
847}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette