From 9468ce7f89f9b84704c94a9b9eb433f4ba5fbde1 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 10 Nov 2017 09:05:29 +0100 Subject: [PATCH] beautify printed ASN.1 output - fixed printing tags on multiple bytes - align indenting with raw tags - use OpenSSL's human readable OID database - only print the canonical names for universal tags --- src/libopensc/asn1.c | 80 +++++++++++++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 20 deletions(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index cf035ea9..15e0dea0 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -43,13 +43,13 @@ static const char *tag2str(unsigned int tag) { static const char *tags[] = { "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */ - "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */ - "ENUMERATED", "", "UTF8STRING", "", /* 10-13 */ - "", "", "SEQUENCE", "SET", /* 15-17 */ - "NUMERICSTRING", "PRINTABLESTRING", "T61STRING", /* 18-20 */ - "VIDEOTEXSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME", /* 21-24 */ - "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", /* 25-27 */ - "UNIVERSALSTRING", "", "BMPSTRING" /* 28-30 */ + "NULL", "OBJECT IDENTIFIER", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */ + "ENUMERATED", "Universal 11", "UTF8String", "Universal 13", /* 10-13 */ + "Universal 14", "Universal 15", "SEQUENCE", "SET", /* 15-17 */ + "NumericString", "PrintableString", "T61String", /* 18-20 */ + "VideotexString", "IA5String", "UTCTIME", "GENERALIZEDTIME", /* 21-24 */ + "GraphicString", "VisibleString", "GeneralString", /* 25-27 */ + "UniversalString", "Universal 29", "BMPString" /* 28-30 */ }; if (tag > 30) @@ -214,6 +214,26 @@ static void sc_asn1_print_bit_string(const u8 * buf, size_t buflen) } } +#ifdef ENABLE_OPENSSL +#include + +static void openssl_print_object_sn(const char *s) +{ + ASN1_OBJECT *obj = OBJ_txt2obj(s, 0); + if (obj) { + int nid = OBJ_obj2nid(obj); + if (nid != NID_undef) { + printf("%s ", OBJ_nid2sn(nid)); + } + ASN1_OBJECT_free(obj); + } +} +#else +static void openssl_print_object_sn(const char *s) +{ +} +#endif + static void sc_asn1_print_object_id(const u8 * buf, size_t buflen) { struct sc_object_id oid; @@ -234,6 +254,8 @@ static void sc_asn1_print_object_id(const u8 * buf, size_t buflen) sprintf(tmp, "%d", oid.value[i]); strcat(sbuf, tmp); } + + openssl_print_object_sn(sbuf); printf("%s", sbuf); } @@ -245,12 +267,16 @@ static void sc_asn1_print_generalizedtime(const u8 * buf, size_t buflen) } static void print_tags_recursive(const u8 * buf0, const u8 * buf, - size_t buflen, int depth) + size_t buflen, size_t depth) { - int i, r; + int r; + size_t i; size_t bytesleft = buflen; const char *classes[4] = { - "Univ", "Appl", "Cntx", "Priv" + "Universal", + "Application", + "Context", + "Private" }; const u8 *p = buf; @@ -271,25 +297,40 @@ static void print_tags_recursive(const u8 * buf0, const u8 * buf, } for (i = 0; i < depth; i++) { putchar(' '); - putchar(' '); } - printf("%02X %s: tag 0x%02X, length %3d: ", - cla | tag, classes[cla >> 6], tag & 0x1f, (int) len); + /* let i be the length of the tag in bytes */ + for (i = 1; i < sizeof tag - 1; i++) { + if (!(tag >> 8*i)) + break; + } + printf("%02X", cla<<(i-1)*8 | tag); + + if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_UNIVERSAL) { + printf(" %s", tag2str(tag)); + } else { + printf(" %s %-2u", + classes[cla >> 6], + i == 1 ? tag & SC_ASN1_TAG_PRIMITIVE : tag & (((unsigned int) ~0) >> (i + 1) * 8)); + } + printf(" (%"SC_FORMAT_LEN_SIZE_T"u byte%s)", + len, + len != 1 ? "s" : ""); + if (len + hlen > bytesleft) { printf(" Illegal length!\n"); return; } p += hlen + len; bytesleft -= hlen + len; - if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_UNIVERSAL) - printf("%s", tag2str(tag)); if (cla & SC_ASN1_TAG_CONSTRUCTED) { putchar('\n'); - print_tags_recursive(buf0, tagp, len, depth + 1); + print_tags_recursive(buf0, tagp, len, depth + 2*i + 1); continue; } - if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_UNIVERSAL) { + + if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_UNIVERSAL + && tag != SC_ASN1_TAG_NULL) { printf(" ["); switch (tag) { case SC_ASN1_TAG_BIT_STRING: @@ -321,10 +362,10 @@ static void print_tags_recursive(const u8 * buf0, const u8 * buf, } if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_APPLICATION) - printf(" [%s]", sc_dump_hex(tagp, len)); + printf(" [%s]", sc_dump_hex(tagp, len)); if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_CONTEXT) - printf(" [%s]", sc_dump_hex(tagp, len)); + printf(" [%s]", sc_dump_hex(tagp, len)); putchar('\n'); } @@ -333,7 +374,6 @@ static void print_tags_recursive(const u8 * buf0, const u8 * buf, void sc_asn1_print_tags(const u8 * buf, size_t buflen) { - printf("Printing tags for buffer of length %d\n", (int) buflen); print_tags_recursive(buf, buf, buflen, 0); }