16f9291ceSJung-uk Kim /*
2*b077aed3SPierre Pronchery * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved.
35c87c606SMark Murray *
4*b077aed3SPierre Pronchery * Licensed under the Apache License 2.0 (the "License"). You may not use
5e71b7053SJung-uk Kim * this file except in compliance with the License. You can obtain a copy
6e71b7053SJung-uk Kim * in the file LICENSE in the source distribution or at
7e71b7053SJung-uk Kim * https://www.openssl.org/source/license.html
85c87c606SMark Murray */
95c87c606SMark Murray
10*b077aed3SPierre Pronchery /* We need to use some engine deprecated APIs */
11*b077aed3SPierre Pronchery #define OPENSSL_SUPPRESS_DEPRECATED
12*b077aed3SPierre Pronchery
1317f01e99SJung-uk Kim #include "eng_local.h"
145c87c606SMark Murray #include <openssl/conf.h>
15*b077aed3SPierre Pronchery #include <openssl/trace.h>
165c87c606SMark Murray
175c87c606SMark Murray /* ENGINE config module */
185c87c606SMark Murray
skip_dot(const char * name)19e71b7053SJung-uk Kim static const char *skip_dot(const char *name)
205c87c606SMark Murray {
21e71b7053SJung-uk Kim const char *p = strchr(name, '.');
22e71b7053SJung-uk Kim
23e71b7053SJung-uk Kim if (p != NULL)
245c87c606SMark Murray return p + 1;
255c87c606SMark Murray return name;
265c87c606SMark Murray }
275c87c606SMark Murray
285c87c606SMark Murray static STACK_OF(ENGINE) *initialized_engines = NULL;
295c87c606SMark Murray
int_engine_init(ENGINE * e)305c87c606SMark Murray static int int_engine_init(ENGINE *e)
315c87c606SMark Murray {
325c87c606SMark Murray if (!ENGINE_init(e))
335c87c606SMark Murray return 0;
345c87c606SMark Murray if (!initialized_engines)
355c87c606SMark Murray initialized_engines = sk_ENGINE_new_null();
366f9291ceSJung-uk Kim if (!initialized_engines || !sk_ENGINE_push(initialized_engines, e)) {
375c87c606SMark Murray ENGINE_finish(e);
385c87c606SMark Murray return 0;
395c87c606SMark Murray }
405c87c606SMark Murray return 1;
415c87c606SMark Murray }
425c87c606SMark Murray
int_engine_configure(const char * name,const char * value,const CONF * cnf)43e71b7053SJung-uk Kim static int int_engine_configure(const char *name, const char *value, const CONF *cnf)
445c87c606SMark Murray {
455c87c606SMark Murray int i;
465c87c606SMark Murray int ret = 0;
475c87c606SMark Murray long do_init = -1;
485c87c606SMark Murray STACK_OF(CONF_VALUE) *ecmds;
496a599222SSimon L. B. Nielsen CONF_VALUE *ecmd = NULL;
50e71b7053SJung-uk Kim const char *ctrlname, *ctrlvalue;
515c87c606SMark Murray ENGINE *e = NULL;
52db522d3aSSimon L. B. Nielsen int soft = 0;
53db522d3aSSimon L. B. Nielsen
545c87c606SMark Murray name = skip_dot(name);
55*b077aed3SPierre Pronchery OSSL_TRACE1(CONF, "Configuring engine %s\n", name);
565c87c606SMark Murray /* Value is a section containing ENGINE commands */
575c87c606SMark Murray ecmds = NCONF_get_section(cnf, value);
585c87c606SMark Murray
596f9291ceSJung-uk Kim if (!ecmds) {
60*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_ENGINE, ENGINE_R_ENGINE_SECTION_ERROR);
615c87c606SMark Murray return 0;
625c87c606SMark Murray }
635c87c606SMark Murray
646f9291ceSJung-uk Kim for (i = 0; i < sk_CONF_VALUE_num(ecmds); i++) {
655c87c606SMark Murray ecmd = sk_CONF_VALUE_value(ecmds, i);
665c87c606SMark Murray ctrlname = skip_dot(ecmd->name);
675c87c606SMark Murray ctrlvalue = ecmd->value;
68*b077aed3SPierre Pronchery OSSL_TRACE2(CONF, "ENGINE: doing ctrl(%s,%s)\n",
69*b077aed3SPierre Pronchery ctrlname, ctrlvalue);
705c87c606SMark Murray
715c87c606SMark Murray /* First handle some special pseudo ctrls */
725c87c606SMark Murray
735c87c606SMark Murray /* Override engine name to use */
74e71b7053SJung-uk Kim if (strcmp(ctrlname, "engine_id") == 0)
755c87c606SMark Murray name = ctrlvalue;
76e71b7053SJung-uk Kim else if (strcmp(ctrlname, "soft_load") == 0)
77db522d3aSSimon L. B. Nielsen soft = 1;
785c87c606SMark Murray /* Load a dynamic ENGINE */
79e71b7053SJung-uk Kim else if (strcmp(ctrlname, "dynamic_path") == 0) {
805c87c606SMark Murray e = ENGINE_by_id("dynamic");
815c87c606SMark Murray if (!e)
825c87c606SMark Murray goto err;
835c87c606SMark Murray if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", ctrlvalue, 0))
845c87c606SMark Murray goto err;
855c87c606SMark Murray if (!ENGINE_ctrl_cmd_string(e, "LIST_ADD", "2", 0))
865c87c606SMark Murray goto err;
875c87c606SMark Murray if (!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
885c87c606SMark Murray goto err;
895c87c606SMark Murray }
905c87c606SMark Murray /* ... add other pseudos here ... */
916f9291ceSJung-uk Kim else {
926f9291ceSJung-uk Kim /*
936f9291ceSJung-uk Kim * At this point we need an ENGINE structural reference if we
946f9291ceSJung-uk Kim * don't already have one.
955c87c606SMark Murray */
966f9291ceSJung-uk Kim if (!e) {
975c87c606SMark Murray e = ENGINE_by_id(name);
986f9291ceSJung-uk Kim if (!e && soft) {
99db522d3aSSimon L. B. Nielsen ERR_clear_error();
100db522d3aSSimon L. B. Nielsen return 1;
101db522d3aSSimon L. B. Nielsen }
1025c87c606SMark Murray if (!e)
1036a599222SSimon L. B. Nielsen goto err;
1045c87c606SMark Murray }
1056f9291ceSJung-uk Kim /*
1066f9291ceSJung-uk Kim * Allow "EMPTY" to mean no value: this allows a valid "value" to
1076f9291ceSJung-uk Kim * be passed to ctrls of type NO_INPUT
1085c87c606SMark Murray */
109e71b7053SJung-uk Kim if (strcmp(ctrlvalue, "EMPTY") == 0)
1105c87c606SMark Murray ctrlvalue = NULL;
111e71b7053SJung-uk Kim if (strcmp(ctrlname, "init") == 0) {
1125c87c606SMark Murray if (!NCONF_get_number_e(cnf, value, "init", &do_init))
1135c87c606SMark Murray goto err;
1146f9291ceSJung-uk Kim if (do_init == 1) {
1155c87c606SMark Murray if (!int_engine_init(e))
1165c87c606SMark Murray goto err;
1176f9291ceSJung-uk Kim } else if (do_init != 0) {
118*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INVALID_INIT_VALUE);
1195c87c606SMark Murray goto err;
1205c87c606SMark Murray }
121e71b7053SJung-uk Kim } else if (strcmp(ctrlname, "default_algorithms") == 0) {
1225c87c606SMark Murray if (!ENGINE_set_default_string(e, ctrlvalue))
1235c87c606SMark Murray goto err;
1246f9291ceSJung-uk Kim } else if (!ENGINE_ctrl_cmd_string(e, ctrlname, ctrlvalue, 0))
1256a599222SSimon L. B. Nielsen goto err;
1265c87c606SMark Murray }
1275c87c606SMark Murray
1285c87c606SMark Murray }
1296f9291ceSJung-uk Kim if (e && (do_init == -1) && !int_engine_init(e)) {
1306a599222SSimon L. B. Nielsen ecmd = NULL;
1315c87c606SMark Murray goto err;
1326a599222SSimon L. B. Nielsen }
1335c87c606SMark Murray ret = 1;
1345c87c606SMark Murray err:
1356f9291ceSJung-uk Kim if (ret != 1) {
136*b077aed3SPierre Pronchery if (ecmd == NULL)
137*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_ENGINE, ENGINE_R_ENGINE_CONFIGURATION_ERROR);
138*b077aed3SPierre Pronchery else
139*b077aed3SPierre Pronchery ERR_raise_data(ERR_LIB_ENGINE, ENGINE_R_ENGINE_CONFIGURATION_ERROR,
140*b077aed3SPierre Pronchery "section=%s, name=%s, value=%s",
141*b077aed3SPierre Pronchery ecmd->section, ecmd->name, ecmd->value);
1426a599222SSimon L. B. Nielsen }
1435c87c606SMark Murray ENGINE_free(e);
1445c87c606SMark Murray return ret;
1455c87c606SMark Murray }
1465c87c606SMark Murray
int_engine_module_init(CONF_IMODULE * md,const CONF * cnf)1475c87c606SMark Murray static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf)
1485c87c606SMark Murray {
1495c87c606SMark Murray STACK_OF(CONF_VALUE) *elist;
1505c87c606SMark Murray CONF_VALUE *cval;
1515c87c606SMark Murray int i;
152*b077aed3SPierre Pronchery OSSL_TRACE2(CONF, "Called engine module: name %s, value %s\n",
1535c87c606SMark Murray CONF_imodule_get_name(md), CONF_imodule_get_value(md));
1545c87c606SMark Murray /* Value is a section containing ENGINEs to configure */
1555c87c606SMark Murray elist = NCONF_get_section(cnf, CONF_imodule_get_value(md));
1565c87c606SMark Murray
1576f9291ceSJung-uk Kim if (!elist) {
158*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_ENGINE, ENGINE_R_ENGINES_SECTION_ERROR);
1595c87c606SMark Murray return 0;
1605c87c606SMark Murray }
1615c87c606SMark Murray
1626f9291ceSJung-uk Kim for (i = 0; i < sk_CONF_VALUE_num(elist); i++) {
1635c87c606SMark Murray cval = sk_CONF_VALUE_value(elist, i);
1645c87c606SMark Murray if (!int_engine_configure(cval->name, cval->value, cnf))
1655c87c606SMark Murray return 0;
1665c87c606SMark Murray }
1675c87c606SMark Murray
1685c87c606SMark Murray return 1;
1695c87c606SMark Murray }
1705c87c606SMark Murray
int_engine_module_finish(CONF_IMODULE * md)1715c87c606SMark Murray static void int_engine_module_finish(CONF_IMODULE *md)
1725c87c606SMark Murray {
1735c87c606SMark Murray ENGINE *e;
174e71b7053SJung-uk Kim
1755c87c606SMark Murray while ((e = sk_ENGINE_pop(initialized_engines)))
1765c87c606SMark Murray ENGINE_finish(e);
1775c87c606SMark Murray sk_ENGINE_free(initialized_engines);
1785c87c606SMark Murray initialized_engines = NULL;
1795c87c606SMark Murray }
1805c87c606SMark Murray
ENGINE_add_conf_module(void)1815c87c606SMark Murray void ENGINE_add_conf_module(void)
1825c87c606SMark Murray {
1835c87c606SMark Murray CONF_module_add("engines",
1846f9291ceSJung-uk Kim int_engine_module_init, int_engine_module_finish);
1855c87c606SMark Murray }
186