asn1: Add --raw-sequence option to asn1_print

This commit is contained in:
Nicolas Williams
2021-03-02 21:39:00 -06:00
parent f5d9ced33c
commit a68ccb6693
2 changed files with 49 additions and 14 deletions

View File

@@ -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

View File

@@ -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;