summaryrefslogtreecommitdiffstats
path: root/crypto/heimdal/lib/asn1/asn1_print.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/heimdal/lib/asn1/asn1_print.c')
-rw-r--r--crypto/heimdal/lib/asn1/asn1_print.c217
1 files changed, 133 insertions, 84 deletions
diff --git a/crypto/heimdal/lib/asn1/asn1_print.c b/crypto/heimdal/lib/asn1/asn1_print.c
index d3199e8..e00bf10 100644
--- a/crypto/heimdal/lib/asn1/asn1_print.c
+++ b/crypto/heimdal/lib/asn1/asn1_print.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -37,63 +37,30 @@
#include <sys/stat.h>
#include <getarg.h>
#include <err.h>
+#include <der.h>
-RCSID("$Id: asn1_print.c,v 1.11 2002/08/29 20:45:35 assar Exp $");
+RCSID("$Id: asn1_print.c 19539 2006-12-28 17:15:05Z lha $");
-const char *class_names[] = {
- "UNIV", /* 0 */
- "APPL", /* 1 */
- "CONTEXT", /* 2 */
- "PRIVATE" /* 3 */
-};
-
-const char *type_names[] = {
- "PRIM", /* 0 */
- "CONS" /* 1 */
-};
+static int indent_flag = 1;
-const char *tag_names[] = {
- NULL, /* 0 */
- NULL, /* 1 */
- "Integer", /* 2 */
- "BitString", /* 3 */
- "OctetString", /* 4 */
- "Null", /* 5 */
- "ObjectID", /* 6 */
- NULL, /* 7 */
- NULL, /* 8 */
- NULL, /* 9 */
- NULL, /* 10 */
- NULL, /* 11 */
- NULL, /* 12 */
- NULL, /* 13 */
- NULL, /* 14 */
- NULL, /* 15 */
- "Sequence", /* 16 */
- "Set", /* 17 */
- NULL, /* 18 */
- "PrintableString", /* 19 */
- NULL, /* 20 */
- NULL, /* 21 */
- "IA5String", /* 22 */
- "UTCTime", /* 23 */
- "GeneralizedTime", /* 24 */
- NULL, /* 25 */
- "VisibleString", /* 26 */
- "GeneralString" /* 27 */
-};
+static unsigned long indefinite_form_loop;
+static unsigned long indefinite_form_loop_max = 10000;
-static int
+static size_t
loop (unsigned char *buf, size_t len, int indent)
{
+ unsigned char *start_buf = buf;
+
while (len > 0) {
int ret;
Der_class class;
Der_type type;
- int tag;
+ unsigned int tag;
size_t sz;
size_t length;
- int i;
+ size_t loop_length = 0;
+ int end_tag = 0;
+ const char *tagname;
ret = der_get_tag (buf, len, &class, &type, &tag, &sz);
if (ret)
@@ -103,42 +70,101 @@ loop (unsigned char *buf, size_t len, int indent)
(unsigned)sz, (unsigned)len);
buf += sz;
len -= sz;
- for (i = 0; i < indent; ++i)
- printf (" ");
- printf ("%s %s ", class_names[class], type_names[type]);
- if (tag_names[tag])
- printf ("%s = ", tag_names[tag]);
+ if (indent_flag) {
+ int i;
+ for (i = 0; i < indent; ++i)
+ printf (" ");
+ }
+ printf ("%s %s ", der_get_class_name(class), der_get_type_name(type));
+ tagname = der_get_tag_name(tag);
+ if (class == ASN1_C_UNIV && tagname != NULL)
+ printf ("%s = ", tagname);
else
printf ("tag %d = ", tag);
ret = der_get_length (buf, len, &length, &sz);
if (ret)
errx (1, "der_get_tag: %s", error_message (ret));
+ if (sz > len)
+ errx (1, "unreasonable tag length (%u) > %u",
+ (unsigned)sz, (unsigned)len);
buf += sz;
len -= sz;
-
- if (class == CONTEXT) {
- printf ("[%d]\n", tag);
- loop (buf, length, indent);
- } else if (class == UNIV) {
+ if (length == ASN1_INDEFINITE) {
+ if ((class == ASN1_C_UNIV && type == PRIM && tag == UT_OctetString) ||
+ (class == ASN1_C_CONTEXT && type == CONS) ||
+ (class == ASN1_C_UNIV && type == CONS && tag == UT_Sequence) ||
+ (class == ASN1_C_UNIV && type == CONS && tag == UT_Set)) {
+ printf("*INDEFINITE FORM*");
+ } else {
+ fflush(stdout);
+ errx(1, "indef form used on unsupported object");
+ }
+ end_tag = 1;
+ if (indefinite_form_loop > indefinite_form_loop_max)
+ errx(1, "indefinite form used recursively more then %lu "
+ "times, aborting", indefinite_form_loop_max);
+ indefinite_form_loop++;
+ length = len;
+ } else if (length > len) {
+ printf("\n");
+ fflush(stdout);
+ errx (1, "unreasonable inner length (%u) > %u",
+ (unsigned)length, (unsigned)len);
+ }
+ if (class == ASN1_C_CONTEXT || class == ASN1_C_APPL) {
+ printf ("%lu bytes [%u]", (unsigned long)length, tag);
+ if (type == CONS) {
+ printf("\n");
+ loop_length = loop (buf, length, indent + 2);
+ } else {
+ printf(" IMPLICIT content\n");
+ }
+ } else if (class == ASN1_C_UNIV) {
switch (tag) {
+ case UT_EndOfContent:
+ printf (" INDEFINITE length was %lu\n",
+ (unsigned long)(buf - start_buf));
+ break;
+ case UT_Set :
case UT_Sequence :
- printf ("{\n");
- loop (buf, length, indent + 2);
- for (i = 0; i < indent; ++i)
- printf (" ");
- printf ("}\n");
+ printf ("%lu bytes {\n", (unsigned long)length);
+ loop_length = loop (buf, length, indent + 2);
+ if (indent_flag) {
+ int i;
+ for (i = 0; i < indent; ++i)
+ printf (" ");
+ printf ("}\n");
+ } else
+ printf ("} indent = %d\n", indent / 2);
break;
case UT_Integer : {
int val;
- ret = der_get_int (buf, length, &val, NULL);
- if (ret)
- errx (1, "der_get_int: %s", error_message (ret));
- printf ("integer %d\n", val);
+ if (length <= sizeof(val)) {
+ ret = der_get_integer (buf, length, &val, NULL);
+ if (ret)
+ errx (1, "der_get_integer: %s", error_message (ret));
+ printf ("integer %d\n", val);
+ } else {
+ heim_integer vali;
+ char *p;
+
+ ret = der_get_heim_integer(buf, length, &vali, NULL);
+ if (ret)
+ errx (1, "der_get_heim_integer: %s",
+ error_message (ret));
+ ret = der_print_hex_heim_integer(&vali, &p);
+ if (ret)
+ errx (1, "der_print_hex_heim_integer: %s",
+ error_message (ret));
+ printf ("BIG NUM integer: length %lu %s\n",
+ (unsigned long)length, p);
+ free(p);
+ }
break;
}
case UT_OctetString : {
- octet_string str;
+ heim_octet_string str;
int i;
unsigned char *uc;
@@ -147,15 +173,17 @@ loop (unsigned char *buf, size_t len, int indent)
errx (1, "der_get_octet_string: %s", error_message (ret));
printf ("(length %lu), ", (unsigned long)length);
uc = (unsigned char *)str.data;
- for (i = 0; i < 16; ++i)
+ for (i = 0; i < min(16,length); ++i)
printf ("%02x", uc[i]);
printf ("\n");
free (str.data);
break;
}
case UT_GeneralizedTime :
- case UT_GeneralString : {
- general_string str;
+ case UT_GeneralString :
+ case UT_PrintableString :
+ case UT_VisibleString : {
+ heim_general_string str;
ret = der_get_general_string (buf, length, &str, NULL);
if (ret)
@@ -166,18 +194,29 @@ loop (unsigned char *buf, size_t len, int indent)
break;
}
case UT_OID: {
- oid o;
- int i;
+ heim_oid o;
+ char *p;
ret = der_get_oid(buf, length, &o, NULL);
if (ret)
errx (1, "der_get_oid: %s", error_message (ret));
+ ret = der_print_heim_oid(&o, '.', &p);
+ der_free_oid(&o);
+ if (ret)
+ errx (1, "der_print_heim_oid: %s", error_message (ret));
+ printf("%s\n", p);
+ free(p);
+
+ break;
+ }
+ case UT_Enumerated: {
+ int num;
+
+ ret = der_get_integer (buf, length, &num, NULL);
+ if (ret)
+ errx (1, "der_get_enum: %s", error_message (ret));
- for (i = 0; i < o.length ; i++)
- printf("%d%s", o.components[i],
- i < o.length - 1 ? "." : "");
- printf("\n");
- free_oid(&o);
+ printf("%u\n", num);
break;
}
default :
@@ -185,6 +224,17 @@ loop (unsigned char *buf, size_t len, int indent)
break;
}
}
+ if (end_tag) {
+ if (loop_length == 0)
+ errx(1, "zero length INDEFINITE data ? indent = %d\n",
+ indent / 2);
+ if (loop_length < length)
+ length = loop_length;
+ if (indefinite_form_loop == 0)
+ errx(1, "internal error in indefinite form loop detection");
+ indefinite_form_loop--;
+ } else if (loop_length)
+ errx(1, "internal error for INDEFINITE form");
buf += length;
len -= length;
}
@@ -205,21 +255,20 @@ doit (const char *filename)
if (fstat (fd, &sb) < 0)
err (1, "stat %s", filename);
len = sb.st_size;
- buf = malloc (len);
- if (buf == NULL)
- err (1, "malloc %u", (unsigned)len);
+ buf = emalloc (len);
if (read (fd, buf, len) != len)
errx (1, "read failed");
close (fd);
ret = loop (buf, len, 0);
free (buf);
- return ret;
+ return 0;
}
static int version_flag;
static int help_flag;
struct getargs args[] = {
+ { "indent", 0, arg_negative_flag, &indent_flag },
{ "version", 0, arg_flag, &version_flag },
{ "help", 0, arg_flag, &help_flag }
};
@@ -235,11 +284,11 @@ usage(int code)
int
main(int argc, char **argv)
{
- int optind = 0;
+ int optidx = 0;
setprogname (argv[0]);
initialize_asn1_error_table ();
- if(getarg(args, num_args, argc, argv, &optind))
+ if(getarg(args, num_args, argc, argv, &optidx))
usage(1);
if(help_flag)
usage(0);
@@ -247,8 +296,8 @@ main(int argc, char **argv)
print_version(NULL);
exit(0);
}
- argv += optind;
- argc -= optind;
+ argv += optidx;
+ argc -= optidx;
if (argc != 1)
usage (1);
return doit (argv[0]);
OpenPOWER on IntegriCloud