opt.c 25 KB

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