Branch data Line data Source code
1 : : /*! \file ssl/ssl_conf.c
2 : : * \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 : :
58 : : #ifdef REF_CHECK
59 : : # include <assert.h>
60 : : #endif
61 : : #include <stdio.h>
62 : : #include "ssl_locl.h"
63 : : #include <openssl/conf.h>
64 : : #include <openssl/objects.h>
65 : : #ifndef OPENSSL_NO_DH
66 : : #include <openssl/dh.h>
67 : : #endif
68 : :
69 : : /* structure holding name tables. This is used for pemitted elements in
70 : : * lists such as TLSv1 and single command line switches such as no_tls1
71 : : */
72 : :
73 : : typedef struct
74 : : {
75 : : const char *name;
76 : : int namelen;
77 : : unsigned int name_flags;
78 : : unsigned long option_value;
79 : : } ssl_flag_tbl;
80 : :
81 : : /* Sense of name is inverted e.g. "TLSv1" will clear SSL_OP_NO_TLSv1 */
82 : : #define SSL_TFLAG_INV 0x1
83 : : /* Flags refers to cert_flags not options */
84 : : #define SSL_TFLAG_CERT 0x2
85 : : /* Option can only be used for clients */
86 : : #define SSL_TFLAG_CLIENT SSL_CONF_FLAG_CLIENT
87 : : /* Option can only be used for servers */
88 : : #define SSL_TFLAG_SERVER SSL_CONF_FLAG_SERVER
89 : : #define SSL_TFLAG_BOTH (SSL_TFLAG_CLIENT|SSL_TFLAG_SERVER)
90 : :
91 : : #define SSL_FLAG_TBL(str, flag) \
92 : : {str, (int)(sizeof(str) - 1), SSL_TFLAG_BOTH, flag}
93 : : #define SSL_FLAG_TBL_SRV(str, flag) \
94 : : {str, (int)(sizeof(str) - 1), SSL_TFLAG_SERVER, flag}
95 : : #define SSL_FLAG_TBL_CLI(str, flag) \
96 : : {str, (int)(sizeof(str) - 1), SSL_TFLAG_CLIENT, flag}
97 : : #define SSL_FLAG_TBL_INV(str, flag) \
98 : : {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_BOTH, flag}
99 : : #define SSL_FLAG_TBL_SRV_INV(str, flag) \
100 : : {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_SERVER, flag}
101 : : #define SSL_FLAG_TBL_CERT(str, flag) \
102 : : {str, (int)(sizeof(str) - 1), SSL_TFLAG_CERT|SSL_TFLAG_BOTH, flag}
103 : :
104 : : /* Opaque structure containing SSL configuration context.
105 : : */
106 : :
107 : : struct ssl_conf_ctx_st
108 : : {
109 : : /* Various flags indicating (among other things) which options we
110 : : * will recognise.
111 : : */
112 : : unsigned int flags;
113 : : /* Prefix and length of commands */
114 : : char *prefix;
115 : : size_t prefixlen;
116 : : /* SSL_CTX or SSL structure to perform operations on */
117 : : SSL_CTX *ctx;
118 : : SSL *ssl;
119 : : /* Pointer to SSL or SSL_CTX options field or NULL if none */
120 : : unsigned long *poptions;
121 : : /* Pointer to SSL or SSL_CTX cert_flags or NULL if none */
122 : : unsigned int *pcert_flags;
123 : : /* Current flag table being worked on */
124 : : const ssl_flag_tbl *tbl;
125 : : /* Size of table */
126 : : size_t ntbl;
127 : : };
128 : :
129 : 0 : static int ssl_match_option(SSL_CONF_CTX *cctx, const ssl_flag_tbl *tbl,
130 : : const char *name, int namelen, int onoff)
131 : : {
132 : : /* If name not relevant for context skip */
133 [ # # ]: 0 : if (!(cctx->flags & tbl->name_flags & SSL_TFLAG_BOTH))
134 : : return 0;
135 [ # # ]: 0 : if (namelen == -1)
136 : : {
137 [ # # ]: 0 : if (strcmp(tbl->name, name))
138 : : return 0;
139 : : }
140 [ # # ][ # # ]: 0 : else if (tbl->namelen != namelen || strncasecmp(tbl->name, name, namelen))
141 : : return 0;
142 [ # # ]: 0 : if (cctx->poptions)
143 : : {
144 [ # # ]: 0 : if (tbl->name_flags & SSL_TFLAG_INV)
145 : 0 : onoff ^= 1;
146 [ # # ]: 0 : if (tbl->name_flags & SSL_TFLAG_CERT)
147 : : {
148 [ # # ]: 0 : if (onoff)
149 : 0 : *cctx->pcert_flags |= tbl->option_value;
150 : : else
151 : 0 : *cctx->pcert_flags &= ~tbl->option_value;
152 : : }
153 : : else
154 : : {
155 [ # # ]: 0 : if (onoff)
156 : 0 : *cctx->poptions |= tbl->option_value;
157 : : else
158 : 0 : *cctx->poptions &= ~tbl->option_value;
159 : : }
160 : : }
161 : : return 1;
162 : : }
163 : :
164 : 0 : static int ssl_set_option_list(const char *elem, int len, void *usr)
165 : : {
166 : 0 : SSL_CONF_CTX *cctx = usr;
167 : : size_t i;
168 : : const ssl_flag_tbl *tbl;
169 : 0 : int onoff = 1;
170 : : /* len == -1 indicates not being called in list context, just for
171 : : * single command line switches, so don't allow +, -.
172 : : */
173 [ # # ]: 0 : if (len != -1)
174 : : {
175 [ # # ]: 0 : if (*elem == '+')
176 : : {
177 : 0 : elem++;
178 : 0 : len--;
179 : 0 : onoff = 1;
180 : : }
181 [ # # ]: 0 : else if (*elem == '-')
182 : : {
183 : 0 : elem++;
184 : 0 : len--;
185 : 0 : onoff = 0;
186 : : }
187 : : }
188 [ # # ]: 0 : for (i = 0, tbl = cctx->tbl; i < cctx->ntbl; i++, tbl++)
189 : : {
190 [ # # ]: 0 : if (ssl_match_option(cctx, tbl, elem, len, onoff))
191 : : return 1;
192 : : }
193 : : return 0;
194 : : }
195 : :
196 : : /* Single command line switches with no argument e.g. -no_ssl3 */
197 : 0 : static int ctrl_str_option(SSL_CONF_CTX *cctx, const char *cmd)
198 : : {
199 : : static const ssl_flag_tbl ssl_option_single[] =
200 : : {
201 : : SSL_FLAG_TBL("no_ssl2", SSL_OP_NO_SSLv2),
202 : : SSL_FLAG_TBL("no_ssl3", SSL_OP_NO_SSLv3),
203 : : SSL_FLAG_TBL("no_tls1", SSL_OP_NO_TLSv1),
204 : : SSL_FLAG_TBL("no_tls1_1", SSL_OP_NO_TLSv1_1),
205 : : SSL_FLAG_TBL("no_tls1_2", SSL_OP_NO_TLSv1_2),
206 : : SSL_FLAG_TBL("bugs", SSL_OP_ALL),
207 : : SSL_FLAG_TBL("no_comp", SSL_OP_NO_COMPRESSION),
208 : : SSL_FLAG_TBL_SRV("ecdh_single", SSL_OP_SINGLE_ECDH_USE),
209 : : #ifndef OPENSSL_NO_TLSEXT
210 : : SSL_FLAG_TBL("no_ticket", SSL_OP_NO_TICKET),
211 : : #endif
212 : : SSL_FLAG_TBL_SRV("serverpref", SSL_OP_CIPHER_SERVER_PREFERENCE),
213 : : SSL_FLAG_TBL("legacy_renegotiation", SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION),
214 : : SSL_FLAG_TBL_SRV("legacy_server_connect", SSL_OP_LEGACY_SERVER_CONNECT),
215 : : SSL_FLAG_TBL_SRV("no_resumption_on_reneg", SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION),
216 : : SSL_FLAG_TBL_SRV_INV("no_legacy_server_connect", SSL_OP_LEGACY_SERVER_CONNECT),
217 : : SSL_FLAG_TBL_CERT("strict", SSL_CERT_FLAG_TLS_STRICT),
218 : : #ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
219 : : SSL_FLAG_TBL_CERT("debug_broken_protocol", SSL_CERT_FLAG_BROKEN_PROTOCOL),
220 : : #endif
221 : : };
222 : 0 : cctx->tbl = ssl_option_single;
223 : 0 : cctx->ntbl = sizeof(ssl_option_single)/sizeof(ssl_flag_tbl);
224 : 0 : return ssl_set_option_list(cmd, -1, cctx);
225 : : }
226 : :
227 : : /* Set supported signature algorithms */
228 : 0 : static int cmd_SignatureAlgorithms(SSL_CONF_CTX *cctx, const char *value)
229 : : {
230 : : int rv;
231 [ # # ]: 0 : if (cctx->ssl)
232 : 0 : rv = SSL_set1_sigalgs_list(cctx->ssl, value);
233 : : /* NB: ctx == NULL performs syntax checking only */
234 : : else
235 : 0 : rv = SSL_CTX_set1_sigalgs_list(cctx->ctx, value);
236 : 0 : return rv > 0;
237 : : }
238 : : /* Set supported client signature algorithms */
239 : 0 : static int cmd_ClientSignatureAlgorithms(SSL_CONF_CTX *cctx, const char *value)
240 : : {
241 : : int rv;
242 [ # # ]: 0 : if (cctx->ssl)
243 : 0 : rv = SSL_set1_client_sigalgs_list(cctx->ssl, value);
244 : : /* NB: ctx == NULL performs syntax checking only */
245 : : else
246 : 0 : rv = SSL_CTX_set1_client_sigalgs_list(cctx->ctx, value);
247 : 0 : return rv > 0;
248 : : }
249 : :
250 : 0 : static int cmd_Curves(SSL_CONF_CTX *cctx, const char *value)
251 : : {
252 : : int rv;
253 [ # # ]: 0 : if (cctx->ssl)
254 : 0 : rv = SSL_set1_curves_list(cctx->ssl, value);
255 : : /* NB: ctx == NULL performs syntax checking only */
256 : : else
257 : 0 : rv = SSL_CTX_set1_curves_list(cctx->ctx, value);
258 : 0 : return rv > 0;
259 : : }
260 : : #ifndef OPENSSL_NO_ECDH
261 : : /* ECDH temporary parameters */
262 : 0 : static int cmd_ECDHParameters(SSL_CONF_CTX *cctx, const char *value)
263 : : {
264 : 0 : int onoff = -1, rv = 1;
265 [ # # ]: 0 : if (!(cctx->flags & SSL_CONF_FLAG_SERVER))
266 : : return -2;
267 [ # # ]: 0 : if (cctx->flags & SSL_CONF_FLAG_FILE)
268 : : {
269 [ # # ]: 0 : if (*value == '+')
270 : : {
271 : 0 : onoff = 1;
272 : 0 : value++;
273 : : }
274 [ # # ]: 0 : if (*value == '-')
275 : : {
276 : 0 : onoff = 0;
277 : 0 : value++;
278 : : }
279 [ # # ]: 0 : if (!strcasecmp(value, "automatic"))
280 : : {
281 [ # # ]: 0 : if (onoff == -1)
282 : 0 : onoff = 1;
283 : : }
284 [ # # ]: 0 : else if (onoff != -1)
285 : : return 0;
286 : : }
287 [ # # ]: 0 : else if (cctx->flags & SSL_CONF_FLAG_CMDLINE)
288 : : {
289 [ # # ]: 0 : if (!strcmp(value, "auto"))
290 : 0 : onoff = 1;
291 : : }
292 : :
293 [ # # ]: 0 : if (onoff != -1)
294 : : {
295 [ # # ]: 0 : if (cctx->ctx)
296 : 0 : rv = SSL_CTX_set_ecdh_auto(cctx->ctx, onoff);
297 [ # # ]: 0 : else if (cctx->ssl)
298 : 0 : rv = SSL_set_ecdh_auto(cctx->ssl, onoff);
299 : : }
300 : : else
301 : : {
302 : : EC_KEY *ecdh;
303 : : int nid;
304 : 0 : nid = EC_curve_nist2nid(value);
305 [ # # ]: 0 : if (nid == NID_undef)
306 : 0 : nid = OBJ_sn2nid(value);
307 [ # # ]: 0 : if (nid == 0)
308 : : return 0;
309 : 0 : ecdh = EC_KEY_new_by_curve_name(nid);
310 [ # # ]: 0 : if (!ecdh)
311 : : return 0;
312 [ # # ]: 0 : if (cctx->ctx)
313 : 0 : rv = SSL_CTX_set_tmp_ecdh(cctx->ctx, ecdh);
314 [ # # ]: 0 : else if (cctx->ssl)
315 : 0 : rv = SSL_set_tmp_ecdh(cctx->ssl, ecdh);
316 : 0 : EC_KEY_free(ecdh);
317 : : }
318 : :
319 : 0 : return rv > 0;
320 : : }
321 : : #endif
322 : 0 : static int cmd_CipherString(SSL_CONF_CTX *cctx, const char *value)
323 : : {
324 : 0 : int rv = 1;
325 [ # # ]: 0 : if (cctx->ctx)
326 : 0 : rv = SSL_CTX_set_cipher_list(cctx->ctx, value);
327 [ # # ]: 0 : if (cctx->ssl)
328 : 0 : rv = SSL_set_cipher_list(cctx->ssl, value);
329 : 0 : return rv > 0;
330 : : }
331 : :
332 : 0 : static int cmd_Protocol(SSL_CONF_CTX *cctx, const char *value)
333 : : {
334 : : static const ssl_flag_tbl ssl_protocol_list[] =
335 : : {
336 : : SSL_FLAG_TBL_INV("ALL", SSL_OP_NO_SSL_MASK),
337 : : SSL_FLAG_TBL_INV("SSLv2", SSL_OP_NO_SSLv2),
338 : : SSL_FLAG_TBL_INV("SSLv3", SSL_OP_NO_SSLv3),
339 : : SSL_FLAG_TBL_INV("TLSv1", SSL_OP_NO_TLSv1),
340 : : SSL_FLAG_TBL_INV("TLSv1.1", SSL_OP_NO_TLSv1_1),
341 : : SSL_FLAG_TBL_INV("TLSv1.2", SSL_OP_NO_TLSv1_2)
342 : : };
343 [ # # ]: 0 : if (!(cctx->flags & SSL_CONF_FLAG_FILE))
344 : : return -2;
345 : 0 : cctx->tbl = ssl_protocol_list;
346 : 0 : cctx->ntbl = sizeof(ssl_protocol_list)/sizeof(ssl_flag_tbl);
347 : 0 : return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
348 : : }
349 : :
350 : 0 : static int cmd_Options(SSL_CONF_CTX *cctx, const char *value)
351 : : {
352 : : static const ssl_flag_tbl ssl_option_list[] =
353 : : {
354 : : SSL_FLAG_TBL_INV("SessionTicket", SSL_OP_NO_TICKET),
355 : : SSL_FLAG_TBL_INV("EmptyFragments", SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS),
356 : : SSL_FLAG_TBL("Bugs", SSL_OP_ALL),
357 : : SSL_FLAG_TBL_INV("Compression", SSL_OP_NO_COMPRESSION),
358 : : SSL_FLAG_TBL_SRV("ServerPreference", SSL_OP_CIPHER_SERVER_PREFERENCE),
359 : : SSL_FLAG_TBL_SRV("NoResumptionOnRenegotiation", SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION),
360 : : SSL_FLAG_TBL_SRV("DHSingle", SSL_OP_SINGLE_DH_USE),
361 : : SSL_FLAG_TBL_SRV("ECDHSingle", SSL_OP_SINGLE_ECDH_USE),
362 : : SSL_FLAG_TBL("UnsafeLegacyRenegotiation", SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION),
363 : : };
364 [ # # ]: 0 : if (!(cctx->flags & SSL_CONF_FLAG_FILE))
365 : : return -2;
366 [ # # ]: 0 : if (value == NULL)
367 : : return -3;
368 : 0 : cctx->tbl = ssl_option_list;
369 : 0 : cctx->ntbl = sizeof(ssl_option_list)/sizeof(ssl_flag_tbl);
370 : 0 : return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
371 : : }
372 : :
373 : 0 : static int cmd_Certificate(SSL_CONF_CTX *cctx, const char *value)
374 : : {
375 : 0 : int rv = 1;
376 [ # # ]: 0 : if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
377 : : return -2;
378 [ # # ]: 0 : if (cctx->ctx)
379 : 0 : rv = SSL_CTX_use_certificate_chain_file(cctx->ctx, value);
380 [ # # ]: 0 : if (cctx->ssl)
381 : 0 : rv = SSL_use_certificate_file(cctx->ssl, value, SSL_FILETYPE_PEM);
382 : 0 : return rv > 0;
383 : : }
384 : :
385 : 0 : static int cmd_PrivateKey(SSL_CONF_CTX *cctx, const char *value)
386 : : {
387 : 0 : int rv = 1;
388 [ # # ]: 0 : if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
389 : : return -2;
390 [ # # ]: 0 : if (cctx->ctx)
391 : 0 : rv = SSL_CTX_use_PrivateKey_file(cctx->ctx, value, SSL_FILETYPE_PEM);
392 [ # # ]: 0 : if (cctx->ssl)
393 : 0 : rv = SSL_use_PrivateKey_file(cctx->ssl, value, SSL_FILETYPE_PEM);
394 : 0 : return rv > 0;
395 : : }
396 : :
397 : 0 : static int cmd_ServerInfoFile(SSL_CONF_CTX *cctx, const char *value)
398 : : {
399 : 0 : int rv = 1;
400 [ # # ]: 0 : if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
401 : : return -2;
402 [ # # ]: 0 : if (!(cctx->flags & SSL_CONF_FLAG_SERVER))
403 : : return -2;
404 [ # # ]: 0 : if (cctx->ctx)
405 : 0 : rv = SSL_CTX_use_serverinfo_file(cctx->ctx, value);
406 : 0 : return rv > 0;
407 : : }
408 : :
409 : : #ifndef OPENSSL_NO_DH
410 : 0 : static int cmd_DHParameters(SSL_CONF_CTX *cctx, const char *value)
411 : : {
412 : 0 : int rv = 0;
413 : 0 : DH *dh = NULL;
414 : 0 : BIO *in = NULL;
415 [ # # ]: 0 : if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
416 : : return -2;
417 [ # # ][ # # ]: 0 : if (cctx->ctx || cctx->ssl)
418 : : {
419 : 0 : in = BIO_new(BIO_s_file_internal());
420 [ # # ]: 0 : if (!in)
421 : : goto end;
422 [ # # ]: 0 : if (BIO_read_filename(in, value) <= 0)
423 : : goto end;
424 : 0 : dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
425 [ # # ]: 0 : if (!dh)
426 : : goto end;
427 : : }
428 : : else
429 : : return 1;
430 [ # # ]: 0 : if (cctx->ctx)
431 : 0 : rv = SSL_CTX_set_tmp_dh(cctx->ctx, dh);
432 [ # # ]: 0 : if (cctx->ssl)
433 : 0 : rv = SSL_set_tmp_dh(cctx->ssl, dh);
434 : : end:
435 [ # # ]: 0 : if (dh)
436 : 0 : DH_free(dh);
437 [ # # ]: 0 : if (in)
438 : 0 : BIO_free(in);
439 : 0 : return rv > 0;
440 : : }
441 : : #endif
442 : : typedef struct
443 : : {
444 : : int (*cmd)(SSL_CONF_CTX *cctx, const char *value);
445 : : const char *str_file;
446 : : const char *str_cmdline;
447 : : unsigned int value_type;
448 : : } ssl_conf_cmd_tbl;
449 : :
450 : : /* Table of supported parameters */
451 : :
452 : : #define SSL_CONF_CMD(name, cmdopt, type) \
453 : : {cmd_##name, #name, cmdopt, type}
454 : :
455 : : #define SSL_CONF_CMD_STRING(name, cmdopt) \
456 : : SSL_CONF_CMD(name, cmdopt, SSL_CONF_TYPE_STRING)
457 : :
458 : : static const ssl_conf_cmd_tbl ssl_conf_cmds[] = {
459 : : SSL_CONF_CMD_STRING(SignatureAlgorithms, "sigalgs"),
460 : : SSL_CONF_CMD_STRING(ClientSignatureAlgorithms, "client_sigalgs"),
461 : : SSL_CONF_CMD_STRING(Curves, "curves"),
462 : : #ifndef OPENSSL_NO_ECDH
463 : : SSL_CONF_CMD_STRING(ECDHParameters, "named_curve"),
464 : : #endif
465 : : SSL_CONF_CMD_STRING(CipherString, "cipher"),
466 : : SSL_CONF_CMD_STRING(Protocol, NULL),
467 : : SSL_CONF_CMD_STRING(Options, NULL),
468 : : SSL_CONF_CMD(Certificate, "cert", SSL_CONF_TYPE_FILE),
469 : : SSL_CONF_CMD(PrivateKey, "key", SSL_CONF_TYPE_FILE),
470 : : SSL_CONF_CMD(ServerInfoFile, NULL, SSL_CONF_TYPE_FILE),
471 : : #ifndef OPENSSL_NO_DH
472 : : SSL_CONF_CMD(DHParameters, "dhparam", SSL_CONF_TYPE_FILE)
473 : : #endif
474 : : };
475 : :
476 : 0 : static int ssl_conf_cmd_skip_prefix(SSL_CONF_CTX *cctx, const char **pcmd)
477 : : {
478 [ # # ][ # # ]: 0 : if (!pcmd || !*pcmd)
479 : : return 0;
480 : : /* If a prefix is set, check and skip */
481 [ # # ]: 0 : if (cctx->prefix)
482 : : {
483 [ # # ]: 0 : if (strlen(*pcmd) <= cctx->prefixlen)
484 : : return 0;
485 [ # # ][ # # ]: 0 : if (cctx->flags & SSL_CONF_FLAG_CMDLINE &&
486 : 0 : strncmp(*pcmd, cctx->prefix, cctx->prefixlen))
487 : : return 0;
488 [ # # ][ # # ]: 0 : if (cctx->flags & SSL_CONF_FLAG_FILE &&
489 : 0 : strncasecmp(*pcmd, cctx->prefix, cctx->prefixlen))
490 : : return 0;
491 : 0 : *pcmd += cctx->prefixlen;
492 : : }
493 [ # # ]: 0 : else if (cctx->flags & SSL_CONF_FLAG_CMDLINE)
494 : : {
495 [ # # ][ # # ]: 0 : if (**pcmd != '-' || !(*pcmd)[1])
496 : : return 0;
497 : 0 : *pcmd += 1;
498 : : }
499 : : return 1;
500 : : }
501 : :
502 : 0 : static const ssl_conf_cmd_tbl *ssl_conf_cmd_lookup(SSL_CONF_CTX *cctx, const char *cmd)
503 : : {
504 : : const ssl_conf_cmd_tbl *t;
505 : : size_t i;
506 [ # # ]: 0 : if (cmd == NULL)
507 : : return NULL;
508 : :
509 : : /* Look for matching parameter name in table */
510 [ # # ]: 0 : for (i = 0, t = ssl_conf_cmds;
511 : 0 : i < sizeof(ssl_conf_cmds)/sizeof(ssl_conf_cmd_tbl); i++, t++)
512 : : {
513 [ # # ]: 0 : if (cctx->flags & SSL_CONF_FLAG_CMDLINE)
514 : : {
515 [ # # ][ # # ]: 0 : if (t->str_cmdline && !strcmp(t->str_cmdline, cmd))
516 : : return t;
517 : : }
518 [ # # ]: 0 : if (cctx->flags & SSL_CONF_FLAG_FILE)
519 : : {
520 [ # # ][ # # ]: 0 : if (t->str_file && !strcasecmp(t->str_file, cmd))
521 : : return t;
522 : : }
523 : : }
524 : : return NULL;
525 : : }
526 : :
527 : 0 : int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value)
528 : : {
529 : : const ssl_conf_cmd_tbl *runcmd;
530 [ # # ]: 0 : if (cmd == NULL)
531 : : {
532 : 0 : SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_INVALID_NULL_CMD_NAME);
533 : 0 : return 0;
534 : : }
535 : :
536 [ # # ]: 0 : if (!ssl_conf_cmd_skip_prefix(cctx, &cmd))
537 : : return -2;
538 : :
539 : 0 : runcmd = ssl_conf_cmd_lookup(cctx, cmd);
540 : :
541 [ # # ]: 0 : if (runcmd)
542 : : {
543 : : int rv;
544 [ # # ]: 0 : if (value == NULL)
545 : : return -3;
546 : 0 : rv = runcmd->cmd(cctx, value);
547 [ # # ]: 0 : if (rv > 0)
548 : : return 2;
549 [ # # ]: 0 : if (rv == -2)
550 : : return -2;
551 [ # # ]: 0 : if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS)
552 : : {
553 : 0 : SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_BAD_VALUE);
554 : 0 : ERR_add_error_data(4, "cmd=", cmd, ", value=", value);
555 : : }
556 : : return 0;
557 : : }
558 : :
559 [ # # ]: 0 : if (cctx->flags & SSL_CONF_FLAG_CMDLINE)
560 : : {
561 [ # # ]: 0 : if (ctrl_str_option(cctx, cmd))
562 : : return 1;
563 : : }
564 : :
565 [ # # ]: 0 : if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS)
566 : : {
567 : 0 : SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_UNKNOWN_CMD_NAME);
568 : 0 : ERR_add_error_data(2, "cmd=", cmd);
569 : : }
570 : :
571 : : return -2;
572 : : }
573 : :
574 : 0 : int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv)
575 : : {
576 : : int rv;
577 : 0 : const char *arg = NULL, *argn;
578 [ # # ][ # # ]: 0 : if (pargc && *pargc == 0)
579 : : return 0;
580 [ # # ][ # # ]: 0 : if (!pargc || *pargc > 0)
581 : 0 : arg = **pargv;
582 [ # # ]: 0 : if (arg == NULL)
583 : : return 0;
584 [ # # ][ # # ]: 0 : if (!pargc || *pargc > 1)
585 : 0 : argn = (*pargv)[1];
586 : : else
587 : : argn = NULL;
588 : 0 : cctx->flags &= ~SSL_CONF_FLAG_FILE;
589 : 0 : cctx->flags |= SSL_CONF_FLAG_CMDLINE;
590 : 0 : rv = SSL_CONF_cmd(cctx, arg, argn);
591 [ # # ]: 0 : if (rv > 0)
592 : : {
593 : : /* Success: update pargc, pargv */
594 : 0 : (*pargv) += rv;
595 [ # # ]: 0 : if (pargc)
596 : 0 : (*pargc) -= rv;
597 : 0 : return rv;
598 : : }
599 : : /* Unknown switch: indicate no arguments processed */
600 [ # # ]: 0 : if (rv == -2)
601 : : return 0;
602 : : /* Some error occurred processing command, return fatal error */
603 [ # # ]: 0 : if (rv == 0)
604 : : return -1;
605 : 0 : return rv;
606 : : }
607 : :
608 : 0 : int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd)
609 : : {
610 [ # # ]: 0 : if (ssl_conf_cmd_skip_prefix(cctx, &cmd))
611 : : {
612 : : const ssl_conf_cmd_tbl *runcmd;
613 : 0 : runcmd = ssl_conf_cmd_lookup(cctx, cmd);
614 [ # # ]: 0 : if (runcmd)
615 : 0 : return runcmd->value_type;
616 : : }
617 : : return SSL_CONF_TYPE_UNKNOWN;
618 : : }
619 : :
620 : 0 : SSL_CONF_CTX *SSL_CONF_CTX_new(void)
621 : : {
622 : : SSL_CONF_CTX *ret;
623 : 0 : ret = OPENSSL_malloc(sizeof(SSL_CONF_CTX));
624 [ # # ]: 0 : if (ret)
625 : : {
626 : 0 : ret->flags = 0;
627 : 0 : ret->prefix = NULL;
628 : 0 : ret->prefixlen = 0;
629 : 0 : ret->ssl = NULL;
630 : 0 : ret->ctx = NULL;
631 : 0 : ret->poptions = NULL;
632 : 0 : ret->pcert_flags = NULL;
633 : 0 : ret->tbl = NULL;
634 : 0 : ret->ntbl = 0;
635 : : }
636 : 0 : return ret;
637 : : }
638 : :
639 : 0 : int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx)
640 : : {
641 : 0 : return 1;
642 : : }
643 : :
644 : 0 : void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx)
645 : : {
646 [ # # ]: 0 : if (cctx)
647 : : {
648 [ # # ]: 0 : if (cctx->prefix)
649 : 0 : OPENSSL_free(cctx->prefix);
650 : 0 : OPENSSL_free(cctx);
651 : : }
652 : 0 : }
653 : :
654 : 0 : unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags)
655 : : {
656 : 0 : cctx->flags |= flags;
657 : 0 : return cctx->flags;
658 : : }
659 : :
660 : 0 : unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags)
661 : : {
662 : 0 : cctx->flags &= ~flags;
663 : 0 : return cctx->flags;
664 : : }
665 : :
666 : 0 : int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre)
667 : : {
668 : 0 : char *tmp = NULL;
669 [ # # ]: 0 : if (pre)
670 : : {
671 : 0 : tmp = BUF_strdup(pre);
672 [ # # ]: 0 : if (tmp == NULL)
673 : : return 0;
674 : : }
675 [ # # ]: 0 : if (cctx->prefix)
676 : 0 : OPENSSL_free(cctx->prefix);
677 : 0 : cctx->prefix = tmp;
678 [ # # ]: 0 : if (tmp)
679 : 0 : cctx->prefixlen = strlen(tmp);
680 : : else
681 : 0 : cctx->prefixlen = 0;
682 : : return 1;
683 : : }
684 : :
685 : 0 : void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl)
686 : : {
687 : 0 : cctx->ssl = ssl;
688 : 0 : cctx->ctx = NULL;
689 [ # # ]: 0 : if (ssl)
690 : : {
691 : 0 : cctx->poptions = &ssl->options;
692 : 0 : cctx->pcert_flags = &ssl->cert->cert_flags;
693 : : }
694 : : else
695 : : {
696 : 0 : cctx->poptions = NULL;
697 : 0 : cctx->pcert_flags = NULL;
698 : : }
699 : 0 : }
700 : :
701 : 0 : void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx)
702 : : {
703 : 0 : cctx->ctx = ctx;
704 : 0 : cctx->ssl = NULL;
705 [ # # ]: 0 : if (ctx)
706 : : {
707 : 0 : cctx->poptions = &ctx->options;
708 : 0 : cctx->pcert_flags = &ctx->cert->cert_flags;
709 : : }
710 : : else
711 : : {
712 : 0 : cctx->poptions = NULL;
713 : 0 : cctx->pcert_flags = NULL;
714 : : }
715 : 0 : }
|