xref: /onnv-gate/usr/src/common/openssl/crypto/asn1/asn1_lib.c (revision 2139:6243c3338933)
10Sstevel@tonic-gate /* crypto/asn1/asn1_lib.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 <limits.h>
610Sstevel@tonic-gate #include "cryptlib.h"
620Sstevel@tonic-gate #include <openssl/asn1.h>
630Sstevel@tonic-gate #include <openssl/asn1_mac.h>
640Sstevel@tonic-gate 
65*2139Sjp161948 static int asn1_get_length(const unsigned char **pp,int *inf,long *rl,int max);
660Sstevel@tonic-gate static void asn1_put_length(unsigned char **pp, int length);
670Sstevel@tonic-gate const char *ASN1_version="ASN.1" OPENSSL_VERSION_PTEXT;
680Sstevel@tonic-gate 
_asn1_check_infinite_end(const unsigned char ** p,long len)69*2139Sjp161948 static int _asn1_check_infinite_end(const unsigned char **p, long len)
700Sstevel@tonic-gate 	{
710Sstevel@tonic-gate 	/* If there is 0 or 1 byte left, the length check should pick
720Sstevel@tonic-gate 	 * things up */
730Sstevel@tonic-gate 	if (len <= 0)
740Sstevel@tonic-gate 		return(1);
750Sstevel@tonic-gate 	else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0))
760Sstevel@tonic-gate 		{
770Sstevel@tonic-gate 		(*p)+=2;
780Sstevel@tonic-gate 		return(1);
790Sstevel@tonic-gate 		}
800Sstevel@tonic-gate 	return(0);
810Sstevel@tonic-gate 	}
820Sstevel@tonic-gate 
ASN1_check_infinite_end(unsigned char ** p,long len)83*2139Sjp161948 int ASN1_check_infinite_end(unsigned char **p, long len)
84*2139Sjp161948 	{
85*2139Sjp161948 	return _asn1_check_infinite_end((const unsigned char **)p, len);
86*2139Sjp161948 	}
870Sstevel@tonic-gate 
ASN1_const_check_infinite_end(const unsigned char ** p,long len)88*2139Sjp161948 int ASN1_const_check_infinite_end(const unsigned char **p, long len)
89*2139Sjp161948 	{
90*2139Sjp161948 	return _asn1_check_infinite_end(p, len);
91*2139Sjp161948 	}
92*2139Sjp161948 
93*2139Sjp161948 
ASN1_get_object(const unsigned char ** pp,long * plength,int * ptag,int * pclass,long omax)94*2139Sjp161948 int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
95*2139Sjp161948 	int *pclass, long omax)
960Sstevel@tonic-gate 	{
970Sstevel@tonic-gate 	int i,ret;
980Sstevel@tonic-gate 	long l;
99*2139Sjp161948 	const unsigned char *p= *pp;
1000Sstevel@tonic-gate 	int tag,xclass,inf;
1010Sstevel@tonic-gate 	long max=omax;
1020Sstevel@tonic-gate 
1030Sstevel@tonic-gate 	if (!max) goto err;
1040Sstevel@tonic-gate 	ret=(*p&V_ASN1_CONSTRUCTED);
1050Sstevel@tonic-gate 	xclass=(*p&V_ASN1_PRIVATE);
1060Sstevel@tonic-gate 	i= *p&V_ASN1_PRIMITIVE_TAG;
1070Sstevel@tonic-gate 	if (i == V_ASN1_PRIMITIVE_TAG)
1080Sstevel@tonic-gate 		{		/* high-tag */
1090Sstevel@tonic-gate 		p++;
1100Sstevel@tonic-gate 		if (--max == 0) goto err;
1110Sstevel@tonic-gate 		l=0;
1120Sstevel@tonic-gate 		while (*p&0x80)
1130Sstevel@tonic-gate 			{
1140Sstevel@tonic-gate 			l<<=7L;
1150Sstevel@tonic-gate 			l|= *(p++)&0x7f;
1160Sstevel@tonic-gate 			if (--max == 0) goto err;
1170Sstevel@tonic-gate 			if (l > (INT_MAX >> 7L)) goto err;
1180Sstevel@tonic-gate 			}
1190Sstevel@tonic-gate 		l<<=7L;
1200Sstevel@tonic-gate 		l|= *(p++)&0x7f;
1210Sstevel@tonic-gate 		tag=(int)l;
1220Sstevel@tonic-gate 		if (--max == 0) goto err;
1230Sstevel@tonic-gate 		}
1240Sstevel@tonic-gate 	else
1250Sstevel@tonic-gate 		{
1260Sstevel@tonic-gate 		tag=i;
1270Sstevel@tonic-gate 		p++;
1280Sstevel@tonic-gate 		if (--max == 0) goto err;
1290Sstevel@tonic-gate 		}
1300Sstevel@tonic-gate 	*ptag=tag;
1310Sstevel@tonic-gate 	*pclass=xclass;
1320Sstevel@tonic-gate 	if (!asn1_get_length(&p,&inf,plength,(int)max)) goto err;
1330Sstevel@tonic-gate 
1340Sstevel@tonic-gate #if 0
1350Sstevel@tonic-gate 	fprintf(stderr,"p=%d + *plength=%ld > omax=%ld + *pp=%d  (%d > %d)\n",
1360Sstevel@tonic-gate 		(int)p,*plength,omax,(int)*pp,(int)(p+ *plength),
1370Sstevel@tonic-gate 		(int)(omax+ *pp));
1380Sstevel@tonic-gate 
1390Sstevel@tonic-gate #endif
1400Sstevel@tonic-gate 	if (*plength > (omax - (p - *pp)))
1410Sstevel@tonic-gate 		{
1420Sstevel@tonic-gate 		ASN1err(ASN1_F_ASN1_GET_OBJECT,ASN1_R_TOO_LONG);
1430Sstevel@tonic-gate 		/* Set this so that even if things are not long enough
1440Sstevel@tonic-gate 		 * the values are set correctly */
1450Sstevel@tonic-gate 		ret|=0x80;
1460Sstevel@tonic-gate 		}
1470Sstevel@tonic-gate 	*pp=p;
1480Sstevel@tonic-gate 	return(ret|inf);
1490Sstevel@tonic-gate err:
1500Sstevel@tonic-gate 	ASN1err(ASN1_F_ASN1_GET_OBJECT,ASN1_R_HEADER_TOO_LONG);
1510Sstevel@tonic-gate 	return(0x80);
1520Sstevel@tonic-gate 	}
1530Sstevel@tonic-gate 
asn1_get_length(const unsigned char ** pp,int * inf,long * rl,int max)154*2139Sjp161948 static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, int max)
1550Sstevel@tonic-gate 	{
156*2139Sjp161948 	const unsigned char *p= *pp;
1570Sstevel@tonic-gate 	unsigned long ret=0;
158*2139Sjp161948 	unsigned int i;
1590Sstevel@tonic-gate 
1600Sstevel@tonic-gate 	if (max-- < 1) return(0);
1610Sstevel@tonic-gate 	if (*p == 0x80)
1620Sstevel@tonic-gate 		{
1630Sstevel@tonic-gate 		*inf=1;
1640Sstevel@tonic-gate 		ret=0;
1650Sstevel@tonic-gate 		p++;
1660Sstevel@tonic-gate 		}
1670Sstevel@tonic-gate 	else
1680Sstevel@tonic-gate 		{
1690Sstevel@tonic-gate 		*inf=0;
1700Sstevel@tonic-gate 		i= *p&0x7f;
1710Sstevel@tonic-gate 		if (*(p++) & 0x80)
1720Sstevel@tonic-gate 			{
1730Sstevel@tonic-gate 			if (i > sizeof(long))
1740Sstevel@tonic-gate 				return 0;
1750Sstevel@tonic-gate 			if (max-- == 0) return(0);
1760Sstevel@tonic-gate 			while (i-- > 0)
1770Sstevel@tonic-gate 				{
1780Sstevel@tonic-gate 				ret<<=8L;
1790Sstevel@tonic-gate 				ret|= *(p++);
1800Sstevel@tonic-gate 				if (max-- == 0) return(0);
1810Sstevel@tonic-gate 				}
1820Sstevel@tonic-gate 			}
1830Sstevel@tonic-gate 		else
1840Sstevel@tonic-gate 			ret=i;
1850Sstevel@tonic-gate 		}
1860Sstevel@tonic-gate 	if (ret > LONG_MAX)
1870Sstevel@tonic-gate 		return 0;
1880Sstevel@tonic-gate 	*pp=p;
1890Sstevel@tonic-gate 	*rl=(long)ret;
1900Sstevel@tonic-gate 	return(1);
1910Sstevel@tonic-gate 	}
1920Sstevel@tonic-gate 
1930Sstevel@tonic-gate /* class 0 is constructed
1940Sstevel@tonic-gate  * constructed == 2 for indefinite length constructed */
ASN1_put_object(unsigned char ** pp,int constructed,int length,int tag,int xclass)1950Sstevel@tonic-gate void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
1960Sstevel@tonic-gate 	     int xclass)
1970Sstevel@tonic-gate 	{
1980Sstevel@tonic-gate 	unsigned char *p= *pp;
1990Sstevel@tonic-gate 	int i, ttag;
2000Sstevel@tonic-gate 
2010Sstevel@tonic-gate 	i=(constructed)?V_ASN1_CONSTRUCTED:0;
2020Sstevel@tonic-gate 	i|=(xclass&V_ASN1_PRIVATE);
2030Sstevel@tonic-gate 	if (tag < 31)
2040Sstevel@tonic-gate 		*(p++)=i|(tag&V_ASN1_PRIMITIVE_TAG);
2050Sstevel@tonic-gate 	else
2060Sstevel@tonic-gate 		{
2070Sstevel@tonic-gate 		*(p++)=i|V_ASN1_PRIMITIVE_TAG;
2080Sstevel@tonic-gate 		for(i = 0, ttag = tag; ttag > 0; i++) ttag >>=7;
2090Sstevel@tonic-gate 		ttag = i;
2100Sstevel@tonic-gate 		while(i-- > 0)
2110Sstevel@tonic-gate 			{
2120Sstevel@tonic-gate 			p[i] = tag & 0x7f;
2130Sstevel@tonic-gate 			if(i != (ttag - 1)) p[i] |= 0x80;
2140Sstevel@tonic-gate 			tag >>= 7;
2150Sstevel@tonic-gate 			}
2160Sstevel@tonic-gate 		p += ttag;
2170Sstevel@tonic-gate 		}
218*2139Sjp161948 	if (constructed == 2)
219*2139Sjp161948 		*(p++)=0x80;
2200Sstevel@tonic-gate 	else
2210Sstevel@tonic-gate 		asn1_put_length(&p,length);
2220Sstevel@tonic-gate 	*pp=p;
2230Sstevel@tonic-gate 	}
2240Sstevel@tonic-gate 
ASN1_put_eoc(unsigned char ** pp)225*2139Sjp161948 int ASN1_put_eoc(unsigned char **pp)
226*2139Sjp161948 	{
227*2139Sjp161948 	unsigned char *p = *pp;
228*2139Sjp161948 	*p++ = 0;
229*2139Sjp161948 	*p++ = 0;
230*2139Sjp161948 	*pp = p;
231*2139Sjp161948 	return 2;
232*2139Sjp161948 	}
233*2139Sjp161948 
asn1_put_length(unsigned char ** pp,int length)2340Sstevel@tonic-gate static void asn1_put_length(unsigned char **pp, int length)
2350Sstevel@tonic-gate 	{
2360Sstevel@tonic-gate 	unsigned char *p= *pp;
2370Sstevel@tonic-gate 	int i,l;
2380Sstevel@tonic-gate 	if (length <= 127)
2390Sstevel@tonic-gate 		*(p++)=(unsigned char)length;
2400Sstevel@tonic-gate 	else
2410Sstevel@tonic-gate 		{
2420Sstevel@tonic-gate 		l=length;
2430Sstevel@tonic-gate 		for (i=0; l > 0; i++)
2440Sstevel@tonic-gate 			l>>=8;
2450Sstevel@tonic-gate 		*(p++)=i|0x80;
2460Sstevel@tonic-gate 		l=i;
2470Sstevel@tonic-gate 		while (i-- > 0)
2480Sstevel@tonic-gate 			{
2490Sstevel@tonic-gate 			p[i]=length&0xff;
2500Sstevel@tonic-gate 			length>>=8;
2510Sstevel@tonic-gate 			}
2520Sstevel@tonic-gate 		p+=l;
2530Sstevel@tonic-gate 		}
2540Sstevel@tonic-gate 	*pp=p;
2550Sstevel@tonic-gate 	}
2560Sstevel@tonic-gate 
ASN1_object_size(int constructed,int length,int tag)2570Sstevel@tonic-gate int ASN1_object_size(int constructed, int length, int tag)
2580Sstevel@tonic-gate 	{
2590Sstevel@tonic-gate 	int ret;
2600Sstevel@tonic-gate 
2610Sstevel@tonic-gate 	ret=length;
2620Sstevel@tonic-gate 	ret++;
2630Sstevel@tonic-gate 	if (tag >= 31)
2640Sstevel@tonic-gate 		{
2650Sstevel@tonic-gate 		while (tag > 0)
2660Sstevel@tonic-gate 			{
2670Sstevel@tonic-gate 			tag>>=7;
2680Sstevel@tonic-gate 			ret++;
2690Sstevel@tonic-gate 			}
2700Sstevel@tonic-gate 		}
271*2139Sjp161948 	if (constructed == 2)
272*2139Sjp161948 		return ret + 3;
2730Sstevel@tonic-gate 	ret++;
2740Sstevel@tonic-gate 	if (length > 127)
2750Sstevel@tonic-gate 		{
2760Sstevel@tonic-gate 		while (length > 0)
2770Sstevel@tonic-gate 			{
2780Sstevel@tonic-gate 			length>>=8;
2790Sstevel@tonic-gate 			ret++;
2800Sstevel@tonic-gate 			}
2810Sstevel@tonic-gate 		}
2820Sstevel@tonic-gate 	return(ret);
2830Sstevel@tonic-gate 	}
2840Sstevel@tonic-gate 
_asn1_Finish(ASN1_const_CTX * c)285*2139Sjp161948 static int _asn1_Finish(ASN1_const_CTX *c)
2860Sstevel@tonic-gate 	{
2870Sstevel@tonic-gate 	if ((c->inf == (1|V_ASN1_CONSTRUCTED)) && (!c->eos))
2880Sstevel@tonic-gate 		{
289*2139Sjp161948 		if (!ASN1_const_check_infinite_end(&c->p,c->slen))
2900Sstevel@tonic-gate 			{
2910Sstevel@tonic-gate 			c->error=ERR_R_MISSING_ASN1_EOS;
2920Sstevel@tonic-gate 			return(0);
2930Sstevel@tonic-gate 			}
2940Sstevel@tonic-gate 		}
2950Sstevel@tonic-gate 	if (	((c->slen != 0) && !(c->inf & 1)) ||
2960Sstevel@tonic-gate 		((c->slen < 0) && (c->inf & 1)))
2970Sstevel@tonic-gate 		{
2980Sstevel@tonic-gate 		c->error=ERR_R_ASN1_LENGTH_MISMATCH;
2990Sstevel@tonic-gate 		return(0);
3000Sstevel@tonic-gate 		}
3010Sstevel@tonic-gate 	return(1);
3020Sstevel@tonic-gate 	}
3030Sstevel@tonic-gate 
asn1_Finish(ASN1_CTX * c)304*2139Sjp161948 int asn1_Finish(ASN1_CTX *c)
305*2139Sjp161948 	{
306*2139Sjp161948 	return _asn1_Finish((ASN1_const_CTX *)c);
307*2139Sjp161948 	}
308*2139Sjp161948 
asn1_const_Finish(ASN1_const_CTX * c)309*2139Sjp161948 int asn1_const_Finish(ASN1_const_CTX *c)
3100Sstevel@tonic-gate 	{
311*2139Sjp161948 	return _asn1_Finish(c);
312*2139Sjp161948 	}
313*2139Sjp161948 
asn1_GetSequence(ASN1_const_CTX * c,long * length)314*2139Sjp161948 int asn1_GetSequence(ASN1_const_CTX *c, long *length)
315*2139Sjp161948 	{
316*2139Sjp161948 	const unsigned char *q;
3170Sstevel@tonic-gate 
3180Sstevel@tonic-gate 	q=c->p;
3190Sstevel@tonic-gate 	c->inf=ASN1_get_object(&(c->p),&(c->slen),&(c->tag),&(c->xclass),
3200Sstevel@tonic-gate 		*length);
3210Sstevel@tonic-gate 	if (c->inf & 0x80)
3220Sstevel@tonic-gate 		{
3230Sstevel@tonic-gate 		c->error=ERR_R_BAD_GET_ASN1_OBJECT_CALL;
3240Sstevel@tonic-gate 		return(0);
3250Sstevel@tonic-gate 		}
3260Sstevel@tonic-gate 	if (c->tag != V_ASN1_SEQUENCE)
3270Sstevel@tonic-gate 		{
3280Sstevel@tonic-gate 		c->error=ERR_R_EXPECTING_AN_ASN1_SEQUENCE;
3290Sstevel@tonic-gate 		return(0);
3300Sstevel@tonic-gate 		}
3310Sstevel@tonic-gate 	(*length)-=(c->p-q);
3320Sstevel@tonic-gate 	if (c->max && (*length < 0))
3330Sstevel@tonic-gate 		{
3340Sstevel@tonic-gate 		c->error=ERR_R_ASN1_LENGTH_MISMATCH;
3350Sstevel@tonic-gate 		return(0);
3360Sstevel@tonic-gate 		}
3370Sstevel@tonic-gate 	if (c->inf == (1|V_ASN1_CONSTRUCTED))
3380Sstevel@tonic-gate 		c->slen= *length+ *(c->pp)-c->p;
3390Sstevel@tonic-gate 	c->eos=0;
3400Sstevel@tonic-gate 	return(1);
3410Sstevel@tonic-gate 	}
3420Sstevel@tonic-gate 
ASN1_STRING_dup(ASN1_STRING * str)3430Sstevel@tonic-gate ASN1_STRING *ASN1_STRING_dup(ASN1_STRING *str)
3440Sstevel@tonic-gate 	{
3450Sstevel@tonic-gate 	ASN1_STRING *ret;
3460Sstevel@tonic-gate 
3470Sstevel@tonic-gate 	if (str == NULL) return(NULL);
3480Sstevel@tonic-gate 	if ((ret=ASN1_STRING_type_new(str->type)) == NULL)
3490Sstevel@tonic-gate 		return(NULL);
3500Sstevel@tonic-gate 	if (!ASN1_STRING_set(ret,str->data,str->length))
3510Sstevel@tonic-gate 		{
3520Sstevel@tonic-gate 		ASN1_STRING_free(ret);
3530Sstevel@tonic-gate 		return(NULL);
3540Sstevel@tonic-gate 		}
3550Sstevel@tonic-gate 	ret->flags = str->flags;
3560Sstevel@tonic-gate 	return(ret);
3570Sstevel@tonic-gate 	}
3580Sstevel@tonic-gate 
ASN1_STRING_set(ASN1_STRING * str,const void * _data,int len)3590Sstevel@tonic-gate int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
3600Sstevel@tonic-gate 	{
3610Sstevel@tonic-gate 	unsigned char *c;
3620Sstevel@tonic-gate 	const char *data=_data;
3630Sstevel@tonic-gate 
3640Sstevel@tonic-gate 	if (len < 0)
3650Sstevel@tonic-gate 		{
3660Sstevel@tonic-gate 		if (data == NULL)
3670Sstevel@tonic-gate 			return(0);
3680Sstevel@tonic-gate 		else
3690Sstevel@tonic-gate 			len=strlen(data);
3700Sstevel@tonic-gate 		}
3710Sstevel@tonic-gate 	if ((str->length < len) || (str->data == NULL))
3720Sstevel@tonic-gate 		{
3730Sstevel@tonic-gate 		c=str->data;
3740Sstevel@tonic-gate 		if (c == NULL)
3750Sstevel@tonic-gate 			str->data=OPENSSL_malloc(len+1);
3760Sstevel@tonic-gate 		else
3770Sstevel@tonic-gate 			str->data=OPENSSL_realloc(c,len+1);
3780Sstevel@tonic-gate 
3790Sstevel@tonic-gate 		if (str->data == NULL)
3800Sstevel@tonic-gate 			{
381*2139Sjp161948 			ASN1err(ASN1_F_ASN1_STRING_SET,ERR_R_MALLOC_FAILURE);
3820Sstevel@tonic-gate 			str->data=c;
3830Sstevel@tonic-gate 			return(0);
3840Sstevel@tonic-gate 			}
3850Sstevel@tonic-gate 		}
3860Sstevel@tonic-gate 	str->length=len;
3870Sstevel@tonic-gate 	if (data != NULL)
3880Sstevel@tonic-gate 		{
3890Sstevel@tonic-gate 		memcpy(str->data,data,len);
3900Sstevel@tonic-gate 		/* an allowance for strings :-) */
3910Sstevel@tonic-gate 		str->data[len]='\0';
3920Sstevel@tonic-gate 		}
3930Sstevel@tonic-gate 	return(1);
3940Sstevel@tonic-gate 	}
3950Sstevel@tonic-gate 
ASN1_STRING_new(void)3960Sstevel@tonic-gate ASN1_STRING *ASN1_STRING_new(void)
3970Sstevel@tonic-gate 	{
3980Sstevel@tonic-gate 	return(ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
3990Sstevel@tonic-gate 	}
4000Sstevel@tonic-gate 
4010Sstevel@tonic-gate 
ASN1_STRING_type_new(int type)4020Sstevel@tonic-gate ASN1_STRING *ASN1_STRING_type_new(int type)
4030Sstevel@tonic-gate 	{
4040Sstevel@tonic-gate 	ASN1_STRING *ret;
4050Sstevel@tonic-gate 
4060Sstevel@tonic-gate 	ret=(ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING));
4070Sstevel@tonic-gate 	if (ret == NULL)
4080Sstevel@tonic-gate 		{
4090Sstevel@tonic-gate 		ASN1err(ASN1_F_ASN1_STRING_TYPE_NEW,ERR_R_MALLOC_FAILURE);
4100Sstevel@tonic-gate 		return(NULL);
4110Sstevel@tonic-gate 		}
4120Sstevel@tonic-gate 	ret->length=0;
4130Sstevel@tonic-gate 	ret->type=type;
4140Sstevel@tonic-gate 	ret->data=NULL;
4150Sstevel@tonic-gate 	ret->flags=0;
4160Sstevel@tonic-gate 	return(ret);
4170Sstevel@tonic-gate 	}
4180Sstevel@tonic-gate 
ASN1_STRING_free(ASN1_STRING * a)4190Sstevel@tonic-gate void ASN1_STRING_free(ASN1_STRING *a)
4200Sstevel@tonic-gate 	{
4210Sstevel@tonic-gate 	if (a == NULL) return;
4220Sstevel@tonic-gate 	if (a->data != NULL) OPENSSL_free(a->data);
4230Sstevel@tonic-gate 	OPENSSL_free(a);
4240Sstevel@tonic-gate 	}
4250Sstevel@tonic-gate 
ASN1_STRING_cmp(ASN1_STRING * a,ASN1_STRING * b)4260Sstevel@tonic-gate int ASN1_STRING_cmp(ASN1_STRING *a, ASN1_STRING *b)
4270Sstevel@tonic-gate 	{
4280Sstevel@tonic-gate 	int i;
4290Sstevel@tonic-gate 
4300Sstevel@tonic-gate 	i=(a->length-b->length);
4310Sstevel@tonic-gate 	if (i == 0)
4320Sstevel@tonic-gate 		{
4330Sstevel@tonic-gate 		i=memcmp(a->data,b->data,a->length);
4340Sstevel@tonic-gate 		if (i == 0)
4350Sstevel@tonic-gate 			return(a->type-b->type);
4360Sstevel@tonic-gate 		else
4370Sstevel@tonic-gate 			return(i);
4380Sstevel@tonic-gate 		}
4390Sstevel@tonic-gate 	else
4400Sstevel@tonic-gate 		return(i);
4410Sstevel@tonic-gate 	}
4420Sstevel@tonic-gate 
asn1_add_error(const unsigned char * address,int offset)443*2139Sjp161948 void asn1_add_error(const unsigned char *address, int offset)
4440Sstevel@tonic-gate 	{
4450Sstevel@tonic-gate 	char buf1[DECIMAL_SIZE(address)+1],buf2[DECIMAL_SIZE(offset)+1];
4460Sstevel@tonic-gate 
4470Sstevel@tonic-gate 	BIO_snprintf(buf1,sizeof buf1,"%lu",(unsigned long)address);
4480Sstevel@tonic-gate 	BIO_snprintf(buf2,sizeof buf2,"%d",offset);
4490Sstevel@tonic-gate 	ERR_add_error_data(4,"address=",buf1," offset=",buf2);
4500Sstevel@tonic-gate 	}
4510Sstevel@tonic-gate 
ASN1_STRING_length(ASN1_STRING * x)4520Sstevel@tonic-gate int ASN1_STRING_length(ASN1_STRING *x)
4530Sstevel@tonic-gate { return M_ASN1_STRING_length(x); }
4540Sstevel@tonic-gate 
ASN1_STRING_length_set(ASN1_STRING * x,int len)4550Sstevel@tonic-gate void ASN1_STRING_length_set(ASN1_STRING *x, int len)
4560Sstevel@tonic-gate { M_ASN1_STRING_length_set(x, len); return; }
4570Sstevel@tonic-gate 
ASN1_STRING_type(ASN1_STRING * x)4580Sstevel@tonic-gate int ASN1_STRING_type(ASN1_STRING *x)
4590Sstevel@tonic-gate { return M_ASN1_STRING_type(x); }
4600Sstevel@tonic-gate 
ASN1_STRING_data(ASN1_STRING * x)4610Sstevel@tonic-gate unsigned char * ASN1_STRING_data(ASN1_STRING *x)
4620Sstevel@tonic-gate { return M_ASN1_STRING_data(x); }
463