eng_cnf.c revision 296341
1139747Simp/* eng_cnf.c */ 24Srgrimes/* 34Srgrimes * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project 44Srgrimes * 2001. 58876Srgrimes */ 64Srgrimes/* ==================================================================== 74Srgrimes * Copyright (c) 2001 The OpenSSL Project. All rights reserved. 84Srgrimes * 94Srgrimes * Redistribution and use in source and binary forms, with or without 104Srgrimes * modification, are permitted provided that the following conditions 118876Srgrimes * are met: 128876Srgrimes * 134Srgrimes * 1. Redistributions of source code must retain the above copyright 144Srgrimes * notice, this list of conditions and the following disclaimer. 158876Srgrimes * 164Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 178876Srgrimes * notice, this list of conditions and the following disclaimer in 184Srgrimes * the documentation and/or other materials provided with the 194Srgrimes * distribution. 204Srgrimes * 214Srgrimes * 3. All advertising materials mentioning features or use of this 228876Srgrimes * software must display the following acknowledgment: 234Srgrimes * "This product includes software developed by the OpenSSL Project 244Srgrimes * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 254Srgrimes * 264Srgrimes * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 274Srgrimes * endorse or promote products derived from this software without 284Srgrimes * prior written permission. For written permission, please contact 294Srgrimes * licensing@OpenSSL.org. 304Srgrimes * 31116176Sobrien * 5. Products derived from this software may not be called "OpenSSL" 32116176Sobrien * nor may "OpenSSL" appear in their names without prior written 33116176Sobrien * permission of the OpenSSL Project. 342056Swollman * 3547098Sbde * 6. Redistributions of any form whatsoever must retain the following 3612734Sbde * acknowledgment: 372056Swollman * "This product includes software developed by the OpenSSL Project 384Srgrimes * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 394Srgrimes * 404Srgrimes * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 4192756Salfred * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 424Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 4312515Sphk * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 444Srgrimes * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4537504Sbde * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 464Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 474Srgrimes * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48137117Sjhb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49195699Srwatson * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50195699Srwatson * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51195699Srwatson * OF THE POSSIBILITY OF SUCH DAMAGE. 52195699Srwatson * ==================================================================== 53195699Srwatson * 54195699Srwatson * This product includes cryptographic software written by Eric Young 554Srgrimes * (eay@cryptsoft.com). This product includes software written by Tim 56131952Smarcel * Hudson (tjh@cryptsoft.com). 57131952Smarcel * 584Srgrimes */ 5912515Sphk 60131952Smarcel#include "eng_int.h" 614Srgrimes#include <openssl/conf.h> 624Srgrimes 63131952Smarcel/* #define ENGINE_CONF_DEBUG */ 644Srgrimes 654Srgrimes/* ENGINE config module */ 664Srgrimes 67131952Smarcelstatic char *skip_dot(char *name) 68131952Smarcel{ 69131952Smarcel char *p; 70131952Smarcel p = strchr(name, '.'); 71131952Smarcel if (p) 724Srgrimes return p + 1; 73131952Smarcel return name; 74131952Smarcel} 75131952Smarcel 76131952Smarcelstatic STACK_OF(ENGINE) *initialized_engines = NULL; 77131952Smarcel 784Srgrimesstatic int int_engine_init(ENGINE *e) 794Srgrimes{ 804Srgrimes if (!ENGINE_init(e)) 814Srgrimes return 0; 824Srgrimes if (!initialized_engines) 834Srgrimes initialized_engines = sk_ENGINE_new_null(); 844Srgrimes if (!initialized_engines || !sk_ENGINE_push(initialized_engines, e)) { 85131952Smarcel ENGINE_finish(e); 864Srgrimes return 0; 874Srgrimes } 884Srgrimes return 1; 894Srgrimes} 90131952Smarcel 914Srgrimesstatic int int_engine_configure(char *name, char *value, const CONF *cnf) 92131952Smarcel{ 934Srgrimes int i; 944Srgrimes int ret = 0; 95131952Smarcel long do_init = -1; 96131952Smarcel STACK_OF(CONF_VALUE) *ecmds; 974Srgrimes CONF_VALUE *ecmd = NULL; 984Srgrimes char *ctrlname, *ctrlvalue; 994Srgrimes ENGINE *e = NULL; 1004Srgrimes int soft = 0; 101131952Smarcel 1024Srgrimes name = skip_dot(name); 103131952Smarcel#ifdef ENGINE_CONF_DEBUG 1044Srgrimes fprintf(stderr, "Configuring engine %s\n", name); 1054Srgrimes#endif 106131952Smarcel /* Value is a section containing ENGINE commands */ 107131952Smarcel ecmds = NCONF_get_section(cnf, value); 1084Srgrimes 109131952Smarcel if (!ecmds) { 1104Srgrimes ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, 111131952Smarcel ENGINE_R_ENGINE_SECTION_ERROR); 112131952Smarcel return 0; 113131952Smarcel } 114131952Smarcel 115131952Smarcel for (i = 0; i < sk_CONF_VALUE_num(ecmds); i++) { 1164Srgrimes ecmd = sk_CONF_VALUE_value(ecmds, i); 1174Srgrimes ctrlname = skip_dot(ecmd->name); 118131952Smarcel ctrlvalue = ecmd->value; 119131952Smarcel#ifdef ENGINE_CONF_DEBUG 1204Srgrimes fprintf(stderr, "ENGINE conf: doing ctrl(%s,%s)\n", ctrlname, 121131952Smarcel ctrlvalue); 1224Srgrimes#endif 123131952Smarcel 124131952Smarcel /* First handle some special pseudo ctrls */ 125131952Smarcel 126131952Smarcel /* Override engine name to use */ 127131952Smarcel if (!strcmp(ctrlname, "engine_id")) 1284Srgrimes name = ctrlvalue; 1294Srgrimes else if (!strcmp(ctrlname, "soft_load")) 1304Srgrimes soft = 1; 131131952Smarcel /* Load a dynamic ENGINE */ 1324Srgrimes else if (!strcmp(ctrlname, "dynamic_path")) { 1334Srgrimes e = ENGINE_by_id("dynamic"); 134131952Smarcel if (!e) 135131952Smarcel goto err; 1364Srgrimes if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", ctrlvalue, 0)) 1374Srgrimes goto err; 1384Srgrimes if (!ENGINE_ctrl_cmd_string(e, "LIST_ADD", "2", 0)) 139131952Smarcel goto err; 140131952Smarcel if (!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) 1414Srgrimes goto err; 1424Srgrimes } 143131952Smarcel /* ... add other pseudos here ... */ 144131952Smarcel else { 1454Srgrimes /* 1464Srgrimes * At this point we need an ENGINE structural reference if we 1474Srgrimes * don't already have one. 1484Srgrimes */ 149131952Smarcel if (!e) { 1504Srgrimes e = ENGINE_by_id(name); 1514Srgrimes if (!e && soft) { 152131952Smarcel ERR_clear_error(); 153131952Smarcel return 1; 1544Srgrimes } 155131952Smarcel if (!e) 156131952Smarcel goto err; 1574Srgrimes } 158131952Smarcel /* 1594Srgrimes * Allow "EMPTY" to mean no value: this allows a valid "value" to 160 * be passed to ctrls of type NO_INPUT 161 */ 162 if (!strcmp(ctrlvalue, "EMPTY")) 163 ctrlvalue = NULL; 164 if (!strcmp(ctrlname, "init")) { 165 if (!NCONF_get_number_e(cnf, value, "init", &do_init)) 166 goto err; 167 if (do_init == 1) { 168 if (!int_engine_init(e)) 169 goto err; 170 } else if (do_init != 0) { 171 ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, 172 ENGINE_R_INVALID_INIT_VALUE); 173 goto err; 174 } 175 } else if (!strcmp(ctrlname, "default_algorithms")) { 176 if (!ENGINE_set_default_string(e, ctrlvalue)) 177 goto err; 178 } else if (!ENGINE_ctrl_cmd_string(e, ctrlname, ctrlvalue, 0)) 179 goto err; 180 } 181 182 } 183 if (e && (do_init == -1) && !int_engine_init(e)) { 184 ecmd = NULL; 185 goto err; 186 } 187 ret = 1; 188 err: 189 if (ret != 1) { 190 ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, 191 ENGINE_R_ENGINE_CONFIGURATION_ERROR); 192 if (ecmd) 193 ERR_add_error_data(6, "section=", ecmd->section, 194 ", name=", ecmd->name, 195 ", value=", ecmd->value); 196 } 197 if (e) 198 ENGINE_free(e); 199 return ret; 200} 201 202static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf) 203{ 204 STACK_OF(CONF_VALUE) *elist; 205 CONF_VALUE *cval; 206 int i; 207#ifdef ENGINE_CONF_DEBUG 208 fprintf(stderr, "Called engine module: name %s, value %s\n", 209 CONF_imodule_get_name(md), CONF_imodule_get_value(md)); 210#endif 211 /* Value is a section containing ENGINEs to configure */ 212 elist = NCONF_get_section(cnf, CONF_imodule_get_value(md)); 213 214 if (!elist) { 215 ENGINEerr(ENGINE_F_INT_ENGINE_MODULE_INIT, 216 ENGINE_R_ENGINES_SECTION_ERROR); 217 return 0; 218 } 219 220 for (i = 0; i < sk_CONF_VALUE_num(elist); i++) { 221 cval = sk_CONF_VALUE_value(elist, i); 222 if (!int_engine_configure(cval->name, cval->value, cnf)) 223 return 0; 224 } 225 226 return 1; 227} 228 229static void int_engine_module_finish(CONF_IMODULE *md) 230{ 231 ENGINE *e; 232 while ((e = sk_ENGINE_pop(initialized_engines))) 233 ENGINE_finish(e); 234 sk_ENGINE_free(initialized_engines); 235 initialized_engines = NULL; 236} 237 238void ENGINE_add_conf_module(void) 239{ 240 CONF_module_add("engines", 241 int_engine_module_init, int_engine_module_finish); 242} 243