2
0

ssl_conf.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691
  1. /*
  2. * ! \file ssl/ssl_conf.c \brief SSL configuration functions
  3. */
  4. /* ====================================================================
  5. * Copyright (c) 2012 The OpenSSL Project. All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. *
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in
  16. * the documentation and/or other materials provided with the
  17. * distribution.
  18. *
  19. * 3. All advertising materials mentioning features or use of this
  20. * software must display the following acknowledgment:
  21. * "This product includes software developed by the OpenSSL Project
  22. * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
  23. *
  24. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  25. * endorse or promote products derived from this software without
  26. * prior written permission. For written permission, please contact
  27. * openssl-core@openssl.org.
  28. *
  29. * 5. Products derived from this software may not be called "OpenSSL"
  30. * nor may "OpenSSL" appear in their names without prior written
  31. * permission of the OpenSSL Project.
  32. *
  33. * 6. Redistributions of any form whatsoever must retain the following
  34. * acknowledgment:
  35. * "This product includes software developed by the OpenSSL Project
  36. * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
  37. *
  38. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  39. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  40. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  41. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  42. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  43. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  44. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  45. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  46. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  47. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  48. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  49. * OF THE POSSIBILITY OF SUCH DAMAGE.
  50. * ====================================================================
  51. *
  52. * This product includes cryptographic software written by Eric Young
  53. * (eay@cryptsoft.com). This product includes software written by Tim
  54. * Hudson (tjh@cryptsoft.com).
  55. *
  56. */
  57. #ifdef REF_CHECK
  58. # include <assert.h>
  59. #endif
  60. #include <stdio.h>
  61. #include "ssl_locl.h"
  62. #include <openssl/conf.h>
  63. #include <openssl/objects.h>
  64. #ifndef OPENSSL_NO_DH
  65. # include <openssl/dh.h>
  66. #endif
  67. /*
  68. * structure holding name tables. This is used for pemitted elements in lists
  69. * such as TLSv1 and single command line switches such as no_tls1
  70. */
  71. typedef struct {
  72. const char *name;
  73. int namelen;
  74. unsigned int name_flags;
  75. unsigned long option_value;
  76. } ssl_flag_tbl;
  77. /* Sense of name is inverted e.g. "TLSv1" will clear SSL_OP_NO_TLSv1 */
  78. #define SSL_TFLAG_INV 0x1
  79. /* Flags refers to cert_flags not options */
  80. #define SSL_TFLAG_CERT 0x2
  81. /* Option can only be used for clients */
  82. #define SSL_TFLAG_CLIENT SSL_CONF_FLAG_CLIENT
  83. /* Option can only be used for servers */
  84. #define SSL_TFLAG_SERVER SSL_CONF_FLAG_SERVER
  85. #define SSL_TFLAG_BOTH (SSL_TFLAG_CLIENT|SSL_TFLAG_SERVER)
  86. #define SSL_FLAG_TBL(str, flag) \
  87. {str, (int)(sizeof(str) - 1), SSL_TFLAG_BOTH, flag}
  88. #define SSL_FLAG_TBL_SRV(str, flag) \
  89. {str, (int)(sizeof(str) - 1), SSL_TFLAG_SERVER, flag}
  90. #define SSL_FLAG_TBL_CLI(str, flag) \
  91. {str, (int)(sizeof(str) - 1), SSL_TFLAG_CLIENT, flag}
  92. #define SSL_FLAG_TBL_INV(str, flag) \
  93. {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_BOTH, flag}
  94. #define SSL_FLAG_TBL_SRV_INV(str, flag) \
  95. {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_SERVER, flag}
  96. #define SSL_FLAG_TBL_CERT(str, flag) \
  97. {str, (int)(sizeof(str) - 1), SSL_TFLAG_CERT|SSL_TFLAG_BOTH, flag}
  98. /*
  99. * Opaque structure containing SSL configuration context.
  100. */
  101. struct ssl_conf_ctx_st {
  102. /*
  103. * Various flags indicating (among other things) which options we will
  104. * recognise.
  105. */
  106. unsigned int flags;
  107. /* Prefix and length of commands */
  108. char *prefix;
  109. size_t prefixlen;
  110. /* SSL_CTX or SSL structure to perform operations on */
  111. SSL_CTX *ctx;
  112. SSL *ssl;
  113. /* Pointer to SSL or SSL_CTX options field or NULL if none */
  114. unsigned long *poptions;
  115. /* Pointer to SSL or SSL_CTX cert_flags or NULL if none */
  116. unsigned int *pcert_flags;
  117. /* Current flag table being worked on */
  118. const ssl_flag_tbl *tbl;
  119. /* Size of table */
  120. size_t ntbl;
  121. };
  122. static int ssl_match_option(SSL_CONF_CTX *cctx, const ssl_flag_tbl *tbl,
  123. const char *name, int namelen, int onoff)
  124. {
  125. /* If name not relevant for context skip */
  126. if (!(cctx->flags & tbl->name_flags & SSL_TFLAG_BOTH))
  127. return 0;
  128. if (namelen == -1) {
  129. if (strcmp(tbl->name, name))
  130. return 0;
  131. } else if (tbl->namelen != namelen
  132. || strncasecmp(tbl->name, name, namelen))
  133. return 0;
  134. if (cctx->poptions) {
  135. if (tbl->name_flags & SSL_TFLAG_INV)
  136. onoff ^= 1;
  137. if (tbl->name_flags & SSL_TFLAG_CERT) {
  138. if (onoff)
  139. *cctx->pcert_flags |= tbl->option_value;
  140. else
  141. *cctx->pcert_flags &= ~tbl->option_value;
  142. } else {
  143. if (onoff)
  144. *cctx->poptions |= tbl->option_value;
  145. else
  146. *cctx->poptions &= ~tbl->option_value;
  147. }
  148. }
  149. return 1;
  150. }
  151. static int ssl_set_option_list(const char *elem, int len, void *usr)
  152. {
  153. SSL_CONF_CTX *cctx = usr;
  154. size_t i;
  155. const ssl_flag_tbl *tbl;
  156. int onoff = 1;
  157. /*
  158. * len == -1 indicates not being called in list context, just for single
  159. * command line switches, so don't allow +, -.
  160. */
  161. if (elem == NULL)
  162. return 0;
  163. if (len != -1) {
  164. if (*elem == '+') {
  165. elem++;
  166. len--;
  167. onoff = 1;
  168. } else if (*elem == '-') {
  169. elem++;
  170. len--;
  171. onoff = 0;
  172. }
  173. }
  174. for (i = 0, tbl = cctx->tbl; i < cctx->ntbl; i++, tbl++) {
  175. if (ssl_match_option(cctx, tbl, elem, len, onoff))
  176. return 1;
  177. }
  178. return 0;
  179. }
  180. /* Single command line switches with no argument e.g. -no_ssl3 */
  181. static int ctrl_str_option(SSL_CONF_CTX *cctx, const char *cmd)
  182. {
  183. static const ssl_flag_tbl ssl_option_single[] = {
  184. SSL_FLAG_TBL("no_ssl2", SSL_OP_NO_SSLv2),
  185. SSL_FLAG_TBL("no_ssl3", SSL_OP_NO_SSLv3),
  186. SSL_FLAG_TBL("no_tls1", SSL_OP_NO_TLSv1),
  187. SSL_FLAG_TBL("no_tls1_1", SSL_OP_NO_TLSv1_1),
  188. SSL_FLAG_TBL("no_tls1_2", SSL_OP_NO_TLSv1_2),
  189. SSL_FLAG_TBL("bugs", SSL_OP_ALL),
  190. SSL_FLAG_TBL("no_comp", SSL_OP_NO_COMPRESSION),
  191. SSL_FLAG_TBL_SRV("ecdh_single", SSL_OP_SINGLE_ECDH_USE),
  192. #ifndef OPENSSL_NO_TLSEXT
  193. SSL_FLAG_TBL("no_ticket", SSL_OP_NO_TICKET),
  194. #endif
  195. SSL_FLAG_TBL_SRV("serverpref", SSL_OP_CIPHER_SERVER_PREFERENCE),
  196. SSL_FLAG_TBL("legacy_renegotiation",
  197. SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION),
  198. SSL_FLAG_TBL_SRV("legacy_server_connect",
  199. SSL_OP_LEGACY_SERVER_CONNECT),
  200. SSL_FLAG_TBL_SRV("no_resumption_on_reneg",
  201. SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION),
  202. SSL_FLAG_TBL_SRV_INV("no_legacy_server_connect",
  203. SSL_OP_LEGACY_SERVER_CONNECT),
  204. SSL_FLAG_TBL_CERT("strict", SSL_CERT_FLAG_TLS_STRICT),
  205. #ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
  206. SSL_FLAG_TBL_CERT("debug_broken_protocol",
  207. SSL_CERT_FLAG_BROKEN_PROTOCOL),
  208. #endif
  209. };
  210. cctx->tbl = ssl_option_single;
  211. cctx->ntbl = sizeof(ssl_option_single) / sizeof(ssl_flag_tbl);
  212. return ssl_set_option_list(cmd, -1, cctx);
  213. }
  214. /* Set supported signature algorithms */
  215. static int cmd_SignatureAlgorithms(SSL_CONF_CTX *cctx, const char *value)
  216. {
  217. int rv;
  218. if (cctx->ssl)
  219. rv = SSL_set1_sigalgs_list(cctx->ssl, value);
  220. /* NB: ctx == NULL performs syntax checking only */
  221. else
  222. rv = SSL_CTX_set1_sigalgs_list(cctx->ctx, value);
  223. return rv > 0;
  224. }
  225. /* Set supported client signature algorithms */
  226. static int cmd_ClientSignatureAlgorithms(SSL_CONF_CTX *cctx,
  227. const char *value)
  228. {
  229. int rv;
  230. if (cctx->ssl)
  231. rv = SSL_set1_client_sigalgs_list(cctx->ssl, value);
  232. /* NB: ctx == NULL performs syntax checking only */
  233. else
  234. rv = SSL_CTX_set1_client_sigalgs_list(cctx->ctx, value);
  235. return rv > 0;
  236. }
  237. static int cmd_Curves(SSL_CONF_CTX *cctx, const char *value)
  238. {
  239. int rv;
  240. if (cctx->ssl)
  241. rv = SSL_set1_curves_list(cctx->ssl, value);
  242. /* NB: ctx == NULL performs syntax checking only */
  243. else
  244. rv = SSL_CTX_set1_curves_list(cctx->ctx, value);
  245. return rv > 0;
  246. }
  247. #ifndef OPENSSL_NO_ECDH
  248. /* ECDH temporary parameters */
  249. static int cmd_ECDHParameters(SSL_CONF_CTX *cctx, const char *value)
  250. {
  251. int onoff = -1, rv = 1;
  252. if (!(cctx->flags & SSL_CONF_FLAG_SERVER))
  253. return -2;
  254. if (cctx->flags & SSL_CONF_FLAG_FILE) {
  255. if (*value == '+') {
  256. onoff = 1;
  257. value++;
  258. }
  259. if (*value == '-') {
  260. onoff = 0;
  261. value++;
  262. }
  263. if (!strcasecmp(value, "automatic")) {
  264. if (onoff == -1)
  265. onoff = 1;
  266. } else if (onoff != -1)
  267. return 0;
  268. } else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
  269. if (!strcmp(value, "auto"))
  270. onoff = 1;
  271. }
  272. if (onoff != -1) {
  273. if (cctx->ctx)
  274. rv = SSL_CTX_set_ecdh_auto(cctx->ctx, onoff);
  275. else if (cctx->ssl)
  276. rv = SSL_set_ecdh_auto(cctx->ssl, onoff);
  277. } else {
  278. EC_KEY *ecdh;
  279. int nid;
  280. nid = EC_curve_nist2nid(value);
  281. if (nid == NID_undef)
  282. nid = OBJ_sn2nid(value);
  283. if (nid == 0)
  284. return 0;
  285. ecdh = EC_KEY_new_by_curve_name(nid);
  286. if (!ecdh)
  287. return 0;
  288. if (cctx->ctx)
  289. rv = SSL_CTX_set_tmp_ecdh(cctx->ctx, ecdh);
  290. else if (cctx->ssl)
  291. rv = SSL_set_tmp_ecdh(cctx->ssl, ecdh);
  292. EC_KEY_free(ecdh);
  293. }
  294. return rv > 0;
  295. }
  296. #endif
  297. static int cmd_CipherString(SSL_CONF_CTX *cctx, const char *value)
  298. {
  299. int rv = 1;
  300. if (cctx->ctx)
  301. rv = SSL_CTX_set_cipher_list(cctx->ctx, value);
  302. if (cctx->ssl)
  303. rv = SSL_set_cipher_list(cctx->ssl, value);
  304. return rv > 0;
  305. }
  306. static int cmd_Protocol(SSL_CONF_CTX *cctx, const char *value)
  307. {
  308. static const ssl_flag_tbl ssl_protocol_list[] = {
  309. SSL_FLAG_TBL_INV("ALL", SSL_OP_NO_SSL_MASK),
  310. SSL_FLAG_TBL_INV("SSLv2", SSL_OP_NO_SSLv2),
  311. SSL_FLAG_TBL_INV("SSLv3", SSL_OP_NO_SSLv3),
  312. SSL_FLAG_TBL_INV("TLSv1", SSL_OP_NO_TLSv1),
  313. SSL_FLAG_TBL_INV("TLSv1.1", SSL_OP_NO_TLSv1_1),
  314. SSL_FLAG_TBL_INV("TLSv1.2", SSL_OP_NO_TLSv1_2)
  315. };
  316. int ret;
  317. int sslv2off;
  318. if (!(cctx->flags & SSL_CONF_FLAG_FILE))
  319. return -2;
  320. cctx->tbl = ssl_protocol_list;
  321. cctx->ntbl = sizeof(ssl_protocol_list) / sizeof(ssl_flag_tbl);
  322. sslv2off = *cctx->poptions & SSL_OP_NO_SSLv2;
  323. ret = CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
  324. /* Never turn on SSLv2 through configuration */
  325. *cctx->poptions |= sslv2off;
  326. return ret;
  327. }
  328. static int cmd_Options(SSL_CONF_CTX *cctx, const char *value)
  329. {
  330. static const ssl_flag_tbl ssl_option_list[] = {
  331. SSL_FLAG_TBL_INV("SessionTicket", SSL_OP_NO_TICKET),
  332. SSL_FLAG_TBL_INV("EmptyFragments",
  333. SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS),
  334. SSL_FLAG_TBL("Bugs", SSL_OP_ALL),
  335. SSL_FLAG_TBL_INV("Compression", SSL_OP_NO_COMPRESSION),
  336. SSL_FLAG_TBL_SRV("ServerPreference", SSL_OP_CIPHER_SERVER_PREFERENCE),
  337. SSL_FLAG_TBL_SRV("NoResumptionOnRenegotiation",
  338. SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION),
  339. SSL_FLAG_TBL_SRV("DHSingle", SSL_OP_SINGLE_DH_USE),
  340. SSL_FLAG_TBL_SRV("ECDHSingle", SSL_OP_SINGLE_ECDH_USE),
  341. SSL_FLAG_TBL("UnsafeLegacyRenegotiation",
  342. SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION),
  343. };
  344. if (!(cctx->flags & SSL_CONF_FLAG_FILE))
  345. return -2;
  346. if (value == NULL)
  347. return -3;
  348. cctx->tbl = ssl_option_list;
  349. cctx->ntbl = sizeof(ssl_option_list) / sizeof(ssl_flag_tbl);
  350. return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
  351. }
  352. static int cmd_Certificate(SSL_CONF_CTX *cctx, const char *value)
  353. {
  354. int rv = 1;
  355. if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
  356. return -2;
  357. if (cctx->ctx)
  358. rv = SSL_CTX_use_certificate_chain_file(cctx->ctx, value);
  359. if (cctx->ssl)
  360. rv = SSL_use_certificate_file(cctx->ssl, value, SSL_FILETYPE_PEM);
  361. return rv > 0;
  362. }
  363. static int cmd_PrivateKey(SSL_CONF_CTX *cctx, const char *value)
  364. {
  365. int rv = 1;
  366. if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
  367. return -2;
  368. if (cctx->ctx)
  369. rv = SSL_CTX_use_PrivateKey_file(cctx->ctx, value, SSL_FILETYPE_PEM);
  370. if (cctx->ssl)
  371. rv = SSL_use_PrivateKey_file(cctx->ssl, value, SSL_FILETYPE_PEM);
  372. return rv > 0;
  373. }
  374. static int cmd_ServerInfoFile(SSL_CONF_CTX *cctx, const char *value)
  375. {
  376. int rv = 1;
  377. if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
  378. return -2;
  379. if (!(cctx->flags & SSL_CONF_FLAG_SERVER))
  380. return -2;
  381. if (cctx->ctx)
  382. rv = SSL_CTX_use_serverinfo_file(cctx->ctx, value);
  383. return rv > 0;
  384. }
  385. #ifndef OPENSSL_NO_DH
  386. static int cmd_DHParameters(SSL_CONF_CTX *cctx, const char *value)
  387. {
  388. int rv = 0;
  389. DH *dh = NULL;
  390. BIO *in = NULL;
  391. if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
  392. return -2;
  393. if (cctx->ctx || cctx->ssl) {
  394. in = BIO_new(BIO_s_file_internal());
  395. if (!in)
  396. goto end;
  397. if (BIO_read_filename(in, value) <= 0)
  398. goto end;
  399. dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
  400. if (!dh)
  401. goto end;
  402. } else
  403. return 1;
  404. if (cctx->ctx)
  405. rv = SSL_CTX_set_tmp_dh(cctx->ctx, dh);
  406. if (cctx->ssl)
  407. rv = SSL_set_tmp_dh(cctx->ssl, dh);
  408. end:
  409. if (dh)
  410. DH_free(dh);
  411. if (in)
  412. BIO_free(in);
  413. return rv > 0;
  414. }
  415. #endif
  416. typedef struct {
  417. int (*cmd) (SSL_CONF_CTX *cctx, const char *value);
  418. const char *str_file;
  419. const char *str_cmdline;
  420. unsigned int value_type;
  421. } ssl_conf_cmd_tbl;
  422. /* Table of supported parameters */
  423. #define SSL_CONF_CMD(name, cmdopt, type) \
  424. {cmd_##name, #name, cmdopt, type}
  425. #define SSL_CONF_CMD_STRING(name, cmdopt) \
  426. SSL_CONF_CMD(name, cmdopt, SSL_CONF_TYPE_STRING)
  427. static const ssl_conf_cmd_tbl ssl_conf_cmds[] = {
  428. SSL_CONF_CMD_STRING(SignatureAlgorithms, "sigalgs"),
  429. SSL_CONF_CMD_STRING(ClientSignatureAlgorithms, "client_sigalgs"),
  430. SSL_CONF_CMD_STRING(Curves, "curves"),
  431. #ifndef OPENSSL_NO_ECDH
  432. SSL_CONF_CMD_STRING(ECDHParameters, "named_curve"),
  433. #endif
  434. SSL_CONF_CMD_STRING(CipherString, "cipher"),
  435. SSL_CONF_CMD_STRING(Protocol, NULL),
  436. SSL_CONF_CMD_STRING(Options, NULL),
  437. SSL_CONF_CMD(Certificate, "cert", SSL_CONF_TYPE_FILE),
  438. SSL_CONF_CMD(PrivateKey, "key", SSL_CONF_TYPE_FILE),
  439. SSL_CONF_CMD(ServerInfoFile, NULL, SSL_CONF_TYPE_FILE),
  440. #ifndef OPENSSL_NO_DH
  441. SSL_CONF_CMD(DHParameters, "dhparam", SSL_CONF_TYPE_FILE)
  442. #endif
  443. };
  444. static int ssl_conf_cmd_skip_prefix(SSL_CONF_CTX *cctx, const char **pcmd)
  445. {
  446. if (!pcmd || !*pcmd)
  447. return 0;
  448. /* If a prefix is set, check and skip */
  449. if (cctx->prefix) {
  450. if (strlen(*pcmd) <= cctx->prefixlen)
  451. return 0;
  452. if (cctx->flags & SSL_CONF_FLAG_CMDLINE &&
  453. strncmp(*pcmd, cctx->prefix, cctx->prefixlen))
  454. return 0;
  455. if (cctx->flags & SSL_CONF_FLAG_FILE &&
  456. strncasecmp(*pcmd, cctx->prefix, cctx->prefixlen))
  457. return 0;
  458. *pcmd += cctx->prefixlen;
  459. } else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
  460. if (**pcmd != '-' || !(*pcmd)[1])
  461. return 0;
  462. *pcmd += 1;
  463. }
  464. return 1;
  465. }
  466. static const ssl_conf_cmd_tbl *ssl_conf_cmd_lookup(SSL_CONF_CTX *cctx,
  467. const char *cmd)
  468. {
  469. const ssl_conf_cmd_tbl *t;
  470. size_t i;
  471. if (cmd == NULL)
  472. return NULL;
  473. /* Look for matching parameter name in table */
  474. for (i = 0, t = ssl_conf_cmds;
  475. i < sizeof(ssl_conf_cmds) / sizeof(ssl_conf_cmd_tbl); i++, t++) {
  476. if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
  477. if (t->str_cmdline && !strcmp(t->str_cmdline, cmd))
  478. return t;
  479. }
  480. if (cctx->flags & SSL_CONF_FLAG_FILE) {
  481. if (t->str_file && !strcasecmp(t->str_file, cmd))
  482. return t;
  483. }
  484. }
  485. return NULL;
  486. }
  487. int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value)
  488. {
  489. const ssl_conf_cmd_tbl *runcmd;
  490. if (cmd == NULL) {
  491. SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_INVALID_NULL_CMD_NAME);
  492. return 0;
  493. }
  494. if (!ssl_conf_cmd_skip_prefix(cctx, &cmd))
  495. return -2;
  496. runcmd = ssl_conf_cmd_lookup(cctx, cmd);
  497. if (runcmd) {
  498. int rv;
  499. if (value == NULL)
  500. return -3;
  501. rv = runcmd->cmd(cctx, value);
  502. if (rv > 0)
  503. return 2;
  504. if (rv == -2)
  505. return -2;
  506. if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) {
  507. SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_BAD_VALUE);
  508. ERR_add_error_data(4, "cmd=", cmd, ", value=", value);
  509. }
  510. return 0;
  511. }
  512. if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
  513. if (ctrl_str_option(cctx, cmd))
  514. return 1;
  515. }
  516. if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) {
  517. SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_UNKNOWN_CMD_NAME);
  518. ERR_add_error_data(2, "cmd=", cmd);
  519. }
  520. return -2;
  521. }
  522. int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv)
  523. {
  524. int rv;
  525. const char *arg = NULL, *argn;
  526. if (pargc && *pargc == 0)
  527. return 0;
  528. if (!pargc || *pargc > 0)
  529. arg = **pargv;
  530. if (arg == NULL)
  531. return 0;
  532. if (!pargc || *pargc > 1)
  533. argn = (*pargv)[1];
  534. else
  535. argn = NULL;
  536. cctx->flags &= ~SSL_CONF_FLAG_FILE;
  537. cctx->flags |= SSL_CONF_FLAG_CMDLINE;
  538. rv = SSL_CONF_cmd(cctx, arg, argn);
  539. if (rv > 0) {
  540. /* Success: update pargc, pargv */
  541. (*pargv) += rv;
  542. if (pargc)
  543. (*pargc) -= rv;
  544. return rv;
  545. }
  546. /* Unknown switch: indicate no arguments processed */
  547. if (rv == -2)
  548. return 0;
  549. /* Some error occurred processing command, return fatal error */
  550. if (rv == 0)
  551. return -1;
  552. return rv;
  553. }
  554. int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd)
  555. {
  556. if (ssl_conf_cmd_skip_prefix(cctx, &cmd)) {
  557. const ssl_conf_cmd_tbl *runcmd;
  558. runcmd = ssl_conf_cmd_lookup(cctx, cmd);
  559. if (runcmd)
  560. return runcmd->value_type;
  561. }
  562. return SSL_CONF_TYPE_UNKNOWN;
  563. }
  564. SSL_CONF_CTX *SSL_CONF_CTX_new(void)
  565. {
  566. SSL_CONF_CTX *ret;
  567. ret = OPENSSL_malloc(sizeof(SSL_CONF_CTX));
  568. if (ret) {
  569. ret->flags = 0;
  570. ret->prefix = NULL;
  571. ret->prefixlen = 0;
  572. ret->ssl = NULL;
  573. ret->ctx = NULL;
  574. ret->poptions = NULL;
  575. ret->pcert_flags = NULL;
  576. ret->tbl = NULL;
  577. ret->ntbl = 0;
  578. }
  579. return ret;
  580. }
  581. int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx)
  582. {
  583. return 1;
  584. }
  585. void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx)
  586. {
  587. if (cctx) {
  588. if (cctx->prefix)
  589. OPENSSL_free(cctx->prefix);
  590. OPENSSL_free(cctx);
  591. }
  592. }
  593. unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags)
  594. {
  595. cctx->flags |= flags;
  596. return cctx->flags;
  597. }
  598. unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags)
  599. {
  600. cctx->flags &= ~flags;
  601. return cctx->flags;
  602. }
  603. int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre)
  604. {
  605. char *tmp = NULL;
  606. if (pre) {
  607. tmp = BUF_strdup(pre);
  608. if (tmp == NULL)
  609. return 0;
  610. }
  611. if (cctx->prefix)
  612. OPENSSL_free(cctx->prefix);
  613. cctx->prefix = tmp;
  614. if (tmp)
  615. cctx->prefixlen = strlen(tmp);
  616. else
  617. cctx->prefixlen = 0;
  618. return 1;
  619. }
  620. void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl)
  621. {
  622. cctx->ssl = ssl;
  623. cctx->ctx = NULL;
  624. if (ssl) {
  625. cctx->poptions = &ssl->options;
  626. cctx->pcert_flags = &ssl->cert->cert_flags;
  627. } else {
  628. cctx->poptions = NULL;
  629. cctx->pcert_flags = NULL;
  630. }
  631. }
  632. void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx)
  633. {
  634. cctx->ctx = ctx;
  635. cctx->ssl = NULL;
  636. if (ctx) {
  637. cctx->poptions = &ctx->options;
  638. cctx->pcert_flags = &ctx->cert->cert_flags;
  639. } else {
  640. cctx->poptions = NULL;
  641. cctx->pcert_flags = NULL;
  642. }
  643. }