version 1.25, 2022/11/11 17:07:39 |
version 1.26, 2023/03/06 14:32:06 |
|
|
int token_in; |
int token_in; |
int token_out; |
int token_out; |
char *untrusted; |
char *untrusted; |
} ts_config; |
} cfg; |
|
|
static int |
static int |
ts_opt_md(int argc, char **argv, int *argsused) |
ts_opt_md(int argc, char **argv, int *argsused) |
|
|
if (*name++ != '-') |
if (*name++ != '-') |
return (1); |
return (1); |
|
|
if ((ts_config.md = EVP_get_digestbyname(name)) == NULL) |
if ((cfg.md = EVP_get_digestbyname(name)) == NULL) |
return (1); |
return (1); |
|
|
*argsused = 1; |
*argsused = 1; |
|
|
static int |
static int |
ts_opt_query(void) |
ts_opt_query(void) |
{ |
{ |
if (ts_config.mode != CMD_NONE) |
if (cfg.mode != CMD_NONE) |
return (1); |
return (1); |
ts_config.mode = CMD_QUERY; |
cfg.mode = CMD_QUERY; |
return (0); |
return (0); |
} |
} |
|
|
static int |
static int |
ts_opt_reply(void) |
ts_opt_reply(void) |
{ |
{ |
if (ts_config.mode != CMD_NONE) |
if (cfg.mode != CMD_NONE) |
return (1); |
return (1); |
ts_config.mode = CMD_REPLY; |
cfg.mode = CMD_REPLY; |
return (0); |
return (0); |
} |
} |
|
|
static int |
static int |
ts_opt_verify(void) |
ts_opt_verify(void) |
{ |
{ |
if (ts_config.mode != CMD_NONE) |
if (cfg.mode != CMD_NONE) |
return (1); |
return (1); |
ts_config.mode = CMD_VERIFY; |
cfg.mode = CMD_VERIFY; |
return (0); |
return (0); |
} |
} |
|
|
|
|
.argname = "file", |
.argname = "file", |
.desc = "Certificate Authority file", |
.desc = "Certificate Authority file", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &ts_config.ca_file, |
.opt.arg = &cfg.ca_file, |
}, |
}, |
{ |
{ |
.name = "CApath", |
.name = "CApath", |
.argname = "path", |
.argname = "path", |
.desc = "Certificate Authority path", |
.desc = "Certificate Authority path", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &ts_config.ca_path, |
.opt.arg = &cfg.ca_path, |
}, |
}, |
{ |
{ |
.name = "cert", |
.name = "cert", |
.desc = "Include signing certificate in the response", |
.desc = "Include signing certificate in the response", |
.type = OPTION_FLAG, |
.type = OPTION_FLAG, |
.opt.flag = &ts_config.cert, |
.opt.flag = &cfg.cert, |
}, |
}, |
{ |
{ |
.name = "chain", |
.name = "chain", |
.argname = "file", |
.argname = "file", |
.desc = "PEM certificates that will be included in the response", |
.desc = "PEM certificates that will be included in the response", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &ts_config.chain, |
.opt.arg = &cfg.chain, |
}, |
}, |
{ |
{ |
.name = "config", |
.name = "config", |
.argname = "file", |
.argname = "file", |
.desc = "Specify an alternative configuration file", |
.desc = "Specify an alternative configuration file", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &ts_config.configfile, |
.opt.arg = &cfg.configfile, |
}, |
}, |
{ |
{ |
.name = "data", |
.name = "data", |
.argname = "file", |
.argname = "file", |
.desc = "Data file for which the time stamp request needs to be created", |
.desc = "Data file for which the time stamp request needs to be created", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &ts_config.data, |
.opt.arg = &cfg.data, |
}, |
}, |
{ |
{ |
.name = "digest", |
.name = "digest", |
.argname = "arg", |
.argname = "arg", |
.desc = "Specify the message imprint explicitly without the data file", |
.desc = "Specify the message imprint explicitly without the data file", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &ts_config.digest, |
.opt.arg = &cfg.digest, |
}, |
}, |
{ |
{ |
.name = "in", |
.name = "in", |
.argname = "file", |
.argname = "file", |
.desc = "Input file", |
.desc = "Input file", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &ts_config.in, |
.opt.arg = &cfg.in, |
}, |
}, |
{ |
{ |
.name = "inkey", |
.name = "inkey", |
.argname = "file", |
.argname = "file", |
.desc = "Input key file", |
.desc = "Input key file", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &ts_config.inkey, |
.opt.arg = &cfg.inkey, |
}, |
}, |
{ |
{ |
.name = "no_nonce", |
.name = "no_nonce", |
.desc = "Specify no nonce in the request", |
.desc = "Specify no nonce in the request", |
.type = OPTION_FLAG, |
.type = OPTION_FLAG, |
.opt.flag = &ts_config.no_nonce, |
.opt.flag = &cfg.no_nonce, |
}, |
}, |
{ |
{ |
.name = "out", |
.name = "out", |
.argname = "file", |
.argname = "file", |
.desc = "Output file", |
.desc = "Output file", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &ts_config.out, |
.opt.arg = &cfg.out, |
}, |
}, |
{ |
{ |
.name = "passin", |
.name = "passin", |
.argname = "src", |
.argname = "src", |
.desc = "Private key password source", |
.desc = "Private key password source", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &ts_config.passin, |
.opt.arg = &cfg.passin, |
}, |
}, |
{ |
{ |
.name = "policy", |
.name = "policy", |
.argname = "object_id", |
.argname = "object_id", |
.desc = "Policy for the TSA to use when creating the time stamp token", |
.desc = "Policy for the TSA to use when creating the time stamp token", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &ts_config.policy, |
.opt.arg = &cfg.policy, |
}, |
}, |
{ |
{ |
.name = "query", |
.name = "query", |
|
|
.argname = "file", |
.argname = "file", |
.desc = "File containing a DER-encoded time stamp request", |
.desc = "File containing a DER-encoded time stamp request", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &ts_config.queryfile, |
.opt.arg = &cfg.queryfile, |
}, |
}, |
{ |
{ |
.name = "reply", |
.name = "reply", |
|
|
.argname = "arg", |
.argname = "arg", |
.desc = "TSA section containing the settings for response generation", |
.desc = "TSA section containing the settings for response generation", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &ts_config.section, |
.opt.arg = &cfg.section, |
}, |
}, |
{ |
{ |
.name = "signer", |
.name = "signer", |
.argname = "file", |
.argname = "file", |
.desc = "Signer certificate file", |
.desc = "Signer certificate file", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &ts_config.signer, |
.opt.arg = &cfg.signer, |
}, |
}, |
{ |
{ |
.name = "text", |
.name = "text", |
.desc = "Output in human-readable text format", |
.desc = "Output in human-readable text format", |
.type = OPTION_FLAG, |
.type = OPTION_FLAG, |
.opt.flag = &ts_config.text, |
.opt.flag = &cfg.text, |
}, |
}, |
{ |
{ |
.name = "token_in", |
.name = "token_in", |
.desc = "Input is a DER-encoded time stamp token", |
.desc = "Input is a DER-encoded time stamp token", |
.type = OPTION_FLAG, |
.type = OPTION_FLAG, |
.opt.flag = &ts_config.token_in, |
.opt.flag = &cfg.token_in, |
}, |
}, |
{ |
{ |
.name = "token_out", |
.name = "token_out", |
.desc = "Output is a DER-encoded time stamp token", |
.desc = "Output is a DER-encoded time stamp token", |
.type = OPTION_FLAG, |
.type = OPTION_FLAG, |
.opt.flag = &ts_config.token_out, |
.opt.flag = &cfg.token_out, |
}, |
}, |
{ |
{ |
.name = "untrusted", |
.name = "untrusted", |
.argname = "file", |
.argname = "file", |
.desc = "File containing untrusted certificates", |
.desc = "File containing untrusted certificates", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &ts_config.untrusted, |
.opt.arg = &cfg.untrusted, |
}, |
}, |
{ |
{ |
.name = "verify", |
.name = "verify", |
|
|
exit(1); |
exit(1); |
} |
} |
|
|
memset(&ts_config, 0, sizeof(ts_config)); |
memset(&cfg, 0, sizeof(cfg)); |
ts_config.mode = CMD_NONE; |
cfg.mode = CMD_NONE; |
|
|
if (options_parse(argc, argv, ts_options, NULL, NULL) != 0) |
if (options_parse(argc, argv, ts_options, NULL, NULL) != 0) |
goto usage; |
goto usage; |
|
|
/* Get the password if required. */ |
/* Get the password if required. */ |
if (ts_config.mode == CMD_REPLY && ts_config.passin != NULL && |
if (cfg.mode == CMD_REPLY && cfg.passin != NULL && |
!app_passwd(bio_err, ts_config.passin, NULL, &password, NULL)) { |
!app_passwd(bio_err, cfg.passin, NULL, &password, NULL)) { |
BIO_printf(bio_err, "Error getting password.\n"); |
BIO_printf(bio_err, "Error getting password.\n"); |
goto cleanup; |
goto cleanup; |
} |
} |
|
|
* Check consistency of parameters and execute the appropriate |
* Check consistency of parameters and execute the appropriate |
* function. |
* function. |
*/ |
*/ |
switch (ts_config.mode) { |
switch (cfg.mode) { |
case CMD_NONE: |
case CMD_NONE: |
goto usage; |
goto usage; |
case CMD_QUERY: |
case CMD_QUERY: |
|
|
* Data file and message imprint cannot be specified at the |
* Data file and message imprint cannot be specified at the |
* same time. |
* same time. |
*/ |
*/ |
ret = ts_config.data != NULL && ts_config.digest != NULL; |
ret = cfg.data != NULL && cfg.digest != NULL; |
if (ret) |
if (ret) |
goto usage; |
goto usage; |
/* Load the config file for possible policy OIDs. */ |
/* Load the config file for possible policy OIDs. */ |
conf = load_config_file(ts_config.configfile); |
conf = load_config_file(cfg.configfile); |
ret = !query_command(ts_config.data, ts_config.digest, |
ret = !query_command(cfg.data, cfg.digest, |
ts_config.md, ts_config.policy, ts_config.no_nonce, |
cfg.md, cfg.policy, cfg.no_nonce, |
ts_config.cert, ts_config.in, ts_config.out, |
cfg.cert, cfg.in, cfg.out, |
ts_config.text); |
cfg.text); |
break; |
break; |
case CMD_REPLY: |
case CMD_REPLY: |
conf = load_config_file(ts_config.configfile); |
conf = load_config_file(cfg.configfile); |
if (ts_config.in == NULL) { |
if (cfg.in == NULL) { |
ret = !(ts_config.queryfile != NULL && conf != NULL && |
ret = !(cfg.queryfile != NULL && conf != NULL && |
!ts_config.token_in); |
!cfg.token_in); |
if (ret) |
if (ret) |
goto usage; |
goto usage; |
} else { |
} else { |
/* 'in' and 'queryfile' are exclusive. */ |
/* 'in' and 'queryfile' are exclusive. */ |
ret = !(ts_config.queryfile == NULL); |
ret = !(cfg.queryfile == NULL); |
if (ret) |
if (ret) |
goto usage; |
goto usage; |
} |
} |
|
|
ret = !reply_command(conf, ts_config.section, |
ret = !reply_command(conf, cfg.section, |
ts_config.queryfile, password, ts_config.inkey, |
cfg.queryfile, password, cfg.inkey, |
ts_config.signer, ts_config.chain, ts_config.policy, |
cfg.signer, cfg.chain, cfg.policy, |
ts_config.in, ts_config.token_in, ts_config.out, |
cfg.in, cfg.token_in, cfg.out, |
ts_config.token_out, ts_config.text); |
cfg.token_out, cfg.text); |
break; |
break; |
case CMD_VERIFY: |
case CMD_VERIFY: |
ret = !(((ts_config.queryfile != NULL && ts_config.data == NULL && |
ret = !(((cfg.queryfile != NULL && cfg.data == NULL && |
ts_config.digest == NULL) || |
cfg.digest == NULL) || |
(ts_config.queryfile == NULL && ts_config.data != NULL && |
(cfg.queryfile == NULL && cfg.data != NULL && |
ts_config.digest == NULL) || |
cfg.digest == NULL) || |
(ts_config.queryfile == NULL && ts_config.data == NULL && |
(cfg.queryfile == NULL && cfg.data == NULL && |
ts_config.digest != NULL)) && |
cfg.digest != NULL)) && |
ts_config.in != NULL); |
cfg.in != NULL); |
if (ret) |
if (ret) |
goto usage; |
goto usage; |
|
|
ret = !verify_command(ts_config.data, ts_config.digest, |
ret = !verify_command(cfg.data, cfg.digest, |
ts_config.queryfile, ts_config.in, ts_config.token_in, |
cfg.queryfile, cfg.in, cfg.token_in, |
ts_config.ca_path, ts_config.ca_file, ts_config.untrusted); |
cfg.ca_path, cfg.ca_file, cfg.untrusted); |
} |
} |
|
|
goto cleanup; |
goto cleanup; |