opt.c 27 KB

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