2
0

opt.c 33 KB

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