asn1: Add --raw-sequence option to asn1_print
This commit is contained in:
		| @@ -56,6 +56,10 @@ | |||||||
| .Fl Fl try-all-types | .Fl Fl try-all-types | ||||||
| .Xc | .Xc | ||||||
| .Oc | .Oc | ||||||
|  | .Oo Fl S \*(Ba Xo | ||||||
|  | .Fl Fl raw-sequence | ||||||
|  | .Xc | ||||||
|  | .Oc | ||||||
| .Oo Fl l v \*(Ba Xo | .Oo Fl l v \*(Ba Xo | ||||||
| .Fl Fl version | .Fl Fl version | ||||||
| .Xc | .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 | ASN.1 modules that are compiled into | ||||||
| .Nm . | .Nm . | ||||||
| Use the | Use the | ||||||
| .Fl Fl list-types |  | ||||||
| option to list ASN.1 types known to |  | ||||||
| .Nm . |  | ||||||
| Use the |  | ||||||
| .Fl Fl try-all-types | .Fl Fl try-all-types | ||||||
| option to attempt decoding as all ASN.1 types known to | option to attempt decoding as all ASN.1 types known to | ||||||
| .Nm . | .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 | .Pp | ||||||
| Options supported: | Options supported: | ||||||
| .Bl -tag -width Ds | .Bl -tag -width Ds | ||||||
| @@ -97,7 +103,16 @@ Do not indent dump. | |||||||
| .It Fl I, Fl Fl inner | .It Fl I, Fl Fl inner | ||||||
| Try to parse inner structures of OCTET STRING and constructed values. | Try to parse inner structures of OCTET STRING and constructed values. | ||||||
| .It Fl l, Fl Fl list-types | .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 v, Fl Fl version | ||||||
| .It Fl h, Fl Fl help | .It Fl h, Fl Fl help | ||||||
| .El | .El | ||||||
|   | |||||||
| @@ -55,6 +55,7 @@ | |||||||
| #include "rfc4108_asn1.h" | #include "rfc4108_asn1.h" | ||||||
| #include "x690sample_asn1.h" | #include "x690sample_asn1.h" | ||||||
|  |  | ||||||
|  | static int sequence_flag = 0; | ||||||
| static int try_all_flag = 0; | static int try_all_flag = 0; | ||||||
| static int indent_flag = 1; | static int indent_flag = 1; | ||||||
| static int inner_flag = 0; | static int inner_flag = 0; | ||||||
| @@ -350,7 +351,7 @@ type_cmp(const void *va, const void *vb) | |||||||
| } | } | ||||||
|  |  | ||||||
| static int | 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; |     const char *typename; | ||||||
|     size_t matches = 0; |     size_t matches = 0; | ||||||
| @@ -360,6 +361,8 @@ dotype(unsigned char *buf, size_t len, char **argv) | |||||||
|     void *v; |     void *v; | ||||||
|     int ret = 0; |     int ret = 0; | ||||||
|  |  | ||||||
|  |     *size = len; | ||||||
|  |  | ||||||
|     memcpy(sorted_types, types, sizeof(types)); |     memcpy(sorted_types, types, sizeof(types)); | ||||||
|     qsort(sorted_types, |     qsort(sorted_types, | ||||||
|           sizeof(types)/sizeof(types[0]), |           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); |         v = ecalloc(1, sorted_types[i].sz); | ||||||
|         ret = sorted_types[i].decode(buf, len, v, &sz); |         ret = sorted_types[i].decode(buf, len, v, &sz); | ||||||
|         if (ret == 0) { |         if (ret == 0) { | ||||||
|             if (sz == len) |             if (sz == len) { | ||||||
|                 fprintf(stderr, "Match: %s\n", typename); |                 fprintf(stderr, "Match: %s\n", typename); | ||||||
|             else |             } else if (sequence_flag) { | ||||||
|  |                 *size = sz; | ||||||
|  |             } else { | ||||||
|                 fprintf(stderr, "Prefix match: %s\n", typename); |                 fprintf(stderr, "Prefix match: %s\n", typename); | ||||||
|  |             } | ||||||
|             s = sorted_types[i].print(v, indent_flag ? ASN1_PRINT_INDENT : 0); |             s = sorted_types[i].print(v, indent_flag ? ASN1_PRINT_INDENT : 0); | ||||||
|             sorted_types[i].release(v); |             sorted_types[i].release(v); | ||||||
|             if (!s) |             if (!s) { | ||||||
|                 ret = errno; |                 ret = errno; | ||||||
|  |                 err(1, "Could not print %s\n", typename); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|         free(v); |         free(v); | ||||||
|         if (ret == 0) { |         if (ret == 0) { | ||||||
| @@ -411,9 +419,8 @@ dotype(unsigned char *buf, size_t len, char **argv) | |||||||
|             i++; |             i++; | ||||||
|             if (try_all_flag) |             if (try_all_flag) | ||||||
|                 continue; |                 continue; | ||||||
|             free(buf); |  | ||||||
|             free(s); |             free(s); | ||||||
|             exit(0); |             return 0; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (argv[0]) |         if (argv[0]) | ||||||
| @@ -513,10 +520,17 @@ doit(char **argv) | |||||||
|     close(fd); |     close(fd); | ||||||
|  |  | ||||||
|     argv++; |     argv++; | ||||||
|     if (argv[0] || try_all_flag) |     if (argv[0] || try_all_flag) { | ||||||
|         ret = dotype(buf, len, argv); |         size_t off = 0; | ||||||
|     else |         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); |         ret = loop(buf, len, 0); | ||||||
|  |     } | ||||||
|     free(buf); |     free(buf); | ||||||
|     return ret; |     return ret; | ||||||
| } | } | ||||||
| @@ -534,6 +548,8 @@ struct getargs args[] = { | |||||||
|         "\tlist ASN.1 types known to this program", NULL }, |         "\tlist ASN.1 types known to this program", NULL }, | ||||||
|     { "try-all-types", 'A', arg_flag, &try_all_flag, |     { "try-all-types", 'A', arg_flag, &try_all_flag, | ||||||
|         "\ttry all known types", NULL }, |         "\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 }, |     { "version", 'v', arg_flag, &version_flag, NULL, NULL }, | ||||||
|     { "help", 'h', arg_flag, &help_flag, NULL, NULL } |     { "help", 'h', arg_flag, &help_flag, NULL, NULL } | ||||||
| }; | }; | ||||||
| @@ -563,6 +579,10 @@ main(int argc, char **argv) | |||||||
|     } |     } | ||||||
|     argv += optidx; |     argv += optidx; | ||||||
|     argc -= optidx; |     argc -= optidx; | ||||||
|  |  | ||||||
|  |     if (sequence_flag && try_all_flag) | ||||||
|  |         errx(1, "--raw-sequence and --try-all-types are mutually exclusive"); | ||||||
|  |  | ||||||
|     if (list_types_flag) { |     if (list_types_flag) { | ||||||
|         size_t i; |         size_t i; | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Nicolas Williams
					Nicolas Williams