xref: /onnv-gate/usr/src/common/openssl/crypto/asn1/asn1_par.c (revision 2139:6243c3338933)
10Sstevel@tonic-gate /* crypto/asn1/asn1_par.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/objects.h>
630Sstevel@tonic-gate #include <openssl/asn1.h>
640Sstevel@tonic-gate 
650Sstevel@tonic-gate static int asn1_print_info(BIO *bp, int tag, int xclass,int constructed,
660Sstevel@tonic-gate 	int indent);
67*2139Sjp161948 static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
680Sstevel@tonic-gate 	int offset, int depth, int indent, int dump);
asn1_print_info(BIO * bp,int tag,int xclass,int constructed,int indent)690Sstevel@tonic-gate static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
700Sstevel@tonic-gate 	     int indent)
710Sstevel@tonic-gate 	{
720Sstevel@tonic-gate 	static const char fmt[]="%-18s";
730Sstevel@tonic-gate 	static const char fmt2[]="%2d %-15s";
740Sstevel@tonic-gate 	char str[128];
750Sstevel@tonic-gate 	const char *p,*p2=NULL;
760Sstevel@tonic-gate 
770Sstevel@tonic-gate 	if (constructed & V_ASN1_CONSTRUCTED)
780Sstevel@tonic-gate 		p="cons: ";
790Sstevel@tonic-gate 	else
800Sstevel@tonic-gate 		p="prim: ";
810Sstevel@tonic-gate 	if (BIO_write(bp,p,6) < 6) goto err;
820Sstevel@tonic-gate 	BIO_indent(bp,indent,128);
830Sstevel@tonic-gate 
840Sstevel@tonic-gate 	p=str;
850Sstevel@tonic-gate 	if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
860Sstevel@tonic-gate 		BIO_snprintf(str,sizeof str,"priv [ %d ] ",tag);
870Sstevel@tonic-gate 	else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
880Sstevel@tonic-gate 		BIO_snprintf(str,sizeof str,"cont [ %d ]",tag);
890Sstevel@tonic-gate 	else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
900Sstevel@tonic-gate 		BIO_snprintf(str,sizeof str,"appl [ %d ]",tag);
910Sstevel@tonic-gate 	else p = ASN1_tag2str(tag);
920Sstevel@tonic-gate 
930Sstevel@tonic-gate 	if (p2 != NULL)
940Sstevel@tonic-gate 		{
950Sstevel@tonic-gate 		if (BIO_printf(bp,fmt2,tag,p2) <= 0) goto err;
960Sstevel@tonic-gate 		}
970Sstevel@tonic-gate 	else
980Sstevel@tonic-gate 		{
990Sstevel@tonic-gate 		if (BIO_printf(bp,fmt,p) <= 0) goto err;
1000Sstevel@tonic-gate 		}
1010Sstevel@tonic-gate 	return(1);
1020Sstevel@tonic-gate err:
1030Sstevel@tonic-gate 	return(0);
1040Sstevel@tonic-gate 	}
1050Sstevel@tonic-gate 
ASN1_parse(BIO * bp,const unsigned char * pp,long len,int indent)106*2139Sjp161948 int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent)
1070Sstevel@tonic-gate 	{
1080Sstevel@tonic-gate 	return(asn1_parse2(bp,&pp,len,0,0,indent,0));
1090Sstevel@tonic-gate 	}
1100Sstevel@tonic-gate 
ASN1_parse_dump(BIO * bp,const unsigned char * pp,long len,int indent,int dump)111*2139Sjp161948 int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, int dump)
1120Sstevel@tonic-gate 	{
1130Sstevel@tonic-gate 	return(asn1_parse2(bp,&pp,len,0,0,indent,dump));
1140Sstevel@tonic-gate 	}
1150Sstevel@tonic-gate 
asn1_parse2(BIO * bp,const unsigned char ** pp,long length,int offset,int depth,int indent,int dump)116*2139Sjp161948 static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offset,
1170Sstevel@tonic-gate 	     int depth, int indent, int dump)
1180Sstevel@tonic-gate 	{
119*2139Sjp161948 	const unsigned char *p,*ep,*tot,*op,*opp;
1200Sstevel@tonic-gate 	long len;
1210Sstevel@tonic-gate 	int tag,xclass,ret=0;
1220Sstevel@tonic-gate 	int nl,hl,j,r;
1230Sstevel@tonic-gate 	ASN1_OBJECT *o=NULL;
1240Sstevel@tonic-gate 	ASN1_OCTET_STRING *os=NULL;
1250Sstevel@tonic-gate 	/* ASN1_BMPSTRING *bmp=NULL;*/
1260Sstevel@tonic-gate 	int dump_indent;
1270Sstevel@tonic-gate 
1280Sstevel@tonic-gate #if 0
1290Sstevel@tonic-gate 	dump_indent = indent;
1300Sstevel@tonic-gate #else
1310Sstevel@tonic-gate 	dump_indent = 6;	/* Because we know BIO_dump_indent() */
1320Sstevel@tonic-gate #endif
1330Sstevel@tonic-gate 	p= *pp;
1340Sstevel@tonic-gate 	tot=p+length;
1350Sstevel@tonic-gate 	op=p-1;
1360Sstevel@tonic-gate 	while ((p < tot) && (op < p))
1370Sstevel@tonic-gate 		{
1380Sstevel@tonic-gate 		op=p;
1390Sstevel@tonic-gate 		j=ASN1_get_object(&p,&len,&tag,&xclass,length);
1400Sstevel@tonic-gate #ifdef LINT
1410Sstevel@tonic-gate 		j=j;
1420Sstevel@tonic-gate #endif
1430Sstevel@tonic-gate 		if (j & 0x80)
1440Sstevel@tonic-gate 			{
1450Sstevel@tonic-gate 			if (BIO_write(bp,"Error in encoding\n",18) <= 0)
1460Sstevel@tonic-gate 				goto end;
1470Sstevel@tonic-gate 			ret=0;
1480Sstevel@tonic-gate 			goto end;
1490Sstevel@tonic-gate 			}
1500Sstevel@tonic-gate 		hl=(p-op);
1510Sstevel@tonic-gate 		length-=hl;
1520Sstevel@tonic-gate 		/* if j == 0x21 it is a constructed indefinite length object */
1530Sstevel@tonic-gate 		if (BIO_printf(bp,"%5ld:",(long)offset+(long)(op- *pp))
1540Sstevel@tonic-gate 			<= 0) goto end;
1550Sstevel@tonic-gate 
1560Sstevel@tonic-gate 		if (j != (V_ASN1_CONSTRUCTED | 1))
1570Sstevel@tonic-gate 			{
1580Sstevel@tonic-gate 			if (BIO_printf(bp,"d=%-2d hl=%ld l=%4ld ",
1590Sstevel@tonic-gate 				depth,(long)hl,len) <= 0)
1600Sstevel@tonic-gate 				goto end;
1610Sstevel@tonic-gate 			}
1620Sstevel@tonic-gate 		else
1630Sstevel@tonic-gate 			{
1640Sstevel@tonic-gate 			if (BIO_printf(bp,"d=%-2d hl=%ld l=inf  ",
1650Sstevel@tonic-gate 				depth,(long)hl) <= 0)
1660Sstevel@tonic-gate 				goto end;
1670Sstevel@tonic-gate 			}
1680Sstevel@tonic-gate 		if (!asn1_print_info(bp,tag,xclass,j,(indent)?depth:0))
1690Sstevel@tonic-gate 			goto end;
1700Sstevel@tonic-gate 		if (j & V_ASN1_CONSTRUCTED)
1710Sstevel@tonic-gate 			{
1720Sstevel@tonic-gate 			ep=p+len;
1730Sstevel@tonic-gate 			if (BIO_write(bp,"\n",1) <= 0) goto end;
1740Sstevel@tonic-gate 			if (len > length)
1750Sstevel@tonic-gate 				{
1760Sstevel@tonic-gate 				BIO_printf(bp,
1770Sstevel@tonic-gate 					"length is greater than %ld\n",length);
1780Sstevel@tonic-gate 				ret=0;
1790Sstevel@tonic-gate 				goto end;
1800Sstevel@tonic-gate 				}
1810Sstevel@tonic-gate 			if ((j == 0x21) && (len == 0))
1820Sstevel@tonic-gate 				{
1830Sstevel@tonic-gate 				for (;;)
1840Sstevel@tonic-gate 					{
1850Sstevel@tonic-gate 					r=asn1_parse2(bp,&p,(long)(tot-p),
1860Sstevel@tonic-gate 						offset+(p - *pp),depth+1,
1870Sstevel@tonic-gate 						indent,dump);
1880Sstevel@tonic-gate 					if (r == 0) { ret=0; goto end; }
1890Sstevel@tonic-gate 					if ((r == 2) || (p >= tot)) break;
1900Sstevel@tonic-gate 					}
1910Sstevel@tonic-gate 				}
1920Sstevel@tonic-gate 			else
1930Sstevel@tonic-gate 				while (p < ep)
1940Sstevel@tonic-gate 					{
1950Sstevel@tonic-gate 					r=asn1_parse2(bp,&p,(long)len,
1960Sstevel@tonic-gate 						offset+(p - *pp),depth+1,
1970Sstevel@tonic-gate 						indent,dump);
1980Sstevel@tonic-gate 					if (r == 0) { ret=0; goto end; }
1990Sstevel@tonic-gate 					}
2000Sstevel@tonic-gate 			}
2010Sstevel@tonic-gate 		else if (xclass != 0)
2020Sstevel@tonic-gate 			{
2030Sstevel@tonic-gate 			p+=len;
2040Sstevel@tonic-gate 			if (BIO_write(bp,"\n",1) <= 0) goto end;
2050Sstevel@tonic-gate 			}
2060Sstevel@tonic-gate 		else
2070Sstevel@tonic-gate 			{
2080Sstevel@tonic-gate 			nl=0;
2090Sstevel@tonic-gate 			if (	(tag == V_ASN1_PRINTABLESTRING) ||
2100Sstevel@tonic-gate 				(tag == V_ASN1_T61STRING) ||
2110Sstevel@tonic-gate 				(tag == V_ASN1_IA5STRING) ||
2120Sstevel@tonic-gate 				(tag == V_ASN1_VISIBLESTRING) ||
2130Sstevel@tonic-gate 				(tag == V_ASN1_UTCTIME) ||
2140Sstevel@tonic-gate 				(tag == V_ASN1_GENERALIZEDTIME))
2150Sstevel@tonic-gate 				{
2160Sstevel@tonic-gate 				if (BIO_write(bp,":",1) <= 0) goto end;
2170Sstevel@tonic-gate 				if ((len > 0) &&
218*2139Sjp161948 					BIO_write(bp,(const char *)p,(int)len)
2190Sstevel@tonic-gate 					!= (int)len)
2200Sstevel@tonic-gate 					goto end;
2210Sstevel@tonic-gate 				}
2220Sstevel@tonic-gate 			else if (tag == V_ASN1_OBJECT)
2230Sstevel@tonic-gate 				{
2240Sstevel@tonic-gate 				opp=op;
2250Sstevel@tonic-gate 				if (d2i_ASN1_OBJECT(&o,&opp,len+hl) != NULL)
2260Sstevel@tonic-gate 					{
2270Sstevel@tonic-gate 					if (BIO_write(bp,":",1) <= 0) goto end;
2280Sstevel@tonic-gate 					i2a_ASN1_OBJECT(bp,o);
2290Sstevel@tonic-gate 					}
2300Sstevel@tonic-gate 				else
2310Sstevel@tonic-gate 					{
2320Sstevel@tonic-gate 					if (BIO_write(bp,":BAD OBJECT",11) <= 0)
2330Sstevel@tonic-gate 						goto end;
2340Sstevel@tonic-gate 					}
2350Sstevel@tonic-gate 				}
2360Sstevel@tonic-gate 			else if (tag == V_ASN1_BOOLEAN)
2370Sstevel@tonic-gate 				{
2380Sstevel@tonic-gate 				int ii;
2390Sstevel@tonic-gate 
2400Sstevel@tonic-gate 				opp=op;
2410Sstevel@tonic-gate 				ii=d2i_ASN1_BOOLEAN(NULL,&opp,len+hl);
2420Sstevel@tonic-gate 				if (ii < 0)
2430Sstevel@tonic-gate 					{
2440Sstevel@tonic-gate 					if (BIO_write(bp,"Bad boolean\n",12))
2450Sstevel@tonic-gate 						goto end;
2460Sstevel@tonic-gate 					}
2470Sstevel@tonic-gate 				BIO_printf(bp,":%d",ii);
2480Sstevel@tonic-gate 				}
2490Sstevel@tonic-gate 			else if (tag == V_ASN1_BMPSTRING)
2500Sstevel@tonic-gate 				{
2510Sstevel@tonic-gate 				/* do the BMP thang */
2520Sstevel@tonic-gate 				}
2530Sstevel@tonic-gate 			else if (tag == V_ASN1_OCTET_STRING)
2540Sstevel@tonic-gate 				{
2550Sstevel@tonic-gate 				int i,printable=1;
2560Sstevel@tonic-gate 
2570Sstevel@tonic-gate 				opp=op;
2580Sstevel@tonic-gate 				os=d2i_ASN1_OCTET_STRING(NULL,&opp,len+hl);
259*2139Sjp161948 				if (os != NULL && os->length > 0)
2600Sstevel@tonic-gate 					{
261*2139Sjp161948 					opp = os->data;
262*2139Sjp161948 					/* testing whether the octet string is
263*2139Sjp161948 					 * printable */
2640Sstevel@tonic-gate 					for (i=0; i<os->length; i++)
2650Sstevel@tonic-gate 						{
2660Sstevel@tonic-gate 						if ((	(opp[i] < ' ') &&
2670Sstevel@tonic-gate 							(opp[i] != '\n') &&
2680Sstevel@tonic-gate 							(opp[i] != '\r') &&
2690Sstevel@tonic-gate 							(opp[i] != '\t')) ||
2700Sstevel@tonic-gate 							(opp[i] > '~'))
2710Sstevel@tonic-gate 							{
2720Sstevel@tonic-gate 							printable=0;
2730Sstevel@tonic-gate 							break;
2740Sstevel@tonic-gate 							}
2750Sstevel@tonic-gate 						}
276*2139Sjp161948 					if (printable)
277*2139Sjp161948 					/* printable string */
2780Sstevel@tonic-gate 						{
2790Sstevel@tonic-gate 						if (BIO_write(bp,":",1) <= 0)
2800Sstevel@tonic-gate 							goto end;
281*2139Sjp161948 						if (BIO_write(bp,(const char *)opp,
2820Sstevel@tonic-gate 							os->length) <= 0)
2830Sstevel@tonic-gate 							goto end;
2840Sstevel@tonic-gate 						}
285*2139Sjp161948 					else if (!dump)
286*2139Sjp161948 					/* not printable => print octet string
287*2139Sjp161948 					 * as hex dump */
288*2139Sjp161948 						{
289*2139Sjp161948 						if (BIO_write(bp,"[HEX DUMP]:",11) <= 0)
290*2139Sjp161948 							goto end;
291*2139Sjp161948 						for (i=0; i<os->length; i++)
292*2139Sjp161948 							{
293*2139Sjp161948 							if (BIO_printf(bp,"%02X"
294*2139Sjp161948 								, opp[i]) <= 0)
295*2139Sjp161948 								goto end;
296*2139Sjp161948 							}
297*2139Sjp161948 						}
298*2139Sjp161948 					else
299*2139Sjp161948 					/* print the normal dump */
3000Sstevel@tonic-gate 						{
3010Sstevel@tonic-gate 						if (!nl)
3020Sstevel@tonic-gate 							{
3030Sstevel@tonic-gate 							if (BIO_write(bp,"\n",1) <= 0)
3040Sstevel@tonic-gate 								goto end;
3050Sstevel@tonic-gate 							}
306*2139Sjp161948 						if (BIO_dump_indent(bp,
307*2139Sjp161948 							(const char *)opp,
308*2139Sjp161948 							((dump == -1 || dump >
309*2139Sjp161948 							os->length)?os->length:dump),
3100Sstevel@tonic-gate 							dump_indent) <= 0)
3110Sstevel@tonic-gate 							goto end;
3120Sstevel@tonic-gate 						nl=1;
3130Sstevel@tonic-gate 						}
314*2139Sjp161948 					}
315*2139Sjp161948 				if (os != NULL)
316*2139Sjp161948 					{
3170Sstevel@tonic-gate 					M_ASN1_OCTET_STRING_free(os);
3180Sstevel@tonic-gate 					os=NULL;
3190Sstevel@tonic-gate 					}
3200Sstevel@tonic-gate 				}
3210Sstevel@tonic-gate 			else if (tag == V_ASN1_INTEGER)
3220Sstevel@tonic-gate 				{
3230Sstevel@tonic-gate 				ASN1_INTEGER *bs;
3240Sstevel@tonic-gate 				int i;
3250Sstevel@tonic-gate 
3260Sstevel@tonic-gate 				opp=op;
3270Sstevel@tonic-gate 				bs=d2i_ASN1_INTEGER(NULL,&opp,len+hl);
3280Sstevel@tonic-gate 				if (bs != NULL)
3290Sstevel@tonic-gate 					{
3300Sstevel@tonic-gate 					if (BIO_write(bp,":",1) <= 0) goto end;
3310Sstevel@tonic-gate 					if (bs->type == V_ASN1_NEG_INTEGER)
3320Sstevel@tonic-gate 						if (BIO_write(bp,"-",1) <= 0)
3330Sstevel@tonic-gate 							goto end;
3340Sstevel@tonic-gate 					for (i=0; i<bs->length; i++)
3350Sstevel@tonic-gate 						{
3360Sstevel@tonic-gate 						if (BIO_printf(bp,"%02X",
3370Sstevel@tonic-gate 							bs->data[i]) <= 0)
3380Sstevel@tonic-gate 							goto end;
3390Sstevel@tonic-gate 						}
3400Sstevel@tonic-gate 					if (bs->length == 0)
3410Sstevel@tonic-gate 						{
3420Sstevel@tonic-gate 						if (BIO_write(bp,"00",2) <= 0)
3430Sstevel@tonic-gate 							goto end;
3440Sstevel@tonic-gate 						}
3450Sstevel@tonic-gate 					}
3460Sstevel@tonic-gate 				else
3470Sstevel@tonic-gate 					{
3480Sstevel@tonic-gate 					if (BIO_write(bp,"BAD INTEGER",11) <= 0)
3490Sstevel@tonic-gate 						goto end;
3500Sstevel@tonic-gate 					}
3510Sstevel@tonic-gate 				M_ASN1_INTEGER_free(bs);
3520Sstevel@tonic-gate 				}
3530Sstevel@tonic-gate 			else if (tag == V_ASN1_ENUMERATED)
3540Sstevel@tonic-gate 				{
3550Sstevel@tonic-gate 				ASN1_ENUMERATED *bs;
3560Sstevel@tonic-gate 				int i;
3570Sstevel@tonic-gate 
3580Sstevel@tonic-gate 				opp=op;
3590Sstevel@tonic-gate 				bs=d2i_ASN1_ENUMERATED(NULL,&opp,len+hl);
3600Sstevel@tonic-gate 				if (bs != NULL)
3610Sstevel@tonic-gate 					{
3620Sstevel@tonic-gate 					if (BIO_write(bp,":",1) <= 0) goto end;
3630Sstevel@tonic-gate 					if (bs->type == V_ASN1_NEG_ENUMERATED)
3640Sstevel@tonic-gate 						if (BIO_write(bp,"-",1) <= 0)
3650Sstevel@tonic-gate 							goto end;
3660Sstevel@tonic-gate 					for (i=0; i<bs->length; i++)
3670Sstevel@tonic-gate 						{
3680Sstevel@tonic-gate 						if (BIO_printf(bp,"%02X",
3690Sstevel@tonic-gate 							bs->data[i]) <= 0)
3700Sstevel@tonic-gate 							goto end;
3710Sstevel@tonic-gate 						}
3720Sstevel@tonic-gate 					if (bs->length == 0)
3730Sstevel@tonic-gate 						{
3740Sstevel@tonic-gate 						if (BIO_write(bp,"00",2) <= 0)
3750Sstevel@tonic-gate 							goto end;
3760Sstevel@tonic-gate 						}
3770Sstevel@tonic-gate 					}
3780Sstevel@tonic-gate 				else
3790Sstevel@tonic-gate 					{
3800Sstevel@tonic-gate 					if (BIO_write(bp,"BAD ENUMERATED",11) <= 0)
3810Sstevel@tonic-gate 						goto end;
3820Sstevel@tonic-gate 					}
3830Sstevel@tonic-gate 				M_ASN1_ENUMERATED_free(bs);
3840Sstevel@tonic-gate 				}
3850Sstevel@tonic-gate 			else if (len > 0 && dump)
3860Sstevel@tonic-gate 				{
3870Sstevel@tonic-gate 				if (!nl)
3880Sstevel@tonic-gate 					{
3890Sstevel@tonic-gate 					if (BIO_write(bp,"\n",1) <= 0)
3900Sstevel@tonic-gate 						goto end;
3910Sstevel@tonic-gate 					}
392*2139Sjp161948 				if (BIO_dump_indent(bp,(const char *)p,
3930Sstevel@tonic-gate 					((dump == -1 || dump > len)?len:dump),
3940Sstevel@tonic-gate 					dump_indent) <= 0)
3950Sstevel@tonic-gate 					goto end;
3960Sstevel@tonic-gate 				nl=1;
3970Sstevel@tonic-gate 				}
3980Sstevel@tonic-gate 
3990Sstevel@tonic-gate 			if (!nl)
4000Sstevel@tonic-gate 				{
4010Sstevel@tonic-gate 				if (BIO_write(bp,"\n",1) <= 0) goto end;
4020Sstevel@tonic-gate 				}
4030Sstevel@tonic-gate 			p+=len;
4040Sstevel@tonic-gate 			if ((tag == V_ASN1_EOC) && (xclass == 0))
4050Sstevel@tonic-gate 				{
4060Sstevel@tonic-gate 				ret=2; /* End of sequence */
4070Sstevel@tonic-gate 				goto end;
4080Sstevel@tonic-gate 				}
4090Sstevel@tonic-gate 			}
4100Sstevel@tonic-gate 		length-=len;
4110Sstevel@tonic-gate 		}
4120Sstevel@tonic-gate 	ret=1;
4130Sstevel@tonic-gate end:
4140Sstevel@tonic-gate 	if (o != NULL) ASN1_OBJECT_free(o);
4150Sstevel@tonic-gate 	if (os != NULL) M_ASN1_OCTET_STRING_free(os);
4160Sstevel@tonic-gate 	*pp=p;
4170Sstevel@tonic-gate 	return(ret);
4180Sstevel@tonic-gate 	}
4190Sstevel@tonic-gate 
ASN1_tag2str(int tag)4200Sstevel@tonic-gate const char *ASN1_tag2str(int tag)
4210Sstevel@tonic-gate {
422*2139Sjp161948 	static const char *tag2str[] = {
4230Sstevel@tonic-gate 	 "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */
4240Sstevel@tonic-gate 	 "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */
4250Sstevel@tonic-gate 	 "ENUMERATED", "<ASN1 11>", "UTF8STRING", "<ASN1 13>", 	    /* 10-13 */
4260Sstevel@tonic-gate 	"<ASN1 14>", "<ASN1 15>", "SEQUENCE", "SET", 		    /* 15-17 */
4270Sstevel@tonic-gate 	"NUMERICSTRING", "PRINTABLESTRING", "T61STRING",	    /* 18-20 */
4280Sstevel@tonic-gate 	"VIDEOTEXSTRING", "IA5STRING", "UTCTIME","GENERALIZEDTIME", /* 21-24 */
4290Sstevel@tonic-gate 	"GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING",	    /* 25-27 */
4300Sstevel@tonic-gate 	"UNIVERSALSTRING", "<ASN1 29>", "BMPSTRING"		    /* 28-30 */
4310Sstevel@tonic-gate 	};
4320Sstevel@tonic-gate 
4330Sstevel@tonic-gate 	if((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
4340Sstevel@tonic-gate 							tag &= ~0x100;
4350Sstevel@tonic-gate 
4360Sstevel@tonic-gate 	if(tag < 0 || tag > 30) return "(unknown)";
4370Sstevel@tonic-gate 	return tag2str[tag];
4380Sstevel@tonic-gate }
4390Sstevel@tonic-gate 
440