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.
This commit is contained in:
Richard Levitte 2000-07-27 17:28:25 +00:00
parent f6c1c9e95d
commit ca1e465f6d
6 changed files with 94 additions and 19 deletions

View file

@ -4,6 +4,11 @@
Changes between 0.9.5a and 0.9.6 [xx XXX 2000] 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. *) Various fixes to use ASN1_TIME instead of ASN1_UTCTIME.
Also change the functions X509_cmp_current_time() and Also change the functions X509_cmp_current_time() and
X509_gmtime_adj() work with an ASN1_TIME structure, X509_gmtime_adj() work with an ASN1_TIME structure,

View file

@ -88,7 +88,7 @@ int MAIN(int argc, char **argv)
unsigned int length=0; unsigned int length=0;
long num,tmplen; long num,tmplen;
BIO *in=NULL,*out=NULL,*b64=NULL, *derout = NULL; 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; char *infile=NULL,*str=NULL,*prog,*oidfile=NULL, *derfile=NULL;
unsigned char *tmpbuf; unsigned char *tmpbuf;
BUF_MEM *buf=NULL; BUF_MEM *buf=NULL;
@ -149,6 +149,16 @@ int MAIN(int argc, char **argv)
length= atoi(*(++argv)); length= atoi(*(++argv));
if (length == 0) goto bad; 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) else if (strcmp(*argv,"-strparse") == 0)
{ {
if (--argc < 1) goto bad; if (--argc < 1) goto bad;
@ -176,6 +186,8 @@ bad:
BIO_printf(bio_err," -offset arg offset into file\n"); 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," -length arg length of section in file\n");
BIO_printf(bio_err," -i indent entries\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," -oid file file of extra oid definitions\n");
BIO_printf(bio_err," -strparse offset\n"); BIO_printf(bio_err," -strparse offset\n");
BIO_printf(bio_err," a series of these can be used to 'dig' into multiple\n"); BIO_printf(bio_err," a series of these can be used to 'dig' into multiple\n");
@ -293,7 +305,8 @@ bad:
} }
} }
if (!noout && 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); ERR_print_errors(bio_err);
goto end; goto end;

View file

@ -737,6 +737,7 @@ int ASN1_GENERALIZEDTIME_print(BIO *fp,ASN1_GENERALIZEDTIME *a);
int ASN1_TIME_print(BIO *fp,ASN1_TIME *a); int ASN1_TIME_print(BIO *fp,ASN1_TIME *a);
int ASN1_STRING_print(BIO *bp,ASN1_STRING *v); int ASN1_STRING_print(BIO *bp,ASN1_STRING *v);
int ASN1_parse(BIO *bp,unsigned char *pp,long len,int indent); 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 #endif
const char *ASN1_tag2str(int tag); const char *ASN1_tag2str(int tag);

View file

