VirtualBox

source: vbox/trunk/src/libs/openssl-3.1.3/crypto/objects/obj_dat.c@ 101211

Last change on this file since 101211 was 101211, checked in by vboxsync, 17 months ago

openssl-3.1.3: Applied and adjusted our OpenSSL changes to 3.1.2. bugref:10527

File size: 20.3 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
232int OBJ_new_nid(int num)
233{
234#ifdef OBJ_USE_LOCK_FOR_NEW_NID
235 static int new_nid = NUM_NID;
236 int i;
237
238 if (!CRYPTO_THREAD_write_lock(ossl_obj_nid_lock)) {
239 ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
240 return NID_undef;
241 }
242 i = new_nid;
243 new_nid += num;
244 CRYPTO_THREAD_unlock(ossl_obj_nid_lock);
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
253static int ossl_obj_add_object(const ASN1_OBJECT *obj, int lock)
254{
255 ASN1_OBJECT *o = NULL;
256 ADDED_OBJ *ao[4] = { NULL, NULL, NULL, NULL }, *aop;
257 int i;
258
259 if ((o = OBJ_dup(obj)) == NULL)
260 return NID_undef;
261 if ((ao[ADDED_NID] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL
262 || (o->length != 0
263 && obj->data != NULL
264 && (ao[ADDED_DATA] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL)
265 || (o->sn != NULL
266 && (ao[ADDED_SNAME] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL)
267 || (o->ln != NULL
268 && (ao[ADDED_LNAME] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL)) {
269 ERR_raise(ERR_LIB_OBJ, ERR_R_MALLOC_FAILURE);
270 goto err2;
271 }
272
273 if (!ossl_obj_write_lock(lock)) {
274 ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
275 goto err2;
276 }
277 if (added == NULL) {
278 added = lh_ADDED_OBJ_new(added_obj_hash, added_obj_cmp);
279 if (added == NULL) {
280 ERR_raise(ERR_LIB_OBJ, ERR_R_MALLOC_FAILURE);
281 goto err;
282 }
283 }
284
285 for (i = ADDED_DATA; i <= ADDED_NID; i++) {
286 if (ao[i] != NULL) {
287 ao[i]->type = i;
288 ao[i]->obj = o;
289 aop = lh_ADDED_OBJ_insert(added, ao[i]);
290 /* memory leak, but should not normally matter */
291 OPENSSL_free(aop);
292 }
293 }
294 o->flags &=
295 ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
296 ASN1_OBJECT_FLAG_DYNAMIC_DATA);
297
298 ossl_obj_unlock(lock);
299 return o->nid;
300
301 err:
302 ossl_obj_unlock(lock);
303 err2:
304 for (i = ADDED_DATA; i <= ADDED_NID; i++)
305 OPENSSL_free(ao[i]);
306 ASN1_OBJECT_free(o);
307 return NID_undef;
308}
309
310ASN1_OBJECT *OBJ_nid2obj(int n)
311{
312 ADDED_OBJ ad, *adp = NULL;
313 ASN1_OBJECT ob;
314
315 if (n == NID_undef
316 || (n > 0 && n < NUM_NID && nid_objs[n].nid != NID_undef))
317 return (ASN1_OBJECT *)&(nid_objs[n]);
318
319 ad.type = ADDED_NID;
320 ad.obj = &ob;
321 ob.nid = n;
322 if (!ossl_obj_read_lock(1)) {
323 ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_READ_LOCK);
324 return NULL;
325 }
326 if (added != NULL)
327 adp = lh_ADDED_OBJ_retrieve(added, &ad);
328 ossl_obj_unlock(1);
329 if (adp != NULL)
330 return adp->obj;
331
332 ERR_raise(ERR_LIB_OBJ, OBJ_R_UNKNOWN_NID);
333 return NULL;
334}
335
336const char *OBJ_nid2sn(int n)
337{
338 ASN1_OBJECT *ob = OBJ_nid2obj(n);
339
340 return ob == NULL ? NULL : ob->sn;
341}
342
343const char *OBJ_nid2ln(int n)
344{
345 ASN1_OBJECT *ob = OBJ_nid2obj(n);
346
347 return ob == NULL ? NULL : ob->ln;
348}
349
350static int obj_cmp(const ASN1_OBJECT *const *ap, const unsigned int *bp)
351{
352 int j;
353 const ASN1_OBJECT *a = *ap;
354 const ASN1_OBJECT *b = &nid_objs[*bp];
355
356 j = (a->length - b->length);
357 if (j)
358 return j;
359 if (a->length == 0)
360 return 0;
361 return memcmp(a->data, b->data, a->length);
362}
363
364IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
365
366static int ossl_obj_obj2nid(const ASN1_OBJECT *a, const int lock)
367{
368 int nid = NID_undef;
369 const unsigned int *op;
370 ADDED_OBJ ad, *adp;
371
372 if (a == NULL)
373 return NID_undef;
374 if (a->nid != NID_undef)
375 return a->nid;
376 if (a->length == 0)
377 return NID_undef;
378
379 op = OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ);
380 if (op != NULL)
381 return nid_objs[*op].nid;
382 if (!ossl_obj_read_lock(lock)) {
383 ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_READ_LOCK);
384 return NID_undef;
385 }
386 if (added != NULL) {
387 ad.type = ADDED_DATA;
388 ad.obj = (ASN1_OBJECT *)a; /* casting away const is harmless here */
389 adp = lh_ADDED_OBJ_retrieve(added, &ad);
390 if (adp != NULL)
391 nid = adp->obj->nid;
392 }
393 ossl_obj_unlock(lock);
394 return nid;
395}
396
397/*
398 * Convert an object name into an ASN1_OBJECT if "noname" is not set then
399 * search for short and long names first. This will convert the "dotted" form
400 * into an object: unlike OBJ_txt2nid it can be used with any objects, not
401 * just registered ones.
402 */
403ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name)
404{
405 int nid = NID_undef;
406 ASN1_OBJECT *op = NULL;
407 unsigned char *buf;
408 unsigned char *p;
409 const unsigned char *cp;
410 int i, j;
411
412 if (!no_name) {
413 if ((nid = OBJ_sn2nid(s)) != NID_undef ||
414 (nid = OBJ_ln2nid(s)) != NID_undef) {
415 return OBJ_nid2obj(nid);
416 }
417 if (!ossl_isdigit(*s)) {
418 ERR_raise(ERR_LIB_OBJ, OBJ_R_UNKNOWN_OBJECT_NAME);
419 return NULL;
420 }
421 }
422
423 /* Work out size of content octets */
424 i = a2d_ASN1_OBJECT(NULL, 0, s, -1);
425 if (i <= 0)
426 return NULL;
427
428 /* Work out total size */
429 j = ASN1_object_size(0, i, V_ASN1_OBJECT);
430 if (j < 0)
431 return NULL;
432
433 if ((buf = OPENSSL_malloc(j)) == NULL) {
434 ERR_raise(ERR_LIB_OBJ, ERR_R_MALLOC_FAILURE);
435 return NULL;
436 }
437
438 p = buf;
439 /* Write out tag+length */
440 ASN1_put_object(&p, 0, i, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
441 /* Write out contents */
442 a2d_ASN1_OBJECT(p, i, s, -1);
443
444 cp = buf;
445 op = d2i_ASN1_OBJECT(NULL, &cp, j);
446 OPENSSL_free(buf);
447 return op;
448}
449
450int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
451{
452 int i, n = 0, len, nid, first, use_bn;
453 BIGNUM *bl;
454 unsigned long l;
455 const unsigned char *p;
456 char tbuf[DECIMAL_SIZE(i) + DECIMAL_SIZE(l) + 2];
457 const char *s;
458
459 /* Ensure that, at every state, |buf| is NUL-terminated. */
460 if (buf != NULL && buf_len > 0)
461 buf[0] = '\0';
462
463 if (a == NULL || a->data == NULL)
464 return 0;
465
466 if (!no_name && (nid = OBJ_obj2nid(a)) != NID_undef) {
467 s = OBJ_nid2ln(nid);
468 if (s == NULL)
469 s = OBJ_nid2sn(nid);
470 if (s != NULL) {
471 if (buf != NULL)
472 OPENSSL_strlcpy(buf, s, buf_len);
473 return (int)strlen(s);
474 }
475 }
476
477 len = a->length;
478 p = a->data;
479
480 first = 1;
481 bl = NULL;
482
483 /*
484 * RFC 2578 (STD 58) says this about OBJECT IDENTIFIERs:
485 *
486 * > 3.5. OBJECT IDENTIFIER values
487 * >
488 * > An OBJECT IDENTIFIER value is an ordered list of non-negative
489 * > numbers. For the SMIv2, each number in the list is referred to as a
490 * > sub-identifier, there are at most 128 sub-identifiers in a value,
491 * > and each sub-identifier has a maximum value of 2^32-1 (4294967295
492 * > decimal).
493 *
494 * So a legitimate OID according to this RFC is at most (32 * 128 / 7),
495 * i.e. 586 bytes long.
496 *
497 * Ref: https://datatracker.ietf.org/doc/html/rfc2578#section-3.5
498 */
499 if (len > 586)
500 goto err;
501
502 while (len > 0) {
503 l = 0;
504 use_bn = 0;
505 for (;;) {
506 unsigned char c = *p++;
507 len--;
508 if ((len == 0) && (c & 0x80))
509 goto err;
510 if (use_bn) {
511 if (!BN_add_word(bl, c & 0x7f))
512 goto err;
513 } else
514 l |= c & 0x7f;
515 if (!(c & 0x80))
516 break;
517 if (!use_bn && (l > (ULONG_MAX >> 7L))) {
518 if (bl == NULL && (bl = BN_new()) == NULL)
519 goto err;
520 if (!BN_set_word(bl, l))
521 goto err;
522 use_bn = 1;
523 }
524 if (use_bn) {
525 if (!BN_lshift(bl, bl, 7))
526 goto err;
527 } else
528 l <<= 7L;
529 }
530
531 if (first) {
532 first = 0;
533 if (l >= 80) {
534 i = 2;
535 if (use_bn) {
536 if (!BN_sub_word(bl, 80))
537 goto err;
538 } else
539 l -= 80;
540 } else {
541 i = (int)(l / 40);
542 l -= (long)(i * 40);
543 }
544 if (buf && (buf_len > 1)) {
545 *buf++ = i + '0';
546 *buf = '\0';
547 buf_len--;
548 }
549 n++;
550 }
551
552 if (use_bn) {
553 char *bndec;
554 bndec = BN_bn2dec(bl);
555 if (!bndec)
556 goto err;
557 i = strlen(bndec);
558 if (buf) {
559 if (buf_len > 1) {
560 *buf++ = '.';
561 *buf = '\0';
562 buf_len--;
563 }
564 OPENSSL_strlcpy(buf, bndec, buf_len);
565 if (i > buf_len) {
566 buf += buf_len;
567 buf_len = 0;
568 } else {
569 buf += i;
570 buf_len -= i;
571 }
572 }
573 n++;
574 n += i;
575 OPENSSL_free(bndec);
576 } else {
577 BIO_snprintf(tbuf, sizeof(tbuf), ".%lu", l);
578 i = strlen(tbuf);
579 if (buf && (buf_len > 0)) {
580 OPENSSL_strlcpy(buf, tbuf, buf_len);
581 if (i > buf_len) {
582 buf += buf_len;
583 buf_len = 0;
584 } else {
585 buf += i;
586 buf_len -= i;
587 }
588 }
589 n += i;
590 l = 0;
591 }
592 }
593
594 BN_free(bl);
595 return n;
596
597 err:
598 BN_free(bl);
599 return -1;
600}
601
602int OBJ_txt2nid(const char *s)
603{
604 ASN1_OBJECT *obj = OBJ_txt2obj(s, 0);
605 int nid = NID_undef;
606
607 if (obj != NULL) {
608 nid = OBJ_obj2nid(obj);
609 ASN1_OBJECT_free(obj);
610 }
611 return nid;
612}
613
614int OBJ_ln2nid(const char *s)
615{
616 ASN1_OBJECT o;
617 const ASN1_OBJECT *oo = &o;
618 ADDED_OBJ ad, *adp;
619 const unsigned int *op;
620 int nid = NID_undef;
621
622 o.ln = s;
623 op = OBJ_bsearch_ln(&oo, ln_objs, NUM_LN);
624 if (op != NULL)
625 return nid_objs[*op].nid;
626 if (!ossl_obj_read_lock(1)) {
627 ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_READ_LOCK);
628 return NID_undef;
629 }
630 if (added != NULL) {
631 ad.type = ADDED_LNAME;
632 ad.obj = &o;
633 adp = lh_ADDED_OBJ_retrieve(added, &ad);
634 if (adp != NULL)
635 nid = adp->obj->nid;
636 }
637 ossl_obj_unlock(1);
638 return nid;
639}
640
641int OBJ_sn2nid(const char *s)
642{
643 ASN1_OBJECT o;
644 const ASN1_OBJECT *oo = &o;
645 ADDED_OBJ ad, *adp;
646 const unsigned int *op;
647 int nid = NID_undef;
648
649 o.sn = s;
650 op = OBJ_bsearch_sn(&oo, sn_objs, NUM_SN);
651 if (op != NULL)
652 return nid_objs[*op].nid;
653 if (!ossl_obj_read_lock(1)) {
654 ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_READ_LOCK);
655 return NID_undef;
656 }
657 if (added != NULL) {
658 ad.type = ADDED_SNAME;
659 ad.obj = &o;
660 adp = lh_ADDED_OBJ_retrieve(added, &ad);
661 if (adp != NULL)
662 nid = adp->obj->nid;
663 }
664 ossl_obj_unlock(1);
665 return nid;
666}
667
668const void *OBJ_bsearch_(const void *key, const void *base, int num, int size,
669 int (*cmp) (const void *, const void *))
670{
671 return OBJ_bsearch_ex_(key, base, num, size, cmp, 0);
672}
673
674const void *OBJ_bsearch_ex_(const void *key, const void *base, int num,
675 int size,
676 int (*cmp) (const void *, const void *),
677 int flags)
678{
679 const char *p = ossl_bsearch(key, base, num, size, cmp, flags);
680
681#ifdef CHARSET_EBCDIC
682 /*
683 * THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and I
684 * don't have perl (yet), we revert to a *LINEAR* search when the object
685 * wasn't found in the binary search.
686 */
687 if (p == NULL) {
688 const char *base_ = base;
689 int l, h, i = 0, c = 0;
690
691 for (i = 0; i < num; ++i) {
692 p = &(base_[i * size]);
693 c = (*cmp) (key, p);
694 if (c == 0
695 || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)))
696 return p;
697 }
698 }
699#endif
700 return p;
701}
702
703/*
704 * Parse a BIO sink to create some extra oid's objects.
705 * Line format:<OID:isdigit or '.']><isspace><SN><isspace><LN>
706 */
707int OBJ_create_objects(BIO *in)
708{
709 char buf[512];
710 int i, num = 0;
711 char *o, *s, *l = NULL;
712
713 for (;;) {
714 s = o = NULL;
715 i = BIO_gets(in, buf, 512);
716 if (i <= 0)
717 return num;
718 buf[i - 1] = '\0';
719 if (!ossl_isalnum(buf[0]))
720 return num;
721 o = s = buf;
722 while (ossl_isdigit(*s) || *s == '.')
723 s++;
724 if (*s != '\0') {
725 *(s++) = '\0';
726 while (ossl_isspace(*s))
727 s++;
728 if (*s == '\0') {
729 s = NULL;
730 } else {
731 l = s;
732 while (*l != '\0' && !ossl_isspace(*l))
733 l++;
734 if (*l != '\0') {
735 *(l++) = '\0';
736 while (ossl_isspace(*l))
737 l++;
738 if (*l == '\0') {
739 l = NULL;
740 }
741 } else {
742 l = NULL;
743 }
744 }
745 } else {
746 s = NULL;
747 }
748 if (*o == '\0')
749 return num;
750 if (!OBJ_create(o, s, l))
751 return num;
752 num++;
753 }
754}
755
756int OBJ_create(const char *oid, const char *sn, const char *ln)
757{
758 ASN1_OBJECT *tmpoid = NULL;
759 int ok = 0;
760
761 /* Check to see if short or long name already present */
762 if ((sn != NULL && OBJ_sn2nid(sn) != NID_undef)
763 || (ln != NULL && OBJ_ln2nid(ln) != NID_undef)) {
764 ERR_raise(ERR_LIB_OBJ, OBJ_R_OID_EXISTS);
765 return 0;
766 }
767
768 /* Convert numerical OID string to an ASN1_OBJECT structure */
769 tmpoid = OBJ_txt2obj(oid, 1);
770 if (tmpoid == NULL)
771 return 0;
772
773 if (!ossl_obj_write_lock(1)) {
774 ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
775 ASN1_OBJECT_free(tmpoid);
776 return 0;
777 }
778
779 /* If NID is not NID_undef then object already exists */
780 if (ossl_obj_obj2nid(tmpoid, 0) != NID_undef) {
781 ERR_raise(ERR_LIB_OBJ, OBJ_R_OID_EXISTS);
782 goto err;
783 }
784
785 tmpoid->nid = OBJ_new_nid(1);
786 if (tmpoid->nid == NID_undef)
787 goto err;
788
789 tmpoid->sn = (char *)sn;
790 tmpoid->ln = (char *)ln;
791
792 ok = ossl_obj_add_object(tmpoid, 0);
793
794 tmpoid->sn = NULL;
795 tmpoid->ln = NULL;
796
797 err:
798 ossl_obj_unlock(1);
799 ASN1_OBJECT_free(tmpoid);
800 return ok;
801}
802
803size_t OBJ_length(const ASN1_OBJECT *obj)
804{
805 if (obj == NULL)
806 return 0;
807 return obj->length;
808}
809
810const unsigned char *OBJ_get0_data(const ASN1_OBJECT *obj)
811{
812 if (obj == NULL)
813 return NULL;
814 return obj->data;
815}
816
817int OBJ_add_object(const ASN1_OBJECT *obj)
818{
819 return ossl_obj_add_object(obj, 1);
820}
821
822int OBJ_obj2nid(const ASN1_OBJECT *a)
823{
824 return ossl_obj_obj2nid(a, 1);
825}
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