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