xref: /onnv-gate/usr/src/common/openssl/crypto/asn1/asn1_par.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /* crypto/asn1/asn1_par.c */
2*0Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3*0Sstevel@tonic-gate  * All rights reserved.
4*0Sstevel@tonic-gate  *
5*0Sstevel@tonic-gate  * This package is an SSL implementation written
6*0Sstevel@tonic-gate  * by Eric Young (eay@cryptsoft.com).
7*0Sstevel@tonic-gate  * The implementation was written so as to conform with Netscapes SSL.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * This library is free for commercial and non-commercial use as long as
10*0Sstevel@tonic-gate  * the following conditions are aheared to.  The following conditions
11*0Sstevel@tonic-gate  * apply to all code found in this distribution, be it the RC4, RSA,
12*0Sstevel@tonic-gate  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13*0Sstevel@tonic-gate  * included with this distribution is covered by the same copyright terms
14*0Sstevel@tonic-gate  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15*0Sstevel@tonic-gate  *
16*0Sstevel@tonic-gate  * Copyright remains Eric Young's, and as such any Copyright notices in
17*0Sstevel@tonic-gate  * the code are not to be removed.
18*0Sstevel@tonic-gate  * If this package is used in a product, Eric Young should be given attribution
19*0Sstevel@tonic-gate  * as the author of the parts of the library used.
20*0Sstevel@tonic-gate  * This can be in the form of a textual message at program startup or
21*0Sstevel@tonic-gate  * in documentation (online or textual) provided with the package.
22*0Sstevel@tonic-gate  *
23*0Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
24*0Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
25*0Sstevel@tonic-gate  * are met:
26*0Sstevel@tonic-gate  * 1. Redistributions of source code must retain the copyright
27*0Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
28*0Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
29*0Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in the
30*0Sstevel@tonic-gate  *    documentation and/or other materials provided with the distribution.
31*0Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this software
32*0Sstevel@tonic-gate  *    must display the following acknowledgement:
33*0Sstevel@tonic-gate  *    "This product includes cryptographic software written by
34*0Sstevel@tonic-gate  *     Eric Young (eay@cryptsoft.com)"
35*0Sstevel@tonic-gate  *    The word 'cryptographic' can be left out if the rouines from the library
36*0Sstevel@tonic-gate  *    being used are not cryptographic related :-).
37*0Sstevel@tonic-gate  * 4. If you include any Windows specific code (or a derivative thereof) from
38*0Sstevel@tonic-gate  *    the apps directory (application code) you must include an acknowledgement:
39*0Sstevel@tonic-gate  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40*0Sstevel@tonic-gate  *
41*0Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42*0Sstevel@tonic-gate  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43*0Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44*0Sstevel@tonic-gate  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45*0Sstevel@tonic-gate  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46*0Sstevel@tonic-gate  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47*0Sstevel@tonic-gate  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48*0Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49*0Sstevel@tonic-gate  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50*0Sstevel@tonic-gate  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51*0Sstevel@tonic-gate  * SUCH DAMAGE.
52*0Sstevel@tonic-gate  *
53*0Sstevel@tonic-gate  * The licence and distribution terms for any publically available version or
54*0Sstevel@tonic-gate  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55*0Sstevel@tonic-gate  * copied and put under another distribution licence
56*0Sstevel@tonic-gate  * [including the GNU Public Licence.]
57*0Sstevel@tonic-gate  */
58*0Sstevel@tonic-gate 
59*0Sstevel@tonic-gate #include <stdio.h>
60*0Sstevel@tonic-gate #include "cryptlib.h"
61*0Sstevel@tonic-gate #include <openssl/buffer.h>
62*0Sstevel@tonic-gate #include <openssl/objects.h>
63*0Sstevel@tonic-gate #include <openssl/asn1.h>
64*0Sstevel@tonic-gate 
65*0Sstevel@tonic-gate static int asn1_print_info(BIO *bp, int tag, int xclass,int constructed,
66*0Sstevel@tonic-gate 	int indent);
67*0Sstevel@tonic-gate static int asn1_parse2(BIO *bp, unsigned char **pp, long length,
68*0Sstevel@tonic-gate 	int offset, int depth, int indent, int dump);
69*0Sstevel@tonic-gate static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
70*0Sstevel@tonic-gate 	     int indent)
71*0Sstevel@tonic-gate 	{
72*0Sstevel@tonic-gate 	static const char fmt[]="%-18s";
73*0Sstevel@tonic-gate 	static const char fmt2[]="%2d %-15s";
74*0Sstevel@tonic-gate 	char str[128];
75*0Sstevel@tonic-gate 	const char *p,*p2=NULL;
76*0Sstevel@tonic-gate 
77*0Sstevel@tonic-gate 	if (constructed & V_ASN1_CONSTRUCTED)
78*0Sstevel@tonic-gate 		p="cons: ";
79*0Sstevel@tonic-gate 	else
80*0Sstevel@tonic-gate 		p="prim: ";
81*0Sstevel@tonic-gate 	if (BIO_write(bp,p,6) < 6) goto err;
82*0Sstevel@tonic-gate 	BIO_indent(bp,indent,128);
83*0Sstevel@tonic-gate 
84*0Sstevel@tonic-gate 	p=str;
85*0Sstevel@tonic-gate 	if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
86*0Sstevel@tonic-gate 		BIO_snprintf(str,sizeof str,"priv [ %d ] ",tag);
87*0Sstevel@tonic-gate 	else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
88*0Sstevel@tonic-gate 		BIO_snprintf(str,sizeof str,"cont [ %d ]",tag);
89*0Sstevel@tonic-gate 	else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
90*0Sstevel@tonic-gate 		BIO_snprintf(str,sizeof str,"appl [ %d ]",tag);
91*0Sstevel@tonic-gate 	else p = ASN1_tag2str(tag);
92*0Sstevel@tonic-gate 
93*0Sstevel@tonic-gate 	if (p2 != NULL)
94*0Sstevel@tonic-gate 		{
95*0Sstevel@tonic-gate 		if (BIO_printf(bp,fmt2,tag,p2) <= 0) goto err;
96*0Sstevel@tonic-gate 		}
97*0Sstevel@tonic-gate 	else
98*0Sstevel@tonic-gate 		{
99*0Sstevel@tonic-gate 		if (BIO_printf(bp,fmt,p) <= 0) goto err;
100*0Sstevel@tonic-gate 		}
101*0Sstevel@tonic-gate 	return(1);
102*0Sstevel@tonic-gate err:
103*0Sstevel@tonic-gate 	return(0);
104*0Sstevel@tonic-gate 	}
105*0Sstevel@tonic-gate 
106*0Sstevel@tonic-gate int ASN1_parse(BIO *bp, unsigned char *pp, long len, int indent)
107*0Sstevel@tonic-gate 	{
108*0Sstevel@tonic-gate 	return(asn1_parse2(bp,&pp,len,0,0,indent,0));
109*0Sstevel@tonic-gate 	}
110*0Sstevel@tonic-gate 
111*0Sstevel@tonic-gate int ASN1_parse_dump(BIO *bp, unsigned char *pp, long len, int indent, int dump)
112*0Sstevel@tonic-gate 	{
113*0Sstevel@tonic-gate 	return(asn1_parse2(bp,&pp,len,0,0,indent,dump));
114*0Sstevel@tonic-gate 	}
115*0Sstevel@tonic-gate 
116*0Sstevel@tonic-gate static int asn1_parse2(BIO *bp, unsigned char **pp, long length, int offset,
117*0Sstevel@tonic-gate 	     int depth, int indent, int dump)
118*0Sstevel@tonic-gate 	{
119*0Sstevel@tonic-gate 	unsigned char *p,*ep,*tot,*op,*opp;
120*0Sstevel@tonic-gate 	long len;
121*0Sstevel@tonic-gate 	int tag,xclass,ret=0;
122*0Sstevel@tonic-gate 	int nl,hl,j,r;
123*0Sstevel@tonic-gate 	ASN1_OBJECT *o=NULL;
124*0Sstevel@tonic-gate 	ASN1_OCTET_STRING *os=NULL;
125*0Sstevel@tonic-gate 	/* ASN1_BMPSTRING *bmp=NULL;*/
126*0Sstevel@tonic-gate 	int dump_indent;
127*0Sstevel@tonic-gate 
128*0Sstevel@tonic-gate #if 0
129*0Sstevel@tonic-gate 	dump_indent = indent;
130*0Sstevel@tonic-gate #else
131*0Sstevel@tonic-gate 	dump_indent = 6;	/* Because we know BIO_dump_indent() */
132*0Sstevel@tonic-gate #endif
133*0Sstevel@tonic-gate 	p= *pp;
134*0Sstevel@tonic-gate 	tot=p+length;
135*0Sstevel@tonic-gate 	op=p-1;
136*0Sstevel@tonic-gate 	while ((p < tot) && (op < p))
137*0Sstevel@tonic-gate 		{
138*0Sstevel@tonic-gate 		op=p;
139*0Sstevel@tonic-gate 		j=ASN1_get_object(&p,&len,&tag,&xclass,length);
140*0Sstevel@tonic-gate #ifdef LINT
141*0Sstevel@tonic-gate 		j=j;
142*0Sstevel@tonic-gate #endif
143*0Sstevel@tonic-gate 		if (j & 0x80)
144*0Sstevel@tonic-gate 			{
145*0Sstevel@tonic-gate 			if (BIO_write(bp,"Error in encoding\n",18) <= 0)
146*0Sstevel@tonic-gate 				goto end;
147*0Sstevel@tonic-gate 			ret=0;
148*0Sstevel@tonic-gate 			goto end;
149*0Sstevel@tonic-gate 			}
150*0Sstevel@tonic-gate 		hl=(p-op);
151*0Sstevel@tonic-gate 		length-=hl;
152*0Sstevel@tonic-gate 		/* if j == 0x21 it is a constructed indefinite length object */
153*0Sstevel@tonic-gate 		if (BIO_printf(bp,"%5ld:",(long)offset+(long)(op- *pp))
154*0Sstevel@tonic-gate 			<= 0) goto end;
155*0Sstevel@tonic-gate 
156*0Sstevel@tonic-gate 		if (j != (V_ASN1_CONSTRUCTED | 1))
157*0Sstevel@tonic-gate 			{
158*0Sstevel@tonic-gate 			if (BIO_printf(bp,"d=%-2d hl=%ld l=%4ld ",
159*0Sstevel@tonic-gate 				depth,(long)hl,len) <= 0)
160*0Sstevel@tonic-gate 				goto end;
161*0Sstevel@tonic-gate 			}
162*0Sstevel@tonic-gate 		else
163*0Sstevel@tonic-gate 			{
164*0Sstevel@tonic-gate 			if (BIO_printf(bp,"d=%-2d hl=%ld l=inf  ",
165*0Sstevel@tonic-gate 				depth,(long)hl) <= 0)
166*0Sstevel@tonic-gate 				goto end;
167*0Sstevel@tonic-gate 			}
168*0Sstevel@tonic-gate 		if (!asn1_print_info(bp,tag,xclass,j,(indent)?depth:0))
169*0Sstevel@tonic-gate 			goto end;
170*0Sstevel@tonic-gate 		if (j & V_ASN1_CONSTRUCTED)
171*0Sstevel@tonic-gate 			{
172*0Sstevel@tonic-gate 			ep=p+len;
173*0Sstevel@tonic-gate 			if (BIO_write(bp,"\n",1) <= 0) goto end;
174*0Sstevel@tonic-gate 			if (len > length)
175*0Sstevel@tonic-gate 				{
176*0Sstevel@tonic-gate 				BIO_printf(bp,
177*0Sstevel@tonic-gate 					"length is greater than %ld\n",length);
178*0Sstevel@tonic-gate 				ret=0;
179*0Sstevel@tonic-gate 				goto end;
180*0Sstevel@tonic-gate 				}
181*0Sstevel@tonic-gate 			if ((j == 0x21) && (len == 0))
182*0Sstevel@tonic-gate 				{
183*0Sstevel@tonic-gate 				for (;;)
184*0Sstevel@tonic-gate 					{
185*0Sstevel@tonic-gate 					r=asn1_parse2(bp,&p,(long)(tot-p),
186*0Sstevel@tonic-gate 						offset+(p - *pp),depth+1,
187*0Sstevel@tonic-gate 						indent,dump);
188*0Sstevel@tonic-gate 					if (r == 0) { ret=0; goto end; }
189*0Sstevel@tonic-gate 					if ((r == 2) || (p >= tot)) break;
190*0Sstevel@tonic-gate 					}
191*0Sstevel@tonic-gate 				}
192*0Sstevel@tonic-gate 			else
193*0Sstevel@tonic-gate 				while (p < ep)
194*0Sstevel@tonic-gate 					{
195*0Sstevel@tonic-gate 					r=asn1_parse2(bp,&p,(long)len,
196*0Sstevel@tonic-gate 						offset+(p - *pp),depth+1,
197*0Sstevel@tonic-gate 						indent,dump);
198*0Sstevel@tonic-gate 					if (r == 0) { ret=0; goto end; }
199*0Sstevel@tonic-gate 					}
200*0Sstevel@tonic-gate 			}
201*0Sstevel@tonic-gate 		else if (xclass != 0)
202*0Sstevel@tonic-gate 			{
203*0Sstevel@tonic-gate 			p+=len;
204*0Sstevel@tonic-gate 			if (BIO_write(bp,"\n",1) <= 0) goto end;
205*0Sstevel@tonic-gate 			}
206*0Sstevel@tonic-gate 		else
207*0Sstevel@tonic-gate 			{
208*0Sstevel@tonic-gate 			nl=0;
209*0Sstevel@tonic-gate 			if (	(tag == V_ASN1_PRINTABLESTRING) ||
210*0Sstevel@tonic-gate 				(tag == V_ASN1_T61STRING) ||
211*0Sstevel@tonic-gate 				(tag == V_ASN1_IA5STRING) ||
212*0Sstevel@tonic-gate 				(tag == V_ASN1_VISIBLESTRING) ||
213*0Sstevel@tonic-gate 				(tag == V_ASN1_UTCTIME) ||
214*0Sstevel@tonic-gate 				(tag == V_ASN1_GENERALIZEDTIME))
215*0Sstevel@tonic-gate 				{
216*0Sstevel@tonic-gate 				if (BIO_write(bp,":",1) <= 0) goto end;
217*0Sstevel@tonic-gate 				if ((len > 0) &&
218*0Sstevel@tonic-gate 					BIO_write(bp,(char *)p,(int)len)
219*0Sstevel@tonic-gate 					!= (int)len)
220*0Sstevel@tonic-gate 					goto end;
221*0Sstevel@tonic-gate 				}
222*0Sstevel@tonic-gate 			else if (tag == V_ASN1_OBJECT)
223*0Sstevel@tonic-gate 				{
224*0Sstevel@tonic-gate 				opp=op;
225*0Sstevel@tonic-gate 				if (d2i_ASN1_OBJECT(&o,&opp,len+hl) != NULL)
226*0Sstevel@tonic-gate 					{
227*0Sstevel@tonic-gate 					if (BIO_write(bp,":",1) <= 0) goto end;
228*0Sstevel@tonic-gate 					i2a_ASN1_OBJECT(bp,o);
229*0Sstevel@tonic-gate 					}
230*0Sstevel@tonic-gate 				else
231*0Sstevel@tonic-gate 					{
232*0Sstevel@tonic-gate 					if (BIO_write(bp,":BAD OBJECT",11) <= 0)
233*0Sstevel@tonic-gate 						goto end;
234*0Sstevel@tonic-gate 					}
235*0Sstevel@tonic-gate 				}
236*0Sstevel@tonic-gate 			else if (tag == V_ASN1_BOOLEAN)
237*0Sstevel@tonic-gate 				{
238*0Sstevel@tonic-gate 				int ii;
239*0Sstevel@tonic-gate 
240*0Sstevel@tonic-gate 				opp=op;
241*0Sstevel@tonic-gate 				ii=d2i_ASN1_BOOLEAN(NULL,&opp,len+hl);
242*0Sstevel@tonic-gate 				if (ii < 0)
243*0Sstevel@tonic-gate 					{
244*0Sstevel@tonic-gate 					if (BIO_write(bp,"Bad boolean\n",12))
245*0Sstevel@tonic-gate 						goto end;
246*0Sstevel@tonic-gate 					}
247*0Sstevel@tonic-gate 				BIO_printf(bp,":%d",ii);
248*0Sstevel@tonic-gate 				}
249*0Sstevel@tonic-gate 			else if (tag == V_ASN1_BMPSTRING)
250*0Sstevel@tonic-gate 				{
251*0Sstevel@tonic-gate 				/* do the BMP thang */
252*0Sstevel@tonic-gate 				}
253*0Sstevel@tonic-gate 			else if (tag == V_ASN1_OCTET_STRING)
254*0Sstevel@tonic-gate 				{
255*0Sstevel@tonic-gate 				int i,printable=1;
256*0Sstevel@tonic-gate 
257*0Sstevel@tonic-gate 				opp=op;
258*0Sstevel@tonic-gate 				os=d2i_ASN1_OCTET_STRING(NULL,&opp,len+hl);
259*0Sstevel@tonic-gate 				if (os != NULL)
260*0Sstevel@tonic-gate 					{
261*0Sstevel@tonic-gate 					opp=os->data;
262*0Sstevel@tonic-gate 					for (i=0; i<os->length; i++)
263*0Sstevel@tonic-gate 						{
264*0Sstevel@tonic-gate 						if ((	(opp[i] < ' ') &&
265*0Sstevel@tonic-gate 							(opp[i] != '\n') &&
266*0Sstevel@tonic-gate 							(opp[i] != '\r') &&
267*0Sstevel@tonic-gate 							(opp[i] != '\t')) ||
268*0Sstevel@tonic-gate 							(opp[i] > '~'))
269*0Sstevel@tonic-gate 							{
270*0Sstevel@tonic-gate 							printable=0;
271*0Sstevel@tonic-gate 							break;
272*0Sstevel@tonic-gate 							}
273*0Sstevel@tonic-gate 						}
274*0Sstevel@tonic-gate 					if (printable && (os->length > 0))
275*0Sstevel@tonic-gate 						{
276*0Sstevel@tonic-gate 						if (BIO_write(bp,":",1) <= 0)
277*0Sstevel@tonic-gate 							goto end;
278*0Sstevel@tonic-gate 						if (BIO_write(bp,(char *)opp,
279*0Sstevel@tonic-gate 							os->length) <= 0)
280*0Sstevel@tonic-gate 							goto end;
281*0Sstevel@tonic-gate 						}
282*0Sstevel@tonic-gate 					if (!printable && (os->length > 0)
283*0Sstevel@tonic-gate 						&& dump)
284*0Sstevel@tonic-gate 						{
285*0Sstevel@tonic-gate 						if (!nl)
286*0Sstevel@tonic-gate 							{
287*0Sstevel@tonic-gate 							if (BIO_write(bp,"\n",1) <= 0)
288*0Sstevel@tonic-gate 								goto end;
289*0Sstevel@tonic-gate 							}
290*0Sstevel@tonic-gate 						if (BIO_dump_indent(bp,(char *)opp,
291*0Sstevel@tonic-gate 							((dump == -1 || dump > os->length)?os->length:dump),
292*0Sstevel@tonic-gate 							dump_indent) <= 0)
293*0Sstevel@tonic-gate 							goto end;
294*0Sstevel@tonic-gate 						nl=1;
295*0Sstevel@tonic-gate 						}
296*0Sstevel@tonic-gate 					M_ASN1_OCTET_STRING_free(os);
297*0Sstevel@tonic-gate 					os=NULL;
298*0Sstevel@tonic-gate 					}
299*0Sstevel@tonic-gate 				}
300*0Sstevel@tonic-gate 			else if (tag == V_ASN1_INTEGER)
301*0Sstevel@tonic-gate 				{
302*0Sstevel@tonic-gate 				ASN1_INTEGER *bs;
303*0Sstevel@tonic-gate 				int i;
304*0Sstevel@tonic-gate 
305*0Sstevel@tonic-gate 				opp=op;
306*0Sstevel@tonic-gate 				bs=d2i_ASN1_INTEGER(NULL,&opp,len+hl);
307*0Sstevel@tonic-gate 				if (bs != NULL)
308*0Sstevel@tonic-gate 					{
309*0Sstevel@tonic-gate 					if (BIO_write(bp,":",1) <= 0) goto end;
310*0Sstevel@tonic-gate 					if (bs->type == V_ASN1_NEG_INTEGER)
311*0Sstevel@tonic-gate 						if (BIO_write(bp,"-",1) <= 0)
312*0Sstevel@tonic-gate 							goto end;
313*0Sstevel@tonic-gate 					for (i=0; i<bs->length; i++)
314*0Sstevel@tonic-gate 						{
315*0Sstevel@tonic-gate 						if (BIO_printf(bp,"%02X",
316*0Sstevel@tonic-gate 							bs->data[i]) <= 0)
317*0Sstevel@tonic-gate 							goto end;
318*0Sstevel@tonic-gate 						}
319*0Sstevel@tonic-gate 					if (bs->length == 0)
320*0Sstevel@tonic-gate 						{
321*0Sstevel@tonic-gate 						if (BIO_write(bp,"00",2) <= 0)
322*0Sstevel@tonic-gate 							goto end;
323*0Sstevel@tonic-gate 						}
324*0Sstevel@tonic-gate 					}
325*0Sstevel@tonic-gate 				else
326*0Sstevel@tonic-gate 					{
327*0Sstevel@tonic-gate 					if (BIO_write(bp,"BAD INTEGER",11) <= 0)
328*0Sstevel@tonic-gate 						goto end;
329*0Sstevel@tonic-gate 					}
330*0Sstevel@tonic-gate 				M_ASN1_INTEGER_free(bs);
331*0Sstevel@tonic-gate 				}
332*0Sstevel@tonic-gate 			else if (tag == V_ASN1_ENUMERATED)
333*0Sstevel@tonic-gate 				{
334*0Sstevel@tonic-gate 				ASN1_ENUMERATED *bs;
335*0Sstevel@tonic-gate 				int i;
336*0Sstevel@tonic-gate 
337*0Sstevel@tonic-gate 				opp=op;
338*0Sstevel@tonic-gate 				bs=d2i_ASN1_ENUMERATED(NULL,&opp,len+hl);
339*0Sstevel@tonic-gate 				if (bs != NULL)
340*0Sstevel@tonic-gate 					{
341*0Sstevel@tonic-gate 					if (BIO_write(bp,":",1) <= 0) goto end;
342*0Sstevel@tonic-gate 					if (bs->type == V_ASN1_NEG_ENUMERATED)
343*0Sstevel@tonic-gate 						if (BIO_write(bp,"-",1) <= 0)
344*0Sstevel@tonic-gate 							goto end;
345*0Sstevel@tonic-gate 					for (i=0; i<bs->length; i++)
346*0Sstevel@tonic-gate 						{
347*0Sstevel@tonic-gate 						if (BIO_printf(bp,"%02X",
348*0Sstevel@tonic-gate 							bs->data[i]) <= 0)
349*0Sstevel@tonic-gate 							goto end;
350*0Sstevel@tonic-gate 						}
351*0Sstevel@tonic-gate 					if (bs->length == 0)
352*0Sstevel@tonic-gate 						{
353*0Sstevel@tonic-gate 						if (BIO_write(bp,"00",2) <= 0)
354*0Sstevel@tonic-gate 							goto end;
355*0Sstevel@tonic-gate 						}
356*0Sstevel@tonic-gate 					}
357*0Sstevel@tonic-gate 				else
358*0Sstevel@tonic-gate 					{
359*0Sstevel@tonic-gate 					if (BIO_write(bp,"BAD ENUMERATED",11) <= 0)
360*0Sstevel@tonic-gate 						goto end;
361*0Sstevel@tonic-gate 					}
362*0Sstevel@tonic-gate 				M_ASN1_ENUMERATED_free(bs);
363*0Sstevel@tonic-gate 				}
364*0Sstevel@tonic-gate 			else if (len > 0 && dump)
365*0Sstevel@tonic-gate 				{
366*0Sstevel@tonic-gate 				if (!nl)
367*0Sstevel@tonic-gate 					{
368*0Sstevel@tonic-gate 					if (BIO_write(bp,"\n",1) <= 0)
369*0Sstevel@tonic-gate 						goto end;
370*0Sstevel@tonic-gate 					}
371*0Sstevel@tonic-gate 				if (BIO_dump_indent(bp,(char *)p,
372*0Sstevel@tonic-gate 					((dump == -1 || dump > len)?len:dump),
373*0Sstevel@tonic-gate 					dump_indent) <= 0)
374*0Sstevel@tonic-gate 					goto end;
375*0Sstevel@tonic-gate 				nl=1;
376*0Sstevel@tonic-gate 				}
377*0Sstevel@tonic-gate 
378*0Sstevel@tonic-gate 			if (!nl)
379*0Sstevel@tonic-gate 				{
380*0Sstevel@tonic-gate 				if (BIO_write(bp,"\n",1) <= 0) goto end;
381*0Sstevel@tonic-gate 				}
382*0Sstevel@tonic-gate 			p+=len;
383*0Sstevel@tonic-gate 			if ((tag == V_ASN1_EOC) && (xclass == 0))
384*0Sstevel@tonic-gate 				{
385*0Sstevel@tonic-gate 				ret=2; /* End of sequence */
386*0Sstevel@tonic-gate 				goto end;
387*0Sstevel@tonic-gate 				}
388*0Sstevel@tonic-gate 			}
389*0Sstevel@tonic-gate 		length-=len;
390*0Sstevel@tonic-gate 		}
391*0Sstevel@tonic-gate 	ret=1;
392*0Sstevel@tonic-gate end:
393*0Sstevel@tonic-gate 	if (o != NULL) ASN1_OBJECT_free(o);
394*0Sstevel@tonic-gate 	if (os != NULL) M_ASN1_OCTET_STRING_free(os);
395*0Sstevel@tonic-gate 	*pp=p;
396*0Sstevel@tonic-gate 	return(ret);
397*0Sstevel@tonic-gate 	}
398*0Sstevel@tonic-gate 
399*0Sstevel@tonic-gate const char *ASN1_tag2str(int tag)
400*0Sstevel@tonic-gate {
401*0Sstevel@tonic-gate 	const static char *tag2str[] = {
402*0Sstevel@tonic-gate 	 "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */
403*0Sstevel@tonic-gate 	 "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */
404*0Sstevel@tonic-gate 	 "ENUMERATED", "<ASN1 11>", "UTF8STRING", "<ASN1 13>", 	    /* 10-13 */
405*0Sstevel@tonic-gate 	"<ASN1 14>", "<ASN1 15>", "SEQUENCE", "SET", 		    /* 15-17 */
406*0Sstevel@tonic-gate 	"NUMERICSTRING", "PRINTABLESTRING", "T61STRING",	    /* 18-20 */
407*0Sstevel@tonic-gate 	"VIDEOTEXSTRING", "IA5STRING", "UTCTIME","GENERALIZEDTIME", /* 21-24 */
408*0Sstevel@tonic-gate 	"GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING",	    /* 25-27 */
409*0Sstevel@tonic-gate 	"UNIVERSALSTRING", "<ASN1 29>", "BMPSTRING"		    /* 28-30 */
410*0Sstevel@tonic-gate 	};
411*0Sstevel@tonic-gate 
412*0Sstevel@tonic-gate 	if((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
413*0Sstevel@tonic-gate 							tag &= ~0x100;
414*0Sstevel@tonic-gate 
415*0Sstevel@tonic-gate 	if(tag < 0 || tag > 30) return "(unknown)";
416*0Sstevel@tonic-gate 	return tag2str[tag];
417*0Sstevel@tonic-gate }
418*0Sstevel@tonic-gate 
419