1 /* 2 * Copyright 2015-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 <openssl/conf.h> 12 #include <openssl/ssl.h> 13 #include "ssl_locl.h" 14 15 /* SSL library configuration module. */ 16 17 struct ssl_conf_name { 18 /* Name of this set of commands */ 19 char *name; 20 /* List of commands */ 21 struct ssl_conf_cmd *cmds; 22 /* Number of commands */ 23 size_t cmd_count; 24 }; 25 26 struct ssl_conf_cmd { 27 /* Command */ 28 char *cmd; 29 /* Argument */ 30 char *arg; 31 }; 32 33 static struct ssl_conf_name *ssl_names; 34 static size_t ssl_names_count; 35 36 static void ssl_module_free(CONF_IMODULE *md) 37 { 38 size_t i, j; 39 if (ssl_names == NULL) 40 return; 41 for (i = 0; i < ssl_names_count; i++) { 42 struct ssl_conf_name *tname = ssl_names + i; 43 OPENSSL_free(tname->name); 44 for (j = 0; j < tname->cmd_count; j++) { 45 OPENSSL_free(tname->cmds[j].cmd); 46 OPENSSL_free(tname->cmds[j].arg); 47 } 48 OPENSSL_free(tname->cmds); 49 } 50 OPENSSL_free(ssl_names); 51 ssl_names = NULL; 52 ssl_names_count = 0; 53 } 54 55 static int ssl_module_init(CONF_IMODULE *md, const CONF *cnf) 56 { 57 size_t i, j, cnt; 58 int rv = 0; 59 const char *ssl_conf_section; 60 STACK_OF(CONF_VALUE) *cmd_lists; 61 ssl_conf_section = CONF_imodule_get_value(md); 62 cmd_lists = NCONF_get_section(cnf, ssl_conf_section); 63 if (sk_CONF_VALUE_num(cmd_lists) <= 0) { 64 if (cmd_lists == NULL) 65 SSLerr(SSL_F_SSL_MODULE_INIT, SSL_R_SSL_SECTION_NOT_FOUND); 66 else 67 SSLerr(SSL_F_SSL_MODULE_INIT, SSL_R_SSL_SECTION_EMPTY); 68 ERR_add_error_data(2, "section=", ssl_conf_section); 69 goto err; 70 } 71 cnt = sk_CONF_VALUE_num(cmd_lists); 72 ssl_names = OPENSSL_zalloc(sizeof(*ssl_names) * cnt); 73 ssl_names_count = cnt; 74 for (i = 0; i < ssl_names_count; i++) { 75 struct ssl_conf_name *ssl_name = ssl_names + i; 76 CONF_VALUE *sect = sk_CONF_VALUE_value(cmd_lists, i); 77 STACK_OF(CONF_VALUE) *cmds = NCONF_get_section(cnf, sect->value); 78 if (sk_CONF_VALUE_num(cmds) <= 0) { 79 if (cmds == NULL) 80 SSLerr(SSL_F_SSL_MODULE_INIT, 81 SSL_R_SSL_COMMAND_SECTION_NOT_FOUND); 82 else 83 SSLerr(SSL_F_SSL_MODULE_INIT, SSL_R_SSL_COMMAND_SECTION_EMPTY); 84 ERR_add_error_data(4, "name=", sect->name, ", value=", sect->value); 85 goto err; 86 } 87 ssl_name->name = BUF_strdup(sect->name); 88 if (ssl_name->name == NULL) 89 goto err; 90 cnt = sk_CONF_VALUE_num(cmds); 91 ssl_name->cmds = OPENSSL_zalloc(cnt * sizeof(struct ssl_conf_cmd)); 92 if (ssl_name->cmds == NULL) 93 goto err; 94 ssl_name->cmd_count = cnt; 95 for (j = 0; j < cnt; j++) { 96 const char *name; 97 CONF_VALUE *cmd_conf = sk_CONF_VALUE_value(cmds, j); 98 struct ssl_conf_cmd *cmd = ssl_name->cmds + j; 99 /* Skip any initial dot in name */ 100 name = strchr(cmd_conf->name, '.'); 101 if (name != NULL) 102 name++; 103 else 104 name = cmd_conf->name; 105 cmd->cmd = BUF_strdup(name); 106 cmd->arg = BUF_strdup(cmd_conf->value); 107 if (cmd->cmd == NULL || cmd->arg == NULL) 108 goto err; 109 } 110 111 } 112 rv = 1; 113 err: 114 if (rv == 0) 115 ssl_module_free(md); 116 return rv; 117 } 118 119 void SSL_add_ssl_module(void) 120 { 121 CONF_module_add("ssl_conf", ssl_module_init, ssl_module_free); 122 } 123 124 static const struct ssl_conf_name *ssl_name_find(const char *name) 125 { 126 size_t i; 127 const struct ssl_conf_name *nm; 128 if (name == NULL) 129 return NULL; 130 for (i = 0, nm = ssl_names; i < ssl_names_count; i++, nm++) { 131 if (strcmp(nm->name, name) == 0) 132 return nm; 133 } 134 return NULL; 135 } 136 137 static int ssl_do_config(SSL *s, SSL_CTX *ctx, const char *name) 138 { 139 SSL_CONF_CTX *cctx = NULL; 140 size_t i; 141 int rv = 0; 142 unsigned int flags; 143 const SSL_METHOD *meth; 144 const struct ssl_conf_name *nm; 145 struct ssl_conf_cmd *cmd; 146 if (s == NULL && ctx == NULL) { 147 SSLerr(SSL_F_SSL_DO_CONFIG, ERR_R_PASSED_NULL_PARAMETER); 148 goto err; 149 } 150 nm = ssl_name_find(name); 151 if (nm == NULL) { 152 SSLerr(SSL_F_SSL_DO_CONFIG, SSL_R_INVALID_CONFIGURATION_NAME); 153 ERR_add_error_data(2, "name=", name); 154 goto err; 155 } 156 cctx = SSL_CONF_CTX_new(); 157 if (cctx == NULL) 158 goto err; 159 flags = SSL_CONF_FLAG_FILE; 160 flags |= SSL_CONF_FLAG_CERTIFICATE | SSL_CONF_FLAG_REQUIRE_PRIVATE; 161 if (s != NULL) { 162 meth = s->method; 163 SSL_CONF_CTX_set_ssl(cctx, s); 164 } else { 165 meth = ctx->method; 166 SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); 167 } 168 if (meth->ssl_accept != ssl_undefined_function) 169 flags |= SSL_CONF_FLAG_SERVER; 170 if (meth->ssl_connect != ssl_undefined_function) 171 flags |= SSL_CONF_FLAG_CLIENT; 172 SSL_CONF_CTX_set_flags(cctx, flags); 173 for (i = 0, cmd = nm->cmds; i < nm->cmd_count; i++, cmd++) { 174 rv = SSL_CONF_cmd(cctx, cmd->cmd, cmd->arg); 175 if (rv <= 0) { 176 if (rv == -2) 177 SSLerr(SSL_F_SSL_DO_CONFIG, SSL_R_UNKNOWN_COMMAND); 178 else 179 SSLerr(SSL_F_SSL_DO_CONFIG, SSL_R_BAD_VALUE); 180 ERR_add_error_data(6, "section=", name, ", cmd=", cmd->cmd, 181 ", arg=", cmd->arg); 182 goto err; 183 } 184 } 185 rv = SSL_CONF_CTX_finish(cctx); 186 err: 187 SSL_CONF_CTX_free(cctx); 188 return rv <= 0 ? 0 : 1; 189 } 190 191 int SSL_config(SSL *s, const char *name) 192 { 193 return ssl_do_config(s, NULL, name); 194 } 195 196 int SSL_CTX_config(SSL_CTX *ctx, const char *name) 197 { 198 return ssl_do_config(NULL, ctx, name); 199 } 200