summaryrefslogtreecommitdiff
path: root/src/usr.bin/openssl/ts.c
diff options
context:
space:
mode:
authorinoguchi <>2022-03-24 11:27:45 +0000
committerinoguchi <>2022-03-24 11:27:45 +0000
commit76013a51bc66b3329f74a077b07c5c10f876736a (patch)
tree5a2c1b53461d3f733e0a928c35d85886fd48d726 /src/usr.bin/openssl/ts.c
parent4ab9607bafc39e3112c831efcc8db6382fb735ba (diff)
downloadopenbsd-76013a51bc66b3329f74a077b07c5c10f876736a.tar.gz
openbsd-76013a51bc66b3329f74a077b07c5c10f876736a.tar.bz2
openbsd-76013a51bc66b3329f74a077b07c5c10f876736a.zip
Convert openssl(1) ts option handling
Apply new option handling to openssl(1) ts, and there is no functional changes here. usage strings are comes from manual page. comments and ok jsing@
Diffstat (limited to 'src/usr.bin/openssl/ts.c')
-rw-r--r--src/usr.bin/openssl/ts.c438
1 files changed, 285 insertions, 153 deletions
diff --git a/src/usr.bin/openssl/ts.c b/src/usr.bin/openssl/ts.c
index 40c1a49b23..e4d299d726 100644
--- a/src/usr.bin/openssl/ts.c
+++ b/src/usr.bin/openssl/ts.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ts.c,v 1.17 2021/12/12 20:22:59 tb Exp $ */ 1/* $OpenBSD: ts.c,v 1.18 2022/03/24 11:27:45 inoguchi Exp $ */
2/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL 2/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
3 * project 2002. 3 * project 2002.
4 */ 4 */
@@ -116,38 +116,271 @@ static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest,
116static X509_STORE *create_cert_store(char *ca_path, char *ca_file); 116static X509_STORE *create_cert_store(char *ca_path, char *ca_file);
117static int verify_cb(int ok, X509_STORE_CTX * ctx); 117static int verify_cb(int ok, X509_STORE_CTX * ctx);
118 118
119enum mode {
120 CMD_NONE, CMD_QUERY, CMD_REPLY, CMD_VERIFY
121};
122
123static struct {
124 char *ca_file;
125 char *ca_path;
126 int cert;
127 char *chain;
128 char *configfile;
129 char *data;
130 char *digest;
131 char *in;
132 char *inkey;
133 const EVP_MD *md;
134 int mode;
135 int no_nonce;
136 char *out;
137 char *passin;
138 char *policy;
139 char *queryfile;
140 char *section;
141 char *signer;
142 int text;
143 int token_in;
144 int token_out;
145 char *untrusted;
146} ts_config;
147
148static int
149ts_opt_md(int argc, char **argv, int *argsused)
150{
151 char *name = argv[0];
152
153 if (*name++ != '-')
154 return (1);
155
156 if ((ts_config.md = EVP_get_digestbyname(name)) == NULL)
157 return (1);
158
159 *argsused = 1;
160 return (0);
161}
162
163static int
164ts_opt_query(void)
165{
166 if (ts_config.mode != CMD_NONE)
167 return (1);
168 ts_config.mode = CMD_QUERY;
169 return (0);
170}
171
172static int
173ts_opt_reply(void)
174{
175 if (ts_config.mode != CMD_NONE)
176 return (1);
177 ts_config.mode = CMD_REPLY;
178 return (0);
179}
180
181static int
182ts_opt_verify(void)
183{
184 if (ts_config.mode != CMD_NONE)
185 return (1);
186 ts_config.mode = CMD_VERIFY;
187 return (0);
188}
189
190static const struct option ts_options[] = {
191 {
192 .name = "CAfile",
193 .argname = "file",
194 .desc = "Certificate Authority file",
195 .type = OPTION_ARG,
196 .opt.arg = &ts_config.ca_file,
197 },
198 {
199 .name = "CApath",
200 .argname = "path",
201 .desc = "Certificate Authority path",
202 .type = OPTION_ARG,
203 .opt.arg = &ts_config.ca_path,
204 },
205 {
206 .name = "cert",
207 .desc = "Include signing certificate in the response",
208 .type = OPTION_FLAG,
209 .opt.flag = &ts_config.cert,
210 },
211 {
212 .name = "chain",
213 .argname = "file",
214 .desc = "PEM certificates that will be included in the response",
215 .type = OPTION_ARG,
216 .opt.arg = &ts_config.chain,
217 },
218 {
219 .name = "config",
220 .argname = "file",
221 .desc = "Specify an alternative configuration file",
222 .type = OPTION_ARG,
223 .opt.arg = &ts_config.configfile,
224 },
225 {
226 .name = "data",
227 .argname = "file",
228 .desc = "Data file for which the time stamp request needs to be created",
229 .type = OPTION_ARG,
230 .opt.arg = &ts_config.data,
231 },
232 {
233 .name = "digest",
234 .argname = "arg",
235 .desc = "Specify the message imprint explicitly without the data file",
236 .type = OPTION_ARG,
237 .opt.arg = &ts_config.digest,
238 },
239 {
240 .name = "in",
241 .argname = "file",
242 .desc = "Input file",
243 .type = OPTION_ARG,
244 .opt.arg = &ts_config.in,
245 },
246 {
247 .name = "inkey",
248 .argname = "file",
249 .desc = "Input key file",
250 .type = OPTION_ARG,
251 .opt.arg = &ts_config.inkey,
252 },
253 {
254 .name = "no_nonce",
255 .desc = "Specify no nonce in the request",
256 .type = OPTION_FLAG,
257 .opt.flag = &ts_config.no_nonce,
258 },
259 {
260 .name = "out",
261 .argname = "file",
262 .desc = "Output file",
263 .type = OPTION_ARG,
264 .opt.arg = &ts_config.out,
265 },
266 {
267 .name = "passin",
268 .argname = "src",
269 .desc = "Private key password source",
270 .type = OPTION_ARG,
271 .opt.arg = &ts_config.passin,
272 },
273 {
274 .name = "policy",
275 .argname = "object_id",
276 .desc = "Policy for the TSA to use when creating the time stamp token",
277 .type = OPTION_ARG,
278 .opt.arg = &ts_config.policy,
279 },
280 {
281 .name = "query",
282 .desc = "Create and print a time stamp request",
283 .type = OPTION_FUNC,
284 .opt.func = ts_opt_query,
285 },
286 {
287 .name = "queryfile",
288 .argname = "file",
289 .desc = "File containing a DER-encoded time stamp request",
290 .type = OPTION_ARG,
291 .opt.arg = &ts_config.queryfile,
292 },
293 {
294 .name = "reply",
295 .desc = "Create a time stamp response",
296 .type = OPTION_FUNC,
297 .opt.func = ts_opt_reply,
298 },
299 {
300 .name = "section",
301 .argname = "arg",
302 .desc = "TSA section containing the settings for response generation",
303 .type = OPTION_ARG,
304 .opt.arg = &ts_config.section,
305 },
306 {
307 .name = "signer",
308 .argname = "file",
309 .desc = "Signer certificate file",
310 .type = OPTION_ARG,
311 .opt.arg = &ts_config.signer,
312 },
313 {
314 .name = "text",
315 .desc = "Output in human-readable text format",
316 .type = OPTION_FLAG,
317 .opt.flag = &ts_config.text,
318 },
319 {
320 .name = "token_in",
321 .desc = "Input is a DER-encoded time stamp token",
322 .type = OPTION_FLAG,
323 .opt.flag = &ts_config.token_in,
324 },
325 {
326 .name = "token_out",
327 .desc = "Output is a DER-encoded time stamp token",
328 .type = OPTION_FLAG,
329 .opt.flag = &ts_config.token_out,
330 },
331 {
332 .name = "untrusted",
333 .argname = "file",
334 .desc = "File containing untrusted certificates",
335 .type = OPTION_ARG,
336 .opt.arg = &ts_config.untrusted,
337 },
338 {
339 .name = "verify",
340 .desc = "Verify a time stamp response",
341 .type = OPTION_FUNC,
342 .opt.func = ts_opt_verify,
343 },
344 {
345 .name = NULL,
346 .desc = "",
347 .type = OPTION_ARGV_FUNC,
348 .opt.argvfunc = ts_opt_md,
349 },
350 { NULL },
351};
352
353static void
354ts_usage(void)
355{
356 fprintf(stderr, "usage:\n"
357 "ts -query [-md4 | -md5 | -ripemd160 | -sha1] [-cert]\n"
358 " [-config configfile] [-data file_to_hash]\n"
359 " [-digest digest_bytes] [-in request.tsq] [-no_nonce]\n"
360 " [-out request.tsq] [-policy object_id] [-text]\n");
361 fprintf(stderr, "\n"
362 "ts -reply [-chain certs_file.pem] [-config configfile]\n"
363 " [-in response.tsr] [-inkey private.pem] [-out response.tsr]\n"
364 " [-passin arg] [-policy object_id] [-queryfile request.tsq]\n"
365 " [-section tsa_section] [-signer tsa_cert.pem] [-text]\n"
366 " [-token_in] [-token_out]\n");
367 fprintf(stderr, "\n"
368 "ts -verify [-CAfile trusted_certs.pem]\n"
369 " [-CApath trusted_cert_path] [-data file_to_hash]\n"
370 " [-digest digest_bytes] [-in response.tsr]\n"
371 " [-queryfile request.tsq] [-token_in]\n"
372 " [-untrusted cert_file.pem]\n");
373 fprintf(stderr, "\n");
374 options_usage(ts_options);
375 fprintf(stderr, "\n");
376}
377
119int 378int
120ts_main(int argc, char **argv) 379ts_main(int argc, char **argv)
121{ 380{
122 int ret = 1; 381 int ret = 1;
123 char *configfile = NULL;
124 char *section = NULL;
125 CONF *conf = NULL; 382 CONF *conf = NULL;
126 enum mode {
127 CMD_NONE, CMD_QUERY, CMD_REPLY, CMD_VERIFY
128 } mode = CMD_NONE;
129 char *data = NULL;
130 char *digest = NULL;
131 const EVP_MD *md = NULL;
132 char *policy = NULL;
133 int no_nonce = 0;
134 int cert = 0;
135 char *in = NULL;
136 char *out = NULL;
137 int text = 0;
138 char *queryfile = NULL;
139 char *passin = NULL; /* Password source. */
140 char *password = NULL; /* Password itself. */ 383 char *password = NULL; /* Password itself. */
141 char *inkey = NULL;
142 char *signer = NULL;
143 char *chain = NULL;
144 char *ca_path = NULL;
145 char *ca_file = NULL;
146 char *untrusted = NULL;
147 /* Input is ContentInfo instead of TimeStampResp. */
148 int token_in = 0;
149 /* Output is ContentInfo instead of TimeStampResp. */
150 int token_out = 0;
151 384
152 if (single_execution) { 385 if (single_execution) {
153 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) { 386 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
@@ -156,98 +389,15 @@ ts_main(int argc, char **argv)
156 } 389 }
157 } 390 }
158 391
159 for (argc--, argv++; argc > 0; argc--, argv++) { 392 memset(&ts_config, 0, sizeof(ts_config));
160 if (strcmp(*argv, "-config") == 0) { 393 ts_config.mode = CMD_NONE;
161 if (argc-- < 1) 394
162 goto usage; 395 if (options_parse(argc, argv, ts_options, NULL, NULL) != 0)
163 configfile = *++argv; 396 goto usage;
164 } else if (strcmp(*argv, "-section") == 0) {
165 if (argc-- < 1)
166 goto usage;
167 section = *++argv;
168 } else if (strcmp(*argv, "-query") == 0) {
169 if (mode != CMD_NONE)
170 goto usage;
171 mode = CMD_QUERY;
172 } else if (strcmp(*argv, "-data") == 0) {
173 if (argc-- < 1)
174 goto usage;
175 data = *++argv;
176 } else if (strcmp(*argv, "-digest") == 0) {
177 if (argc-- < 1)
178 goto usage;
179 digest = *++argv;
180 } else if (strcmp(*argv, "-policy") == 0) {
181 if (argc-- < 1)
182 goto usage;
183 policy = *++argv;
184 } else if (strcmp(*argv, "-no_nonce") == 0) {
185 no_nonce = 1;
186 } else if (strcmp(*argv, "-cert") == 0) {
187 cert = 1;
188 } else if (strcmp(*argv, "-in") == 0) {
189 if (argc-- < 1)
190 goto usage;
191 in = *++argv;
192 } else if (strcmp(*argv, "-token_in") == 0) {
193 token_in = 1;
194 } else if (strcmp(*argv, "-out") == 0) {
195 if (argc-- < 1)
196 goto usage;
197 out = *++argv;
198 } else if (strcmp(*argv, "-token_out") == 0) {
199 token_out = 1;
200 } else if (strcmp(*argv, "-text") == 0) {
201 text = 1;
202 } else if (strcmp(*argv, "-reply") == 0) {
203 if (mode != CMD_NONE)
204 goto usage;
205 mode = CMD_REPLY;
206 } else if (strcmp(*argv, "-queryfile") == 0) {
207 if (argc-- < 1)
208 goto usage;
209 queryfile = *++argv;
210 } else if (strcmp(*argv, "-passin") == 0) {
211 if (argc-- < 1)
212 goto usage;
213 passin = *++argv;
214 } else if (strcmp(*argv, "-inkey") == 0) {
215 if (argc-- < 1)
216 goto usage;
217 inkey = *++argv;
218 } else if (strcmp(*argv, "-signer") == 0) {
219 if (argc-- < 1)
220 goto usage;
221 signer = *++argv;
222 } else if (strcmp(*argv, "-chain") == 0) {
223 if (argc-- < 1)
224 goto usage;
225 chain = *++argv;
226 } else if (strcmp(*argv, "-verify") == 0) {
227 if (mode != CMD_NONE)
228 goto usage;
229 mode = CMD_VERIFY;
230 } else if (strcmp(*argv, "-CApath") == 0) {
231 if (argc-- < 1)
232 goto usage;
233 ca_path = *++argv;
234 } else if (strcmp(*argv, "-CAfile") == 0) {
235 if (argc-- < 1)
236 goto usage;
237 ca_file = *++argv;
238 } else if (strcmp(*argv, "-untrusted") == 0) {
239 if (argc-- < 1)
240 goto usage;
241 untrusted = *++argv;
242 } else if ((md = EVP_get_digestbyname(*argv + 1)) != NULL) {
243 /* empty. */
244 } else
245 goto usage;
246 }
247 397
248 /* Get the password if required. */ 398 /* Get the password if required. */
249 if (mode == CMD_REPLY && passin && 399 if (ts_config.mode == CMD_REPLY && ts_config.passin &&
250 !app_passwd(bio_err, passin, NULL, &password, NULL)) { 400 !app_passwd(bio_err, ts_config.passin, NULL, &password, NULL)) {
251 BIO_printf(bio_err, "Error getting password.\n"); 401 BIO_printf(bio_err, "Error getting password.\n");
252 goto cleanup; 402 goto cleanup;
253 } 403 }
@@ -255,7 +405,7 @@ ts_main(int argc, char **argv)
255 * Check consistency of parameters and execute the appropriate 405 * Check consistency of parameters and execute the appropriate
256 * function. 406 * function.
257 */ 407 */
258 switch (mode) { 408 switch (ts_config.mode) {
259 case CMD_NONE: 409 case CMD_NONE:
260 goto usage; 410 goto usage;
261 case CMD_QUERY: 411 case CMD_QUERY:
@@ -263,64 +413,46 @@ ts_main(int argc, char **argv)
263 * Data file and message imprint cannot be specified at the 413 * Data file and message imprint cannot be specified at the
264 * same time. 414 * same time.
265 */ 415 */
266 ret = data != NULL && digest != NULL; 416 ret = ts_config.data != NULL && ts_config.digest != NULL;
267 if (ret) 417 if (ret)
268 goto usage; 418 goto usage;
269 /* Load the config file for possible policy OIDs. */ 419 /* Load the config file for possible policy OIDs. */
270 conf = load_config_file(configfile); 420 conf = load_config_file(ts_config.configfile);
271 ret = !query_command(data, digest, md, policy, no_nonce, cert, 421 ret = !query_command(ts_config.data, ts_config.digest, ts_config.md, ts_config.policy, ts_config.no_nonce, ts_config.cert,
272 in, out, text); 422 ts_config.in, ts_config.out, ts_config.text);
273 break; 423 break;
274 case CMD_REPLY: 424 case CMD_REPLY:
275 conf = load_config_file(configfile); 425 conf = load_config_file(ts_config.configfile);
276 if (in == NULL) { 426 if (ts_config.in == NULL) {
277 ret = !(queryfile != NULL && conf != NULL && !token_in); 427 ret = !(ts_config.queryfile != NULL && conf != NULL && !ts_config.token_in);
278 if (ret) 428 if (ret)
279 goto usage; 429 goto usage;
280 } else { 430 } else {
281 /* 'in' and 'queryfile' are exclusive. */ 431 /* 'in' and 'queryfile' are exclusive. */
282 ret = !(queryfile == NULL); 432 ret = !(ts_config.queryfile == NULL);
283 if (ret) 433 if (ret)
284 goto usage; 434 goto usage;
285 } 435 }
286 436
287 ret = !reply_command(conf, section, queryfile, 437 ret = !reply_command(conf, ts_config.section, ts_config.queryfile,
288 password, inkey, signer, chain, policy, 438 password, ts_config.inkey, ts_config.signer, ts_config.chain, ts_config.policy,
289 in, token_in, out, token_out, text); 439 ts_config.in, ts_config.token_in, ts_config.out, ts_config.token_out, ts_config.text);
290 break; 440 break;
291 case CMD_VERIFY: 441 case CMD_VERIFY:
292 ret = !(((queryfile && !data && !digest) || 442 ret = !(((ts_config.queryfile && !ts_config.data && !ts_config.digest) ||
293 (!queryfile && data && !digest) || 443 (!ts_config.queryfile && ts_config.data && !ts_config.digest) ||
294 (!queryfile && !data && digest)) && in != NULL); 444 (!ts_config.queryfile && !ts_config.data && ts_config.digest)) && ts_config.in != NULL);
295 if (ret) 445 if (ret)
296 goto usage; 446 goto usage;
297 447
298 ret = !verify_command(data, digest, queryfile, in, token_in, 448 ret = !verify_command(ts_config.data, ts_config.digest, ts_config.queryfile, ts_config.in, ts_config.token_in,
299 ca_path, ca_file, untrusted); 449 ts_config.ca_path, ts_config.ca_file, ts_config.untrusted);
300 } 450 }
301 451
302 goto cleanup; 452 goto cleanup;
303 453
304 usage: 454 usage:
305 BIO_printf(bio_err, "usage:\n" 455 ts_usage();
306 "ts -query [-config configfile] "
307 "[-data file_to_hash] [-digest digest_bytes]"
308 "[-md4|-md5|-sha1|-ripemd160] "
309 "[-policy object_id] [-no_nonce] [-cert] "
310 "[-in request.tsq] [-out request.tsq] [-text]\n");
311 BIO_printf(bio_err, "or\n"
312 "ts -reply [-config configfile] [-section tsa_section] "
313 "[-queryfile request.tsq] [-passin password] "
314 "[-signer tsa_cert.pem] [-inkey private_key.pem] "
315 "[-chain certs_file.pem] [-policy object_id] "
316 "[-in response.tsr] [-token_in] "
317 "[-out response.tsr] [-token_out] [-text]\n");
318 BIO_printf(bio_err, "or\n"
319 "ts -verify [-data file_to_hash] [-digest digest_bytes] "
320 "[-queryfile request.tsq] "
321 "-in response.tsr [-token_in] "
322 "-CApath ca_path -CAfile ca_file.pem "
323 "-untrusted cert_file.pem\n");
324 456
325 cleanup: 457 cleanup:
326 /* Clean up. */ 458 /* Clean up. */