From ca1e465f6dd96d8dc15e418eda13fc3bd26362b2 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Thu, 27 Jul 2000 17:28:25 +0000 Subject: [PATCH] Add the possibility to get hexdumps of unprintable data when using 'openssl asn1parse'. As a side effect, the functions ASN1_parse_dump and BIO_dump_indent are added. --- CHANGES | 5 +++++ apps/asn1pars.c | 17 +++++++++++++-- crypto/asn1/asn1.h | 1 + crypto/asn1/asn1_par.c | 48 +++++++++++++++++++++++++++++++++++++----- crypto/bio/b_dump.c | 41 +++++++++++++++++++++++++----------- crypto/bio/bio.h | 1 + 6 files changed, 94 insertions(+), 19 deletions(-) diff --git a/CHANGES b/CHANGES index e739139cd9..a0dd5491e8 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,11 @@ Changes between 0.9.5a and 0.9.6 [xx XXX 2000] + *) Make it possible to get hexdumps of unprintable data with 'openssl + asn1parse'. By implication, the functions ASN1_parse_dump() and + BIO_dump_indent() are added. + [Richard Levitte] + *) Various fixes to use ASN1_TIME instead of ASN1_UTCTIME. Also change the functions X509_cmp_current_time() and X509_gmtime_adj() work with an ASN1_TIME structure, diff --git a/apps/asn1pars.c b/apps/asn1pars.c index 2d64492ffd..30e1da443a 100644 --- a/apps/asn1pars.c +++ b/apps/asn1pars.c @@ -88,7 +88,7 @@ int MAIN(int argc, char **argv) unsigned int length=0; long num,tmplen; BIO *in=NULL,*out=NULL,*b64=NULL, *derout = NULL; - int informat,indent=0, noout = 0; + int informat,indent=0, noout = 0, dump = 0; char *infile=NULL,*str=NULL,*prog,*oidfile=NULL, *derfile=NULL; unsigned char *tmpbuf; BUF_MEM *buf=NULL; @@ -149,6 +149,16 @@ int MAIN(int argc, char **argv) length= atoi(*(++argv)); if (length == 0) goto bad; } + else if (strcmp(*argv,"-dump") == 0) + { + dump= -1; + } + else if (strcmp(*argv,"-dlimit") == 0) + { + if (--argc < 1) goto bad; + dump= atoi(*(++argv)); + if (dump <= 0) goto bad; + } else if (strcmp(*argv,"-strparse") == 0) { if (--argc < 1) goto bad; @@ -176,6 +186,8 @@ bad: BIO_printf(bio_err," -offset arg offset into file\n"); BIO_printf(bio_err," -length arg length of section in file\n"); BIO_printf(bio_err," -i indent entries\n"); + BIO_printf(bio_err," -dump dump unknown data in hex form\n"); + BIO_printf(bio_err," -dlimit arg dump the first arg bytes of unknown data in hex form\n"); BIO_printf(bio_err," -oid file file of extra oid definitions\n"); BIO_printf(bio_err," -strparse offset\n"); BIO_printf(bio_err," a series of these can be used to 'dig' into multiple\n"); @@ -293,7 +305,8 @@ bad: } } if (!noout && - !ASN1_parse(out,(unsigned char *)&(str[offset]),length,indent)) + !ASN1_parse_dump(out,(unsigned char *)&(str[offset]),length, + indent,dump)) { ERR_print_errors(bio_err); goto end; diff --git a/crypto/asn1/asn1.h b/crypto/asn1/asn1.h index 79df50a85b..e269644128 100644 --- a/crypto/asn1/asn1.h +++ b/crypto/asn1/asn1.h @@ -737,6 +737,7 @@ int ASN1_GENERALIZEDTIME_print(BIO *fp,ASN1_GENERALIZEDTIME *a); int ASN1_TIME_print(BIO *fp,ASN1_TIME *a); int ASN1_STRING_print(BIO *bp,ASN1_STRING *v); int ASN1_parse(BIO *bp,unsigned char *pp,long len,int indent); +int ASN1_parse_dump(BIO *bp,unsigned char *pp,long len,int indent,int dump); #endif const char *ASN1_tag2str(int tag); diff --git a/crypto/asn1/asn1_par.c b/crypto/asn1/asn1_par.c index d1e9816bad..dc868a4d87 100644 --- a/crypto/asn1/asn1_par.c +++ b/crypto/asn1/asn1_par.c @@ -65,7 +65,7 @@ static int asn1_print_info(BIO *bp, int tag, int xclass,int constructed, int indent); static int asn1_parse2(BIO *bp, unsigned char **pp, long length, - int offset, int depth, int indent); + int offset, int depth, int indent, int dump); static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed, int indent) { @@ -110,11 +110,16 @@ err: int ASN1_parse(BIO *bp, unsigned char *pp, long len, int indent) { - return(asn1_parse2(bp,&pp,len,0,0,indent)); + return(asn1_parse2(bp,&pp,len,0,0,indent,0)); + } + +int ASN1_parse_dump(BIO *bp, unsigned char *pp, long len, int indent, int dump) + { + return(asn1_parse2(bp,&pp,len,0,0,indent,dump)); } static int asn1_parse2(BIO *bp, unsigned char **pp, long length, int offset, - int depth, int indent) + int depth, int indent, int dump) { unsigned char *p,*ep,*tot,*op,*opp; long len; @@ -123,7 +128,13 @@ static int asn1_parse2(BIO *bp, unsigned char **pp, long length, int offset, ASN1_OBJECT *o=NULL; ASN1_OCTET_STRING *os=NULL; /* ASN1_BMPSTRING *bmp=NULL;*/ + int dump_indent; +#if 0 + dump_indent = indent; +#else + dump_indent = 6; /* Because we know BIO_dump_indent() */ +#endif p= *pp; tot=p+length; op=p-1; @@ -178,7 +189,7 @@ static int asn1_parse2(BIO *bp, unsigned char **pp, long length, int offset, { r=asn1_parse2(bp,&p,(long)(tot-p), offset+(p - *pp),depth+1, - indent); + indent,dump); if (r == 0) { ret=0; goto end; } if ((r == 2) || (p >= tot)) break; } @@ -188,7 +199,7 @@ static int asn1_parse2(BIO *bp, unsigned char **pp, long length, int offset, { r=asn1_parse2(bp,&p,(long)len, offset+(p - *pp),depth+1, - indent); + indent,dump); if (r == 0) { ret=0; goto end; } } } @@ -273,6 +284,20 @@ static int asn1_parse2(BIO *bp, unsigned char **pp, long length, int offset, os->length) <= 0) goto end; } + if (!printable && (os->length > 0) + && dump) + { + if (!nl) + { + if (BIO_write(bp,"\n",1) <= 0) + goto end; + } + if (BIO_dump_indent(bp,opp, + ((dump == -1 || dump > os->length)?os->length:dump), + dump_indent) <= 0) + goto end; + nl=1; + } M_ASN1_OCTET_STRING_free(os); os=NULL; } @@ -341,6 +366,19 @@ static int asn1_parse2(BIO *bp, unsigned char **pp, long length, int offset, } M_ASN1_ENUMERATED_free(bs); } + else if (len > 0 && dump) + { + if (!nl) + { + if (BIO_write(bp,"\n",1) <= 0) + goto end; + } + if (BIO_dump_indent(bp,p, + ((dump == -1 || dump > len)?len:dump), + dump_indent) <= 0) + goto end; + nl=1; + } if (!nl) { diff --git a/crypto/bio/b_dump.c b/crypto/bio/b_dump.c index f5aeb237f5..7cbe4f22b5 100644 --- a/crypto/bio/b_dump.c +++ b/crypto/bio/b_dump.c @@ -66,13 +66,20 @@ #define TRUNCATE #define DUMP_WIDTH 16 +#define DUMP_WIDTH_LESS_INDENT(i) (DUMP_WIDTH-((i-(i>6?6:i)+3)/4)) int BIO_dump(BIO *bio, const char *s, int len) + { + return BIO_dump_indent(bio, s, len, 0); + } + +int BIO_dump_indent(BIO *bio, const char *s, int len, int indent) { int ret=0; - char buf[160+1],tmp[20]; + char buf[288+1],tmp[20],str[128+1]; int i,j,rows,trunc; unsigned char ch; + int dump_width; trunc=0; @@ -81,27 +88,37 @@ int BIO_dump(BIO *bio, const char *s, int len) trunc++; #endif - rows=(len/DUMP_WIDTH); - if ((rows*DUMP_WIDTH) 128) indent=128; + memset(str,' ',indent); + } + str[indent]='\0'; + + dump_width=DUMP_WIDTH_LESS_INDENT(indent); + rows=(len/dump_width); + if ((rows*dump_width)=len) { + strcpy(buf,str); + sprintf(tmp,"%04x - ",i*dump_width); + strcat(buf,tmp); + for(j=0;j=len) { strcat(buf," "); } else { - ch=((unsigned char)*(s+i*DUMP_WIDTH+j)) & 0xff; + ch=((unsigned char)*(s+i*dump_width+j)) & 0xff; sprintf(tmp,"%02x%c",ch,j==7?'-':' '); strcat(buf,tmp); } } strcat(buf," "); - for(j=0;j=len) + for(j=0;j=len) break; - ch=((unsigned char)*(s+i*DUMP_WIDTH+j)) & 0xff; + ch=((unsigned char)*(s+i*dump_width+j)) & 0xff; #ifndef CHARSET_EBCDIC sprintf(tmp,"%c",((ch>=' ')&&(ch<='~'))?ch:'.'); #else @@ -119,7 +136,7 @@ int BIO_dump(BIO *bio, const char *s, int len) } #ifdef TRUNCATE if (trunc > 0) { - sprintf(buf,"%04x - \n",len+trunc); + sprintf(buf,"%s%04x - \n",str,len+trunc); ret+=BIO_write(bio,(char *)buf,strlen(buf)); } #endif diff --git a/crypto/bio/bio.h b/crypto/bio/bio.h index 5634a96a79..76748e05d8 100644 --- a/crypto/bio/bio.h +++ b/crypto/bio/bio.h @@ -559,6 +559,7 @@ int BIO_sock_non_fatal_error(int error); int BIO_fd_should_retry(int i); int BIO_fd_non_fatal_error(int error); int BIO_dump(BIO *b,const char *bytes,int len); +int BIO_dump_indent(BIO *b,const char *bytes,int len,int indent); struct hostent *BIO_gethostbyname(const char *name); /* We might want a thread-safe interface too: -- 2.25.1