ssl_conf.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  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. * [email protected].
  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. * ([email protected]). This product includes software written by Tim
  54. * Hudson ([email protected]).
  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. if (!(cctx->flags & SSL_CONF_FLAG_FILE))
  317. return -2;
  318. cctx->tbl = ssl_protocol_list;
  319. cctx->ntbl = sizeof(ssl_protocol_list) / sizeof(ssl_flag_tbl);
  320. return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
  321. }
  322. static int cmd_Options(SSL_CONF_CTX *cctx, const char *value)
  323. {
  324. static const ssl_flag_tbl ssl_option_list[] = {
  325. SSL_FLAG_TBL_INV("SessionTicket", SSL_OP_NO_TICKET),
  326. SSL_FLAG_TBL_INV("EmptyFragments",
  327. SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS),
  328. SSL_FLAG_TBL("Bugs", SSL_OP_ALL),
  329. SSL_FLAG_TBL_INV("Compression", SSL_OP_NO_COMPRESSION),
  330. SSL_FLAG_TBL_SRV("ServerPreference", SSL_OP_CIPHER_SERVER_PREFERENCE),
  331. SSL_FLAG_TBL_SRV("NoResumptionOnRenegotiation",
  332. SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION),
  333. SSL_FLAG_TBL_SRV("DHSingle", SSL_OP_SINGLE_DH_USE),
  334. SSL_FLAG_TBL_SRV("ECDHSingle", SSL_OP_SINGLE_ECDH_USE),
  335. SSL_FLAG_TBL("UnsafeLegacyRenegotiation",
  336. SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION),
  337. };
  338. if (!(cctx->flags & SSL_CONF_FLAG_FILE))
  339. return -2;
  340. if (value == NULL)
  341. return -3;
  342. cctx->tbl = ssl_option_list;
  343. cctx->ntbl = sizeof(ssl_option_list) / sizeof(ssl_flag_tbl);
  344. return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
  345. }
  346. static int cmd_Certificate(SSL_CONF_CTX *cctx, const char *value)
  347. {
  348. int rv = 1;
  349. if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
  350. return -2;
  351. if (cctx->ctx)
  352. rv = SSL_CTX_use_certificate_chain_file(cctx->ctx, value);
  353. if (cctx->ssl)
  354. rv = SSL_use_certificate_file(cctx->ssl, value, SSL_FILETYPE_PEM);
  355. return rv > 0;
  356. }
  357. static int cmd_PrivateKey(SSL_CONF_CTX *cctx, const char *value)
  358. {
  359. int rv = 1;
  360. if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
  361. return -2;
  362. if (cctx->ctx)
  363. rv = SSL_CTX_use_PrivateKey_file(cctx->ctx, value, SSL_FILETYPE_PEM);
  364. if (cctx->ssl)
  365. rv = SSL_use_PrivateKey_file(cctx->ssl, value, SSL_FILETYPE_PEM);
  366. return rv > 0;
  367. }
  368. static int cmd_ServerInfoFile(SSL_CONF_CTX *cctx, const char *value)
  369. {
  370. int rv = 1;
  371. if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
  372. return -2;
  373. if (!(cctx->flags & SSL_CONF_FLAG_SERVER))
  374. return -2;
  375. if (cctx->ctx)
  376. rv = SSL_CTX_use_serverinfo_file(cctx->ctx, value);
  377. return rv > 0;
  378. }
  379. #ifndef OPENSSL_NO_DH
  380. static int cmd_DHParameters(SSL_CONF_CTX *cctx, const char *value)
  381. {
  382. int rv = 0;
  383. DH *dh = NULL;
  384. BIO *in = NULL;
  385. if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
  386. return -2;
  387. if (cctx->ctx || cctx->ssl) {
  388. in = BIO_new(BIO_s_file_internal());
  389. if (!in)
  390. goto end;
  391. if (BIO_read_filename(in, value) <= 0)
  392. goto end;
  393. dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
  394. if (!dh)
  395. goto end;
  396. } else
  397. return 1;
  398. if (cctx->ctx)
  399. rv = SSL_CTX_set_tmp_dh(cctx->ctx, dh);
  400. if (cctx->ssl)
  401. rv = SSL_set_tmp_dh(cctx->ssl, dh);
  402. end:
  403. if (dh)
  404. DH_free(dh);
  405. if (in)
  406. BIO_free(in);
  407. return rv > 0;
  408. }
  409. #endif
  410. typedef struct {
  411. int (*cmd) (SSL_CONF_CTX *cctx, const char *value);
  412. const char *str_file;
  413. const char *str_cmdline;
  414. unsigned int value_type;
  415. } ssl_conf_cmd_tbl;
  416. /* Table of supported parameters */
  417. #define SSL_CONF_CMD(name, cmdopt, type) \
  418. {cmd_##name, #name, cmdopt, type}
  419. #define SSL_CONF_CMD_STRING(name, cmdopt) \
  420. SSL_CONF_CMD(name, cmdopt, SSL_CONF_TYPE_STRING)
  421. static const ssl_conf_cmd_tbl ssl_conf_cmds[] = {
  422. SSL_CONF_CMD_STRING(SignatureAlgorithms, "sigalgs"),
  423. SSL_CONF_CMD_STRING(ClientSignatureAlgorithms, "client_sigalgs"),
  424. SSL_CONF_CMD_STRING(Curves, "curves"),
  425. #ifndef OPENSSL_NO_ECDH
  426. SSL_CONF_CMD_STRING(ECDHParameters, "named_curve"),
  427. #endif
  428. SSL_CONF_CMD_STRING(CipherString, "cipher"),
  429. SSL_CONF_CMD_STRING(Protocol, NULL),
  430. SSL_CONF_CMD_STRING(Options, NULL),
  431. SSL_CONF_CMD(Certificate, "cert", SSL_CONF_TYPE_FILE),
  432. SSL_CONF_CMD(PrivateKey, "key", SSL_CONF_TYPE_FILE),
  433. SSL_CONF_CMD(ServerInfoFile, NULL, SSL_CONF_TYPE_FILE),
  434. #ifndef OPENSSL_NO_DH
  435. SSL_CONF_CMD(DHParameters, "dhparam", SSL_CONF_TYPE_FILE)
  436. #endif
  437. };
  438. static int ssl_conf_cmd_skip_prefix(SSL_CONF_CTX *cctx, const char **pcmd)
  439. {
  440. if (!pcmd || !*pcmd)
  441. return 0;
  442. /* If a prefix is set, check and skip */
  443. if (cctx->prefix) {
  444. if (strlen(*pcmd) <= cctx->prefixlen)
  445. return 0;
  446. if (cctx->flags & SSL_CONF_FLAG_CMDLINE &&
  447. strncmp(*pcmd, cctx->prefix, cctx->prefixlen))
  448. return 0;
  449. if (cctx->flags & SSL_CONF_FLAG_FILE &&
  450. strncasecmp(*pcmd, cctx->prefix, cctx->prefixlen))
  451. return 0;
  452. *pcmd += cctx->prefixlen;
  453. } else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
  454. if (**pcmd != '-' || !(*pcmd)[1])
  455. return 0;
  456. *pcmd += 1;
  457. }
  458. return 1;
  459. }
  460. static const ssl_conf_cmd_tbl *ssl_conf_cmd_lookup(SSL_CONF_CTX *cctx,
  461. const char *cmd)
  462. {
  463. const ssl_conf_cmd_tbl *t;
  464. size_t i;
  465. if (cmd == NULL)
  466. return NULL;
  467. /* Look for matching parameter name in table */
  468. for (i = 0, t = ssl_conf_cmds;
  469. i < sizeof(ssl_conf_cmds) / sizeof(ssl_conf_cmd_tbl); i++, t++) {
  470. if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
  471. if (t->str_cmdline && !strcmp(t->str_cmdline, cmd))
  472. return t;
  473. }
  474. if (cctx->flags & SSL_CONF_FLAG_FILE) {
  475. if (t->str_file && !strcasecmp(t->str_file, cmd))
  476. return t;
  477. }
  478. }
  479. return NULL;
  480. }
  481. int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value)
  482. {
  483. const ssl_conf_cmd_tbl *runcmd;
  484. if (cmd == NULL) {
  485. SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_INVALID_NULL_CMD_NAME);
  486. return 0;
  487. }
  488. if (!ssl_conf_cmd_skip_prefix(cctx, &cmd))
  489. return -2;
  490. runcmd = ssl_conf_cmd_lookup(cctx, cmd);
  491. if (runcmd) {
  492. int rv;
  493. if (value == NULL)
  494. return -3;
  495. rv = runcmd->cmd(cctx, value);
  496. if (rv > 0)
  497. return 2;
  498. if (rv == -2)
  499. return -2;
  500. if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) {
  501. SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_BAD_VALUE);
  502. ERR_add_error_data(4, "cmd=", cmd, ", value=", value);
  503. }
  504. return 0;
  505. }
  506. if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
  507. if (ctrl_str_option(cctx, cmd))
  508. return 1;
  509. }
  510. if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) {
  511. SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_UNKNOWN_CMD_NAME);
  512. ERR_add_error_data(2, "cmd=", cmd);
  513. }
  514. return -2;
  515. }
  516. int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv)
  517. {
  518. int rv;
  519. const char *arg = NULL, *argn;
  520. if (pargc && *pargc == 0)
  521. return 0;
  522. if (!pargc || *pargc > 0)
  523. arg = **pargv;
  524. if (arg == NULL)
  525. return 0;
  526. if (!pargc || *pargc > 1)
  527. argn = (*pargv)[1];
  528. else
  529. argn = NULL;
  530. cctx->flags &= ~SSL_CONF_FLAG_FILE;
  531. cctx->flags |= SSL_CONF_FLAG_CMDLINE;
  532. rv = SSL_CONF_cmd(cctx, arg, argn);
  533. if (rv > 0) {
  534. /* Success: update pargc, pargv */
  535. (*pargv) += rv;
  536. if (pargc)
  537. (*pargc) -= rv;
  538. return rv;
  539. }
  540. /* Unknown switch: indicate no arguments processed */
  541. if (rv == -2)
  542. return 0;
  543. /* Some error occurred processing command, return fatal error */
  544. if (rv == 0)
  545. return -1;
  546. return rv;
  547. }
  548. int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd)
  549. {
  550. if (ssl_conf_cmd_skip_prefix(cctx, &cmd)) {
  551. const ssl_conf_cmd_tbl *runcmd;
  552. runcmd = ssl_conf_cmd_lookup(cctx, cmd);
  553. if (runcmd)
  554. return runcmd->value_type;
  555. }
  556. return SSL_CONF_TYPE_UNKNOWN;
  557. }
  558. SSL_CONF_CTX *SSL_CONF_CTX_new(void)
  559. {
  560. SSL_CONF_CTX *ret;
  561. ret = OPENSSL_malloc(sizeof(SSL_CONF_CTX));
  562. if (ret) {
  563. ret->flags = 0;
  564. ret->prefix = NULL;
  565. ret->prefixlen = 0;
  566. ret->ssl = NULL;
  567. ret->ctx = NULL;
  568. ret->poptions = NULL;
  569. ret->pcert_flags = NULL;
  570. ret->tbl = NULL;
  571. ret->ntbl = 0;
  572. }
  573. return ret;
  574. }
  575. int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx)
  576. {
  577. return 1;
  578. }
  579. void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx)
  580. {
  581. if (cctx) {
  582. if (cctx->prefix)
  583. OPENSSL_free(cctx->prefix);
  584. OPENSSL_free(cctx);
  585. }
  586. }
  587. unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags)
  588. {
  589. cctx->flags |= flags;
  590. return cctx->flags;
  591. }
  592. unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags)
  593. {
  594. cctx->flags &= ~flags;
  595. return cctx->flags;
  596. }
  597. int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre)
  598. {
  599. char *tmp = NULL;
  600. if (pre) {
  601. tmp = BUF_strdup(pre);
  602. if (tmp == NULL)
  603. return 0;
  604. }
  605. if (cctx->prefix)
  606. OPENSSL_free(cctx->prefix);
  607. cctx->prefix = tmp;
  608. if (tmp)
  609. cctx->prefixlen = strlen(tmp);
  610. else
  611. cctx->prefixlen = 0;
  612. return 1;
  613. }
  614. void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl)
  615. {
  616. cctx->ssl = ssl;
  617. cctx->ctx = NULL;
  618. if (ssl) {
  619. cctx->poptions = &ssl->options;
  620. cctx->pcert_flags = &ssl->cert->cert_flags;
  621. } else {
  622. cctx->poptions = NULL;
  623. cctx->pcert_flags = NULL;
  624. }
  625. }
  626. void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx)
  627. {
  628. cctx->ctx = ctx;
  629. cctx->ssl = NULL;
  630. if (ctx) {
  631. cctx->poptions = &ctx->options;
  632. cctx->pcert_flags = &ctx->cert->cert_flags;
  633. } else {
  634. cctx->poptions = NULL;
  635. cctx->pcert_flags = NULL;
  636. }
  637. }