1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci#include <stdio.h>
11e1051a39Sopenharmony_ci#include "crypto/ctype.h"
12e1051a39Sopenharmony_ci#include <limits.h>
13e1051a39Sopenharmony_ci#include "internal/cryptlib.h"
14e1051a39Sopenharmony_ci#include <openssl/lhash.h>
15e1051a39Sopenharmony_ci#include <openssl/asn1.h>
16e1051a39Sopenharmony_ci#include "crypto/objects.h"
17e1051a39Sopenharmony_ci#include <openssl/bn.h>
18e1051a39Sopenharmony_ci#include "crypto/asn1.h"
19e1051a39Sopenharmony_ci#include "obj_local.h"
20e1051a39Sopenharmony_ci
21e1051a39Sopenharmony_ci/* obj_dat.h is generated from objects.h by obj_dat.pl */
22e1051a39Sopenharmony_ci#include "obj_dat.h"
23e1051a39Sopenharmony_ci
24e1051a39Sopenharmony_ciDECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
25e1051a39Sopenharmony_ciDECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
26e1051a39Sopenharmony_ciDECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
27e1051a39Sopenharmony_ci
28e1051a39Sopenharmony_ci#define ADDED_DATA      0
29e1051a39Sopenharmony_ci#define ADDED_SNAME     1
30e1051a39Sopenharmony_ci#define ADDED_LNAME     2
31e1051a39Sopenharmony_ci#define ADDED_NID       3
32e1051a39Sopenharmony_ci
33e1051a39Sopenharmony_cistruct added_obj_st {
34e1051a39Sopenharmony_ci    int type;
35e1051a39Sopenharmony_ci    ASN1_OBJECT *obj;
36e1051a39Sopenharmony_ci};
37e1051a39Sopenharmony_ci
38e1051a39Sopenharmony_cistatic int new_nid = NUM_NID;
39e1051a39Sopenharmony_cistatic LHASH_OF(ADDED_OBJ) *added = NULL;
40e1051a39Sopenharmony_ci
41e1051a39Sopenharmony_cistatic int sn_cmp(const ASN1_OBJECT *const *a, const unsigned int *b)
42e1051a39Sopenharmony_ci{
43e1051a39Sopenharmony_ci    return strcmp((*a)->sn, nid_objs[*b].sn);
44e1051a39Sopenharmony_ci}
45e1051a39Sopenharmony_ci
46e1051a39Sopenharmony_ciIMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
47e1051a39Sopenharmony_ci
48e1051a39Sopenharmony_cistatic int ln_cmp(const ASN1_OBJECT *const *a, const unsigned int *b)
49e1051a39Sopenharmony_ci{
50e1051a39Sopenharmony_ci    return strcmp((*a)->ln, nid_objs[*b].ln);
51e1051a39Sopenharmony_ci}
52e1051a39Sopenharmony_ci
53e1051a39Sopenharmony_ciIMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
54e1051a39Sopenharmony_ci
55e1051a39Sopenharmony_cistatic unsigned long added_obj_hash(const ADDED_OBJ *ca)
56e1051a39Sopenharmony_ci{
57e1051a39Sopenharmony_ci    const ASN1_OBJECT *a;
58e1051a39Sopenharmony_ci    int i;
59e1051a39Sopenharmony_ci    unsigned long ret = 0;
60e1051a39Sopenharmony_ci    unsigned char *p;
61e1051a39Sopenharmony_ci
62e1051a39Sopenharmony_ci    a = ca->obj;
63e1051a39Sopenharmony_ci    switch (ca->type) {
64e1051a39Sopenharmony_ci    case ADDED_DATA:
65e1051a39Sopenharmony_ci        ret = a->length << 20L;
66e1051a39Sopenharmony_ci        p = (unsigned char *)a->data;
67e1051a39Sopenharmony_ci        for (i = 0; i < a->length; i++)
68e1051a39Sopenharmony_ci            ret ^= p[i] << ((i * 3) % 24);
69e1051a39Sopenharmony_ci        break;
70e1051a39Sopenharmony_ci    case ADDED_SNAME:
71e1051a39Sopenharmony_ci        ret = OPENSSL_LH_strhash(a->sn);
72e1051a39Sopenharmony_ci        break;
73e1051a39Sopenharmony_ci    case ADDED_LNAME:
74e1051a39Sopenharmony_ci        ret = OPENSSL_LH_strhash(a->ln);
75e1051a39Sopenharmony_ci        break;
76e1051a39Sopenharmony_ci    case ADDED_NID:
77e1051a39Sopenharmony_ci        ret = a->nid;
78e1051a39Sopenharmony_ci        break;
79e1051a39Sopenharmony_ci    default:
80e1051a39Sopenharmony_ci        /* abort(); */
81e1051a39Sopenharmony_ci        return 0;
82e1051a39Sopenharmony_ci    }
83e1051a39Sopenharmony_ci    ret &= 0x3fffffffL;
84e1051a39Sopenharmony_ci    ret |= ((unsigned long)ca->type) << 30L;
85e1051a39Sopenharmony_ci    return ret;
86e1051a39Sopenharmony_ci}
87e1051a39Sopenharmony_ci
88e1051a39Sopenharmony_cistatic int added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb)
89e1051a39Sopenharmony_ci{
90e1051a39Sopenharmony_ci    ASN1_OBJECT *a, *b;
91e1051a39Sopenharmony_ci    int i;
92e1051a39Sopenharmony_ci
93e1051a39Sopenharmony_ci    i = ca->type - cb->type;
94e1051a39Sopenharmony_ci    if (i)
95e1051a39Sopenharmony_ci        return i;
96e1051a39Sopenharmony_ci    a = ca->obj;
97e1051a39Sopenharmony_ci    b = cb->obj;
98e1051a39Sopenharmony_ci    switch (ca->type) {
99e1051a39Sopenharmony_ci    case ADDED_DATA:
100e1051a39Sopenharmony_ci        i = (a->length - b->length);
101e1051a39Sopenharmony_ci        if (i)
102e1051a39Sopenharmony_ci            return i;
103e1051a39Sopenharmony_ci        return memcmp(a->data, b->data, (size_t)a->length);
104e1051a39Sopenharmony_ci    case ADDED_SNAME:
105e1051a39Sopenharmony_ci        if (a->sn == NULL)
106e1051a39Sopenharmony_ci            return -1;
107e1051a39Sopenharmony_ci        else if (b->sn == NULL)
108e1051a39Sopenharmony_ci            return 1;
109e1051a39Sopenharmony_ci        else
110e1051a39Sopenharmony_ci            return strcmp(a->sn, b->sn);
111e1051a39Sopenharmony_ci    case ADDED_LNAME:
112e1051a39Sopenharmony_ci        if (a->ln == NULL)
113e1051a39Sopenharmony_ci            return -1;
114e1051a39Sopenharmony_ci        else if (b->ln == NULL)
115e1051a39Sopenharmony_ci            return 1;
116e1051a39Sopenharmony_ci        else
117e1051a39Sopenharmony_ci            return strcmp(a->ln, b->ln);
118e1051a39Sopenharmony_ci    case ADDED_NID:
119e1051a39Sopenharmony_ci        return a->nid - b->nid;
120e1051a39Sopenharmony_ci    default:
121e1051a39Sopenharmony_ci        /* abort(); */
122e1051a39Sopenharmony_ci        return 0;
123e1051a39Sopenharmony_ci    }
124e1051a39Sopenharmony_ci}
125e1051a39Sopenharmony_ci
126e1051a39Sopenharmony_cistatic int init_added(void)
127e1051a39Sopenharmony_ci{
128e1051a39Sopenharmony_ci    if (added != NULL)
129e1051a39Sopenharmony_ci        return 1;
130e1051a39Sopenharmony_ci    added = lh_ADDED_OBJ_new(added_obj_hash, added_obj_cmp);
131e1051a39Sopenharmony_ci    return added != NULL;
132e1051a39Sopenharmony_ci}
133e1051a39Sopenharmony_ci
134e1051a39Sopenharmony_cistatic void cleanup1_doall(ADDED_OBJ *a)
135e1051a39Sopenharmony_ci{
136e1051a39Sopenharmony_ci    a->obj->nid = 0;
137e1051a39Sopenharmony_ci    a->obj->flags |= ASN1_OBJECT_FLAG_DYNAMIC |
138e1051a39Sopenharmony_ci        ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | ASN1_OBJECT_FLAG_DYNAMIC_DATA;
139e1051a39Sopenharmony_ci}
140e1051a39Sopenharmony_ci
141e1051a39Sopenharmony_cistatic void cleanup2_doall(ADDED_OBJ *a)
142e1051a39Sopenharmony_ci{
143e1051a39Sopenharmony_ci    a->obj->nid++;
144e1051a39Sopenharmony_ci}
145e1051a39Sopenharmony_ci
146e1051a39Sopenharmony_cistatic void cleanup3_doall(ADDED_OBJ *a)
147e1051a39Sopenharmony_ci{
148e1051a39Sopenharmony_ci    if (--a->obj->nid == 0)
149e1051a39Sopenharmony_ci        ASN1_OBJECT_free(a->obj);
150e1051a39Sopenharmony_ci    OPENSSL_free(a);
151e1051a39Sopenharmony_ci}
152e1051a39Sopenharmony_ci
153e1051a39Sopenharmony_civoid ossl_obj_cleanup_int(void)
154e1051a39Sopenharmony_ci{
155e1051a39Sopenharmony_ci    if (added == NULL)
156e1051a39Sopenharmony_ci        return;
157e1051a39Sopenharmony_ci    lh_ADDED_OBJ_set_down_load(added, 0);
158e1051a39Sopenharmony_ci    lh_ADDED_OBJ_doall(added, cleanup1_doall); /* zero counters */
159e1051a39Sopenharmony_ci    lh_ADDED_OBJ_doall(added, cleanup2_doall); /* set counters */
160e1051a39Sopenharmony_ci    lh_ADDED_OBJ_doall(added, cleanup3_doall); /* free objects */
161e1051a39Sopenharmony_ci    lh_ADDED_OBJ_free(added);
162e1051a39Sopenharmony_ci    added = NULL;
163e1051a39Sopenharmony_ci}
164e1051a39Sopenharmony_ci
165e1051a39Sopenharmony_ciint OBJ_new_nid(int num)
166e1051a39Sopenharmony_ci{
167e1051a39Sopenharmony_ci    int i;
168e1051a39Sopenharmony_ci
169e1051a39Sopenharmony_ci    i = new_nid;
170e1051a39Sopenharmony_ci    new_nid += num;
171e1051a39Sopenharmony_ci    return i;
172e1051a39Sopenharmony_ci}
173e1051a39Sopenharmony_ci
174e1051a39Sopenharmony_ciint OBJ_add_object(const ASN1_OBJECT *obj)
175e1051a39Sopenharmony_ci{
176e1051a39Sopenharmony_ci    ASN1_OBJECT *o;
177e1051a39Sopenharmony_ci    ADDED_OBJ *ao[4] = { NULL, NULL, NULL, NULL }, *aop;
178e1051a39Sopenharmony_ci    int i;
179e1051a39Sopenharmony_ci
180e1051a39Sopenharmony_ci    if (added == NULL)
181e1051a39Sopenharmony_ci        if (!init_added())
182e1051a39Sopenharmony_ci            return 0;
183e1051a39Sopenharmony_ci    if ((o = OBJ_dup(obj)) == NULL)
184e1051a39Sopenharmony_ci        goto err;
185e1051a39Sopenharmony_ci    if ((ao[ADDED_NID] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL)
186e1051a39Sopenharmony_ci        goto err2;
187e1051a39Sopenharmony_ci    if ((o->length != 0) && (obj->data != NULL))
188e1051a39Sopenharmony_ci        if ((ao[ADDED_DATA] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL)
189e1051a39Sopenharmony_ci            goto err2;
190e1051a39Sopenharmony_ci    if (o->sn != NULL)
191e1051a39Sopenharmony_ci        if ((ao[ADDED_SNAME] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL)
192e1051a39Sopenharmony_ci            goto err2;
193e1051a39Sopenharmony_ci    if (o->ln != NULL)
194e1051a39Sopenharmony_ci        if ((ao[ADDED_LNAME] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL)
195e1051a39Sopenharmony_ci            goto err2;
196e1051a39Sopenharmony_ci
197e1051a39Sopenharmony_ci    for (i = ADDED_DATA; i <= ADDED_NID; i++) {
198e1051a39Sopenharmony_ci        if (ao[i] != NULL) {
199e1051a39Sopenharmony_ci            ao[i]->type = i;
200e1051a39Sopenharmony_ci            ao[i]->obj = o;
201e1051a39Sopenharmony_ci            aop = lh_ADDED_OBJ_insert(added, ao[i]);
202e1051a39Sopenharmony_ci            /* memory leak, but should not normally matter */
203e1051a39Sopenharmony_ci            OPENSSL_free(aop);
204e1051a39Sopenharmony_ci        }
205e1051a39Sopenharmony_ci    }
206e1051a39Sopenharmony_ci    o->flags &=
207e1051a39Sopenharmony_ci        ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
208e1051a39Sopenharmony_ci          ASN1_OBJECT_FLAG_DYNAMIC_DATA);
209e1051a39Sopenharmony_ci
210e1051a39Sopenharmony_ci    return o->nid;
211e1051a39Sopenharmony_ci err2:
212e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_OBJ, ERR_R_MALLOC_FAILURE);
213e1051a39Sopenharmony_ci err:
214e1051a39Sopenharmony_ci    for (i = ADDED_DATA; i <= ADDED_NID; i++)
215e1051a39Sopenharmony_ci        OPENSSL_free(ao[i]);
216e1051a39Sopenharmony_ci    ASN1_OBJECT_free(o);
217e1051a39Sopenharmony_ci    return NID_undef;
218e1051a39Sopenharmony_ci}
219e1051a39Sopenharmony_ci
220e1051a39Sopenharmony_ciASN1_OBJECT *OBJ_nid2obj(int n)
221e1051a39Sopenharmony_ci{
222e1051a39Sopenharmony_ci    ADDED_OBJ ad, *adp;
223e1051a39Sopenharmony_ci    ASN1_OBJECT ob;
224e1051a39Sopenharmony_ci
225e1051a39Sopenharmony_ci    if ((n >= 0) && (n < NUM_NID)) {
226e1051a39Sopenharmony_ci        if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
227e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_OBJ, OBJ_R_UNKNOWN_NID);
228e1051a39Sopenharmony_ci            return NULL;
229e1051a39Sopenharmony_ci        }
230e1051a39Sopenharmony_ci        return (ASN1_OBJECT *)&(nid_objs[n]);
231e1051a39Sopenharmony_ci    }
232e1051a39Sopenharmony_ci
233e1051a39Sopenharmony_ci    /* Make sure we've loaded config before checking for any "added" objects */
234e1051a39Sopenharmony_ci    OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
235e1051a39Sopenharmony_ci
236e1051a39Sopenharmony_ci    if (added == NULL)
237e1051a39Sopenharmony_ci        return NULL;
238e1051a39Sopenharmony_ci
239e1051a39Sopenharmony_ci    ad.type = ADDED_NID;
240e1051a39Sopenharmony_ci    ad.obj = &ob;
241e1051a39Sopenharmony_ci    ob.nid = n;
242e1051a39Sopenharmony_ci    adp = lh_ADDED_OBJ_retrieve(added, &ad);
243e1051a39Sopenharmony_ci    if (adp != NULL)
244e1051a39Sopenharmony_ci        return adp->obj;
245e1051a39Sopenharmony_ci
246e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_OBJ, OBJ_R_UNKNOWN_NID);
247e1051a39Sopenharmony_ci    return NULL;
248e1051a39Sopenharmony_ci}
249e1051a39Sopenharmony_ci
250e1051a39Sopenharmony_ciconst char *OBJ_nid2sn(int n)
251e1051a39Sopenharmony_ci{
252e1051a39Sopenharmony_ci    ADDED_OBJ ad, *adp;
253e1051a39Sopenharmony_ci    ASN1_OBJECT ob;
254e1051a39Sopenharmony_ci
255e1051a39Sopenharmony_ci    if ((n >= 0) && (n < NUM_NID)) {
256e1051a39Sopenharmony_ci        if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
257e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_OBJ, OBJ_R_UNKNOWN_NID);
258e1051a39Sopenharmony_ci            return NULL;
259e1051a39Sopenharmony_ci        }
260e1051a39Sopenharmony_ci        return nid_objs[n].sn;
261e1051a39Sopenharmony_ci    }
262e1051a39Sopenharmony_ci
263e1051a39Sopenharmony_ci    /* Make sure we've loaded config before checking for any "added" objects */
264e1051a39Sopenharmony_ci    OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
265e1051a39Sopenharmony_ci
266e1051a39Sopenharmony_ci    if (added == NULL)
267e1051a39Sopenharmony_ci        return NULL;
268e1051a39Sopenharmony_ci
269e1051a39Sopenharmony_ci    ad.type = ADDED_NID;
270e1051a39Sopenharmony_ci    ad.obj = &ob;
271e1051a39Sopenharmony_ci    ob.nid = n;
272e1051a39Sopenharmony_ci    adp = lh_ADDED_OBJ_retrieve(added, &ad);
273e1051a39Sopenharmony_ci    if (adp != NULL)
274e1051a39Sopenharmony_ci        return adp->obj->sn;
275e1051a39Sopenharmony_ci
276e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_OBJ, OBJ_R_UNKNOWN_NID);
277e1051a39Sopenharmony_ci    return NULL;
278e1051a39Sopenharmony_ci}
279e1051a39Sopenharmony_ci
280e1051a39Sopenharmony_ciconst char *OBJ_nid2ln(int n)
281e1051a39Sopenharmony_ci{
282e1051a39Sopenharmony_ci    ADDED_OBJ ad, *adp;
283e1051a39Sopenharmony_ci    ASN1_OBJECT ob;
284e1051a39Sopenharmony_ci
285e1051a39Sopenharmony_ci    if ((n >= 0) && (n < NUM_NID)) {
286e1051a39Sopenharmony_ci        if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
287e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_OBJ, OBJ_R_UNKNOWN_NID);
288e1051a39Sopenharmony_ci            return NULL;
289e1051a39Sopenharmony_ci        }
290e1051a39Sopenharmony_ci        return nid_objs[n].ln;
291e1051a39Sopenharmony_ci    }
292e1051a39Sopenharmony_ci
293e1051a39Sopenharmony_ci    /* Make sure we've loaded config before checking for any "added" objects */
294e1051a39Sopenharmony_ci    OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
295e1051a39Sopenharmony_ci
296e1051a39Sopenharmony_ci    if (added == NULL)
297e1051a39Sopenharmony_ci        return NULL;
298e1051a39Sopenharmony_ci
299e1051a39Sopenharmony_ci    ad.type = ADDED_NID;
300e1051a39Sopenharmony_ci    ad.obj = &ob;
301e1051a39Sopenharmony_ci    ob.nid = n;
302e1051a39Sopenharmony_ci    adp = lh_ADDED_OBJ_retrieve(added, &ad);
303e1051a39Sopenharmony_ci    if (adp != NULL)
304e1051a39Sopenharmony_ci        return adp->obj->ln;
305e1051a39Sopenharmony_ci
306e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_OBJ, OBJ_R_UNKNOWN_NID);
307e1051a39Sopenharmony_ci    return NULL;
308e1051a39Sopenharmony_ci}
309e1051a39Sopenharmony_ci
310e1051a39Sopenharmony_cistatic int obj_cmp(const ASN1_OBJECT *const *ap, const unsigned int *bp)
311e1051a39Sopenharmony_ci{
312e1051a39Sopenharmony_ci    int j;
313e1051a39Sopenharmony_ci    const ASN1_OBJECT *a = *ap;
314e1051a39Sopenharmony_ci    const ASN1_OBJECT *b = &nid_objs[*bp];
315e1051a39Sopenharmony_ci
316e1051a39Sopenharmony_ci    j = (a->length - b->length);
317e1051a39Sopenharmony_ci    if (j)
318e1051a39Sopenharmony_ci        return j;
319e1051a39Sopenharmony_ci    if (a->length == 0)
320e1051a39Sopenharmony_ci        return 0;
321e1051a39Sopenharmony_ci    return memcmp(a->data, b->data, a->length);
322e1051a39Sopenharmony_ci}
323e1051a39Sopenharmony_ci
324e1051a39Sopenharmony_ciIMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
325e1051a39Sopenharmony_ci
326e1051a39Sopenharmony_ciint OBJ_obj2nid(const ASN1_OBJECT *a)
327e1051a39Sopenharmony_ci{
328e1051a39Sopenharmony_ci    const unsigned int *op;
329e1051a39Sopenharmony_ci    ADDED_OBJ ad, *adp;
330e1051a39Sopenharmony_ci
331e1051a39Sopenharmony_ci    if (a == NULL)
332e1051a39Sopenharmony_ci        return NID_undef;
333e1051a39Sopenharmony_ci    if (a->nid != 0)
334e1051a39Sopenharmony_ci        return a->nid;
335e1051a39Sopenharmony_ci
336e1051a39Sopenharmony_ci    if (a->length == 0)
337e1051a39Sopenharmony_ci        return NID_undef;
338e1051a39Sopenharmony_ci
339e1051a39Sopenharmony_ci    /* Make sure we've loaded config before checking for any "added" objects */
340e1051a39Sopenharmony_ci    OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
341e1051a39Sopenharmony_ci
342e1051a39Sopenharmony_ci    if (added != NULL) {
343e1051a39Sopenharmony_ci        ad.type = ADDED_DATA;
344e1051a39Sopenharmony_ci        ad.obj = (ASN1_OBJECT *)a; /* XXX: ugly but harmless */
345e1051a39Sopenharmony_ci        adp = lh_ADDED_OBJ_retrieve(added, &ad);
346e1051a39Sopenharmony_ci        if (adp != NULL)
347e1051a39Sopenharmony_ci            return adp->obj->nid;
348e1051a39Sopenharmony_ci    }
349e1051a39Sopenharmony_ci    op = OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ);
350e1051a39Sopenharmony_ci    if (op == NULL)
351e1051a39Sopenharmony_ci        return NID_undef;
352e1051a39Sopenharmony_ci    return nid_objs[*op].nid;
353e1051a39Sopenharmony_ci}
354e1051a39Sopenharmony_ci
355e1051a39Sopenharmony_ci/*
356e1051a39Sopenharmony_ci * Convert an object name into an ASN1_OBJECT if "noname" is not set then
357e1051a39Sopenharmony_ci * search for short and long names first. This will convert the "dotted" form
358e1051a39Sopenharmony_ci * into an object: unlike OBJ_txt2nid it can be used with any objects, not
359e1051a39Sopenharmony_ci * just registered ones.
360e1051a39Sopenharmony_ci */
361e1051a39Sopenharmony_ci
362e1051a39Sopenharmony_ciASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name)
363e1051a39Sopenharmony_ci{
364e1051a39Sopenharmony_ci    int nid = NID_undef;
365e1051a39Sopenharmony_ci    ASN1_OBJECT *op;
366e1051a39Sopenharmony_ci    unsigned char *buf;
367e1051a39Sopenharmony_ci    unsigned char *p;
368e1051a39Sopenharmony_ci    const unsigned char *cp;
369e1051a39Sopenharmony_ci    int i, j;
370e1051a39Sopenharmony_ci
371e1051a39Sopenharmony_ci    if (!no_name) {
372e1051a39Sopenharmony_ci        if (((nid = OBJ_sn2nid(s)) != NID_undef) ||
373e1051a39Sopenharmony_ci            ((nid = OBJ_ln2nid(s)) != NID_undef))
374e1051a39Sopenharmony_ci            return OBJ_nid2obj(nid);
375e1051a39Sopenharmony_ci        if (!ossl_isdigit(*s)) {
376e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_OBJ, OBJ_R_UNKNOWN_OBJECT_NAME);
377e1051a39Sopenharmony_ci            return NULL;
378e1051a39Sopenharmony_ci        }
379e1051a39Sopenharmony_ci    }
380e1051a39Sopenharmony_ci
381e1051a39Sopenharmony_ci    /* Work out size of content octets */
382e1051a39Sopenharmony_ci    i = a2d_ASN1_OBJECT(NULL, 0, s, -1);
383e1051a39Sopenharmony_ci    if (i <= 0) {
384e1051a39Sopenharmony_ci        /* Don't clear the error */
385e1051a39Sopenharmony_ci        /*
386e1051a39Sopenharmony_ci         * ERR_clear_error();
387e1051a39Sopenharmony_ci         */
388e1051a39Sopenharmony_ci        return NULL;
389e1051a39Sopenharmony_ci    }
390e1051a39Sopenharmony_ci    /* Work out total size */
391e1051a39Sopenharmony_ci    j = ASN1_object_size(0, i, V_ASN1_OBJECT);
392e1051a39Sopenharmony_ci    if (j < 0)
393e1051a39Sopenharmony_ci        return NULL;
394e1051a39Sopenharmony_ci
395e1051a39Sopenharmony_ci    if ((buf = OPENSSL_malloc(j)) == NULL) {
396e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_OBJ, ERR_R_MALLOC_FAILURE);
397e1051a39Sopenharmony_ci        return NULL;
398e1051a39Sopenharmony_ci    }
399e1051a39Sopenharmony_ci
400e1051a39Sopenharmony_ci    p = buf;
401e1051a39Sopenharmony_ci    /* Write out tag+length */
402e1051a39Sopenharmony_ci    ASN1_put_object(&p, 0, i, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
403e1051a39Sopenharmony_ci    /* Write out contents */
404e1051a39Sopenharmony_ci    a2d_ASN1_OBJECT(p, i, s, -1);
405e1051a39Sopenharmony_ci
406e1051a39Sopenharmony_ci    cp = buf;
407e1051a39Sopenharmony_ci    op = d2i_ASN1_OBJECT(NULL, &cp, j);
408e1051a39Sopenharmony_ci    OPENSSL_free(buf);
409e1051a39Sopenharmony_ci    return op;
410e1051a39Sopenharmony_ci}
411e1051a39Sopenharmony_ci
412e1051a39Sopenharmony_ciint OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
413e1051a39Sopenharmony_ci{
414e1051a39Sopenharmony_ci    int i, n = 0, len, nid, first, use_bn;
415e1051a39Sopenharmony_ci    BIGNUM *bl;
416e1051a39Sopenharmony_ci    unsigned long l;
417e1051a39Sopenharmony_ci    const unsigned char *p;
418e1051a39Sopenharmony_ci    char tbuf[DECIMAL_SIZE(i) + DECIMAL_SIZE(l) + 2];
419e1051a39Sopenharmony_ci
420e1051a39Sopenharmony_ci    /* Ensure that, at every state, |buf| is NUL-terminated. */
421e1051a39Sopenharmony_ci    if (buf && buf_len > 0)
422e1051a39Sopenharmony_ci        buf[0] = '\0';
423e1051a39Sopenharmony_ci
424e1051a39Sopenharmony_ci    if ((a == NULL) || (a->data == NULL))
425e1051a39Sopenharmony_ci        return 0;
426e1051a39Sopenharmony_ci
427e1051a39Sopenharmony_ci    if (!no_name && (nid = OBJ_obj2nid(a)) != NID_undef) {
428e1051a39Sopenharmony_ci        const char *s;
429e1051a39Sopenharmony_ci        s = OBJ_nid2ln(nid);
430e1051a39Sopenharmony_ci        if (s == NULL)
431e1051a39Sopenharmony_ci            s = OBJ_nid2sn(nid);
432e1051a39Sopenharmony_ci        if (s) {
433e1051a39Sopenharmony_ci            if (buf)
434e1051a39Sopenharmony_ci                OPENSSL_strlcpy(buf, s, buf_len);
435e1051a39Sopenharmony_ci            n = strlen(s);
436e1051a39Sopenharmony_ci            return n;
437e1051a39Sopenharmony_ci        }
438e1051a39Sopenharmony_ci    }
439e1051a39Sopenharmony_ci
440e1051a39Sopenharmony_ci    len = a->length;
441e1051a39Sopenharmony_ci    p = a->data;
442e1051a39Sopenharmony_ci
443e1051a39Sopenharmony_ci    first = 1;
444e1051a39Sopenharmony_ci    bl = NULL;
445e1051a39Sopenharmony_ci
446e1051a39Sopenharmony_ci    /*
447e1051a39Sopenharmony_ci     * RFC 2578 (STD 58) says this about OBJECT IDENTIFIERs:
448e1051a39Sopenharmony_ci     *
449e1051a39Sopenharmony_ci     * > 3.5. OBJECT IDENTIFIER values
450e1051a39Sopenharmony_ci     * >
451e1051a39Sopenharmony_ci     * > An OBJECT IDENTIFIER value is an ordered list of non-negative
452e1051a39Sopenharmony_ci     * > numbers. For the SMIv2, each number in the list is referred to as a
453e1051a39Sopenharmony_ci     * > sub-identifier, there are at most 128 sub-identifiers in a value,
454e1051a39Sopenharmony_ci     * > and each sub-identifier has a maximum value of 2^32-1 (4294967295
455e1051a39Sopenharmony_ci     * > decimal).
456e1051a39Sopenharmony_ci     *
457e1051a39Sopenharmony_ci     * So a legitimate OID according to this RFC is at most (32 * 128 / 7),
458e1051a39Sopenharmony_ci     * i.e. 586 bytes long.
459e1051a39Sopenharmony_ci     *
460e1051a39Sopenharmony_ci     * Ref: https://datatracker.ietf.org/doc/html/rfc2578#section-3.5
461e1051a39Sopenharmony_ci     */
462e1051a39Sopenharmony_ci    if (len > 586)
463e1051a39Sopenharmony_ci        goto err;
464e1051a39Sopenharmony_ci
465e1051a39Sopenharmony_ci    while (len > 0) {
466e1051a39Sopenharmony_ci        l = 0;
467e1051a39Sopenharmony_ci        use_bn = 0;
468e1051a39Sopenharmony_ci        for (;;) {
469e1051a39Sopenharmony_ci            unsigned char c = *p++;
470e1051a39Sopenharmony_ci            len--;
471e1051a39Sopenharmony_ci            if ((len == 0) && (c & 0x80))
472e1051a39Sopenharmony_ci                goto err;
473e1051a39Sopenharmony_ci            if (use_bn) {
474e1051a39Sopenharmony_ci                if (!BN_add_word(bl, c & 0x7f))
475e1051a39Sopenharmony_ci                    goto err;
476e1051a39Sopenharmony_ci            } else
477e1051a39Sopenharmony_ci                l |= c & 0x7f;
478e1051a39Sopenharmony_ci            if (!(c & 0x80))
479e1051a39Sopenharmony_ci                break;
480e1051a39Sopenharmony_ci            if (!use_bn && (l > (ULONG_MAX >> 7L))) {
481e1051a39Sopenharmony_ci                if (bl == NULL && (bl = BN_new()) == NULL)
482e1051a39Sopenharmony_ci                    goto err;
483e1051a39Sopenharmony_ci                if (!BN_set_word(bl, l))
484e1051a39Sopenharmony_ci                    goto err;
485e1051a39Sopenharmony_ci                use_bn = 1;
486e1051a39Sopenharmony_ci            }
487e1051a39Sopenharmony_ci            if (use_bn) {
488e1051a39Sopenharmony_ci                if (!BN_lshift(bl, bl, 7))
489e1051a39Sopenharmony_ci                    goto err;
490e1051a39Sopenharmony_ci            } else
491e1051a39Sopenharmony_ci                l <<= 7L;
492e1051a39Sopenharmony_ci        }
493e1051a39Sopenharmony_ci
494e1051a39Sopenharmony_ci        if (first) {
495e1051a39Sopenharmony_ci            first = 0;
496e1051a39Sopenharmony_ci            if (l >= 80) {
497e1051a39Sopenharmony_ci                i = 2;
498e1051a39Sopenharmony_ci                if (use_bn) {
499e1051a39Sopenharmony_ci                    if (!BN_sub_word(bl, 80))
500e1051a39Sopenharmony_ci                        goto err;
501e1051a39Sopenharmony_ci                } else
502e1051a39Sopenharmony_ci                    l -= 80;
503e1051a39Sopenharmony_ci            } else {
504e1051a39Sopenharmony_ci                i = (int)(l / 40);
505e1051a39Sopenharmony_ci                l -= (long)(i * 40);
506e1051a39Sopenharmony_ci            }
507e1051a39Sopenharmony_ci            if (buf && (buf_len > 1)) {
508e1051a39Sopenharmony_ci                *buf++ = i + '0';
509e1051a39Sopenharmony_ci                *buf = '\0';
510e1051a39Sopenharmony_ci                buf_len--;
511e1051a39Sopenharmony_ci            }
512e1051a39Sopenharmony_ci            n++;
513e1051a39Sopenharmony_ci        }
514e1051a39Sopenharmony_ci
515e1051a39Sopenharmony_ci        if (use_bn) {
516e1051a39Sopenharmony_ci            char *bndec;
517e1051a39Sopenharmony_ci            bndec = BN_bn2dec(bl);
518e1051a39Sopenharmony_ci            if (!bndec)
519e1051a39Sopenharmony_ci                goto err;
520e1051a39Sopenharmony_ci            i = strlen(bndec);
521e1051a39Sopenharmony_ci            if (buf) {
522e1051a39Sopenharmony_ci                if (buf_len > 1) {
523e1051a39Sopenharmony_ci                    *buf++ = '.';
524e1051a39Sopenharmony_ci                    *buf = '\0';
525e1051a39Sopenharmony_ci                    buf_len--;
526e1051a39Sopenharmony_ci                }
527e1051a39Sopenharmony_ci                OPENSSL_strlcpy(buf, bndec, buf_len);
528e1051a39Sopenharmony_ci                if (i > buf_len) {
529e1051a39Sopenharmony_ci                    buf += buf_len;
530e1051a39Sopenharmony_ci                    buf_len = 0;
531e1051a39Sopenharmony_ci                } else {
532e1051a39Sopenharmony_ci                    buf += i;
533e1051a39Sopenharmony_ci                    buf_len -= i;
534e1051a39Sopenharmony_ci                }
535e1051a39Sopenharmony_ci            }
536e1051a39Sopenharmony_ci            n++;
537e1051a39Sopenharmony_ci            n += i;
538e1051a39Sopenharmony_ci            OPENSSL_free(bndec);
539e1051a39Sopenharmony_ci        } else {
540e1051a39Sopenharmony_ci            BIO_snprintf(tbuf, sizeof(tbuf), ".%lu", l);
541e1051a39Sopenharmony_ci            i = strlen(tbuf);
542e1051a39Sopenharmony_ci            if (buf && (buf_len > 0)) {
543e1051a39Sopenharmony_ci                OPENSSL_strlcpy(buf, tbuf, buf_len);
544e1051a39Sopenharmony_ci                if (i > buf_len) {
545e1051a39Sopenharmony_ci                    buf += buf_len;
546e1051a39Sopenharmony_ci                    buf_len = 0;
547e1051a39Sopenharmony_ci                } else {
548e1051a39Sopenharmony_ci                    buf += i;
549e1051a39Sopenharmony_ci                    buf_len -= i;
550e1051a39Sopenharmony_ci                }
551e1051a39Sopenharmony_ci            }
552e1051a39Sopenharmony_ci            n += i;
553e1051a39Sopenharmony_ci            l = 0;
554e1051a39Sopenharmony_ci        }
555e1051a39Sopenharmony_ci    }
556e1051a39Sopenharmony_ci
557e1051a39Sopenharmony_ci    BN_free(bl);
558e1051a39Sopenharmony_ci    return n;
559e1051a39Sopenharmony_ci
560e1051a39Sopenharmony_ci err:
561e1051a39Sopenharmony_ci    BN_free(bl);
562e1051a39Sopenharmony_ci    return -1;
563e1051a39Sopenharmony_ci}
564e1051a39Sopenharmony_ci
565e1051a39Sopenharmony_ciint OBJ_txt2nid(const char *s)
566e1051a39Sopenharmony_ci{
567e1051a39Sopenharmony_ci    ASN1_OBJECT *obj;
568e1051a39Sopenharmony_ci    int nid;
569e1051a39Sopenharmony_ci    obj = OBJ_txt2obj(s, 0);
570e1051a39Sopenharmony_ci    nid = OBJ_obj2nid(obj);
571e1051a39Sopenharmony_ci    ASN1_OBJECT_free(obj);
572e1051a39Sopenharmony_ci    return nid;
573e1051a39Sopenharmony_ci}
574e1051a39Sopenharmony_ci
575e1051a39Sopenharmony_ciint OBJ_ln2nid(const char *s)
576e1051a39Sopenharmony_ci{
577e1051a39Sopenharmony_ci    ASN1_OBJECT o;
578e1051a39Sopenharmony_ci    const ASN1_OBJECT *oo = &o;
579e1051a39Sopenharmony_ci    ADDED_OBJ ad, *adp;
580e1051a39Sopenharmony_ci    const unsigned int *op;
581e1051a39Sopenharmony_ci
582e1051a39Sopenharmony_ci    /* Make sure we've loaded config before checking for any "added" objects */
583e1051a39Sopenharmony_ci    OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
584e1051a39Sopenharmony_ci
585e1051a39Sopenharmony_ci    o.ln = s;
586e1051a39Sopenharmony_ci    if (added != NULL) {
587e1051a39Sopenharmony_ci        ad.type = ADDED_LNAME;
588e1051a39Sopenharmony_ci        ad.obj = &o;
589e1051a39Sopenharmony_ci        adp = lh_ADDED_OBJ_retrieve(added, &ad);
590e1051a39Sopenharmony_ci        if (adp != NULL)
591e1051a39Sopenharmony_ci            return adp->obj->nid;
592e1051a39Sopenharmony_ci    }
593e1051a39Sopenharmony_ci    op = OBJ_bsearch_ln(&oo, ln_objs, NUM_LN);
594e1051a39Sopenharmony_ci    if (op == NULL)
595e1051a39Sopenharmony_ci        return NID_undef;
596e1051a39Sopenharmony_ci    return nid_objs[*op].nid;
597e1051a39Sopenharmony_ci}
598e1051a39Sopenharmony_ci
599e1051a39Sopenharmony_ciint OBJ_sn2nid(const char *s)
600e1051a39Sopenharmony_ci{
601e1051a39Sopenharmony_ci    ASN1_OBJECT o;
602e1051a39Sopenharmony_ci    const ASN1_OBJECT *oo = &o;
603e1051a39Sopenharmony_ci    ADDED_OBJ ad, *adp;
604e1051a39Sopenharmony_ci    const unsigned int *op;
605e1051a39Sopenharmony_ci
606e1051a39Sopenharmony_ci    /* Make sure we've loaded config before checking for any "added" objects */
607e1051a39Sopenharmony_ci    OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
608e1051a39Sopenharmony_ci
609e1051a39Sopenharmony_ci    o.sn = s;
610e1051a39Sopenharmony_ci    if (added != NULL) {
611e1051a39Sopenharmony_ci        ad.type = ADDED_SNAME;
612e1051a39Sopenharmony_ci        ad.obj = &o;
613e1051a39Sopenharmony_ci        adp = lh_ADDED_OBJ_retrieve(added, &ad);
614e1051a39Sopenharmony_ci        if (adp != NULL)
615e1051a39Sopenharmony_ci            return adp->obj->nid;
616e1051a39Sopenharmony_ci    }
617e1051a39Sopenharmony_ci    op = OBJ_bsearch_sn(&oo, sn_objs, NUM_SN);
618e1051a39Sopenharmony_ci    if (op == NULL)
619e1051a39Sopenharmony_ci        return NID_undef;
620e1051a39Sopenharmony_ci    return nid_objs[*op].nid;
621e1051a39Sopenharmony_ci}
622e1051a39Sopenharmony_ci
623e1051a39Sopenharmony_ciconst void *OBJ_bsearch_(const void *key, const void *base, int num, int size,
624e1051a39Sopenharmony_ci                         int (*cmp) (const void *, const void *))
625e1051a39Sopenharmony_ci{
626e1051a39Sopenharmony_ci    return OBJ_bsearch_ex_(key, base, num, size, cmp, 0);
627e1051a39Sopenharmony_ci}
628e1051a39Sopenharmony_ci
629e1051a39Sopenharmony_ciconst void *OBJ_bsearch_ex_(const void *key, const void *base, int num,
630e1051a39Sopenharmony_ci                            int size,
631e1051a39Sopenharmony_ci                            int (*cmp) (const void *, const void *),
632e1051a39Sopenharmony_ci                            int flags)
633e1051a39Sopenharmony_ci{
634e1051a39Sopenharmony_ci    const char *p = ossl_bsearch(key, base, num, size, cmp, flags);
635e1051a39Sopenharmony_ci
636e1051a39Sopenharmony_ci#ifdef CHARSET_EBCDIC
637e1051a39Sopenharmony_ci    /*
638e1051a39Sopenharmony_ci     * THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and I
639e1051a39Sopenharmony_ci     * don't have perl (yet), we revert to a *LINEAR* search when the object
640e1051a39Sopenharmony_ci     * wasn't found in the binary search.
641e1051a39Sopenharmony_ci     */
642e1051a39Sopenharmony_ci    if (p == NULL) {
643e1051a39Sopenharmony_ci        const char *base_ = base;
644e1051a39Sopenharmony_ci        int l, h, i = 0, c = 0;
645e1051a39Sopenharmony_ci
646e1051a39Sopenharmony_ci        for (i = 0; i < num; ++i) {
647e1051a39Sopenharmony_ci            p = &(base_[i * size]);
648e1051a39Sopenharmony_ci            c = (*cmp) (key, p);
649e1051a39Sopenharmony_ci            if (c == 0
650e1051a39Sopenharmony_ci                || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)))
651e1051a39Sopenharmony_ci                return p;
652e1051a39Sopenharmony_ci        }
653e1051a39Sopenharmony_ci    }
654e1051a39Sopenharmony_ci#endif
655e1051a39Sopenharmony_ci    return p;
656e1051a39Sopenharmony_ci}
657e1051a39Sopenharmony_ci
658e1051a39Sopenharmony_ci/*
659e1051a39Sopenharmony_ci * Parse a BIO sink to create some extra oid's objects.
660e1051a39Sopenharmony_ci * Line format:<OID:isdigit or '.']><isspace><SN><isspace><LN>
661e1051a39Sopenharmony_ci */
662e1051a39Sopenharmony_ciint OBJ_create_objects(BIO *in)
663e1051a39Sopenharmony_ci{
664e1051a39Sopenharmony_ci    char buf[512];
665e1051a39Sopenharmony_ci    int i, num = 0;
666e1051a39Sopenharmony_ci    char *o, *s, *l = NULL;
667e1051a39Sopenharmony_ci
668e1051a39Sopenharmony_ci    for (;;) {
669e1051a39Sopenharmony_ci        s = o = NULL;
670e1051a39Sopenharmony_ci        i = BIO_gets(in, buf, 512);
671e1051a39Sopenharmony_ci        if (i <= 0)
672e1051a39Sopenharmony_ci            return num;
673e1051a39Sopenharmony_ci        buf[i - 1] = '\0';
674e1051a39Sopenharmony_ci        if (!ossl_isalnum(buf[0]))
675e1051a39Sopenharmony_ci            return num;
676e1051a39Sopenharmony_ci        o = s = buf;
677e1051a39Sopenharmony_ci        while (ossl_isdigit(*s) || *s == '.')
678e1051a39Sopenharmony_ci            s++;
679e1051a39Sopenharmony_ci        if (*s != '\0') {
680e1051a39Sopenharmony_ci            *(s++) = '\0';
681e1051a39Sopenharmony_ci            while (ossl_isspace(*s))
682e1051a39Sopenharmony_ci                s++;
683e1051a39Sopenharmony_ci            if (*s == '\0') {
684e1051a39Sopenharmony_ci                s = NULL;
685e1051a39Sopenharmony_ci            } else {
686e1051a39Sopenharmony_ci                l = s;
687e1051a39Sopenharmony_ci                while (*l != '\0' && !ossl_isspace(*l))
688e1051a39Sopenharmony_ci                    l++;
689e1051a39Sopenharmony_ci                if (*l != '\0') {
690e1051a39Sopenharmony_ci                    *(l++) = '\0';
691e1051a39Sopenharmony_ci                    while (ossl_isspace(*l))
692e1051a39Sopenharmony_ci                        l++;
693e1051a39Sopenharmony_ci                    if (*l == '\0') {
694e1051a39Sopenharmony_ci                        l = NULL;
695e1051a39Sopenharmony_ci                    }
696e1051a39Sopenharmony_ci                } else {
697e1051a39Sopenharmony_ci                    l = NULL;
698e1051a39Sopenharmony_ci                }
699e1051a39Sopenharmony_ci            }
700e1051a39Sopenharmony_ci        } else {
701e1051a39Sopenharmony_ci            s = NULL;
702e1051a39Sopenharmony_ci        }
703e1051a39Sopenharmony_ci        if (*o == '\0')
704e1051a39Sopenharmony_ci            return num;
705e1051a39Sopenharmony_ci        if (!OBJ_create(o, s, l))
706e1051a39Sopenharmony_ci            return num;
707e1051a39Sopenharmony_ci        num++;
708e1051a39Sopenharmony_ci    }
709e1051a39Sopenharmony_ci}
710e1051a39Sopenharmony_ci
711e1051a39Sopenharmony_ciint OBJ_create(const char *oid, const char *sn, const char *ln)
712e1051a39Sopenharmony_ci{
713e1051a39Sopenharmony_ci    ASN1_OBJECT *tmpoid = NULL;
714e1051a39Sopenharmony_ci    int ok = 0;
715e1051a39Sopenharmony_ci
716e1051a39Sopenharmony_ci    /* Check to see if short or long name already present */
717e1051a39Sopenharmony_ci    if ((sn != NULL && OBJ_sn2nid(sn) != NID_undef)
718e1051a39Sopenharmony_ci            || (ln != NULL && OBJ_ln2nid(ln) != NID_undef)) {
719e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_OBJ, OBJ_R_OID_EXISTS);
720e1051a39Sopenharmony_ci        return 0;
721e1051a39Sopenharmony_ci    }
722e1051a39Sopenharmony_ci
723e1051a39Sopenharmony_ci    /* Convert numerical OID string to an ASN1_OBJECT structure */
724e1051a39Sopenharmony_ci    tmpoid = OBJ_txt2obj(oid, 1);
725e1051a39Sopenharmony_ci    if (tmpoid == NULL)
726e1051a39Sopenharmony_ci        return 0;
727e1051a39Sopenharmony_ci
728e1051a39Sopenharmony_ci    /* If NID is not NID_undef then object already exists */
729e1051a39Sopenharmony_ci    if (OBJ_obj2nid(tmpoid) != NID_undef) {
730e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_OBJ, OBJ_R_OID_EXISTS);
731e1051a39Sopenharmony_ci        goto err;
732e1051a39Sopenharmony_ci    }
733e1051a39Sopenharmony_ci
734e1051a39Sopenharmony_ci    tmpoid->nid = OBJ_new_nid(1);
735e1051a39Sopenharmony_ci    if (tmpoid->nid == NID_undef)
736e1051a39Sopenharmony_ci        goto err;
737e1051a39Sopenharmony_ci
738e1051a39Sopenharmony_ci    tmpoid->sn = (char *)sn;
739e1051a39Sopenharmony_ci    tmpoid->ln = (char *)ln;
740e1051a39Sopenharmony_ci
741e1051a39Sopenharmony_ci    ok = OBJ_add_object(tmpoid);
742e1051a39Sopenharmony_ci
743e1051a39Sopenharmony_ci    tmpoid->sn = NULL;
744e1051a39Sopenharmony_ci    tmpoid->ln = NULL;
745e1051a39Sopenharmony_ci
746e1051a39Sopenharmony_ci err:
747e1051a39Sopenharmony_ci    ASN1_OBJECT_free(tmpoid);
748e1051a39Sopenharmony_ci    return ok;
749e1051a39Sopenharmony_ci}
750e1051a39Sopenharmony_ci
751e1051a39Sopenharmony_cisize_t OBJ_length(const ASN1_OBJECT *obj)
752e1051a39Sopenharmony_ci{
753e1051a39Sopenharmony_ci    if (obj == NULL)
754e1051a39Sopenharmony_ci        return 0;
755e1051a39Sopenharmony_ci    return obj->length;
756e1051a39Sopenharmony_ci}
757e1051a39Sopenharmony_ci
758e1051a39Sopenharmony_ciconst unsigned char *OBJ_get0_data(const ASN1_OBJECT *obj)
759e1051a39Sopenharmony_ci{
760e1051a39Sopenharmony_ci    if (obj == NULL)
761e1051a39Sopenharmony_ci        return NULL;
762e1051a39Sopenharmony_ci    return obj->data;
763e1051a39Sopenharmony_ci}
764