2
0

opt.c 25 KB

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