Add the possibility to get hexdumps of unprintable data when using
authorRichard Levitte <levitte@openssl.org>
Thu, 27 Jul 2000 17:28:25 +0000 (17:28 +0000)
committerRichard Levitte <levitte@openssl.org>
Thu, 27 Jul 2000 17:28:25 +0000 (17:28 +0000)
'openssl asn1parse'.  As a side effect, the functions ASN1_parse_dump
and BIO_dump_indent are added.

CHANGES
apps/asn1pars.c
crypto/asn1/asn1.h
crypto/asn1/asn1_par.c
crypto/bio/b_dump.c
crypto/bio/bio.h

diff --git a/CHANGES b/CHANGES
index e739139cd994e97511d64b8f12d867ba3344fa91..a0dd5491e8defa0ca436848e0c1d9b1bfa12d6d5 100644 (file)
--- 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,
index 2d64492ffd8412172eec06e3af80c610f71b133f..30e1da443a7be0f62629ea041e54bf5b76b06bed 100644 (file)
@@ -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;
index 79df50a85b396ced53ff74a178a57c496cb14281..e2696441285ca12acf230cac78a4ac1ba7410cc9 100644 (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_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);
 
index d1e9816bad328f2781d045bd7a6d9bd7e017006e..dc868a4d87b636bc10f2ce7682fb0ba6c3066b2c 100644 (file)
@@ -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) 
                                {
index f5aeb237f502bf2bf5cbec36422f4dbb32ec93ee..7cbe4f22b51e55ec51748455c41d2d50095ae3ab 100644 (file)
 
 #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)<len)
+  if (indent < 0)
+    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++;
   for(i=0;i<rows;i++) {
     buf[0]='\0';       /* start with empty string */
-    sprintf(tmp,"%04x - ",i*DUMP_WIDTH);
-    strcpy(buf,tmp);
-    for(j=0;j<DUMP_WIDTH;j++) {
-      if (((i*DUMP_WIDTH)+j)>=len) {
+    strcpy(buf,str);
+    sprintf(tmp,"%04x - ",i*dump_width);
+    strcat(buf,tmp);
+    for(j=0;j<dump_width;j++) {
+      if (((i*dump_width)+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<DUMP_WIDTH;j++) {
-      if (((i*DUMP_WIDTH)+j)>=len)
+    for(j=0;j<dump_width;j++) {
+      if (((i*dump_width)+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 - <SPACES/NULS>\n",len+trunc);
+    sprintf(buf,"%s%04x - <SPACES/NULS>\n",str,len+trunc);
     ret+=BIO_write(bio,(char *)buf,strlen(buf));
   }
 #endif
index 5634a96a79a960bc05a324252f833ba51077b734..76748e05d8eb18b25a4743af7ea65aaffe7e3bda 100644 (file)
@@ -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: