xref: /openbsd-src/lib/libcrypto/objects/obj_dat.c (revision 343bd8e235c70a471fa28e1edfa8b5c6b26d5aa3)
1*343bd8e2Sjsing /* $OpenBSD: obj_dat.c,v 1.91 2024/07/14 14:32:45 jsing Exp $ */
25b37fcf3Sryker /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
35b37fcf3Sryker  * All rights reserved.
45b37fcf3Sryker  *
55b37fcf3Sryker  * This package is an SSL implementation written
65b37fcf3Sryker  * by Eric Young (eay@cryptsoft.com).
75b37fcf3Sryker  * The implementation was written so as to conform with Netscapes SSL.
85b37fcf3Sryker  *
95b37fcf3Sryker  * This library is free for commercial and non-commercial use as long as
105b37fcf3Sryker  * the following conditions are aheared to.  The following conditions
115b37fcf3Sryker  * apply to all code found in this distribution, be it the RC4, RSA,
125b37fcf3Sryker  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
135b37fcf3Sryker  * included with this distribution is covered by the same copyright terms
145b37fcf3Sryker  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
155b37fcf3Sryker  *
165b37fcf3Sryker  * Copyright remains Eric Young's, and as such any Copyright notices in
175b37fcf3Sryker  * the code are not to be removed.
185b37fcf3Sryker  * If this package is used in a product, Eric Young should be given attribution
195b37fcf3Sryker  * as the author of the parts of the library used.
205b37fcf3Sryker  * This can be in the form of a textual message at program startup or
215b37fcf3Sryker  * in documentation (online or textual) provided with the package.
225b37fcf3Sryker  *
235b37fcf3Sryker  * Redistribution and use in source and binary forms, with or without
245b37fcf3Sryker  * modification, are permitted provided that the following conditions
255b37fcf3Sryker  * are met:
265b37fcf3Sryker  * 1. Redistributions of source code must retain the copyright
275b37fcf3Sryker  *    notice, this list of conditions and the following disclaimer.
285b37fcf3Sryker  * 2. Redistributions in binary form must reproduce the above copyright
295b37fcf3Sryker  *    notice, this list of conditions and the following disclaimer in the
305b37fcf3Sryker  *    documentation and/or other materials provided with the distribution.
315b37fcf3Sryker  * 3. All advertising materials mentioning features or use of this software
325b37fcf3Sryker  *    must display the following acknowledgement:
335b37fcf3Sryker  *    "This product includes cryptographic software written by
345b37fcf3Sryker  *     Eric Young (eay@cryptsoft.com)"
355b37fcf3Sryker  *    The word 'cryptographic' can be left out if the rouines from the library
365b37fcf3Sryker  *    being used are not cryptographic related :-).
375b37fcf3Sryker  * 4. If you include any Windows specific code (or a derivative thereof) from
385b37fcf3Sryker  *    the apps directory (application code) you must include an acknowledgement:
395b37fcf3Sryker  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
405b37fcf3Sryker  *
415b37fcf3Sryker  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
425b37fcf3Sryker  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
435b37fcf3Sryker  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
445b37fcf3Sryker  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
455b37fcf3Sryker  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
465b37fcf3Sryker  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
475b37fcf3Sryker  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
485b37fcf3Sryker  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
495b37fcf3Sryker  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
505b37fcf3Sryker  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
515b37fcf3Sryker  * SUCH DAMAGE.
525b37fcf3Sryker  *
535b37fcf3Sryker  * The licence and distribution terms for any publically available version or
545b37fcf3Sryker  * derivative of this code cannot be changed.  i.e. this code cannot simply be
555b37fcf3Sryker  * copied and put under another distribution licence
565b37fcf3Sryker  * [including the GNU Public Licence.]
575b37fcf3Sryker  */
585b37fcf3Sryker 
595b37fcf3Sryker #include <ctype.h>
604fcf65c5Sdjm #include <limits.h>
61a8913c44Sjsing #include <stdio.h>
62f4a64515Stb #include <stdlib.h>
63a8913c44Sjsing #include <string.h>
64a8913c44Sjsing 
658cf4d6a6Sjsing #include <openssl/opensslconf.h>
668cf4d6a6Sjsing 
67913ec974Sbeck #include <openssl/asn1.h>
684fcf65c5Sdjm #include <openssl/bn.h>
69b6ab114eSjsing #include <openssl/err.h>
70b6ab114eSjsing #include <openssl/lhash.h>
71b6ab114eSjsing #include <openssl/objects.h>
725b37fcf3Sryker 
73c9675a23Stb #include "asn1_local.h"
74ec30313dStb 
755b37fcf3Sryker /* obj_dat.h is generated from objects.h by obj_dat.pl */
765b37fcf3Sryker #include "obj_dat.h"
775b37fcf3Sryker 
785b37fcf3Sryker #define ADDED_DATA	0
795b37fcf3Sryker #define ADDED_SNAME	1
805b37fcf3Sryker #define ADDED_LNAME	2
815b37fcf3Sryker #define ADDED_NID	3
825b37fcf3Sryker 
83223e7da0Sjsing typedef struct added_obj_st {
845b37fcf3Sryker 	int type;
855b37fcf3Sryker 	ASN1_OBJECT *obj;
865b37fcf3Sryker } ADDED_OBJ;
870a5d6edeSdjm DECLARE_LHASH_OF(ADDED_OBJ);
885b37fcf3Sryker 
895b37fcf3Sryker static int new_nid = NUM_NID;
900a5d6edeSdjm static LHASH_OF(ADDED_OBJ) *added = NULL;
915b37fcf3Sryker 
92223e7da0Sjsing static unsigned long
added_obj_hash(const ADDED_OBJ * ca)93223e7da0Sjsing added_obj_hash(const ADDED_OBJ *ca)
945b37fcf3Sryker {
95da347917Sbeck 	const ASN1_OBJECT *a;
965b37fcf3Sryker 	int i;
975b37fcf3Sryker 	unsigned long ret = 0;
985b37fcf3Sryker 	unsigned char *p;
995b37fcf3Sryker 
1005b37fcf3Sryker 	a = ca->obj;
101223e7da0Sjsing 	switch (ca->type) {
1025b37fcf3Sryker 	case ADDED_DATA:
1035b37fcf3Sryker 		ret = a->length << 20L;
1045b37fcf3Sryker 		p = (unsigned char *)a->data;
1055b37fcf3Sryker 		for (i = 0; i < a->length; i++)
1065b37fcf3Sryker 			ret ^= p[i] << ((i * 3) % 24);
1075b37fcf3Sryker 		break;
1085b37fcf3Sryker 	case ADDED_SNAME:
1095b37fcf3Sryker 		ret = lh_strhash(a->sn);
1105b37fcf3Sryker 		break;
1115b37fcf3Sryker 	case ADDED_LNAME:
1125b37fcf3Sryker 		ret = lh_strhash(a->ln);
1135b37fcf3Sryker 		break;
1145b37fcf3Sryker 	case ADDED_NID:
1155b37fcf3Sryker 		ret = a->nid;
1165b37fcf3Sryker 		break;
1175b37fcf3Sryker 	default:
118c109e398Sbeck 		return 0;
1195b37fcf3Sryker 	}
1205b37fcf3Sryker 	ret &= 0x3fffffffL;
1215b37fcf3Sryker 	ret |= ca->type << 30L;
1225b37fcf3Sryker 	return (ret);
1235b37fcf3Sryker }
IMPLEMENT_LHASH_HASH_FN(added_obj,ADDED_OBJ)1240a5d6edeSdjm static IMPLEMENT_LHASH_HASH_FN(added_obj, ADDED_OBJ)
1255b37fcf3Sryker 
126223e7da0Sjsing static int
127223e7da0Sjsing added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb)
1285b37fcf3Sryker {
129812e19bfStb 	const ASN1_OBJECT *a, *b;
130acdf279eStb 	int cmp;
1315b37fcf3Sryker 
132acdf279eStb 	if ((cmp = ca->type - cb->type) != 0)
133acdf279eStb 		return cmp;
134acdf279eStb 
1355b37fcf3Sryker 	a = ca->obj;
1365b37fcf3Sryker 	b = cb->obj;
137223e7da0Sjsing 	switch (ca->type) {
1385b37fcf3Sryker 	case ADDED_DATA:
1398128758fStb 		return OBJ_cmp(a, b);
1405b37fcf3Sryker 	case ADDED_SNAME:
141223e7da0Sjsing 		if (a->sn == NULL)
142a55266ccStb 			return -1;
143b0b039deStb 		if (b->sn == NULL)
144a55266ccStb 			return 1;
145a55266ccStb 		return strcmp(a->sn, b->sn);
1465b37fcf3Sryker 	case ADDED_LNAME:
147223e7da0Sjsing 		if (a->ln == NULL)
148a55266ccStb 			return -1;
149b0b039deStb 		if (b->ln == NULL)
150a55266ccStb 			return 1;
151a55266ccStb 		return strcmp(a->ln, b->ln);
1525b37fcf3Sryker 	case ADDED_NID:
153a55266ccStb 		return a->nid - b->nid;
1545b37fcf3Sryker 	default:
155c109e398Sbeck 		return 0;
1565b37fcf3Sryker 	}
1575b37fcf3Sryker }
IMPLEMENT_LHASH_COMP_FN(added_obj,ADDED_OBJ)1580a5d6edeSdjm static IMPLEMENT_LHASH_COMP_FN(added_obj, ADDED_OBJ)
1595b37fcf3Sryker 
160223e7da0Sjsing static void
161223e7da0Sjsing cleanup1_doall(ADDED_OBJ *a)
1625b37fcf3Sryker {
1635b37fcf3Sryker 	a->obj->nid = 0;
1645b37fcf3Sryker 	a->obj->flags |= ASN1_OBJECT_FLAG_DYNAMIC |
165913ec974Sbeck 	    ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
166913ec974Sbeck 	    ASN1_OBJECT_FLAG_DYNAMIC_DATA;
1675b37fcf3Sryker }
1685b37fcf3Sryker 
1691b9cf3a3Stb static void
cleanup2_doall(ADDED_OBJ * a)1701b9cf3a3Stb cleanup2_doall(ADDED_OBJ *a)
171223e7da0Sjsing {
172223e7da0Sjsing 	a->obj->nid++;
173223e7da0Sjsing }
1745b37fcf3Sryker 
175223e7da0Sjsing static void
cleanup3_doall(ADDED_OBJ * a)176223e7da0Sjsing cleanup3_doall(ADDED_OBJ *a)
1775b37fcf3Sryker {
1785b37fcf3Sryker 	if (--a->obj->nid == 0)
1795b37fcf3Sryker 		ASN1_OBJECT_free(a->obj);
1806f3a6cb1Sbeck 	free(a);
1815b37fcf3Sryker }
1825b37fcf3Sryker 
IMPLEMENT_LHASH_DOALL_FN(cleanup1,ADDED_OBJ)1830a5d6edeSdjm static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ)
1840a5d6edeSdjm static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ)
1850a5d6edeSdjm static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ)
1860a5d6edeSdjm 
187223e7da0Sjsing void
188223e7da0Sjsing OBJ_cleanup(void)
1895b37fcf3Sryker {
190223e7da0Sjsing 	if (added == NULL)
191223e7da0Sjsing 		return;
19220273a99Sjsing 
1930a5d6edeSdjm 	lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup1)); /* zero counters */
1940a5d6edeSdjm 	lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup2)); /* set counters */
1950a5d6edeSdjm 	lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup3)); /* free objects */
1960a5d6edeSdjm 	lh_ADDED_OBJ_free(added);
1975b37fcf3Sryker 	added = NULL;
1985b37fcf3Sryker }
1991e9308c1Sbeck LCRYPTO_ALIAS(OBJ_cleanup);
2005b37fcf3Sryker 
201223e7da0Sjsing int
OBJ_new_nid(int num)202223e7da0Sjsing OBJ_new_nid(int num)
2035b37fcf3Sryker {
2045b37fcf3Sryker 	int i;
2055b37fcf3Sryker 
2065b37fcf3Sryker 	i = new_nid;
2075b37fcf3Sryker 	new_nid += num;
2085b37fcf3Sryker 	return (i);
2095b37fcf3Sryker }
2101e9308c1Sbeck LCRYPTO_ALIAS(OBJ_new_nid);
2115b37fcf3Sryker 
212fb2db234Stb static int
OBJ_add_object(const ASN1_OBJECT * obj)213223e7da0Sjsing OBJ_add_object(const ASN1_OBJECT *obj)
2145b37fcf3Sryker {
215281c2125Stb 	ASN1_OBJECT *o = NULL;
216ba5406e9Sbeck 	ADDED_OBJ *ao[4] = {NULL, NULL, NULL, NULL}, *aop;
2175b37fcf3Sryker 	int i;
2185b37fcf3Sryker 
2195b37fcf3Sryker 	if (added == NULL)
220281c2125Stb 		added = lh_ADDED_OBJ_new();
221281c2125Stb 	if (added == NULL)
222281c2125Stb 		goto err;
223281c2125Stb 	if (obj == NULL || obj->nid == NID_undef)
224281c2125Stb 		goto err;
225223e7da0Sjsing 	if ((o = OBJ_dup(obj)) == NULL)
226223e7da0Sjsing 		goto err;
2274163340bSderaadt 	if (!(ao[ADDED_NID] = malloc(sizeof(ADDED_OBJ))))
228223e7da0Sjsing 		goto err2;
2295b37fcf3Sryker 	if ((o->length != 0) && (obj->data != NULL))
2304163340bSderaadt 		if (!(ao[ADDED_DATA] = malloc(sizeof(ADDED_OBJ))))
231223e7da0Sjsing 			goto err2;
2325b37fcf3Sryker 	if (o->sn != NULL)
2334163340bSderaadt 		if (!(ao[ADDED_SNAME] = malloc(sizeof(ADDED_OBJ))))
234223e7da0Sjsing 			goto err2;
2355b37fcf3Sryker 	if (o->ln != NULL)
2364163340bSderaadt 		if (!(ao[ADDED_LNAME] = malloc(sizeof(ADDED_OBJ))))
237223e7da0Sjsing 			goto err2;
2385b37fcf3Sryker 
239223e7da0Sjsing 	for (i = ADDED_DATA; i <= ADDED_NID; i++) {
240223e7da0Sjsing 		if (ao[i] != NULL) {
2415b37fcf3Sryker 			ao[i]->type = i;
2425b37fcf3Sryker 			ao[i]->obj = o;
2430a5d6edeSdjm 			aop = lh_ADDED_OBJ_insert(added, ao[i]);
24471743258Sjmc 			/* memory leak, but should not normally matter */
2456f3a6cb1Sbeck 			free(aop);
2465b37fcf3Sryker 		}
2475b37fcf3Sryker 	}
248223e7da0Sjsing 	o->flags &= ~(ASN1_OBJECT_FLAG_DYNAMIC |
249223e7da0Sjsing 	    ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
250913ec974Sbeck 	    ASN1_OBJECT_FLAG_DYNAMIC_DATA);
251913ec974Sbeck 
2525b37fcf3Sryker 	return (o->nid);
253223e7da0Sjsing 
25440d8aef3Sdjm  err2:
2555067ae9fSbeck 	OBJerror(ERR_R_MALLOC_FAILURE);
2565b37fcf3Sryker  err:
2575b37fcf3Sryker 	for (i = ADDED_DATA; i <= ADDED_NID; i++)
258223e7da0Sjsing 		free(ao[i]);
2595be22244Stb 	ASN1_OBJECT_free(o);
2605b37fcf3Sryker 	return (NID_undef);
2615b37fcf3Sryker }
2625b37fcf3Sryker 
263223e7da0Sjsing ASN1_OBJECT *
OBJ_nid2obj(int nid)264fda3605fStb OBJ_nid2obj(int nid)
2655b37fcf3Sryker {
266fda3605fStb 	if (nid >= 0 && nid < NUM_NID) {
267fda3605fStb 		if (nid == NID_undef || nid_objs[nid].nid != NID_undef)
268fda3605fStb 			return (ASN1_OBJECT *)&nid_objs[nid];
2695b37fcf3Sryker 
270fda3605fStb 		goto unknown;
271fda3605fStb 	}
272fda3605fStb 
273fda3605fStb 	/* XXX - locking. */
274fda3605fStb 	if (added != NULL) {
275fda3605fStb 		ASN1_OBJECT aobj = {
276fda3605fStb 			.nid = nid,
277fda3605fStb 		};
278fda3605fStb 		ADDED_OBJ needle = {
279fda3605fStb 			.type = ADDED_NID,
280fda3605fStb 			.obj = &aobj,
281fda3605fStb 		};
282fda3605fStb 		ADDED_OBJ *found;
283fda3605fStb 
284fda3605fStb 		if ((found = lh_ADDED_OBJ_retrieve(added, &needle)) != NULL)
285fda3605fStb 			return found->obj;
286fda3605fStb 	}
287fda3605fStb 
288fda3605fStb  unknown:
2895067ae9fSbeck 	OBJerror(OBJ_R_UNKNOWN_NID);
290fda3605fStb 
291fda3605fStb 	return NULL;
2925b37fcf3Sryker }
2931e9308c1Sbeck LCRYPTO_ALIAS(OBJ_nid2obj);
2945b37fcf3Sryker 
295223e7da0Sjsing const char *
OBJ_nid2sn(int nid)296cefe4e31Stb OBJ_nid2sn(int nid)
2975b37fcf3Sryker {
2982de383afStb 	ASN1_OBJECT *aobj;
2995b37fcf3Sryker 
3002de383afStb 	if ((aobj = OBJ_nid2obj(nid)) == NULL)
301cefe4e31Stb 		return NULL;
3022de383afStb 
3032de383afStb 	return aobj->sn;
3045b37fcf3Sryker }
3051e9308c1Sbeck LCRYPTO_ALIAS(OBJ_nid2sn);
3065b37fcf3Sryker 
307223e7da0Sjsing const char *
OBJ_nid2ln(int nid)308b203e67eStb OBJ_nid2ln(int nid)
3095b37fcf3Sryker {
3102de383afStb 	ASN1_OBJECT *aobj;
3115b37fcf3Sryker 
3122de383afStb 	if ((aobj = OBJ_nid2obj(nid)) == NULL)
313b203e67eStb 		return NULL;
3142de383afStb 
3152de383afStb 	return aobj->ln;
3165b37fcf3Sryker }
3171e9308c1Sbeck LCRYPTO_ALIAS(OBJ_nid2ln);
3185b37fcf3Sryker 
319223e7da0Sjsing static int
obj_objs_cmp(const void * aobj,const void * b)320f4a64515Stb obj_objs_cmp(const void *aobj, const void *b)
3210a5d6edeSdjm {
322f4a64515Stb 	const unsigned int *nid = b;
3230a5d6edeSdjm 
324a82d74d5Stb 	OPENSSL_assert(*nid < NUM_NID);
3252157d97eStb 
326f4a64515Stb 	return OBJ_cmp(aobj, &nid_objs[*nid]);
32776ce35bfSjsing }
3280a5d6edeSdjm 
329223e7da0Sjsing int
OBJ_obj2nid(const ASN1_OBJECT * aobj)330f4a64515Stb OBJ_obj2nid(const ASN1_OBJECT *aobj)
3315b37fcf3Sryker {
332f4a64515Stb 	const unsigned int *nid;
3335b37fcf3Sryker 
334f4a64515Stb 	if (aobj == NULL || aobj->length == 0)
335f4a64515Stb 		return NID_undef;
3365b37fcf3Sryker 
337f4a64515Stb 	if (aobj->nid != NID_undef)
338f4a64515Stb 		return aobj->nid;
339f4a64515Stb 
340f4a64515Stb 	/* XXX - locking. OpenSSL 3 moved this after built-in object lookup. */
341223e7da0Sjsing 	if (added != NULL) {
342f4a64515Stb 		ADDED_OBJ needle = {
343f4a64515Stb 			.type = ADDED_DATA,
344f4a64515Stb 			.obj = (ASN1_OBJECT *)aobj,
345f4a64515Stb 		};
346f4a64515Stb 		ADDED_OBJ *found;
347f4a64515Stb 
348f4a64515Stb 		if ((found = lh_ADDED_OBJ_retrieve(added, &needle)) != NULL)
349f4a64515Stb 			return found->obj->nid;
3505b37fcf3Sryker 	}
351f4a64515Stb 
352f4a64515Stb 	/* obj_objs holds built-in obj NIDs in ascending OBJ_cmp() order. */
353f4a64515Stb 	nid = bsearch(aobj, obj_objs, NUM_OBJ, sizeof(unsigned int), obj_objs_cmp);
354f4a64515Stb 	if (nid != NULL)
355f4a64515Stb 		return *nid;
356f4a64515Stb 
357f4a64515Stb 	return NID_undef;
3585b37fcf3Sryker }
3591e9308c1Sbeck LCRYPTO_ALIAS(OBJ_obj2nid);
3605b37fcf3Sryker 
361dc45ccddStb static int
sn_objs_cmp(const void * sn,const void * b)362dc45ccddStb sn_objs_cmp(const void *sn, const void *b)
3635b37fcf3Sryker {
36463389b84Stb 	const unsigned int *nid = b;
3655b37fcf3Sryker 
366a82d74d5Stb 	OPENSSL_assert(*nid < NUM_NID);
3672157d97eStb 
368dc45ccddStb 	return strcmp(sn, nid_objs[*nid].sn);
3695b37fcf3Sryker }
37063389b84Stb 
37163389b84Stb int
OBJ_sn2nid(const char * sn)37263389b84Stb OBJ_sn2nid(const char *sn)
37363389b84Stb {
37463389b84Stb 	const unsigned int *nid;
37563389b84Stb 
37663389b84Stb 	/* XXX - locking. OpenSSL 3 moved this after built-in object lookup. */
37763389b84Stb 	if (added != NULL) {
37863389b84Stb 		ASN1_OBJECT aobj = {
37963389b84Stb 			.sn = sn,
38063389b84Stb 		};
38163389b84Stb 		ADDED_OBJ needle = {
38263389b84Stb 			.type = ADDED_SNAME,
38363389b84Stb 			.obj = &aobj,
38463389b84Stb 		};
38563389b84Stb 		ADDED_OBJ *found;
38663389b84Stb 
38763389b84Stb 		if ((found = lh_ADDED_OBJ_retrieve(added, &needle)) != NULL)
38863389b84Stb 			return found->obj->nid;
38963389b84Stb 	}
39063389b84Stb 
39163389b84Stb 	/* sn_objs holds NIDs in ascending alphabetical order of SN. */
39263389b84Stb 	nid = bsearch(sn, sn_objs, NUM_SN, sizeof(unsigned int), sn_objs_cmp);
39363389b84Stb 	if (nid != NULL)
39463389b84Stb 		return *nid;
39563389b84Stb 
39663389b84Stb 	return NID_undef;
3975b37fcf3Sryker }
3981e9308c1Sbeck LCRYPTO_ALIAS(OBJ_sn2nid);
3995b37fcf3Sryker 
400bd5b787cStb static int
ln_objs_cmp(const void * ln,const void * b)401bd5b787cStb ln_objs_cmp(const void *ln, const void *b)
402bd5b787cStb {
403bd5b787cStb 	const unsigned int *nid = b;
404bd5b787cStb 
405bd5b787cStb 	OPENSSL_assert(*nid < NUM_NID);
406bd5b787cStb 
407bd5b787cStb 	return strcmp(ln, nid_objs[*nid].ln);
408bd5b787cStb }
409bd5b787cStb 
410bd5b787cStb int
OBJ_ln2nid(const char * ln)411bd5b787cStb OBJ_ln2nid(const char *ln)
412bd5b787cStb {
413bd5b787cStb 	const unsigned int *nid;
414bd5b787cStb 
415bd5b787cStb 	/* XXX - locking. OpenSSL 3 moved this after built-in object lookup. */
416bd5b787cStb 	if (added != NULL) {
417bd5b787cStb 		ASN1_OBJECT aobj = {
418bd5b787cStb 			.ln = ln,
419bd5b787cStb 		};
420bd5b787cStb 		ADDED_OBJ needle = {
421bd5b787cStb 			.type = ADDED_LNAME,
422bd5b787cStb 			.obj = &aobj,
423bd5b787cStb 		};
424bd5b787cStb 		ADDED_OBJ *found;
425bd5b787cStb 
426bd5b787cStb 		if ((found = lh_ADDED_OBJ_retrieve(added, &needle)) != NULL)
427bd5b787cStb 			return found->obj->nid;
428bd5b787cStb 	}
429bd5b787cStb 
430bd5b787cStb 	/* ln_objs holds NIDs in ascending alphabetical order of LN. */
431bd5b787cStb 	nid = bsearch(ln, ln_objs, NUM_LN, sizeof(unsigned int), ln_objs_cmp);
432bd5b787cStb 	if (nid != NULL)
433bd5b787cStb 		return *nid;
434bd5b787cStb 
435bd5b787cStb 	return NID_undef;
436bd5b787cStb }
437bd5b787cStb LCRYPTO_ALIAS(OBJ_ln2nid);
438bd5b787cStb 
439337c377eStb /* Convert an object name into an ASN1_OBJECT
440337c377eStb  * if "noname" is not set then search for short and long names first.
441337c377eStb  * This will convert the "dotted" form into an object: unlike OBJ_txt2nid
442337c377eStb  * it can be used with any objects, not just registered ones.
443337c377eStb  */
444337c377eStb 
445337c377eStb ASN1_OBJECT *
OBJ_txt2obj(const char * s,int no_name)446337c377eStb OBJ_txt2obj(const char *s, int no_name)
447337c377eStb {
448337c377eStb 	int nid;
449337c377eStb 
450337c377eStb 	if (!no_name) {
451337c377eStb 		if ((nid = OBJ_sn2nid(s)) != NID_undef ||
452337c377eStb 		    (nid = OBJ_ln2nid(s)) != NID_undef)
453337c377eStb 			return OBJ_nid2obj(nid);
454337c377eStb 	}
455337c377eStb 
456337c377eStb 	return t2i_ASN1_OBJECT_internal(s);
457337c377eStb }
458337c377eStb LCRYPTO_ALIAS(OBJ_txt2obj);
459337c377eStb 
460337c377eStb int
OBJ_obj2txt(char * buf,int buf_len,const ASN1_OBJECT * aobj,int no_name)461337c377eStb OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *aobj, int no_name)
462337c377eStb {
463337c377eStb 	return i2t_ASN1_OBJECT_internal(aobj, buf, buf_len, no_name);
464337c377eStb }
465337c377eStb LCRYPTO_ALIAS(OBJ_obj2txt);
466337c377eStb 
467337c377eStb int
OBJ_txt2nid(const char * s)468337c377eStb OBJ_txt2nid(const char *s)
469337c377eStb {
470337c377eStb 	ASN1_OBJECT *obj;
471337c377eStb 	int nid;
472337c377eStb 
473337c377eStb 	obj = OBJ_txt2obj(s, 0);
474337c377eStb 	nid = OBJ_obj2nid(obj);
475337c377eStb 	ASN1_OBJECT_free(obj);
476337c377eStb 	return nid;
477337c377eStb }
478337c377eStb LCRYPTO_ALIAS(OBJ_txt2nid);
479337c377eStb 
480223e7da0Sjsing int
OBJ_create_objects(BIO * in)481223e7da0Sjsing OBJ_create_objects(BIO *in)
4825b37fcf3Sryker {
4838b5c64d9Sbeck 	char buf[512];
484913ec974Sbeck 	int i, num = 0;
4855b37fcf3Sryker 	char *o, *s, *l = NULL;
4865b37fcf3Sryker 
487223e7da0Sjsing 	for (;;) {
4885b37fcf3Sryker 		s = o = NULL;
4895b37fcf3Sryker 		i = BIO_gets(in, buf, 512);
490223e7da0Sjsing 		if (i <= 0)
491223e7da0Sjsing 			return (num);
4925b37fcf3Sryker 		buf[i - 1] = '\0';
493223e7da0Sjsing 		if (!isalnum((unsigned char)buf[0]))
494223e7da0Sjsing 			return (num);
4955b37fcf3Sryker 		o = s=buf;
496913ec974Sbeck 		while (isdigit((unsigned char)*s) || (*s == '.'))
4975b37fcf3Sryker 			s++;
498223e7da0Sjsing 		if (*s != '\0') {
4995b37fcf3Sryker 			*(s++) = '\0';
500913ec974Sbeck 			while (isspace((unsigned char)*s))
5015b37fcf3Sryker 				s++;
5025b37fcf3Sryker 			if (*s == '\0')
5035b37fcf3Sryker 				s = NULL;
504223e7da0Sjsing 			else {
5055b37fcf3Sryker 				l = s;
506223e7da0Sjsing 				while ((*l != '\0') &&
507223e7da0Sjsing 				    !isspace((unsigned char)*l))
5085b37fcf3Sryker 					l++;
509223e7da0Sjsing 				if (*l != '\0') {
5105b37fcf3Sryker 					*(l++) = '\0';
511913ec974Sbeck 					while (isspace((unsigned char)*l))
5125b37fcf3Sryker 						l++;
513223e7da0Sjsing 					if (*l == '\0')
514223e7da0Sjsing 						l = NULL;
515223e7da0Sjsing 				} else
5165b37fcf3Sryker 					l = NULL;
5175b37fcf3Sryker 			}
518223e7da0Sjsing 		} else
5195b37fcf3Sryker 			s = NULL;
520223e7da0Sjsing 		if ((o == NULL) || (*o == '\0'))
521223e7da0Sjsing 			return (num);
522223e7da0Sjsing 		if (!OBJ_create(o, s, l))
523223e7da0Sjsing 			return (num);
5245b37fcf3Sryker 		num++;
5255b37fcf3Sryker 	}
526913ec974Sbeck 	/* return(num); */
5275b37fcf3Sryker }
5281e9308c1Sbeck LCRYPTO_ALIAS(OBJ_create_objects);
5295b37fcf3Sryker 
530223e7da0Sjsing int
OBJ_create(const char * oid,const char * sn,const char * ln)531223e7da0Sjsing OBJ_create(const char *oid, const char *sn, const char *ln)
5325b37fcf3Sryker {
533874d382aStb 	ASN1_OBJECT *aobj = NULL;
53430b1f96fStb 	unsigned char *buf = NULL;
5355a0b87fdStb 	int len, nid;
536386630a6Stb 	int ret = 0;
5375b37fcf3Sryker 
5385caa395dStb 	if ((len = a2d_ASN1_OBJECT(NULL, 0, oid, -1)) <= 0)
53930b1f96fStb 		goto err;
5405b37fcf3Sryker 
541718766e5Stb 	if ((buf = calloc(1, len)) == NULL) {
5425067ae9fSbeck 		OBJerror(ERR_R_MALLOC_FAILURE);
54330b1f96fStb 		goto err;
5445b37fcf3Sryker 	}
5455caa395dStb 
5465caa395dStb 	if ((len = a2d_ASN1_OBJECT(buf, len, oid, -1)) == 0)
547da347917Sbeck 		goto err;
5485caa395dStb 
5495a0b87fdStb 	nid = OBJ_new_nid(1);
550874d382aStb 	if ((aobj = ASN1_OBJECT_create(nid, buf, len, sn, ln)) == NULL)
5515b37fcf3Sryker 		goto err;
5525caa395dStb 
553874d382aStb 	ret = OBJ_add_object(aobj);
554223e7da0Sjsing 
5555b37fcf3Sryker  err:
556874d382aStb 	ASN1_OBJECT_free(aobj);
5576f3a6cb1Sbeck 	free(buf);
55830b1f96fStb 
559386630a6Stb 	return ret;
5605b37fcf3Sryker }
5611e9308c1Sbeck LCRYPTO_ALIAS(OBJ_create);
562460715d7Stb 
563460715d7Stb size_t
OBJ_length(const ASN1_OBJECT * obj)564460715d7Stb OBJ_length(const ASN1_OBJECT *obj)
565460715d7Stb {
566460715d7Stb 	if (obj == NULL)
567460715d7Stb 		return 0;
568460715d7Stb 
569460715d7Stb 	if (obj->length < 0)
570460715d7Stb 		return 0;
571460715d7Stb 
572460715d7Stb 	return obj->length;
573460715d7Stb }
5741e9308c1Sbeck LCRYPTO_ALIAS(OBJ_length);
575460715d7Stb 
576460715d7Stb const unsigned char *
OBJ_get0_data(const ASN1_OBJECT * obj)577460715d7Stb OBJ_get0_data(const ASN1_OBJECT *obj)
578460715d7Stb {
579460715d7Stb 	if (obj == NULL)
580460715d7Stb 		return NULL;
581460715d7Stb 
582460715d7Stb 	return obj->data;
583460715d7Stb }
5841e9308c1Sbeck LCRYPTO_ALIAS(OBJ_get0_data);
585