version 1.12, 2022/11/11 17:07:38 |
version 1.13, 2023/03/06 14:32:05 |
|
|
int offset; |
int offset; |
char *oidfile; |
char *oidfile; |
STACK_OF(OPENSSL_STRING) *osk; |
STACK_OF(OPENSSL_STRING) *osk; |
} asn1pars_config; |
} cfg; |
|
|
static int |
static int |
asn1pars_opt_dlimit(char *arg) |
asn1pars_opt_dlimit(char *arg) |
{ |
{ |
const char *errstr; |
const char *errstr; |
|
|
asn1pars_config.dump = strtonum(arg, 1, INT_MAX, &errstr); |
cfg.dump = strtonum(arg, 1, INT_MAX, &errstr); |
if (errstr) { |
if (errstr) { |
fprintf(stderr, "-dlimit must be from 1 to INT_MAX: %s\n", |
fprintf(stderr, "-dlimit must be from 1 to INT_MAX: %s\n", |
errstr); |
errstr); |
|
|
{ |
{ |
const char *errstr; |
const char *errstr; |
|
|
asn1pars_config.length = strtonum(arg, 1, UINT_MAX, &errstr); |
cfg.length = strtonum(arg, 1, UINT_MAX, &errstr); |
if (errstr) { |
if (errstr) { |
fprintf(stderr, "-length must be from 1 to UINT_MAX: %s\n", |
fprintf(stderr, "-length must be from 1 to UINT_MAX: %s\n", |
errstr); |
errstr); |
|
|
static int |
static int |
asn1pars_opt_strparse(char *arg) |
asn1pars_opt_strparse(char *arg) |
{ |
{ |
if (sk_OPENSSL_STRING_push(asn1pars_config.osk, arg) == 0) { |
if (sk_OPENSSL_STRING_push(cfg.osk, arg) == 0) { |
fprintf(stderr, "-strparse cannot add argument\n"); |
fprintf(stderr, "-strparse cannot add argument\n"); |
return (-1); |
return (-1); |
} |
} |
|
|
.desc = "Dump unknown data in hex form", |
.desc = "Dump unknown data in hex form", |
.type = OPTION_VALUE, |
.type = OPTION_VALUE, |
.value = -1, |
.value = -1, |
.opt.value = &asn1pars_config.dump, |
.opt.value = &cfg.dump, |
}, |
}, |
{ |
{ |
.name = "dlimit", |
.name = "dlimit", |
|
|
.argname = "file", |
.argname = "file", |
.desc = "File to generate ASN.1 structure from", |
.desc = "File to generate ASN.1 structure from", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &asn1pars_config.genconf, |
.opt.arg = &cfg.genconf, |
}, |
}, |
{ |
{ |
.name = "genstr", |
.name = "genstr", |
.argname = "string", |
.argname = "string", |
.desc = "String to generate ASN.1 structure from", |
.desc = "String to generate ASN.1 structure from", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &asn1pars_config.genstr, |
.opt.arg = &cfg.genstr, |
}, |
}, |
{ |
{ |
.name = "i", |
.name = "i", |
.desc = "Indent output according to depth of structures", |
.desc = "Indent output according to depth of structures", |
.type = OPTION_FLAG, |
.type = OPTION_FLAG, |
.opt.flag = &asn1pars_config.indent, |
.opt.flag = &cfg.indent, |
}, |
}, |
{ |
{ |
.name = "in", |
.name = "in", |
.argname = "file", |
.argname = "file", |
.desc = "The input file (default stdin)", |
.desc = "The input file (default stdin)", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &asn1pars_config.infile, |
.opt.arg = &cfg.infile, |
}, |
}, |
{ |
{ |
.name = "inform", |
.name = "inform", |
.argname = "fmt", |
.argname = "fmt", |
.desc = "Input format (DER, TXT or PEM (default))", |
.desc = "Input format (DER, TXT or PEM (default))", |
.type = OPTION_ARG_FORMAT, |
.type = OPTION_ARG_FORMAT, |
.opt.value = &asn1pars_config.informat, |
.opt.value = &cfg.informat, |
}, |
}, |
{ |
{ |
.name = "length", |
.name = "length", |
|
|
.name = "noout", |
.name = "noout", |
.desc = "Do not produce any output", |
.desc = "Do not produce any output", |
.type = OPTION_FLAG, |
.type = OPTION_FLAG, |
.opt.flag = &asn1pars_config.noout, |
.opt.flag = &cfg.noout, |
}, |
}, |
{ |
{ |
.name = "offset", |
.name = "offset", |
.argname = "num", |
.argname = "num", |
.desc = "Offset to begin parsing", |
.desc = "Offset to begin parsing", |
.type = OPTION_ARG_INT, |
.type = OPTION_ARG_INT, |
.opt.value = &asn1pars_config.offset, |
.opt.value = &cfg.offset, |
}, |
}, |
{ |
{ |
.name = "oid", |
.name = "oid", |
.argname = "file", |
.argname = "file", |
.desc = "File containing additional object identifiers (OIDs)", |
.desc = "File containing additional object identifiers (OIDs)", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &asn1pars_config.oidfile, |
.opt.arg = &cfg.oidfile, |
}, |
}, |
{ |
{ |
.name = "out", |
.name = "out", |
.argname = "file", |
.argname = "file", |
.desc = "Output file in DER format", |
.desc = "Output file in DER format", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &asn1pars_config.derfile, |
.opt.arg = &cfg.derfile, |
}, |
}, |
{ |
{ |
.name = "strparse", |
.name = "strparse", |
|
|
exit(1); |
exit(1); |
} |
} |
|
|
memset(&asn1pars_config, 0, sizeof(asn1pars_config)); |
memset(&cfg, 0, sizeof(cfg)); |
|
|
asn1pars_config.informat = FORMAT_PEM; |
cfg.informat = FORMAT_PEM; |
if ((asn1pars_config.osk = sk_OPENSSL_STRING_new_null()) == NULL) { |
if ((cfg.osk = sk_OPENSSL_STRING_new_null()) == NULL) { |
BIO_printf(bio_err, "Memory allocation failure\n"); |
BIO_printf(bio_err, "Memory allocation failure\n"); |
goto end; |
goto end; |
} |
} |
|
|
} |
} |
BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT); |
BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT); |
|
|
if (asn1pars_config.oidfile != NULL) { |
if (cfg.oidfile != NULL) { |
if (BIO_read_filename(in, asn1pars_config.oidfile) <= 0) { |
if (BIO_read_filename(in, cfg.oidfile) <= 0) { |
BIO_printf(bio_err, "problems opening %s\n", |
BIO_printf(bio_err, "problems opening %s\n", |
asn1pars_config.oidfile); |
cfg.oidfile); |
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
goto end; |
goto end; |
} |
} |
OBJ_create_objects(in); |
OBJ_create_objects(in); |
} |
} |
if (asn1pars_config.infile == NULL) |
if (cfg.infile == NULL) |
BIO_set_fp(in, stdin, BIO_NOCLOSE); |
BIO_set_fp(in, stdin, BIO_NOCLOSE); |
else { |
else { |
if (BIO_read_filename(in, asn1pars_config.infile) <= 0) { |
if (BIO_read_filename(in, cfg.infile) <= 0) { |
perror(asn1pars_config.infile); |
perror(cfg.infile); |
goto end; |
goto end; |
} |
} |
} |
} |
|
|
if (asn1pars_config.derfile) { |
if (cfg.derfile) { |
if (!(derout = BIO_new_file(asn1pars_config.derfile, "wb"))) { |
if (!(derout = BIO_new_file(cfg.derfile, "wb"))) { |
BIO_printf(bio_err, "problems opening %s\n", |
BIO_printf(bio_err, "problems opening %s\n", |
asn1pars_config.derfile); |
cfg.derfile); |
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
goto end; |
goto end; |
} |
} |
|
|
if (!BUF_MEM_grow(buf, BUFSIZ * 8)) |
if (!BUF_MEM_grow(buf, BUFSIZ * 8)) |
goto end; /* Pre-allocate :-) */ |
goto end; /* Pre-allocate :-) */ |
|
|
if (asn1pars_config.genstr || asn1pars_config.genconf) { |
if (cfg.genstr || cfg.genconf) { |
num = do_generate(bio_err, asn1pars_config.genstr, |
num = do_generate(bio_err, cfg.genstr, |
asn1pars_config.genconf, buf); |
cfg.genconf, buf); |
if (num < 0) { |
if (num < 0) { |
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
goto end; |
goto end; |
} |
} |
} else { |
} else { |
|
|
if (asn1pars_config.informat == FORMAT_PEM) { |
if (cfg.informat == FORMAT_PEM) { |
BIO *tmp; |
BIO *tmp; |
|
|
if ((b64 = BIO_new(BIO_f_base64())) == NULL) |
if ((b64 = BIO_new(BIO_f_base64())) == NULL) |
|
|
|
|
/* If any structs to parse go through in sequence */ |
/* If any structs to parse go through in sequence */ |
|
|
if (sk_OPENSSL_STRING_num(asn1pars_config.osk)) { |
if (sk_OPENSSL_STRING_num(cfg.osk)) { |
tmpbuf = (unsigned char *) str; |
tmpbuf = (unsigned char *) str; |
tmplen = num; |
tmplen = num; |
for (i = 0; i < sk_OPENSSL_STRING_num(asn1pars_config.osk); |
for (i = 0; i < sk_OPENSSL_STRING_num(cfg.osk); |
i++) { |
i++) { |
ASN1_TYPE *atmp; |
ASN1_TYPE *atmp; |
int typ; |
int typ; |
j = strtonum( |
j = strtonum( |
sk_OPENSSL_STRING_value(asn1pars_config.osk, i), |
sk_OPENSSL_STRING_value(cfg.osk, i), |
1, INT_MAX, &errstr); |
1, INT_MAX, &errstr); |
if (errstr) { |
if (errstr) { |
BIO_printf(bio_err, |
BIO_printf(bio_err, |
"'%s' is an invalid number: %s\n", |
"'%s' is an invalid number: %s\n", |
sk_OPENSSL_STRING_value(asn1pars_config.osk, |
sk_OPENSSL_STRING_value(cfg.osk, |
i), errstr); |
i), errstr); |
continue; |
continue; |
} |
} |
|
|
str = (char *) tmpbuf; |
str = (char *) tmpbuf; |
num = tmplen; |
num = tmplen; |
} |
} |
if (asn1pars_config.offset >= num) { |
if (cfg.offset >= num) { |
BIO_printf(bio_err, "Error: offset too large\n"); |
BIO_printf(bio_err, "Error: offset too large\n"); |
goto end; |
goto end; |
} |
} |
num -= asn1pars_config.offset; |
num -= cfg.offset; |
|
|
if ((asn1pars_config.length == 0) || |
if ((cfg.length == 0) || |
((long)asn1pars_config.length > num)) |
((long)cfg.length > num)) |
asn1pars_config.length = (unsigned int) num; |
cfg.length = (unsigned int) num; |
if (derout) { |
if (derout) { |
if (BIO_write(derout, str + asn1pars_config.offset, |
if (BIO_write(derout, str + cfg.offset, |
asn1pars_config.length) != (int)asn1pars_config.length) { |
cfg.length) != (int)cfg.length) { |
BIO_printf(bio_err, "Error writing output\n"); |
BIO_printf(bio_err, "Error writing output\n"); |
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
goto end; |
goto end; |
} |
} |
} |
} |
if (!asn1pars_config.noout && |
if (!cfg.noout && |
!ASN1_parse_dump(out, |
!ASN1_parse_dump(out, |
(unsigned char *)&(str[asn1pars_config.offset]), |
(unsigned char *)&(str[cfg.offset]), |
asn1pars_config.length, asn1pars_config.indent, |
cfg.length, cfg.indent, |
asn1pars_config.dump)) { |
cfg.dump)) { |
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
goto end; |
goto end; |
} |
} |
|
|
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
BUF_MEM_free(buf); |
BUF_MEM_free(buf); |
ASN1_TYPE_free(at); |
ASN1_TYPE_free(at); |
sk_OPENSSL_STRING_free(asn1pars_config.osk); |
sk_OPENSSL_STRING_free(cfg.osk); |
OBJ_cleanup(); |
OBJ_cleanup(); |
|
|
return (ret); |
return (ret); |