From a68ccb6693447edd6be62a094eda00019596a69e Mon Sep 17 00:00:00 2001 From: Nicolas Williams Date: Tue, 2 Mar 2021 21:39:00 -0600 Subject: [PATCH] asn1: Add --raw-sequence option to asn1_print --- lib/asn1/asn1_print.1 | 25 ++++++++++++++++++++----- lib/asn1/asn1_print.c | 38 +++++++++++++++++++++++++++++--------- 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/lib/asn1/asn1_print.1 b/lib/asn1/asn1_print.1 index 93a29310c..066b7636e 100644 --- a/lib/asn1/asn1_print.1 +++ b/lib/asn1/asn1_print.1 @@ -56,6 +56,10 @@ .Fl Fl try-all-types .Xc .Oc +.Oo Fl S \*(Ba Xo +.Fl Fl raw-sequence +.Xc +.Oc .Oo Fl l v \*(Ba Xo .Fl Fl version .Xc @@ -82,13 +86,15 @@ are given, they must be the names of ASN.1 types exported by an ASN.1 modules that are compiled into .Nm . Use the -.Fl Fl list-types -option to list ASN.1 types known to -.Nm . -Use the .Fl Fl try-all-types option to attempt decoding as all ASN.1 types known to .Nm . +If neither any +.Ar TypeName +nor +.Fl Fl try-all-types +are given, then the value will be parsed and displayed using just +the self-describing nature of DER. .Pp Options supported: .Bl -tag -width Ds @@ -97,7 +103,16 @@ Do not indent dump. .It Fl I, Fl Fl inner Try to parse inner structures of OCTET STRING and constructed values. .It Fl l, Fl Fl list-types -Try to parse inner structures of OCTET STRING and constructed values. +List all types known to +.Nm . +.It Fl A, Fl Fl try-all-types +Attempt to decode the value as any of all types known to +.Nm . +.It Fl S, Fl Fl raw-sequence +If a value parses as a given +.Ar TypeName +but any bytes are left over, try to parse those separately as +well until all bytes are consumed or an error occurs. .It Fl v, Fl Fl version .It Fl h, Fl Fl help .El diff --git a/lib/asn1/asn1_print.c b/lib/asn1/asn1_print.c index 652b23ba4..2165a6610 100644 --- a/lib/asn1/asn1_print.c +++ b/lib/asn1/asn1_print.c @@ -55,6 +55,7 @@ #include "rfc4108_asn1.h" #include "x690sample_asn1.h" +static int sequence_flag = 0; static int try_all_flag = 0; static int indent_flag = 1; static int inner_flag = 0; @@ -350,7 +351,7 @@ type_cmp(const void *va, const void *vb) } static int -dotype(unsigned char *buf, size_t len, char **argv) +dotype(unsigned char *buf, size_t len, char **argv, size_t *size) { const char *typename; size_t matches = 0; @@ -360,6 +361,8 @@ dotype(unsigned char *buf, size_t len, char **argv) void *v; int ret = 0; + *size = len; + memcpy(sorted_types, types, sizeof(types)); qsort(sorted_types, sizeof(types)/sizeof(types[0]), @@ -394,14 +397,19 @@ dotype(unsigned char *buf, size_t len, char **argv) v = ecalloc(1, sorted_types[i].sz); ret = sorted_types[i].decode(buf, len, v, &sz); if (ret == 0) { - if (sz == len) + if (sz == len) { fprintf(stderr, "Match: %s\n", typename); - else + } else if (sequence_flag) { + *size = sz; + } else { fprintf(stderr, "Prefix match: %s\n", typename); + } s = sorted_types[i].print(v, indent_flag ? ASN1_PRINT_INDENT : 0); sorted_types[i].release(v); - if (!s) + if (!s) { ret = errno; + err(1, "Could not print %s\n", typename); + } } free(v); if (ret == 0) { @@ -411,9 +419,8 @@ dotype(unsigned char *buf, size_t len, char **argv) i++; if (try_all_flag) continue; - free(buf); free(s); - exit(0); + return 0; } if (argv[0]) @@ -513,10 +520,17 @@ doit(char **argv) close(fd); argv++; - if (argv[0] || try_all_flag) - ret = dotype(buf, len, argv); - else + if (argv[0] || try_all_flag) { + size_t off = 0; + size_t sz = 0; + + do { + ret = dotype(buf + off, len - off, argv, &sz); + off += sz; + } while (ret == 0 && sequence_flag && off < len); + } else { ret = loop(buf, len, 0); + } free(buf); return ret; } @@ -534,6 +548,8 @@ struct getargs args[] = { "\tlist ASN.1 types known to this program", NULL }, { "try-all-types", 'A', arg_flag, &try_all_flag, "\ttry all known types", NULL }, + { "raw-sequence", 'S', arg_flag, &sequence_flag, + "\ttry parsing leftover data", NULL }, { "version", 'v', arg_flag, &version_flag, NULL, NULL }, { "help", 'h', arg_flag, &help_flag, NULL, NULL } }; @@ -563,6 +579,10 @@ main(int argc, char **argv) } argv += optidx; argc -= optidx; + + if (sequence_flag && try_all_flag) + errx(1, "--raw-sequence and --try-all-types are mutually exclusive"); + if (list_types_flag) { size_t i;