@ -65,7 +65,7 @@
static int asn1_print_info(BIO *bp, int tag, int xclass,int constructed, static int asn1_print_info(BIO *bp, int tag, int xclass,int constructed,
int indent); int indent);
static int asn1_parse2(BIO *bp, unsigned char **pp, long length, 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, static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
int indent) int indent)
{ {
@ -110,11 +110,16 @@ err:
int ASN1_parse(BIO *bp, unsigned char *pp, long len, int indent) 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, 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; unsigned char *p,*ep,*tot,*op,*opp;
long len; long len;
@ -123,7 +128,13 @@ static int asn1_parse2(BIO *bp, unsigned char **pp, long length, int offset,
ASN1_OBJECT *o=NULL; ASN1_OBJECT *o=NULL;
ASN1_OCTET_STRING *os=NULL; ASN1_OCTET_STRING *os=NULL;
/* ASN1_BMPSTRING *bmp=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; p= *pp;
tot=p+length; tot=p+length;
op=p-1; 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), r=asn1_parse2(bp,&p,(long)(tot-p),
offset+(p - *pp),depth+1, offset+(p - *pp),depth+1,
indent); indent,dump);
if (r == 0) { ret=0; goto end; } if (r == 0) { ret=0; goto end; }
if ((r == 2) || (p >= tot)) break; 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, r=asn1_parse2(bp,&p,(long)len,
offset+(p - *pp),depth+1, offset+(p - *pp),depth+1,
indent); indent,dump);
if (r == 0) { ret=0; goto end; } 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) os->length) <= 0)
goto end; 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); M_ASN1_OCTET_STRING_free(os);
os=NULL; os=NULL;
} }
@ -341,6 +366,19 @@ static int asn1_parse2(BIO *bp, unsigned char **pp, long length, int offset,
} }
M_ASN1_ENUMERATED_free(bs); 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) if (!nl)
{ {

View file

@ -66,13 +66,20 @@
#define TRUNCATE #define TRUNCATE
#define DUMP_WIDTH 16 #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) 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; int ret=0;
char buf[160+1],tmp[20]; char buf[288+1],tmp[20],str[128+1];
int i,j,rows,trunc; int i,j,rows,trunc;
unsigned char ch; unsigned char ch;
int dump_width;
trunc=0; trunc=0;
@ -81,27 +88,37 @@ int BIO_dump(BIO *bio, const char *s, int len)
trunc++; trunc++;
#endif #endif
rows=(len/DUMP_WIDTH); if (indent < 0)
if ((rows*DUMP_WIDTH)<len) indent = 0;
if (indent) {
if (indent > 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)
rows++; rows++;
for(i=0;i<rows;i++) { for(i=0;i<rows;i++) {
buf[0]='\0'; /* start with empty string */ buf[0]='\0'; /* start with empty string */
sprintf(tmp,"%04x - ",i*DUMP_WIDTH); strcpy(buf,str);
strcpy(buf,tmp); sprintf(tmp,"%04x - ",i*dump_width);
for(j=0;j<DUMP_WIDTH;j++) { strcat(buf,tmp);
if (((i*DUMP_WIDTH)+j)>=len) { for(j=0;j<dump_width;j++) {
if (((i*dump_width)+j)>=len) {
strcat(buf," "); strcat(buf," ");
} else { } 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?'-':' '); sprintf(tmp,"%02x%c",ch,j==7?'-':' ');
strcat(buf,tmp); strcat(buf,tmp);
} }
} }
strcat(buf," "); strcat(buf," ");
for(j=0;j<DUMP_WIDTH;j++) { for(j=0;j<dump_width;j++) {
if (((i*DUMP_WIDTH)+j)>=len) if (((i*dump_width)+j)>=len)
break; break;
ch=((unsigned char)*(s+i*DUMP_WIDTH+j)) & 0xff; ch=((unsigned char)*(s+i*dump_width+j)) & 0xff;
#ifndef CHARSET_EBCDIC #ifndef CHARSET_EBCDIC
sprintf(tmp,"%c",((ch>=' ')&&(ch<='~'))?ch:'.'); sprintf(tmp,"%c",((ch>=' ')&&(ch<='~'))?ch:'.');
#else #else
@ -119,7 +136,7 @@ int BIO_dump(BIO *bio, const char *s, int len)
} }
#ifdef TRUNCATE #ifdef TRUNCATE
if (trunc > 0) { if (trunc > 0) {
sprintf(buf,"%04x - <SPACES/NULS>\n",len+trunc); sprintf(buf,"%s%04x - <SPACES/NULS>\n",str,len+trunc);
ret+=BIO_write(bio,(char *)buf,strlen(buf)); ret+=BIO_write(bio,(char *)buf,strlen(buf));
} }
#endif #endif

View file

@ -559,6 +559,7 @@ int BIO_sock_non_fatal_error(int error);
int BIO_fd_should_retry(int i); int BIO_fd_should_retry(int i);
int BIO_fd_non_fatal_error(int error); int BIO_fd_non_fatal_error(int error);
int BIO_dump(BIO *b,const char *bytes,int len); 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); struct hostent *BIO_gethostbyname(const char *name);
/* We might want a thread-safe interface too: /* We might want a thread-safe interface too: