Coverage Report

Created: 2018-08-29 13:53

/src/openssl/crypto/engine/eng_cnf.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2002-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 "eng_int.h"
11
#include <openssl/conf.h>
12
13
/* #define ENGINE_CONF_DEBUG */
14
15
/* ENGINE config module */
16
17
static const char *skip_dot(const char *name)
18
0
{
19
0
    const char *p = strchr(name, '.');
20
0
21
0
    if (p != NULL)
22
0
        return p + 1;
23
0
    return name;
24
0
}
25
26
static STACK_OF(ENGINE) *initialized_engines = NULL;
27
28
static int int_engine_init(ENGINE *e)
29
0
{
30
0
    if (!ENGINE_init(e))
31
0
        return 0;
32
0
    if (!initialized_engines)
33
0
        initialized_engines = sk_ENGINE_new_null();
34
0
    if (!initialized_engines || !sk_ENGINE_push(initialized_engines, e)) {
35
0
        ENGINE_finish(e);
36
0
        return 0;
37
0
    }
38
0
    return 1;
39
0
}
40
41
static int int_engine_configure(const char *name, const char *value, const CONF *cnf)
42
{
43
    int i;
44
    int ret = 0;
45
    long do_init = -1;
46
    STACK_OF(CONF_VALUE) *ecmds;
47
    CONF_VALUE *ecmd = NULL;
48
    const char *ctrlname, *ctrlvalue;
49
    ENGINE *e = NULL;
50
    int soft = 0;
51
52
    name = skip_dot(name);
53
#ifdef ENGINE_CONF_DEBUG
54
    fprintf(stderr, "Configuring engine %s\n", name);
55
#endif
56
    /* Value is a section containing ENGINE commands */
57
    ecmds = NCONF_get_section(cnf, value);
58
59
    if (!ecmds) {
60
        ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE,
61
                  ENGINE_R_ENGINE_SECTION_ERROR);
62
        return 0;
63
    }
64
65
    for (i = 0; i < sk_CONF_VALUE_num(ecmds); i++) {
66
        ecmd = sk_CONF_VALUE_value(ecmds, i);
67
        ctrlname = skip_dot(ecmd->name);
68
        ctrlvalue = ecmd->value;
69
#ifdef ENGINE_CONF_DEBUG
70
        fprintf(stderr, "ENGINE conf: doing ctrl(%s,%s)\n", ctrlname,
71
                ctrlvalue);
72
#endif
73
74
        /* First handle some special pseudo ctrls */
75
76
        /* Override engine name to use */
77
        if (strcmp(ctrlname, "engine_id") == 0)
78
            name = ctrlvalue;
79
        else if (strcmp(ctrlname, "soft_load") == 0)
80
            soft = 1;
81
        /* Load a dynamic ENGINE */
82
        else if (strcmp(ctrlname, "dynamic_path") == 0) {
83
            e = ENGINE_by_id("dynamic");
84
            if (!e)
85
                goto err;
86
            if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", ctrlvalue, 0))
87
                goto err;
88
            if (!ENGINE_ctrl_cmd_string(e, "LIST_ADD", "2", 0))
89
                goto err;
90
            if (!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
91
                goto err;
92
        }
93
        /* ... add other pseudos here ... */
94
        else {
95
            /*
96
             * At this point we need an ENGINE structural reference if we
97
             * don't already have one.
98
             */
99
            if (!e) {
100
                e = ENGINE_by_id(name);
101
                if (!e && soft) {
102
                    ERR_clear_error();
103
                    return 1;
104
                }
105
                if (!e)
106
                    goto err;
107
            }
108
            /*
109
             * Allow "EMPTY" to mean no value: this allows a valid "value" to
110
             * be passed to ctrls of type NO_INPUT
111
             */
112
            if (strcmp(ctrlvalue, "EMPTY") == 0)
113
                ctrlvalue = NULL;
114
            if (strcmp(ctrlname, "init") == 0) {
115
                if (!NCONF_get_number_e(cnf, value, "init", &do_init))
116
                    goto err;
117
                if (do_init == 1) {
118
                    if (!int_engine_init(e))
119
                        goto err;
120
                } else if (do_init != 0) {
121
                    ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE,
122
                              ENGINE_R_INVALID_INIT_VALUE);
123
                    goto err;
124
                }
125
            } else if (strcmp(ctrlname, "default_algorithms") == 0) {
126
                if (!ENGINE_set_default_string(e, ctrlvalue))
127
                    goto err;
128
            } else if (!ENGINE_ctrl_cmd_string(e, ctrlname, ctrlvalue, 0))
129
                goto err;
130
        }
131
132
    }
133
    if (e && (do_init == -1) && !int_engine_init(e)) {
134
        ecmd = NULL;
135
        goto err;
136
    }
137
    ret = 1;
138
 err:
139
    if (ret != 1) {
140
        ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE,
141
                  ENGINE_R_ENGINE_CONFIGURATION_ERROR);
142
        if (ecmd)
143
            ERR_add_error_data(6, "section=", ecmd->section,
144
                               ", name=", ecmd->name,
145
                               ", value=", ecmd->value);
146
    }
147
    ENGINE_free(e);
148
    return ret;
149
}
150
151
static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf)
152
0
{
153
0
    STACK_OF(CONF_VALUE) *elist;
154
0
    CONF_VALUE *cval;
155
0
    int i;
156
#ifdef ENGINE_CONF_DEBUG
157
    fprintf(stderr, "Called engine module: name %s, value %s\n",
158
            CONF_imodule_get_name(md), CONF_imodule_get_value(md));
159
#endif
160
    /* Value is a section containing ENGINEs to configure */
161
0
    elist = NCONF_get_section(cnf, CONF_imodule_get_value(md));
162
0
163
0
    if (!elist) {
164
0
        ENGINEerr(ENGINE_F_INT_ENGINE_MODULE_INIT,
165
0
                  ENGINE_R_ENGINES_SECTION_ERROR);
166
0
        return 0;
167
0
    }
168
0
169
0
    for (i = 0; i < sk_CONF_VALUE_num(elist); i++) {
170
0
        cval = sk_CONF_VALUE_value(elist, i);
171
0
        if (!int_engine_configure(cval->name, cval->value, cnf))
172
0
            return 0;
173
0
    }
174
0
175
0
    return 1;
176
0
}
177
178
static void int_engine_module_finish(CONF_IMODULE *md)
179
0
{
180
0
    ENGINE *e;
181
0
182
0
    while ((e = sk_ENGINE_pop(initialized_engines)))
183
0
        ENGINE_finish(e);
184
0
    sk_ENGINE_free(initialized_engines);
185
0
    initialized_engines = NULL;
186
0
}
187
188
void ENGINE_add_conf_module(void)
189
0
{
190
0
    CONF_module_add("engines",
191
0
                    int_engine_module_init, int_engine_module_finish);
192
0
}