xref: /onnv-gate/usr/src/common/openssl/crypto/asn1/a_object.c (revision 2139:6243c3338933)
10Sstevel@tonic-gate /* crypto/asn1/a_object.c */
20Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
30Sstevel@tonic-gate  * All rights reserved.
40Sstevel@tonic-gate  *
50Sstevel@tonic-gate  * This package is an SSL implementation written
60Sstevel@tonic-gate  * by Eric Young (eay@cryptsoft.com).
70Sstevel@tonic-gate  * The implementation was written so as to conform with Netscapes SSL.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * This library is free for commercial and non-commercial use as long as
100Sstevel@tonic-gate  * the following conditions are aheared to.  The following conditions
110Sstevel@tonic-gate  * apply to all code found in this distribution, be it the RC4, RSA,
120Sstevel@tonic-gate  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
130Sstevel@tonic-gate  * included with this distribution is covered by the same copyright terms
140Sstevel@tonic-gate  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
150Sstevel@tonic-gate  *
160Sstevel@tonic-gate  * Copyright remains Eric Young's, and as such any Copyright notices in
170Sstevel@tonic-gate  * the code are not to be removed.
180Sstevel@tonic-gate  * If this package is used in a product, Eric Young should be given attribution
190Sstevel@tonic-gate  * as the author of the parts of the library used.
200Sstevel@tonic-gate  * This can be in the form of a textual message at program startup or
210Sstevel@tonic-gate  * in documentation (online or textual) provided with the package.
220Sstevel@tonic-gate  *
230Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
240Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
250Sstevel@tonic-gate  * are met:
260Sstevel@tonic-gate  * 1. Redistributions of source code must retain the copyright
270Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
280Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
290Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in the
300Sstevel@tonic-gate  *    documentation and/or other materials provided with the distribution.
310Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this software
320Sstevel@tonic-gate  *    must display the following acknowledgement:
330Sstevel@tonic-gate  *    "This product includes cryptographic software written by
340Sstevel@tonic-gate  *     Eric Young (eay@cryptsoft.com)"
350Sstevel@tonic-gate  *    The word 'cryptographic' can be left out if the rouines from the library
360Sstevel@tonic-gate  *    being used are not cryptographic related :-).
370Sstevel@tonic-gate  * 4. If you include any Windows specific code (or a derivative thereof) from
380Sstevel@tonic-gate  *    the apps directory (application code) you must include an acknowledgement:
390Sstevel@tonic-gate  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
400Sstevel@tonic-gate  *
410Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
420Sstevel@tonic-gate  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
430Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
440Sstevel@tonic-gate  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
450Sstevel@tonic-gate  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
460Sstevel@tonic-gate  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
470Sstevel@tonic-gate  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
480Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
490Sstevel@tonic-gate  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
500Sstevel@tonic-gate  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
510Sstevel@tonic-gate  * SUCH DAMAGE.
520Sstevel@tonic-gate  *
530Sstevel@tonic-gate  * The licence and distribution terms for any publically available version or
540Sstevel@tonic-gate  * derivative of this code cannot be changed.  i.e. this code cannot simply be
550Sstevel@tonic-gate  * copied and put under another distribution licence
560Sstevel@tonic-gate  * [including the GNU Public Licence.]
570Sstevel@tonic-gate  */
580Sstevel@tonic-gate 
590Sstevel@tonic-gate #include <stdio.h>
600Sstevel@tonic-gate #include "cryptlib.h"
610Sstevel@tonic-gate #include <openssl/buffer.h>
620Sstevel@tonic-gate #include <openssl/asn1.h>
630Sstevel@tonic-gate #include <openssl/objects.h>
640Sstevel@tonic-gate 
i2d_ASN1_OBJECT(ASN1_OBJECT * a,unsigned char ** pp)650Sstevel@tonic-gate int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
660Sstevel@tonic-gate 	{
670Sstevel@tonic-gate 	unsigned char *p;
680Sstevel@tonic-gate 	int objsize;
690Sstevel@tonic-gate 
700Sstevel@tonic-gate 	if ((a == NULL) || (a->data == NULL)) return(0);
710Sstevel@tonic-gate 
720Sstevel@tonic-gate 	objsize = ASN1_object_size(0,a->length,V_ASN1_OBJECT);
730Sstevel@tonic-gate 	if (pp == NULL) return objsize;
740Sstevel@tonic-gate 
750Sstevel@tonic-gate 	p= *pp;
760Sstevel@tonic-gate 	ASN1_put_object(&p,0,a->length,V_ASN1_OBJECT,V_ASN1_UNIVERSAL);
770Sstevel@tonic-gate 	memcpy(p,a->data,a->length);
780Sstevel@tonic-gate 	p+=a->length;
790Sstevel@tonic-gate 
800Sstevel@tonic-gate 	*pp=p;
810Sstevel@tonic-gate 	return(objsize);
820Sstevel@tonic-gate 	}
830Sstevel@tonic-gate 
a2d_ASN1_OBJECT(unsigned char * out,int olen,const char * buf,int num)840Sstevel@tonic-gate int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
850Sstevel@tonic-gate 	{
860Sstevel@tonic-gate 	int i,first,len=0,c;
870Sstevel@tonic-gate 	char tmp[24];
880Sstevel@tonic-gate 	const char *p;
890Sstevel@tonic-gate 	unsigned long l;
900Sstevel@tonic-gate 
910Sstevel@tonic-gate 	if (num == 0)
920Sstevel@tonic-gate 		return(0);
930Sstevel@tonic-gate 	else if (num == -1)
940Sstevel@tonic-gate 		num=strlen(buf);
950Sstevel@tonic-gate 
960Sstevel@tonic-gate 	p=buf;
970Sstevel@tonic-gate 	c= *(p++);
980Sstevel@tonic-gate 	num--;
990Sstevel@tonic-gate 	if ((c >= '0') && (c <= '2'))
1000Sstevel@tonic-gate 		{
1010Sstevel@tonic-gate 		first=(c-'0')*40;
1020Sstevel@tonic-gate 		}
1030Sstevel@tonic-gate 	else
1040Sstevel@tonic-gate 		{
1050Sstevel@tonic-gate 		ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_FIRST_NUM_TOO_LARGE);
1060Sstevel@tonic-gate 		goto err;
1070Sstevel@tonic-gate 		}
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate 	if (num <= 0)
1100Sstevel@tonic-gate 		{
1110Sstevel@tonic-gate 		ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_MISSING_SECOND_NUMBER);
1120Sstevel@tonic-gate 		goto err;
1130Sstevel@tonic-gate 		}
1140Sstevel@tonic-gate 	c= *(p++);
1150Sstevel@tonic-gate 	num--;
1160Sstevel@tonic-gate 	for (;;)
1170Sstevel@tonic-gate 		{
1180Sstevel@tonic-gate 		if (num <= 0) break;
1190Sstevel@tonic-gate 		if ((c != '.') && (c != ' '))
1200Sstevel@tonic-gate 			{
1210Sstevel@tonic-gate 			ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_SEPARATOR);
1220Sstevel@tonic-gate 			goto err;
1230Sstevel@tonic-gate 			}
1240Sstevel@tonic-gate 		l=0;
1250Sstevel@tonic-gate 		for (;;)
1260Sstevel@tonic-gate 			{
1270Sstevel@tonic-gate 			if (num <= 0) break;
1280Sstevel@tonic-gate 			num--;
1290Sstevel@tonic-gate 			c= *(p++);
1300Sstevel@tonic-gate 			if ((c == ' ') || (c == '.'))
1310Sstevel@tonic-gate 				break;
1320Sstevel@tonic-gate 			if ((c < '0') || (c > '9'))
1330Sstevel@tonic-gate 				{
1340Sstevel@tonic-gate 				ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_DIGIT);
1350Sstevel@tonic-gate 				goto err;
1360Sstevel@tonic-gate 				}
1370Sstevel@tonic-gate 			l=l*10L+(long)(c-'0');
1380Sstevel@tonic-gate 			}
1390Sstevel@tonic-gate 		if (len == 0)
1400Sstevel@tonic-gate 			{
1410Sstevel@tonic-gate 			if ((first < 2) && (l >= 40))
1420Sstevel@tonic-gate 				{
1430Sstevel@tonic-gate 				ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_SECOND_NUMBER_TOO_LARGE);
1440Sstevel@tonic-gate 				goto err;
1450Sstevel@tonic-gate 				}
1460Sstevel@tonic-gate 			l+=(long)first;
1470Sstevel@tonic-gate 			}
1480Sstevel@tonic-gate 		i=0;
1490Sstevel@tonic-gate 		for (;;)
1500Sstevel@tonic-gate 			{
1510Sstevel@tonic-gate 			tmp[i++]=(unsigned char)l&0x7f;
1520Sstevel@tonic-gate 			l>>=7L;
1530Sstevel@tonic-gate 			if (l == 0L) break;
1540Sstevel@tonic-gate 			}
1550Sstevel@tonic-gate 		if (out != NULL)
1560Sstevel@tonic-gate 			{
1570Sstevel@tonic-gate 			if (len+i > olen)
1580Sstevel@tonic-gate 				{
1590Sstevel@tonic-gate 				ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_BUFFER_TOO_SMALL);
1600Sstevel@tonic-gate 				goto err;
1610Sstevel@tonic-gate 				}
1620Sstevel@tonic-gate 			while (--i > 0)
1630Sstevel@tonic-gate 				out[len++]=tmp[i]|0x80;
1640Sstevel@tonic-gate 			out[len++]=tmp[0];
1650Sstevel@tonic-gate 			}
1660Sstevel@tonic-gate 		else
1670Sstevel@tonic-gate 			len+=i;
1680Sstevel@tonic-gate 		}
1690Sstevel@tonic-gate 	return(len);
1700Sstevel@tonic-gate err:
1710Sstevel@tonic-gate 	return(0);
1720Sstevel@tonic-gate 	}
1730Sstevel@tonic-gate 
i2t_ASN1_OBJECT(char * buf,int buf_len,ASN1_OBJECT * a)1740Sstevel@tonic-gate int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
1750Sstevel@tonic-gate {
1760Sstevel@tonic-gate 	return OBJ_obj2txt(buf, buf_len, a, 0);
1770Sstevel@tonic-gate }
1780Sstevel@tonic-gate 
i2a_ASN1_OBJECT(BIO * bp,ASN1_OBJECT * a)1790Sstevel@tonic-gate int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
1800Sstevel@tonic-gate 	{
1810Sstevel@tonic-gate 	char buf[80];
1820Sstevel@tonic-gate 	int i;
1830Sstevel@tonic-gate 
1840Sstevel@tonic-gate 	if ((a == NULL) || (a->data == NULL))
1850Sstevel@tonic-gate 		return(BIO_write(bp,"NULL",4));
1860Sstevel@tonic-gate 	i=i2t_ASN1_OBJECT(buf,sizeof buf,a);
187*2139Sjp161948 	if (i > (int)sizeof(buf)) i=sizeof buf;
1880Sstevel@tonic-gate 	BIO_write(bp,buf,i);
1890Sstevel@tonic-gate 	return(i);
1900Sstevel@tonic-gate 	}
1910Sstevel@tonic-gate 
d2i_ASN1_OBJECT(ASN1_OBJECT ** a,const unsigned char ** pp,long length)192*2139Sjp161948 ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
1930Sstevel@tonic-gate 	     long length)
1940Sstevel@tonic-gate {
195*2139Sjp161948 	const unsigned char *p;
1960Sstevel@tonic-gate 	long len;
1970Sstevel@tonic-gate 	int tag,xclass;
1980Sstevel@tonic-gate 	int inf,i;
1990Sstevel@tonic-gate 	ASN1_OBJECT *ret = NULL;
2000Sstevel@tonic-gate 	p= *pp;
2010Sstevel@tonic-gate 	inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
2020Sstevel@tonic-gate 	if (inf & 0x80)
2030Sstevel@tonic-gate 		{
2040Sstevel@tonic-gate 		i=ASN1_R_BAD_OBJECT_HEADER;
2050Sstevel@tonic-gate 		goto err;
2060Sstevel@tonic-gate 		}
2070Sstevel@tonic-gate 
2080Sstevel@tonic-gate 	if (tag != V_ASN1_OBJECT)
2090Sstevel@tonic-gate 		{
2100Sstevel@tonic-gate 		i=ASN1_R_EXPECTING_AN_OBJECT;
2110Sstevel@tonic-gate 		goto err;
2120Sstevel@tonic-gate 		}
2130Sstevel@tonic-gate 	ret = c2i_ASN1_OBJECT(a, &p, len);
2140Sstevel@tonic-gate 	if(ret) *pp = p;
2150Sstevel@tonic-gate 	return ret;
2160Sstevel@tonic-gate err:
2170Sstevel@tonic-gate 	ASN1err(ASN1_F_D2I_ASN1_OBJECT,i);
2180Sstevel@tonic-gate 	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
2190Sstevel@tonic-gate 		ASN1_OBJECT_free(ret);
2200Sstevel@tonic-gate 	return(NULL);
2210Sstevel@tonic-gate }
c2i_ASN1_OBJECT(ASN1_OBJECT ** a,const unsigned char ** pp,long len)222*2139Sjp161948 ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
2230Sstevel@tonic-gate 	     long len)
2240Sstevel@tonic-gate 	{
2250Sstevel@tonic-gate 	ASN1_OBJECT *ret=NULL;
226*2139Sjp161948 	const unsigned char *p;
2270Sstevel@tonic-gate 	int i;
2280Sstevel@tonic-gate 
2290Sstevel@tonic-gate 	/* only the ASN1_OBJECTs from the 'table' will have values
2300Sstevel@tonic-gate 	 * for ->sn or ->ln */
2310Sstevel@tonic-gate 	if ((a == NULL) || ((*a) == NULL) ||
2320Sstevel@tonic-gate 		!((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC))
2330Sstevel@tonic-gate 		{
2340Sstevel@tonic-gate 		if ((ret=ASN1_OBJECT_new()) == NULL) return(NULL);
2350Sstevel@tonic-gate 		}
2360Sstevel@tonic-gate 	else	ret=(*a);
2370Sstevel@tonic-gate 
2380Sstevel@tonic-gate 	p= *pp;
2390Sstevel@tonic-gate 	if ((ret->data == NULL) || (ret->length < len))
2400Sstevel@tonic-gate 		{
2410Sstevel@tonic-gate 		if (ret->data != NULL) OPENSSL_free(ret->data);
2420Sstevel@tonic-gate 		ret->data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1);
2430Sstevel@tonic-gate 		ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA;
2440Sstevel@tonic-gate 		if (ret->data == NULL)
2450Sstevel@tonic-gate 			{ i=ERR_R_MALLOC_FAILURE; goto err; }
2460Sstevel@tonic-gate 		}
2470Sstevel@tonic-gate 	memcpy(ret->data,p,(int)len);
2480Sstevel@tonic-gate 	ret->length=(int)len;
2490Sstevel@tonic-gate 	ret->sn=NULL;
2500Sstevel@tonic-gate 	ret->ln=NULL;
2510Sstevel@tonic-gate 	/* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
2520Sstevel@tonic-gate 	p+=len;
2530Sstevel@tonic-gate 
2540Sstevel@tonic-gate 	if (a != NULL) (*a)=ret;
2550Sstevel@tonic-gate 	*pp=p;
2560Sstevel@tonic-gate 	return(ret);
2570Sstevel@tonic-gate err:
258*2139Sjp161948 	ASN1err(ASN1_F_C2I_ASN1_OBJECT,i);
2590Sstevel@tonic-gate 	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
2600Sstevel@tonic-gate 		ASN1_OBJECT_free(ret);
2610Sstevel@tonic-gate 	return(NULL);
2620Sstevel@tonic-gate 	}
2630Sstevel@tonic-gate 
ASN1_OBJECT_new(void)2640Sstevel@tonic-gate ASN1_OBJECT *ASN1_OBJECT_new(void)
2650Sstevel@tonic-gate 	{
2660Sstevel@tonic-gate 	ASN1_OBJECT *ret;
2670Sstevel@tonic-gate 
2680Sstevel@tonic-gate 	ret=(ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
2690Sstevel@tonic-gate 	if (ret == NULL)
2700Sstevel@tonic-gate 		{
2710Sstevel@tonic-gate 		ASN1err(ASN1_F_ASN1_OBJECT_NEW,ERR_R_MALLOC_FAILURE);
2720Sstevel@tonic-gate 		return(NULL);
2730Sstevel@tonic-gate 		}
2740Sstevel@tonic-gate 	ret->length=0;
2750Sstevel@tonic-gate 	ret->data=NULL;
2760Sstevel@tonic-gate 	ret->nid=0;
2770Sstevel@tonic-gate 	ret->sn=NULL;
2780Sstevel@tonic-gate 	ret->ln=NULL;
2790Sstevel@tonic-gate 	ret->flags=ASN1_OBJECT_FLAG_DYNAMIC;
2800Sstevel@tonic-gate 	return(ret);
2810Sstevel@tonic-gate 	}
2820Sstevel@tonic-gate 
ASN1_OBJECT_free(ASN1_OBJECT * a)2830Sstevel@tonic-gate void ASN1_OBJECT_free(ASN1_OBJECT *a)
2840Sstevel@tonic-gate 	{
2850Sstevel@tonic-gate 	if (a == NULL) return;
2860Sstevel@tonic-gate 	if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS)
2870Sstevel@tonic-gate 		{
2880Sstevel@tonic-gate #ifndef CONST_STRICT /* disable purely for compile-time strict const checking. Doing this on a "real" compile will cause memory leaks */
2890Sstevel@tonic-gate 		if (a->sn != NULL) OPENSSL_free((void *)a->sn);
2900Sstevel@tonic-gate 		if (a->ln != NULL) OPENSSL_free((void *)a->ln);
2910Sstevel@tonic-gate #endif
2920Sstevel@tonic-gate 		a->sn=a->ln=NULL;
2930Sstevel@tonic-gate 		}
2940Sstevel@tonic-gate 	if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA)
2950Sstevel@tonic-gate 		{
2960Sstevel@tonic-gate 		if (a->data != NULL) OPENSSL_free(a->data);
2970Sstevel@tonic-gate 		a->data=NULL;
2980Sstevel@tonic-gate 		a->length=0;
2990Sstevel@tonic-gate 		}
3000Sstevel@tonic-gate 	if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
3010Sstevel@tonic-gate 		OPENSSL_free(a);
3020Sstevel@tonic-gate 	}
3030Sstevel@tonic-gate 
ASN1_OBJECT_create(int nid,unsigned char * data,int len,const char * sn,const char * ln)3040Sstevel@tonic-gate ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
3050Sstevel@tonic-gate 	     const char *sn, const char *ln)
3060Sstevel@tonic-gate 	{
3070Sstevel@tonic-gate 	ASN1_OBJECT o;
3080Sstevel@tonic-gate 
3090Sstevel@tonic-gate 	o.sn=sn;
3100Sstevel@tonic-gate 	o.ln=ln;
3110Sstevel@tonic-gate 	o.data=data;
3120Sstevel@tonic-gate 	o.nid=nid;
3130Sstevel@tonic-gate 	o.length=len;
3140Sstevel@tonic-gate 	o.flags=ASN1_OBJECT_FLAG_DYNAMIC|ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|
3150Sstevel@tonic-gate 		ASN1_OBJECT_FLAG_DYNAMIC_DATA;
3160Sstevel@tonic-gate 	return(OBJ_dup(&o));
3170Sstevel@tonic-gate 	}
3180Sstevel@tonic-gate 
3190Sstevel@tonic-gate IMPLEMENT_STACK_OF(ASN1_OBJECT)
3200Sstevel@tonic-gate IMPLEMENT_ASN1_SET_OF(ASN1_OBJECT)
321