opt.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122
  1. /*
  2. * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. /*
  10. * This file is also used by the test suite. Do not #include "apps.h".
  11. */
  12. #include "opt.h"
  13. #include "fmt.h"
  14. #include "internal/nelem.h"
  15. #include <string.h>
  16. #if !defined(OPENSSL_SYS_MSDOS)
  17. # include <unistd.h>
  18. #endif
  19. #include <stdlib.h>
  20. #include <errno.h>
  21. #include <ctype.h>
  22. #include <limits.h>
  23. #include <openssl/err.h>
  24. #include <openssl/bio.h>
  25. #include <openssl/x509v3.h>
  26. #define MAX_OPT_HELP_WIDTH 30
  27. const char OPT_HELP_STR[] = "-H";
  28. const char OPT_MORE_STR[] = "-M";
  29. const char OPT_SECTION_STR[] = "-S";
  30. const char OPT_PARAM_STR[] = "-P";
  31. /* Our state */
  32. static char **argv;
  33. static int argc;
  34. static int opt_index;
  35. static char *arg;
  36. static char *flag;
  37. static char *dunno;
  38. static const OPTIONS *unknown;
  39. static const OPTIONS *opts;
  40. static char prog[40];
  41. /*
  42. * Return the simple name of the program; removing various platform gunk.
  43. */
  44. #if defined(OPENSSL_SYS_WIN32)
  45. const char *opt_path_end(const char *filename)
  46. {
  47. const char *p;
  48. /* find the last '/', '\' or ':' */
  49. for (p = filename + strlen(filename); --p > filename; )
  50. if (*p == '/' || *p == '\\' || *p == ':') {
  51. p++;
  52. break;
  53. }
  54. return p;
  55. }
  56. char *opt_progname(const char *argv0)
  57. {
  58. size_t i, n;
  59. const char *p;
  60. char *q;
  61. p = opt_path_end(argv0);
  62. /* Strip off trailing nonsense. */
  63. n = strlen(p);
  64. if (n > 4 &&
  65. (strcmp(&p[n - 4], ".exe") == 0 || strcmp(&p[n - 4], ".EXE") == 0))
  66. n -= 4;
  67. /* Copy over the name, in lowercase. */
  68. if (n > sizeof(prog) - 1)
  69. n = sizeof(prog) - 1;
  70. for (q = prog, i = 0; i < n; i++, p++)
  71. *q++ = tolower((unsigned char)*p);
  72. *q = '\0';
  73. return prog;
  74. }
  75. #elif defined(OPENSSL_SYS_VMS)
  76. const char *opt_path_end(const char *filename)
  77. {
  78. const char *p;
  79. /* Find last special character sys:[foo.bar]openssl */
  80. for (p = filename + strlen(filename); --p > filename;)
  81. if (*p == ':' || *p == ']' || *p == '>') {
  82. p++;
  83. break;
  84. }
  85. return p;
  86. }
  87. char *opt_progname(const char *argv0)
  88. {
  89. const char *p, *q;
  90. /* Find last special character sys:[foo.bar]openssl */
  91. p = opt_path_end(argv0);
  92. q = strrchr(p, '.');
  93. if (prog != p)
  94. strncpy(prog, p, sizeof(prog) - 1);
  95. prog[sizeof(prog) - 1] = '\0';
  96. if (q != NULL && q - p < sizeof(prog))
  97. prog[q - p] = '\0';
  98. return prog;
  99. }
  100. #else
  101. const char *opt_path_end(const char *filename)
  102. {
  103. const char *p;
  104. /* Could use strchr, but this is like the ones above. */
  105. for (p = filename + strlen(filename); --p > filename;)
  106. if (*p == '/') {
  107. p++;
  108. break;
  109. }
  110. return p;
  111. }
  112. char *opt_progname(const char *argv0)
  113. {
  114. const char *p;
  115. p = opt_path_end(argv0);
  116. if (prog != p)
  117. strncpy(prog, p, sizeof(prog) - 1);
  118. prog[sizeof(prog) - 1] = '\0';
  119. return prog;
  120. }
  121. #endif
  122. char *opt_appname(const char *argv0)
  123. {
  124. size_t len = strlen(prog);
  125. if (argv0 != NULL)
  126. BIO_snprintf(prog + len, sizeof(prog) - len - 1, " %s", argv0);
  127. return prog;
  128. }
  129. char *opt_getprog(void)
  130. {
  131. return prog;
  132. }
  133. /* Set up the arg parsing. */
  134. char *opt_init(int ac, char **av, const OPTIONS *o)
  135. {
  136. /* Store state. */
  137. argc = ac;
  138. argv = av;
  139. opt_begin();
  140. opts = o;
  141. unknown = NULL;
  142. /* Make sure prog name is set for usage output */
  143. (void)opt_progname(argv[0]);
  144. /* Check all options up until the PARAM marker (if present) */
  145. for (; o->name != NULL && o->name != OPT_PARAM_STR; ++o) {
  146. #ifndef NDEBUG
  147. const OPTIONS *next;
  148. int duplicated, i;
  149. #endif
  150. if (o->name == OPT_HELP_STR
  151. || o->name == OPT_MORE_STR
  152. || o->name == OPT_SECTION_STR)
  153. continue;
  154. #ifndef NDEBUG
  155. i = o->valtype;
  156. /* Make sure options are legit. */
  157. OPENSSL_assert(o->name[0] != '-');
  158. if (o->valtype == '.')
  159. OPENSSL_assert(o->retval == OPT_PARAM);
  160. else
  161. OPENSSL_assert(o->retval == OPT_DUP || o->retval > OPT_PARAM);
  162. switch (i) {
  163. case 0: case '-': case '.':
  164. case '/': case '<': case '>': case 'E': case 'F':
  165. case 'M': case 'U': case 'f': case 'l': case 'n': case 'p': case 's':
  166. case 'u': case 'c': case ':': case 'N':
  167. break;
  168. default:
  169. OPENSSL_assert(0);
  170. }
  171. /* Make sure there are no duplicates. */
  172. for (next = o + 1; next->name; ++next) {
  173. /*
  174. * Some compilers inline strcmp and the assert string is too long.
  175. */
  176. duplicated = next->retval != OPT_DUP
  177. && strcmp(o->name, next->name) == 0;
  178. if (duplicated) {
  179. opt_printf_stderr("%s: Internal error: duplicate option %s\n",
  180. prog, o->name);
  181. OPENSSL_assert(!duplicated);
  182. }
  183. }
  184. #endif
  185. if (o->name[0] == '\0') {
  186. OPENSSL_assert(unknown == NULL);
  187. unknown = o;
  188. OPENSSL_assert(unknown->valtype == 0 || unknown->valtype == '-');
  189. }
  190. }
  191. return prog;
  192. }
  193. static OPT_PAIR formats[] = {
  194. {"PEM/DER", OPT_FMT_PEMDER},
  195. {"pkcs12", OPT_FMT_PKCS12},
  196. {"smime", OPT_FMT_SMIME},
  197. {"engine", OPT_FMT_ENGINE},
  198. {"msblob", OPT_FMT_MSBLOB},
  199. {"nss", OPT_FMT_NSS},
  200. {"text", OPT_FMT_TEXT},
  201. {"http", OPT_FMT_HTTP},
  202. {"pvk", OPT_FMT_PVK},
  203. {NULL}
  204. };
  205. /* Print an error message about a failed format parse. */
  206. static int opt_format_error(const char *s, unsigned long flags)
  207. {
  208. OPT_PAIR *ap;
  209. if (flags == OPT_FMT_PEMDER) {
  210. opt_printf_stderr("%s: Bad format \"%s\"; must be pem or der\n",
  211. prog, s);
  212. } else {
  213. opt_printf_stderr("%s: Bad format \"%s\"; must be one of:\n",
  214. prog, s);
  215. for (ap = formats; ap->name; ap++)
  216. if (flags & ap->retval)
  217. opt_printf_stderr(" %s\n", ap->name);
  218. }
  219. return 0;
  220. }
  221. /* Parse a format string, put it into *result; return 0 on failure, else 1. */
  222. int opt_format(const char *s, unsigned long flags, int *result)
  223. {
  224. switch (*s) {
  225. default:
  226. opt_printf_stderr("%s: Bad format \"%s\"\n", prog, s);
  227. return 0;
  228. case 'D':
  229. case 'd':
  230. if ((flags & OPT_FMT_PEMDER) == 0)
  231. return opt_format_error(s, flags);
  232. *result = FORMAT_ASN1;
  233. break;
  234. case 'T':
  235. case 't':
  236. if ((flags & OPT_FMT_TEXT) == 0)
  237. return opt_format_error(s, flags);
  238. *result = FORMAT_TEXT;
  239. break;
  240. case 'N':
  241. case 'n':
  242. if ((flags & OPT_FMT_NSS) == 0)
  243. return opt_format_error(s, flags);
  244. if (strcmp(s, "NSS") != 0 && strcmp(s, "nss") != 0)
  245. return opt_format_error(s, flags);
  246. *result = FORMAT_NSS;
  247. break;
  248. case 'S':
  249. case 's':
  250. if ((flags & OPT_FMT_SMIME) == 0)
  251. return opt_format_error(s, flags);
  252. *result = FORMAT_SMIME;
  253. break;
  254. case 'M':
  255. case 'm':
  256. if ((flags & OPT_FMT_MSBLOB) == 0)
  257. return opt_format_error(s, flags);
  258. *result = FORMAT_MSBLOB;
  259. break;
  260. case 'E':
  261. case 'e':
  262. if ((flags & OPT_FMT_ENGINE) == 0)
  263. return opt_format_error(s, flags);
  264. *result = FORMAT_ENGINE;
  265. break;
  266. case 'H':
  267. case 'h':
  268. if ((flags & OPT_FMT_HTTP) == 0)
  269. return opt_format_error(s, flags);
  270. *result = FORMAT_HTTP;
  271. break;
  272. case '1':
  273. if ((flags & OPT_FMT_PKCS12) == 0)
  274. return opt_format_error(s, flags);
  275. *result = FORMAT_PKCS12;
  276. break;
  277. case 'P':
  278. case 'p':
  279. if (s[1] == '\0' || strcmp(s, "PEM") == 0 || strcmp(s, "pem") == 0) {
  280. if ((flags & OPT_FMT_PEMDER) == 0)
  281. return opt_format_error(s, flags);
  282. *result = FORMAT_PEM;
  283. } else if (strcmp(s, "PVK") == 0 || strcmp(s, "pvk") == 0) {
  284. if ((flags & OPT_FMT_PVK) == 0)
  285. return opt_format_error(s, flags);
  286. *result = FORMAT_PVK;
  287. } else if (strcmp(s, "P12") == 0 || strcmp(s, "p12") == 0
  288. || strcmp(s, "PKCS12") == 0 || strcmp(s, "pkcs12") == 0) {
  289. if ((flags & OPT_FMT_PKCS12) == 0)
  290. return opt_format_error(s, flags);
  291. *result = FORMAT_PKCS12;
  292. } else {
  293. opt_printf_stderr("%s: Bad format \"%s\"\n", prog, s);
  294. return 0;
  295. }
  296. break;
  297. }
  298. return 1;
  299. }
  300. /* Return string representing the given format. */
  301. static const char *format2str(int format)
  302. {
  303. switch (format) {
  304. default:
  305. return "(undefined)";
  306. case FORMAT_PEM:
  307. return "PEM";
  308. case FORMAT_ASN1:
  309. return "DER";
  310. case FORMAT_TEXT:
  311. return "TEXT";
  312. case FORMAT_NSS:
  313. return "NSS";
  314. case FORMAT_SMIME:
  315. return "SMIME";
  316. case FORMAT_MSBLOB:
  317. return "MSBLOB";
  318. case FORMAT_ENGINE:
  319. return "ENGINE";
  320. case FORMAT_HTTP:
  321. return "HTTP";
  322. case FORMAT_PKCS12:
  323. return "P12";
  324. case FORMAT_PVK:
  325. return "PVK";
  326. }
  327. }
  328. /* Print an error message about unsuitable/unsupported format requested. */
  329. void print_format_error(int format, unsigned long flags)
  330. {
  331. (void)opt_format_error(format2str(format), flags);
  332. }
  333. /* Parse a cipher name, put it in *EVP_CIPHER; return 0 on failure, else 1. */
  334. int opt_cipher_silent(const char *name, EVP_CIPHER **cipherp)
  335. {
  336. EVP_CIPHER_free(*cipherp);
  337. ERR_set_mark();
  338. if ((*cipherp = EVP_CIPHER_fetch(NULL, name, NULL)) != NULL
  339. || (*cipherp = (EVP_CIPHER *)EVP_get_cipherbyname(name)) != NULL) {
  340. ERR_pop_to_mark();
  341. return 1;
  342. }
  343. ERR_clear_last_mark();
  344. return 0;
  345. }
  346. int opt_cipher(const char *name, EVP_CIPHER **cipherp)
  347. {
  348. int ret;
  349. if ((ret = opt_cipher_silent(name, cipherp)) == 0)
  350. opt_printf_stderr("%s: Unknown cipher: %s\n", prog, name);
  351. return ret;
  352. }
  353. /*
  354. * Parse message digest name, put it in *EVP_MD; return 0 on failure, else 1.
  355. */
  356. int opt_md_silent(const char *name, EVP_MD **mdp)
  357. {
  358. EVP_MD_free(*mdp);
  359. ERR_set_mark();
  360. if ((*mdp = EVP_MD_fetch(NULL, name, NULL)) != NULL
  361. || (*mdp = (EVP_MD *)EVP_get_digestbyname(name)) != NULL) {
  362. ERR_pop_to_mark();
  363. return 1;
  364. }
  365. ERR_clear_last_mark();
  366. return 0;
  367. }
  368. int opt_md(const char *name, EVP_MD **mdp)
  369. {
  370. int ret;
  371. if ((ret = opt_md_silent(name, mdp)) == 0)
  372. opt_printf_stderr("%s: Unknown option or message digest: %s\n", prog,
  373. name != NULL ? name : "\"\"");
  374. return ret;
  375. }
  376. /* Look through a list of name/value pairs. */
  377. int opt_pair(const char *name, const OPT_PAIR* pairs, int *result)
  378. {
  379. const OPT_PAIR *pp;
  380. for (pp = pairs; pp->name; pp++)
  381. if (strcmp(pp->name, name) == 0) {
  382. *result = pp->retval;
  383. return 1;
  384. }
  385. opt_printf_stderr("%s: Value must be one of:\n", prog);
  386. for (pp = pairs; pp->name; pp++)
  387. opt_printf_stderr("\t%s\n", pp->name);
  388. return 0;
  389. }
  390. /* Look through a list of valid names */
  391. int opt_string(const char *name, const char **options)
  392. {
  393. const char **p;
  394. for (p = options; *p != NULL; p++)
  395. if (strcmp(*p, name) == 0)
  396. return 1;
  397. opt_printf_stderr("%s: Value must be one of:\n", prog);
  398. for (p = options; *p != NULL; p++)
  399. opt_printf_stderr("\t%s\n", *p);
  400. return 0;
  401. }
  402. /* Parse an int, put it into *result; return 0 on failure, else 1. */
  403. int opt_int(const char *value, int *result)
  404. {
  405. long l;
  406. if (!opt_long(value, &l))
  407. return 0;
  408. *result = (int)l;
  409. if (*result != l) {
  410. opt_printf_stderr("%s: Value \"%s\" outside integer range\n",
  411. prog, value);
  412. return 0;
  413. }
  414. return 1;
  415. }
  416. /* Parse and return an integer, assuming range has been checked before. */
  417. int opt_int_arg(void)
  418. {
  419. int result = -1;
  420. (void)opt_int(arg, &result);
  421. return result;
  422. }
  423. static void opt_number_error(const char *v)
  424. {
  425. size_t i = 0;
  426. struct strstr_pair_st {
  427. char *prefix;
  428. char *name;
  429. } b[] = {
  430. {"0x", "a hexadecimal"},
  431. {"0X", "a hexadecimal"},
  432. {"0", "an octal"}
  433. };
  434. for (i = 0; i < OSSL_NELEM(b); i++) {
  435. if (strncmp(v, b[i].prefix, strlen(b[i].prefix)) == 0) {
  436. opt_printf_stderr("%s: Can't parse \"%s\" as %s number\n",
  437. prog, v, b[i].name);
  438. return;
  439. }
  440. }
  441. opt_printf_stderr("%s: Can't parse \"%s\" as a number\n", prog, v);
  442. return;
  443. }
  444. /* Parse a long, put it into *result; return 0 on failure, else 1. */
  445. int opt_long(const char *value, long *result)
  446. {
  447. int oerrno = errno;
  448. long l;
  449. char *endp;
  450. errno = 0;
  451. l = strtol(value, &endp, 0);
  452. if (*endp
  453. || endp == value
  454. || ((l == LONG_MAX || l == LONG_MIN) && errno == ERANGE)
  455. || (l == 0 && errno != 0)) {
  456. opt_number_error(value);
  457. errno = oerrno;
  458. return 0;
  459. }
  460. *result = l;
  461. errno = oerrno;
  462. return 1;
  463. }
  464. #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && \
  465. defined(INTMAX_MAX) && defined(UINTMAX_MAX) && \
  466. !defined(OPENSSL_NO_INTTYPES_H)
  467. /* Parse an intmax_t, put it into *result; return 0 on failure, else 1. */
  468. int opt_intmax(const char *value, intmax_t *result)
  469. {
  470. int oerrno = errno;
  471. intmax_t m;
  472. char *endp;
  473. errno = 0;
  474. m = strtoimax(value, &endp, 0);
  475. if (*endp
  476. || endp == value
  477. || ((m == INTMAX_MAX || m == INTMAX_MIN) && errno == ERANGE)
  478. || (m == 0 && errno != 0)) {
  479. opt_number_error(value);
  480. errno = oerrno;
  481. return 0;
  482. }
  483. *result = m;
  484. errno = oerrno;
  485. return 1;
  486. }
  487. /* Parse a uintmax_t, put it into *result; return 0 on failure, else 1. */
  488. int opt_uintmax(const char *value, uintmax_t *result)
  489. {
  490. int oerrno = errno;
  491. uintmax_t m;
  492. char *endp;
  493. errno = 0;
  494. m = strtoumax(value, &endp, 0);
  495. if (*endp
  496. || endp == value
  497. || (m == UINTMAX_MAX && errno == ERANGE)
  498. || (m == 0 && errno != 0)) {
  499. opt_number_error(value);
  500. errno = oerrno;
  501. return 0;
  502. }
  503. *result = m;
  504. errno = oerrno;
  505. return 1;
  506. }
  507. #endif
  508. /*
  509. * Parse an unsigned long, put it into *result; return 0 on failure, else 1.
  510. */
  511. int opt_ulong(const char *value, unsigned long *result)
  512. {
  513. int oerrno = errno;
  514. char *endptr;
  515. unsigned long l;
  516. errno = 0;
  517. l = strtoul(value, &endptr, 0);
  518. if (*endptr
  519. || endptr == value
  520. || ((l == ULONG_MAX) && errno == ERANGE)
  521. || (l == 0 && errno != 0)) {
  522. opt_number_error(value);
  523. errno = oerrno;
  524. return 0;
  525. }
  526. *result = l;
  527. errno = oerrno;
  528. return 1;
  529. }
  530. /*
  531. * We pass opt as an int but cast it to "enum range" so that all the
  532. * items in the OPT_V_ENUM enumeration are caught; this makes -Wswitch
  533. * in gcc do the right thing.
  534. */
  535. enum range { OPT_V_ENUM };
  536. int opt_verify(int opt, X509_VERIFY_PARAM *vpm)
  537. {
  538. int i;
  539. ossl_intmax_t t = 0;
  540. ASN1_OBJECT *otmp;
  541. X509_PURPOSE *xptmp;
  542. const X509_VERIFY_PARAM *vtmp;
  543. OPENSSL_assert(vpm != NULL);
  544. OPENSSL_assert(opt > OPT_V__FIRST);
  545. OPENSSL_assert(opt < OPT_V__LAST);
  546. switch ((enum range)opt) {
  547. case OPT_V__FIRST:
  548. case OPT_V__LAST:
  549. return 0;
  550. case OPT_V_POLICY:
  551. otmp = OBJ_txt2obj(opt_arg(), 0);
  552. if (otmp == NULL) {
  553. opt_printf_stderr("%s: Invalid Policy %s\n", prog, opt_arg());
  554. return 0;
  555. }
  556. X509_VERIFY_PARAM_add0_policy(vpm, otmp);
  557. break;
  558. case OPT_V_PURPOSE:
  559. /* purpose name -> purpose index */
  560. i = X509_PURPOSE_get_by_sname(opt_arg());
  561. if (i < 0) {
  562. opt_printf_stderr("%s: Invalid purpose %s\n", prog, opt_arg());
  563. return 0;
  564. }
  565. /* purpose index -> purpose object */
  566. xptmp = X509_PURPOSE_get0(i);
  567. /* purpose object -> purpose value */
  568. i = X509_PURPOSE_get_id(xptmp);
  569. if (!X509_VERIFY_PARAM_set_purpose(vpm, i)) {
  570. opt_printf_stderr("%s: Internal error setting purpose %s\n",
  571. prog, opt_arg());
  572. return 0;
  573. }
  574. break;
  575. case OPT_V_VERIFY_NAME:
  576. vtmp = X509_VERIFY_PARAM_lookup(opt_arg());
  577. if (vtmp == NULL) {
  578. opt_printf_stderr("%s: Invalid verify name %s\n",
  579. prog, opt_arg());
  580. return 0;
  581. }
  582. X509_VERIFY_PARAM_set1(vpm, vtmp);
  583. break;
  584. case OPT_V_VERIFY_DEPTH:
  585. i = atoi(opt_arg());
  586. if (i >= 0)
  587. X509_VERIFY_PARAM_set_depth(vpm, i);
  588. break;
  589. case OPT_V_VERIFY_AUTH_LEVEL:
  590. i = atoi(opt_arg());
  591. if (i >= 0)
  592. X509_VERIFY_PARAM_set_auth_level(vpm, i);
  593. break;
  594. case OPT_V_ATTIME:
  595. if (!opt_intmax(opt_arg(), &t))
  596. return 0;
  597. if (t != (time_t)t) {
  598. opt_printf_stderr("%s: epoch time out of range %s\n",
  599. prog, opt_arg());
  600. return 0;
  601. }
  602. X509_VERIFY_PARAM_set_time(vpm, (time_t)t);
  603. break;
  604. case OPT_V_VERIFY_HOSTNAME:
  605. if (!X509_VERIFY_PARAM_set1_host(vpm, opt_arg(), 0))
  606. return 0;
  607. break;
  608. case OPT_V_VERIFY_EMAIL:
  609. if (!X509_VERIFY_PARAM_set1_email(vpm, opt_arg(), 0))
  610. return 0;
  611. break;
  612. case OPT_V_VERIFY_IP:
  613. if (!X509_VERIFY_PARAM_set1_ip_asc(vpm, opt_arg()))
  614. return 0;
  615. break;
  616. case OPT_V_IGNORE_CRITICAL:
  617. X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_IGNORE_CRITICAL);
  618. break;
  619. case OPT_V_ISSUER_CHECKS:
  620. /* NOP, deprecated */
  621. break;
  622. case OPT_V_CRL_CHECK:
  623. X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CRL_CHECK);
  624. break;
  625. case OPT_V_CRL_CHECK_ALL:
  626. X509_VERIFY_PARAM_set_flags(vpm,
  627. X509_V_FLAG_CRL_CHECK |
  628. X509_V_FLAG_CRL_CHECK_ALL);
  629. break;
  630. case OPT_V_POLICY_CHECK:
  631. X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_POLICY_CHECK);
  632. break;
  633. case OPT_V_EXPLICIT_POLICY:
  634. X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_EXPLICIT_POLICY);
  635. break;
  636. case OPT_V_INHIBIT_ANY:
  637. X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_INHIBIT_ANY);
  638. break;
  639. case OPT_V_INHIBIT_MAP:
  640. X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_INHIBIT_MAP);
  641. break;
  642. case OPT_V_X509_STRICT:
  643. X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_X509_STRICT);
  644. break;
  645. case OPT_V_EXTENDED_CRL:
  646. X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_EXTENDED_CRL_SUPPORT);
  647. break;
  648. case OPT_V_USE_DELTAS:
  649. X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_USE_DELTAS);
  650. break;
  651. case OPT_V_POLICY_PRINT:
  652. X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NOTIFY_POLICY);
  653. break;
  654. case OPT_V_CHECK_SS_SIG:
  655. X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CHECK_SS_SIGNATURE);
  656. break;
  657. case OPT_V_TRUSTED_FIRST:
  658. X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_TRUSTED_FIRST);
  659. break;
  660. case OPT_V_SUITEB_128_ONLY:
  661. X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_128_LOS_ONLY);
  662. break;
  663. case OPT_V_SUITEB_128:
  664. X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_128_LOS);
  665. break;
  666. case OPT_V_SUITEB_192:
  667. X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_192_LOS);
  668. break;
  669. case OPT_V_PARTIAL_CHAIN:
  670. X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_PARTIAL_CHAIN);
  671. break;
  672. case OPT_V_NO_ALT_CHAINS:
  673. X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NO_ALT_CHAINS);
  674. break;
  675. case OPT_V_NO_CHECK_TIME:
  676. X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NO_CHECK_TIME);
  677. break;
  678. case OPT_V_ALLOW_PROXY_CERTS:
  679. X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_ALLOW_PROXY_CERTS);
  680. break;
  681. }
  682. return 1;
  683. }
  684. void opt_begin(void)
  685. {
  686. opt_index = 1;
  687. arg = NULL;
  688. flag = NULL;
  689. }
  690. /*
  691. * Parse the next flag (and value if specified), return 0 if done, -1 on
  692. * error, otherwise the flag's retval.
  693. */
  694. int opt_next(void)
  695. {
  696. char *p;
  697. const OPTIONS *o;
  698. int ival;
  699. long lval;
  700. unsigned long ulval;
  701. ossl_intmax_t imval;
  702. ossl_uintmax_t umval;
  703. /* Look at current arg; at end of the list? */
  704. arg = NULL;
  705. p = argv[opt_index];
  706. if (p == NULL)
  707. return 0;
  708. /* If word doesn't start with a -, we're done. */
  709. if (*p != '-')
  710. return 0;
  711. /* Hit "--" ? We're done. */
  712. opt_index++;
  713. if (strcmp(p, "--") == 0)
  714. return 0;
  715. /* Allow -nnn and --nnn */
  716. if (*++p == '-')
  717. p++;
  718. flag = p - 1;
  719. /* If we have --flag=foo, snip it off */
  720. if ((arg = strchr(p, '=')) != NULL)
  721. *arg++ = '\0';
  722. for (o = opts; o->name; ++o) {
  723. /* If not this option, move on to the next one. */
  724. if (!(strcmp(p, "h") == 0 && strcmp(o->name, "help") == 0)
  725. && strcmp(p, o->name) != 0)
  726. continue;
  727. /* If it doesn't take a value, make sure none was given. */
  728. if (o->valtype == 0 || o->valtype == '-') {
  729. if (arg) {
  730. opt_printf_stderr("%s: Option -%s does not take a value\n",
  731. prog, p);
  732. return -1;
  733. }
  734. return o->retval;
  735. }
  736. /* Want a value; get the next param if =foo not used. */
  737. if (arg == NULL) {
  738. if (argv[opt_index] == NULL) {
  739. opt_printf_stderr("%s: Option -%s needs a value\n",
  740. prog, o->name);
  741. return -1;
  742. }
  743. arg = argv[opt_index++];
  744. }
  745. /* Syntax-check value. */
  746. switch (o->valtype) {
  747. default:
  748. case 's':
  749. case ':':
  750. /* Just a string. */
  751. break;
  752. case '.':
  753. /* Parameters */
  754. break;
  755. case '/':
  756. if (opt_isdir(arg) > 0)
  757. break;
  758. opt_printf_stderr("%s: Not a directory: %s\n", prog, arg);
  759. return -1;
  760. case '<':
  761. /* Input file. */
  762. break;
  763. case '>':
  764. /* Output file. */
  765. break;
  766. case 'p':
  767. case 'n':
  768. case 'N':
  769. if (!opt_int(arg, &ival))
  770. return -1;
  771. if (o->valtype == 'p' && ival <= 0) {
  772. opt_printf_stderr("%s: Non-positive number \"%s\" for option -%s\n",
  773. prog, arg, o->name);
  774. return -1;
  775. }
  776. if (o->valtype == 'N' && ival < 0) {
  777. opt_printf_stderr("%s: Negative number \"%s\" for option -%s\n",
  778. prog, arg, o->name);
  779. return -1;
  780. }
  781. break;
  782. case 'M':
  783. if (!opt_intmax(arg, &imval))
  784. return -1;
  785. break;
  786. case 'U':
  787. if (!opt_uintmax(arg, &umval))
  788. return -1;
  789. break;
  790. case 'l':
  791. if (!opt_long(arg, &lval))
  792. return -1;
  793. break;
  794. case 'u':
  795. if (!opt_ulong(arg, &ulval))
  796. return -1;
  797. break;
  798. case 'c':
  799. case 'E':
  800. case 'F':
  801. case 'f':
  802. if (opt_format(arg,
  803. o->valtype == 'c' ? OPT_FMT_PDS :
  804. o->valtype == 'E' ? OPT_FMT_PDE :
  805. o->valtype == 'F' ? OPT_FMT_PEMDER
  806. : OPT_FMT_ANY, &ival))
  807. break;
  808. opt_printf_stderr("%s: Invalid format \"%s\" for option -%s\n",
  809. prog, arg, o->name);
  810. return -1;
  811. }
  812. /* Return the flag value. */
  813. return o->retval;
  814. }
  815. if (unknown != NULL) {
  816. dunno = p;
  817. return unknown->retval;
  818. }
  819. opt_printf_stderr("%s: Unknown option: -%s\n", prog, p);
  820. return -1;
  821. }
  822. /* Return the most recent flag parameter. */
  823. char *opt_arg(void)
  824. {
  825. return arg;
  826. }
  827. /* Return the most recent flag (option name including the preceding '-'). */
  828. char *opt_flag(void)
  829. {
  830. return flag;
  831. }
  832. /* Return the unknown option. */
  833. char *opt_unknown(void)
  834. {
  835. return dunno;
  836. }
  837. /* Return the rest of the arguments after parsing flags. */
  838. char **opt_rest(void)
  839. {
  840. return &argv[opt_index];
  841. }
  842. /* How many items in remaining args? */
  843. int opt_num_rest(void)
  844. {
  845. int i = 0;
  846. char **pp;
  847. for (pp = opt_rest(); *pp; pp++, i++)
  848. continue;
  849. return i;
  850. }
  851. /* Return a string describing the parameter type. */
  852. static const char *valtype2param(const OPTIONS *o)
  853. {
  854. switch (o->valtype) {
  855. case 0:
  856. case '-':
  857. return "";
  858. case ':':
  859. return "uri";
  860. case 's':
  861. return "val";
  862. case '/':
  863. return "dir";
  864. case '<':
  865. return "infile";
  866. case '>':
  867. return "outfile";
  868. case 'p':
  869. return "+int";
  870. case 'n':
  871. return "int";
  872. case 'l':
  873. return "long";
  874. case 'u':
  875. return "ulong";
  876. case 'E':
  877. return "PEM|DER|ENGINE";
  878. case 'F':
  879. return "PEM|DER";
  880. case 'f':
  881. return "format";
  882. case 'M':
  883. return "intmax";
  884. case 'N':
  885. return "nonneg";
  886. case 'U':
  887. return "uintmax";
  888. }
  889. return "parm";
  890. }
  891. static void opt_print(const OPTIONS *o, int doingparams, int width)
  892. {
  893. const char* help;
  894. char start[80 + 1];
  895. char *p;
  896. help = o->helpstr ? o->helpstr : "(No additional info)";
  897. if (o->name == OPT_HELP_STR) {
  898. opt_printf_stderr(help, prog);
  899. return;
  900. }
  901. if (o->name == OPT_SECTION_STR) {
  902. opt_printf_stderr("\n");
  903. opt_printf_stderr(help, prog);
  904. return;
  905. }
  906. if (o->name == OPT_PARAM_STR) {
  907. opt_printf_stderr("\nParameters:\n");
  908. return;
  909. }
  910. /* Pad out prefix */
  911. memset(start, ' ', sizeof(start) - 1);
  912. start[sizeof(start) - 1] = '\0';
  913. if (o->name == OPT_MORE_STR) {
  914. /* Continuation of previous line; pad and print. */
  915. start[width] = '\0';
  916. opt_printf_stderr("%s %s\n", start, help);
  917. return;
  918. }
  919. /* Build up the "-flag [param]" part. */
  920. p = start;
  921. *p++ = ' ';
  922. if (!doingparams)
  923. *p++ = '-';
  924. if (o->name[0])
  925. p += strlen(strcpy(p, o->name));
  926. else
  927. *p++ = '*';
  928. if (o->valtype != '-') {
  929. *p++ = ' ';
  930. p += strlen(strcpy(p, valtype2param(o)));
  931. }
  932. *p = ' ';
  933. if ((int)(p - start) >= MAX_OPT_HELP_WIDTH) {
  934. *p = '\0';
  935. opt_printf_stderr("%s\n", start);
  936. memset(start, ' ', sizeof(start));
  937. }
  938. start[width] = '\0';
  939. opt_printf_stderr("%s %s\n", start, help);
  940. }
  941. void opt_help(const OPTIONS *list)
  942. {
  943. const OPTIONS *o;
  944. int i, sawparams = 0, width = 5;
  945. int standard_prolog;
  946. char start[80 + 1];
  947. /* Starts with its own help message? */
  948. standard_prolog = list[0].name != OPT_HELP_STR;
  949. /* Find the widest help. */
  950. for (o = list; o->name; o++) {
  951. if (o->name == OPT_MORE_STR)
  952. continue;
  953. i = 2 + (int)strlen(o->name);
  954. if (o->valtype != '-')
  955. i += 1 + strlen(valtype2param(o));
  956. if (i < MAX_OPT_HELP_WIDTH && i > width)
  957. width = i;
  958. OPENSSL_assert(i < (int)sizeof(start));
  959. }
  960. if (standard_prolog) {
  961. opt_printf_stderr("Usage: %s [options]\n", prog);
  962. if (list[0].name != OPT_SECTION_STR)
  963. opt_printf_stderr("Valid options are:\n", prog);
  964. }
  965. /* Now let's print. */
  966. for (o = list; o->name; o++) {
  967. if (o->name == OPT_PARAM_STR)
  968. sawparams = 1;
  969. opt_print(o, sawparams, width);
  970. }
  971. }
  972. /* opt_isdir section */
  973. #ifdef _WIN32
  974. # include <windows.h>
  975. int opt_isdir(const char *name)
  976. {
  977. DWORD attr;
  978. # if defined(UNICODE) || defined(_UNICODE)
  979. size_t i, len_0 = strlen(name) + 1;
  980. WCHAR tempname[MAX_PATH];
  981. if (len_0 > MAX_PATH)
  982. return -1;
  983. # if !defined(_WIN32_WCE) || _WIN32_WCE>=101
  984. if (!MultiByteToWideChar(CP_ACP, 0, name, len_0, tempname, MAX_PATH))
  985. # endif
  986. for (i = 0; i < len_0; i++)
  987. tempname[i] = (WCHAR)name[i];
  988. attr = GetFileAttributes(tempname);
  989. # else
  990. attr = GetFileAttributes(name);
  991. # endif
  992. if (attr == INVALID_FILE_ATTRIBUTES)
  993. return -1;
  994. return ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0);
  995. }
  996. #else
  997. # include <sys/stat.h>
  998. # ifndef S_ISDIR
  999. # if defined(_S_IFMT) && defined(_S_IFDIR)
  1000. # define S_ISDIR(a) (((a) & _S_IFMT) == _S_IFDIR)
  1001. # else
  1002. # define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR)
  1003. # endif
  1004. # endif
  1005. int opt_isdir(const char *name)
  1006. {
  1007. # if defined(S_ISDIR)
  1008. struct stat st;
  1009. if (stat(name, &st) == 0)
  1010. return S_ISDIR(st.st_mode);
  1011. else
  1012. return -1;
  1013. # else
  1014. return -1;
  1015. # endif
  1016. }
  1017. #endif