opt.c 31 KB

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