source: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_conf.c@ 331

Last change on this file since 331 was 331, checked in by coas-nagasima, 6 years ago

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 26.3 KB
RevLine 
[331]1/*
2 * Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (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#include <stdio.h>
11#include "ssl_locl.h"
12#include <openssl/conf.h>
13#include <openssl/objects.h>
14#include <openssl/dh.h>
15
16/*
17 * structure holding name tables. This is used for permitted elements in lists
18 * such as TLSv1.
19 */
20
21typedef struct {
22 const char *name;
23 int namelen;
24 unsigned int name_flags;
25 unsigned long option_value;
26} ssl_flag_tbl;
27
28/* Switch table: use for single command line switches like no_tls2 */
29typedef struct {
30 unsigned long option_value;
31 unsigned int name_flags;
32} ssl_switch_tbl;
33
34/* Sense of name is inverted e.g. "TLSv1" will clear SSL_OP_NO_TLSv1 */
35#define SSL_TFLAG_INV 0x1
36/* Mask for type of flag referred to */
37#define SSL_TFLAG_TYPE_MASK 0xf00
38/* Flag is for options */
39#define SSL_TFLAG_OPTION 0x000
40/* Flag is for cert_flags */
41#define SSL_TFLAG_CERT 0x100
42/* Flag is for verify mode */
43#define SSL_TFLAG_VFY 0x200
44/* Option can only be used for clients */
45#define SSL_TFLAG_CLIENT SSL_CONF_FLAG_CLIENT
46/* Option can only be used for servers */
47#define SSL_TFLAG_SERVER SSL_CONF_FLAG_SERVER
48#define SSL_TFLAG_BOTH (SSL_TFLAG_CLIENT|SSL_TFLAG_SERVER)
49
50#define SSL_FLAG_TBL(str, flag) \
51 {str, (int)(sizeof(str) - 1), SSL_TFLAG_BOTH, flag}
52#define SSL_FLAG_TBL_SRV(str, flag) \
53 {str, (int)(sizeof(str) - 1), SSL_TFLAG_SERVER, flag}
54#define SSL_FLAG_TBL_CLI(str, flag) \
55 {str, (int)(sizeof(str) - 1), SSL_TFLAG_CLIENT, flag}
56#define SSL_FLAG_TBL_INV(str, flag) \
57 {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_BOTH, flag}
58#define SSL_FLAG_TBL_SRV_INV(str, flag) \
59 {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_SERVER, flag}
60#define SSL_FLAG_TBL_CERT(str, flag) \
61 {str, (int)(sizeof(str) - 1), SSL_TFLAG_CERT|SSL_TFLAG_BOTH, flag}
62
63#define SSL_FLAG_VFY_CLI(str, flag) \
64 {str, (int)(sizeof(str) - 1), SSL_TFLAG_VFY | SSL_TFLAG_CLIENT, flag}
65#define SSL_FLAG_VFY_SRV(str, flag) \
66 {str, (int)(sizeof(str) - 1), SSL_TFLAG_VFY | SSL_TFLAG_SERVER, flag}
67
68/*
69 * Opaque structure containing SSL configuration context.
70 */
71
72struct ssl_conf_ctx_st {
73 /*
74 * Various flags indicating (among other things) which options we will
75 * recognise.
76 */
77 unsigned int flags;
78 /* Prefix and length of commands */
79 char *prefix;
80 size_t prefixlen;
81 /* SSL_CTX or SSL structure to perform operations on */
82 SSL_CTX *ctx;
83 SSL *ssl;
84 /* Pointer to SSL or SSL_CTX options field or NULL if none */
85 uint32_t *poptions;
86 /* Certificate filenames for each type */
87 char *cert_filename[SSL_PKEY_NUM];
88 /* Pointer to SSL or SSL_CTX cert_flags or NULL if none */
89 uint32_t *pcert_flags;
90 /* Pointer to SSL or SSL_CTX verify_mode or NULL if none */
91 uint32_t *pvfy_flags;
92 /* Pointer to SSL or SSL_CTX min_version field or NULL if none */
93 int *min_version;
94 /* Pointer to SSL or SSL_CTX max_version field or NULL if none */
95 int *max_version;
96 /* Current flag table being worked on */
97 const ssl_flag_tbl *tbl;
98 /* Size of table */
99 size_t ntbl;
100 /* Client CA names */
101 STACK_OF(X509_NAME) *canames;
102};
103
104static void ssl_set_option(SSL_CONF_CTX *cctx, unsigned int name_flags,
105 unsigned long option_value, int onoff)
106{
107 uint32_t *pflags;
108 if (cctx->poptions == NULL)
109 return;
110 if (name_flags & SSL_TFLAG_INV)
111 onoff ^= 1;
112 switch (name_flags & SSL_TFLAG_TYPE_MASK) {
113
114 case SSL_TFLAG_CERT:
115 pflags = cctx->pcert_flags;
116 break;
117
118 case SSL_TFLAG_VFY:
119 pflags = cctx->pvfy_flags;
120 break;
121
122 case SSL_TFLAG_OPTION:
123 pflags = cctx->poptions;
124 break;
125
126 default:
127 return;
128
129 }
130 if (onoff)
131 *pflags |= option_value;
132 else
133 *pflags &= ~option_value;
134}
135
136static int ssl_match_option(SSL_CONF_CTX *cctx, const ssl_flag_tbl *tbl,
137 const char *name, int namelen, int onoff)
138{
139 /* If name not relevant for context skip */
140 if (!(cctx->flags & tbl->name_flags & SSL_TFLAG_BOTH))
141 return 0;
142 if (namelen == -1) {
143 if (strcmp(tbl->name, name))
144 return 0;
145 } else if (tbl->namelen != namelen || strncasecmp(tbl->name, name, namelen))
146 return 0;
147 ssl_set_option(cctx, tbl->name_flags, tbl->option_value, onoff);
148 return 1;
149}
150
151static 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
181/* Set supported signature algorithms */
182static int cmd_SignatureAlgorithms(SSL_CONF_CTX *cctx, const char *value)
183{
184 int rv;
185 if (cctx->ssl)
186 rv = SSL_set1_sigalgs_list(cctx->ssl, value);
187 /* NB: ctx == NULL performs syntax checking only */
188 else
189 rv = SSL_CTX_set1_sigalgs_list(cctx->ctx, value);
190 return rv > 0;
191}
192
193/* Set supported client signature algorithms */
194static int cmd_ClientSignatureAlgorithms(SSL_CONF_CTX *cctx, const char *value)
195{
196 int rv;
197 if (cctx->ssl)
198 rv = SSL_set1_client_sigalgs_list(cctx->ssl, value);
199 /* NB: ctx == NULL performs syntax checking only */
200 else
201 rv = SSL_CTX_set1_client_sigalgs_list(cctx->ctx, value);
202 return rv > 0;
203}
204
205static int cmd_Curves(SSL_CONF_CTX *cctx, const char *value)
206{
207 int rv;
208 if (cctx->ssl)
209 rv = SSL_set1_curves_list(cctx->ssl, value);
210 /* NB: ctx == NULL performs syntax checking only */
211 else
212 rv = SSL_CTX_set1_curves_list(cctx->ctx, value);
213 return rv > 0;
214}
215
216#ifndef OPENSSL_NO_EC
217/* ECDH temporary parameters */
218static int cmd_ECDHParameters(SSL_CONF_CTX *cctx, const char *value)
219{
220 int rv = 1;
221 EC_KEY *ecdh;
222 int nid;
223
224 nid = EC_curve_nist2nid(value);
225 if (nid == NID_undef)
226 nid = OBJ_sn2nid(value);
227 if (nid == 0)
228 return 0;
229 ecdh = EC_KEY_new_by_curve_name(nid);
230 if (!ecdh)
231 return 0;
232 if (cctx->ctx)
233 rv = SSL_CTX_set_tmp_ecdh(cctx->ctx, ecdh);
234 else if (cctx->ssl)
235 rv = SSL_set_tmp_ecdh(cctx->ssl, ecdh);
236 EC_KEY_free(ecdh);
237
238 return rv > 0;
239}
240#endif
241static int cmd_CipherString(SSL_CONF_CTX *cctx, const char *value)
242{
243 int rv = 1;
244 if (cctx->ctx)
245 rv = SSL_CTX_set_cipher_list(cctx->ctx, value);
246 if (cctx->ssl)
247 rv = SSL_set_cipher_list(cctx->ssl, value);
248 return rv > 0;
249}
250
251static int cmd_Protocol(SSL_CONF_CTX *cctx, const char *value)
252{
253 static const ssl_flag_tbl ssl_protocol_list[] = {
254 SSL_FLAG_TBL_INV("ALL", SSL_OP_NO_SSL_MASK),
255 SSL_FLAG_TBL_INV("SSLv2", SSL_OP_NO_SSLv2),
256 SSL_FLAG_TBL_INV("SSLv3", SSL_OP_NO_SSLv3),
257 SSL_FLAG_TBL_INV("TLSv1", SSL_OP_NO_TLSv1),
258 SSL_FLAG_TBL_INV("TLSv1.1", SSL_OP_NO_TLSv1_1),
259 SSL_FLAG_TBL_INV("TLSv1.2", SSL_OP_NO_TLSv1_2),
260 SSL_FLAG_TBL_INV("DTLSv1", SSL_OP_NO_DTLSv1),
261 SSL_FLAG_TBL_INV("DTLSv1.2", SSL_OP_NO_DTLSv1_2)
262 };
263 cctx->tbl = ssl_protocol_list;
264 cctx->ntbl = OSSL_NELEM(ssl_protocol_list);
265 return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
266}
267
268/*
269 * protocol_from_string - converts a protocol version string to a number
270 *
271 * Returns -1 on failure or the version on success
272 */
273static int protocol_from_string(const char *value)
274{
275 struct protocol_versions {
276 const char *name;
277 int version;
278 };
279 static const struct protocol_versions versions[] = {
280 {"None", 0},
281 {"SSLv3", SSL3_VERSION},
282 {"TLSv1", TLS1_VERSION},
283 {"TLSv1.1", TLS1_1_VERSION},
284 {"TLSv1.2", TLS1_2_VERSION},
285 {"DTLSv1", DTLS1_VERSION},
286 {"DTLSv1.2", DTLS1_2_VERSION}
287 };
288 size_t i;
289 size_t n = OSSL_NELEM(versions);
290
291 for (i = 0; i < n; i++)
292 if (strcmp(versions[i].name, value) == 0)
293 return versions[i].version;
294 return -1;
295}
296
297static int min_max_proto(SSL_CONF_CTX *cctx, const char *value, int *bound)
298{
299 int method_version;
300 int new_version;
301
302 if (cctx->ctx != NULL)
303 method_version = cctx->ctx->method->version;
304 else if (cctx->ssl != NULL)
305 method_version = cctx->ssl->ctx->method->version;
306 else
307 return 0;
308 if ((new_version = protocol_from_string(value)) < 0)
309 return 0;
310 return ssl_set_version_bound(method_version, new_version, bound);
311}
312
313/*
314 * cmd_MinProtocol - Set min protocol version
315 * @cctx: config structure to save settings in
316 * @value: The min protocol version in string form
317 *
318 * Returns 1 on success and 0 on failure.
319 */
320static int cmd_MinProtocol(SSL_CONF_CTX *cctx, const char *value)
321{
322 return min_max_proto(cctx, value, cctx->min_version);
323}
324
325/*
326 * cmd_MaxProtocol - Set max protocol version
327 * @cctx: config structure to save settings in
328 * @value: The max protocol version in string form
329 *
330 * Returns 1 on success and 0 on failure.
331 */
332static int cmd_MaxProtocol(SSL_CONF_CTX *cctx, const char *value)
333{
334 return min_max_proto(cctx, value, cctx->max_version);
335}
336
337static int cmd_Options(SSL_CONF_CTX *cctx, const char *value)
338{
339 static const ssl_flag_tbl ssl_option_list[] = {
340 SSL_FLAG_TBL_INV("SessionTicket", SSL_OP_NO_TICKET),
341 SSL_FLAG_TBL_INV("EmptyFragments",
342 SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS),
343 SSL_FLAG_TBL("Bugs", SSL_OP_ALL),
344 SSL_FLAG_TBL_INV("Compression", SSL_OP_NO_COMPRESSION),
345 SSL_FLAG_TBL_SRV("ServerPreference", SSL_OP_CIPHER_SERVER_PREFERENCE),
346 SSL_FLAG_TBL_SRV("NoResumptionOnRenegotiation",
347 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION),
348 SSL_FLAG_TBL_SRV("DHSingle", SSL_OP_SINGLE_DH_USE),
349 SSL_FLAG_TBL_SRV("ECDHSingle", SSL_OP_SINGLE_ECDH_USE),
350 SSL_FLAG_TBL("UnsafeLegacyRenegotiation",
351 SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION),
352 };
353 if (value == NULL)
354 return -3;
355 cctx->tbl = ssl_option_list;
356 cctx->ntbl = OSSL_NELEM(ssl_option_list);
357 return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
358}
359
360static int cmd_VerifyMode(SSL_CONF_CTX *cctx, const char *value)
361{
362 static const ssl_flag_tbl ssl_vfy_list[] = {
363 SSL_FLAG_VFY_CLI("Peer", SSL_VERIFY_PEER),
364 SSL_FLAG_VFY_SRV("Request", SSL_VERIFY_PEER),
365 SSL_FLAG_VFY_SRV("Require",
366 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT),
367 SSL_FLAG_VFY_SRV("Once", SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE)
368 };
369 if (value == NULL)
370 return -3;
371 cctx->tbl = ssl_vfy_list;
372 cctx->ntbl = OSSL_NELEM(ssl_vfy_list);
373 return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
374}
375
376static int cmd_Certificate(SSL_CONF_CTX *cctx, const char *value)
377{
378 int rv = 1;
379 CERT *c = NULL;
380 if (cctx->ctx) {
381 rv = SSL_CTX_use_certificate_chain_file(cctx->ctx, value);
382 c = cctx->ctx->cert;
383 }
384 if (cctx->ssl) {
385 rv = SSL_use_certificate_chain_file(cctx->ssl, value);
386 c = cctx->ssl->cert;
387 }
388 if (rv > 0 && c && cctx->flags & SSL_CONF_FLAG_REQUIRE_PRIVATE) {
389 char **pfilename = &cctx->cert_filename[c->key - c->pkeys];
390 OPENSSL_free(*pfilename);
391 *pfilename = OPENSSL_strdup(value);
392 if (!*pfilename)
393 rv = 0;
394 }
395
396 return rv > 0;
397}
398
399static int cmd_PrivateKey(SSL_CONF_CTX *cctx, const char *value)
400{
401 int rv = 1;
402 if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
403 return -2;
404 if (cctx->ctx)
405 rv = SSL_CTX_use_PrivateKey_file(cctx->ctx, value, SSL_FILETYPE_PEM);
406 if (cctx->ssl)
407 rv = SSL_use_PrivateKey_file(cctx->ssl, value, SSL_FILETYPE_PEM);
408 return rv > 0;
409}
410
411static int cmd_ServerInfoFile(SSL_CONF_CTX *cctx, const char *value)
412{
413 int rv = 1;
414 if (cctx->ctx)
415 rv = SSL_CTX_use_serverinfo_file(cctx->ctx, value);
416 return rv > 0;
417}
418
419static int do_store(SSL_CONF_CTX *cctx,
420 const char *CAfile, const char *CApath, int verify_store)
421{
422 CERT *cert;
423 X509_STORE **st;
424 if (cctx->ctx)
425 cert = cctx->ctx->cert;
426 else if (cctx->ssl)
427 cert = cctx->ssl->cert;
428 else
429 return 1;
430 st = verify_store ? &cert->verify_store : &cert->chain_store;
431 if (*st == NULL) {
432 *st = X509_STORE_new();
433 if (*st == NULL)
434 return 0;
435 }
436 return X509_STORE_load_locations(*st, CAfile, CApath) > 0;
437}
438
439static int cmd_ChainCAPath(SSL_CONF_CTX *cctx, const char *value)
440{
441 return do_store(cctx, NULL, value, 0);
442}
443
444static int cmd_ChainCAFile(SSL_CONF_CTX *cctx, const char *value)
445{
446 return do_store(cctx, value, NULL, 0);
447}
448
449static int cmd_VerifyCAPath(SSL_CONF_CTX *cctx, const char *value)
450{
451 return do_store(cctx, NULL, value, 1);
452}
453
454static int cmd_VerifyCAFile(SSL_CONF_CTX *cctx, const char *value)
455{
456 return do_store(cctx, value, NULL, 1);
457}
458
459static int cmd_ClientCAFile(SSL_CONF_CTX *cctx, const char *value)
460{
461 if (cctx->canames == NULL)
462 cctx->canames = sk_X509_NAME_new_null();
463 if (cctx->canames == NULL)
464 return 0;
465 return SSL_add_file_cert_subjects_to_stack(cctx->canames, value);
466}
467
468static int cmd_ClientCAPath(SSL_CONF_CTX *cctx, const char *value)
469{
470 if (cctx->canames == NULL)
471 cctx->canames = sk_X509_NAME_new_null();
472 if (cctx->canames == NULL)
473 return 0;
474 return SSL_add_dir_cert_subjects_to_stack(cctx->canames, value);
475}
476
477#ifndef OPENSSL_NO_DH
478static int cmd_DHParameters(SSL_CONF_CTX *cctx, const char *value)
479{
480 int rv = 0;
481 DH *dh = NULL;
482 BIO *in = NULL;
483 if (cctx->ctx || cctx->ssl) {
484 in = BIO_new(BIO_s_file());
485 if (in == NULL)
486 goto end;
487 if (BIO_read_filename(in, value) <= 0)
488 goto end;
489 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
490 if (dh == NULL)
491 goto end;
492 } else
493 return 1;
494 if (cctx->ctx)
495 rv = SSL_CTX_set_tmp_dh(cctx->ctx, dh);
496 if (cctx->ssl)
497 rv = SSL_set_tmp_dh(cctx->ssl, dh);
498 end:
499 DH_free(dh);
500 BIO_free(in);
501 return rv > 0;
502}
503#endif
504typedef struct {
505 int (*cmd) (SSL_CONF_CTX *cctx, const char *value);
506 const char *str_file;
507 const char *str_cmdline;
508 unsigned short flags;
509 unsigned short value_type;
510} ssl_conf_cmd_tbl;
511
512/* Table of supported parameters */
513
514#define SSL_CONF_CMD(name, cmdopt, flags, type) \
515 {cmd_##name, #name, cmdopt, flags, type}
516
517#define SSL_CONF_CMD_STRING(name, cmdopt, flags) \
518 SSL_CONF_CMD(name, cmdopt, flags, SSL_CONF_TYPE_STRING)
519
520#define SSL_CONF_CMD_SWITCH(name, flags) \
521 {0, NULL, name, flags, SSL_CONF_TYPE_NONE}
522
523/* See apps/apps.h if you change this table. */
524static const ssl_conf_cmd_tbl ssl_conf_cmds[] = {
525 SSL_CONF_CMD_SWITCH("no_ssl3", 0),
526 SSL_CONF_CMD_SWITCH("no_tls1", 0),
527 SSL_CONF_CMD_SWITCH("no_tls1_1", 0),
528 SSL_CONF_CMD_SWITCH("no_tls1_2", 0),
529 SSL_CONF_CMD_SWITCH("bugs", 0),
530 SSL_CONF_CMD_SWITCH("no_comp", 0),
531 SSL_CONF_CMD_SWITCH("comp", 0),
532 SSL_CONF_CMD_SWITCH("ecdh_single", SSL_CONF_FLAG_SERVER),
533 SSL_CONF_CMD_SWITCH("no_ticket", 0),
534 SSL_CONF_CMD_SWITCH("serverpref", SSL_CONF_FLAG_SERVER),
535 SSL_CONF_CMD_SWITCH("legacy_renegotiation", 0),
536 SSL_CONF_CMD_SWITCH("legacy_server_connect", SSL_CONF_FLAG_SERVER),
537 SSL_CONF_CMD_SWITCH("no_resumption_on_reneg", SSL_CONF_FLAG_SERVER),
538 SSL_CONF_CMD_SWITCH("no_legacy_server_connect", SSL_CONF_FLAG_SERVER),
539 SSL_CONF_CMD_SWITCH("strict", 0),
540 SSL_CONF_CMD_STRING(SignatureAlgorithms, "sigalgs", 0),
541 SSL_CONF_CMD_STRING(ClientSignatureAlgorithms, "client_sigalgs", 0),
542 SSL_CONF_CMD_STRING(Curves, "curves", 0),
543#ifndef OPENSSL_NO_EC
544 SSL_CONF_CMD_STRING(ECDHParameters, "named_curve", SSL_CONF_FLAG_SERVER),
545#endif
546 SSL_CONF_CMD_STRING(CipherString, "cipher", 0),
547 SSL_CONF_CMD_STRING(Protocol, NULL, 0),
548 SSL_CONF_CMD_STRING(MinProtocol, "min_protocol", 0),
549 SSL_CONF_CMD_STRING(MaxProtocol, "max_protocol", 0),
550 SSL_CONF_CMD_STRING(Options, NULL, 0),
551 SSL_CONF_CMD_STRING(VerifyMode, NULL, 0),
552 SSL_CONF_CMD(Certificate, "cert", SSL_CONF_FLAG_CERTIFICATE,
553 SSL_CONF_TYPE_FILE),
554 SSL_CONF_CMD(PrivateKey, "key", SSL_CONF_FLAG_CERTIFICATE,
555 SSL_CONF_TYPE_FILE),
556 SSL_CONF_CMD(ServerInfoFile, NULL,
557 SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
558 SSL_CONF_TYPE_FILE),
559 SSL_CONF_CMD(ChainCAPath, "chainCApath", SSL_CONF_FLAG_CERTIFICATE,
560 SSL_CONF_TYPE_DIR),
561 SSL_CONF_CMD(ChainCAFile, "chainCAfile", SSL_CONF_FLAG_CERTIFICATE,
562 SSL_CONF_TYPE_FILE),
563 SSL_CONF_CMD(VerifyCAPath, "verifyCApath", SSL_CONF_FLAG_CERTIFICATE,
564 SSL_CONF_TYPE_DIR),
565 SSL_CONF_CMD(VerifyCAFile, "verifyCAfile", SSL_CONF_FLAG_CERTIFICATE,
566 SSL_CONF_TYPE_FILE),
567 SSL_CONF_CMD(ClientCAFile, NULL,
568 SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
569 SSL_CONF_TYPE_FILE),
570 SSL_CONF_CMD(ClientCAPath, NULL,
571 SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
572 SSL_CONF_TYPE_DIR),
573#ifndef OPENSSL_NO_DH
574 SSL_CONF_CMD(DHParameters, "dhparam",
575 SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
576 SSL_CONF_TYPE_FILE)
577#endif
578};
579
580/* Supported switches: must match order of switches in ssl_conf_cmds */
581static const ssl_switch_tbl ssl_cmd_switches[] = {
582 {SSL_OP_NO_SSLv3, 0}, /* no_ssl3 */
583 {SSL_OP_NO_TLSv1, 0}, /* no_tls1 */
584 {SSL_OP_NO_TLSv1_1, 0}, /* no_tls1_1 */
585 {SSL_OP_NO_TLSv1_2, 0}, /* no_tls1_2 */
586 {SSL_OP_ALL, 0}, /* bugs */
587 {SSL_OP_NO_COMPRESSION, 0}, /* no_comp */
588 {SSL_OP_NO_COMPRESSION, SSL_TFLAG_INV}, /* comp */
589 {SSL_OP_SINGLE_ECDH_USE, 0}, /* ecdh_single */
590 {SSL_OP_NO_TICKET, 0}, /* no_ticket */
591 {SSL_OP_CIPHER_SERVER_PREFERENCE, 0}, /* serverpref */
592 /* legacy_renegotiation */
593 {SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION, 0},
594 /* legacy_server_connect */
595 {SSL_OP_LEGACY_SERVER_CONNECT, 0},
596 /* no_resumption_on_reneg */
597 {SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION, 0},
598 /* no_legacy_server_connect */
599 {SSL_OP_LEGACY_SERVER_CONNECT, SSL_TFLAG_INV},
600 {SSL_CERT_FLAG_TLS_STRICT, SSL_TFLAG_CERT}, /* strict */
601};
602
603static int ssl_conf_cmd_skip_prefix(SSL_CONF_CTX *cctx, const char **pcmd)
604{
605 if (!pcmd || !*pcmd)
606 return 0;
607 /* If a prefix is set, check and skip */
608 if (cctx->prefix) {
609 if (strlen(*pcmd) <= cctx->prefixlen)
610 return 0;
611 if (cctx->flags & SSL_CONF_FLAG_CMDLINE &&
612 strncmp(*pcmd, cctx->prefix, cctx->prefixlen))
613 return 0;
614 if (cctx->flags & SSL_CONF_FLAG_FILE &&
615 strncasecmp(*pcmd, cctx->prefix, cctx->prefixlen))
616 return 0;
617 *pcmd += cctx->prefixlen;
618 } else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
619 if (**pcmd != '-' || !(*pcmd)[1])
620 return 0;
621 *pcmd += 1;
622 }
623 return 1;
624}
625
626/* Determine if a command is allowed according to cctx flags */
627static int ssl_conf_cmd_allowed(SSL_CONF_CTX *cctx, const ssl_conf_cmd_tbl * t)
628{
629 unsigned int tfl = t->flags;
630 unsigned int cfl = cctx->flags;
631 if ((tfl & SSL_CONF_FLAG_SERVER) && !(cfl & SSL_CONF_FLAG_SERVER))
632 return 0;
633 if ((tfl & SSL_CONF_FLAG_CLIENT) && !(cfl & SSL_CONF_FLAG_CLIENT))
634 return 0;
635 if ((tfl & SSL_CONF_FLAG_CERTIFICATE)
636 && !(cfl & SSL_CONF_FLAG_CERTIFICATE))
637 return 0;
638 return 1;
639}
640
641static const ssl_conf_cmd_tbl *ssl_conf_cmd_lookup(SSL_CONF_CTX *cctx,
642 const char *cmd)
643{
644 const ssl_conf_cmd_tbl *t;
645 size_t i;
646 if (cmd == NULL)
647 return NULL;
648
649 /* Look for matching parameter name in table */
650 for (i = 0, t = ssl_conf_cmds; i < OSSL_NELEM(ssl_conf_cmds); i++, t++) {
651 if (ssl_conf_cmd_allowed(cctx, t)) {
652 if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
653 if (t->str_cmdline && strcmp(t->str_cmdline, cmd) == 0)
654 return t;
655 }
656 if (cctx->flags & SSL_CONF_FLAG_FILE) {
657 if (t->str_file && strcasecmp(t->str_file, cmd) == 0)
658 return t;
659 }
660 }
661 }
662 return NULL;
663}
664
665static int ctrl_switch_option(SSL_CONF_CTX *cctx, const ssl_conf_cmd_tbl * cmd)
666{
667 /* Find index of command in table */
668 size_t idx = cmd - ssl_conf_cmds;
669 const ssl_switch_tbl *scmd;
670 /* Sanity check index */
671 if (idx >= OSSL_NELEM(ssl_cmd_switches))
672 return 0;
673 /* Obtain switches entry with same index */
674 scmd = ssl_cmd_switches + idx;
675 ssl_set_option(cctx, scmd->name_flags, scmd->option_value, 1);
676 return 1;
677}
678
679int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value)
680{
681 const ssl_conf_cmd_tbl *runcmd;
682 if (cmd == NULL) {
683 SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_INVALID_NULL_CMD_NAME);
684 return 0;
685 }
686
687 if (!ssl_conf_cmd_skip_prefix(cctx, &cmd))
688 return -2;
689
690 runcmd = ssl_conf_cmd_lookup(cctx, cmd);
691
692 if (runcmd) {
693 int rv;
694 if (runcmd->value_type == SSL_CONF_TYPE_NONE) {
695 return ctrl_switch_option(cctx, runcmd);
696 }
697 if (value == NULL)
698 return -3;
699 rv = runcmd->cmd(cctx, value);
700 if (rv > 0)
701 return 2;
702 if (rv == -2)
703 return -2;
704 if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) {
705 SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_BAD_VALUE);
706 ERR_add_error_data(4, "cmd=", cmd, ", value=", value);
707 }
708 return 0;
709 }
710
711 if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) {
712 SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_UNKNOWN_CMD_NAME);
713 ERR_add_error_data(2, "cmd=", cmd);
714 }
715
716 return -2;
717}
718
719int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv)
720{
721 int rv;
722 const char *arg = NULL, *argn;
723 if (pargc && *pargc == 0)
724 return 0;
725 if (!pargc || *pargc > 0)
726 arg = **pargv;
727 if (arg == NULL)
728 return 0;
729 if (!pargc || *pargc > 1)
730 argn = (*pargv)[1];
731 else
732 argn = NULL;
733 cctx->flags &= ~SSL_CONF_FLAG_FILE;
734 cctx->flags |= SSL_CONF_FLAG_CMDLINE;
735 rv = SSL_CONF_cmd(cctx, arg, argn);
736 if (rv > 0) {
737 /* Success: update pargc, pargv */
738 (*pargv) += rv;
739 if (pargc)
740 (*pargc) -= rv;
741 return rv;
742 }
743 /* Unknown switch: indicate no arguments processed */
744 if (rv == -2)
745 return 0;
746 /* Some error occurred processing command, return fatal error */
747 if (rv == 0)
748 return -1;
749 return rv;
750}
751
752int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd)
753{
754 if (ssl_conf_cmd_skip_prefix(cctx, &cmd)) {
755 const ssl_conf_cmd_tbl *runcmd;
756 runcmd = ssl_conf_cmd_lookup(cctx, cmd);
757 if (runcmd)
758 return runcmd->value_type;
759 }
760 return SSL_CONF_TYPE_UNKNOWN;
761}
762
763SSL_CONF_CTX *SSL_CONF_CTX_new(void)
764{
765 SSL_CONF_CTX *ret = OPENSSL_zalloc(sizeof(*ret));
766
767 return ret;
768}
769
770int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx)
771{
772 /* See if any certificates are missing private keys */
773 size_t i;
774 CERT *c = NULL;
775 if (cctx->ctx)
776 c = cctx->ctx->cert;
777 else if (cctx->ssl)
778 c = cctx->ssl->cert;
779 if (c && cctx->flags & SSL_CONF_FLAG_REQUIRE_PRIVATE) {
780 for (i = 0; i < SSL_PKEY_NUM; i++) {
781 const char *p = cctx->cert_filename[i];
782 /*
783 * If missing private key try to load one from certificate file
784 */
785 if (p && !c->pkeys[i].privatekey) {
786 if (!cmd_PrivateKey(cctx, p))
787 return 0;
788 }
789 }
790 }
791 if (cctx->canames) {
792 if (cctx->ssl)
793 SSL_set_client_CA_list(cctx->ssl, cctx->canames);
794 else if (cctx->ctx)
795 SSL_CTX_set_client_CA_list(cctx->ctx, cctx->canames);
796 else
797 sk_X509_NAME_pop_free(cctx->canames, X509_NAME_free);
798 cctx->canames = NULL;
799 }
800 return 1;
801}
802
803void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx)
804{
805 if (cctx) {
806 size_t i;
807 for (i = 0; i < SSL_PKEY_NUM; i++)
808 OPENSSL_free(cctx->cert_filename[i]);
809 OPENSSL_free(cctx->prefix);
810 sk_X509_NAME_pop_free(cctx->canames, X509_NAME_free);
811 OPENSSL_free(cctx);
812 }
813}
814
815unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags)
816{
817 cctx->flags |= flags;
818 return cctx->flags;
819}
820
821unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags)
822{
823 cctx->flags &= ~flags;
824 return cctx->flags;
825}
826
827int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre)
828{
829 char *tmp = NULL;
830 if (pre) {
831 tmp = OPENSSL_strdup(pre);
832 if (tmp == NULL)
833 return 0;
834 }
835 OPENSSL_free(cctx->prefix);
836 cctx->prefix = tmp;
837 if (tmp)
838 cctx->prefixlen = strlen(tmp);
839 else
840 cctx->prefixlen = 0;
841 return 1;
842}
843
844void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl)
845{
846 cctx->ssl = ssl;
847 cctx->ctx = NULL;
848 if (ssl) {
849 cctx->poptions = &ssl->options;
850 cctx->min_version = &ssl->min_proto_version;
851 cctx->max_version = &ssl->max_proto_version;
852 cctx->pcert_flags = &ssl->cert->cert_flags;
853 cctx->pvfy_flags = &ssl->verify_mode;
854 } else {
855 cctx->poptions = NULL;
856 cctx->min_version = NULL;
857 cctx->max_version = NULL;
858 cctx->pcert_flags = NULL;
859 cctx->pvfy_flags = NULL;
860 }
861}
862
863void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx)
864{
865 cctx->ctx = ctx;
866 cctx->ssl = NULL;
867 if (ctx) {
868 cctx->poptions = &ctx->options;
869 cctx->min_version = &ctx->min_proto_version;
870 cctx->max_version = &ctx->max_proto_version;
871 cctx->pcert_flags = &ctx->cert->cert_flags;
872 cctx->pvfy_flags = &ctx->verify_mode;
873 } else {
874 cctx->poptions = NULL;
875 cctx->min_version = NULL;
876 cctx->max_version = NULL;
877 cctx->pcert_flags = NULL;
878 cctx->pvfy_flags = NULL;
879 }
880}
Note: See TracBrowser for help on using the repository browser.