]> CyberLeo.Net >> Repos - FreeBSD/releng/9.3.git/blob - crypto/openssl/crypto/conf/conf_lib.c
Fix multiple OpenSSL vulnerabilities.
[FreeBSD/releng/9.3.git] / crypto / openssl / crypto / conf / conf_lib.c
1 /* conf_lib.c */
2 /*
3  * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project
4  * 2000.
5  */
6 /* ====================================================================
7  * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in
18  *    the documentation and/or other materials provided with the
19  *    distribution.
20  *
21  * 3. All advertising materials mentioning features or use of this
22  *    software must display the following acknowledgment:
23  *    "This product includes software developed by the OpenSSL Project
24  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25  *
26  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27  *    endorse or promote products derived from this software without
28  *    prior written permission. For written permission, please contact
29  *    licensing@OpenSSL.org.
30  *
31  * 5. Products derived from this software may not be called "OpenSSL"
32  *    nor may "OpenSSL" appear in their names without prior written
33  *    permission of the OpenSSL Project.
34  *
35  * 6. Redistributions of any form whatsoever must retain the following
36  *    acknowledgment:
37  *    "This product includes software developed by the OpenSSL Project
38  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
44  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51  * OF THE POSSIBILITY OF SUCH DAMAGE.
52  * ====================================================================
53  *
54  * This product includes cryptographic software written by Eric Young
55  * (eay@cryptsoft.com).  This product includes software written by Tim
56  * Hudson (tjh@cryptsoft.com).
57  *
58  */
59
60 #include <stdio.h>
61 #include <openssl/crypto.h>
62 #include <openssl/err.h>
63 #include <openssl/conf.h>
64 #include <openssl/conf_api.h>
65 #include <openssl/lhash.h>
66
67 const char CONF_version[] = "CONF" OPENSSL_VERSION_PTEXT;
68
69 static CONF_METHOD *default_CONF_method = NULL;
70
71 /* Init a 'CONF' structure from an old LHASH */
72
73 void CONF_set_nconf(CONF *conf, LHASH *hash)
74 {
75     if (default_CONF_method == NULL)
76         default_CONF_method = NCONF_default();
77
78     default_CONF_method->init(conf);
79     conf->data = hash;
80 }
81
82 /*
83  * The following section contains the "CONF classic" functions, rewritten in
84  * terms of the new CONF interface.
85  */
86
87 int CONF_set_default_method(CONF_METHOD *meth)
88 {
89     default_CONF_method = meth;
90     return 1;
91 }
92
93 LHASH *CONF_load(LHASH *conf, const char *file, long *eline)
94 {
95     LHASH *ltmp;
96     BIO *in = NULL;
97
98 #ifdef OPENSSL_SYS_VMS
99     in = BIO_new_file(file, "r");
100 #else
101     in = BIO_new_file(file, "rb");
102 #endif
103     if (in == NULL) {
104         CONFerr(CONF_F_CONF_LOAD, ERR_R_SYS_LIB);
105         return NULL;
106     }
107
108     ltmp = CONF_load_bio(conf, in, eline);
109     BIO_free(in);
110
111     return ltmp;
112 }
113
114 #ifndef OPENSSL_NO_FP_API
115 LHASH *CONF_load_fp(LHASH *conf, FILE *fp, long *eline)
116 {
117     BIO *btmp;
118     LHASH *ltmp;
119     if (!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) {
120         CONFerr(CONF_F_CONF_LOAD_FP, ERR_R_BUF_LIB);
121         return NULL;
122     }
123     ltmp = CONF_load_bio(conf, btmp, eline);
124     BIO_free(btmp);
125     return ltmp;
126 }
127 #endif
128
129 LHASH *CONF_load_bio(LHASH *conf, BIO *bp, long *eline)
130 {
131     CONF ctmp;
132     int ret;
133
134     CONF_set_nconf(&ctmp, conf);
135
136     ret = NCONF_load_bio(&ctmp, bp, eline);
137     if (ret)
138         return ctmp.data;
139     return NULL;
140 }
141
142 STACK_OF(CONF_VALUE) *CONF_get_section(LHASH *conf, const char *section)
143 {
144     if (conf == NULL) {
145         return NULL;
146     } else {
147         CONF ctmp;
148         CONF_set_nconf(&ctmp, conf);
149         return NCONF_get_section(&ctmp, section);
150     }
151 }
152
153 char *CONF_get_string(LHASH *conf, const char *group, const char *name)
154 {
155     if (conf == NULL) {
156         return NCONF_get_string(NULL, group, name);
157     } else {
158         CONF ctmp;
159         CONF_set_nconf(&ctmp, conf);
160         return NCONF_get_string(&ctmp, group, name);
161     }
162 }
163
164 long CONF_get_number(LHASH *conf, const char *group, const char *name)
165 {
166     int status;
167     long result = 0;
168
169     if (conf == NULL) {
170         status = NCONF_get_number_e(NULL, group, name, &result);
171     } else {
172         CONF ctmp;
173         CONF_set_nconf(&ctmp, conf);
174         status = NCONF_get_number_e(&ctmp, group, name, &result);
175     }
176
177     if (status == 0) {
178         /* This function does not believe in errors... */
179         ERR_clear_error();
180     }
181     return result;
182 }
183
184 void CONF_free(LHASH *conf)
185 {
186     CONF ctmp;
187     CONF_set_nconf(&ctmp, conf);
188     NCONF_free_data(&ctmp);
189 }
190
191 #ifndef OPENSSL_NO_FP_API
192 int CONF_dump_fp(LHASH *conf, FILE *out)
193 {
194     BIO *btmp;
195     int ret;
196
197     if (!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) {
198         CONFerr(CONF_F_CONF_DUMP_FP, ERR_R_BUF_LIB);
199         return 0;
200     }
201     ret = CONF_dump_bio(conf, btmp);
202     BIO_free(btmp);
203     return ret;
204 }
205 #endif
206
207 int CONF_dump_bio(LHASH *conf, BIO *out)
208 {
209     CONF ctmp;
210     CONF_set_nconf(&ctmp, conf);
211     return NCONF_dump_bio(&ctmp, out);
212 }
213
214 /*
215  * The following section contains the "New CONF" functions.  They are
216  * completely centralised around a new CONF structure that may contain
217  * basically anything, but at least a method pointer and a table of data.
218  * These functions are also written in terms of the bridge functions used by
219  * the "CONF classic" functions, for consistency.
220  */
221
222 CONF *NCONF_new(CONF_METHOD *meth)
223 {
224     CONF *ret;
225
226     if (meth == NULL)
227         meth = NCONF_default();
228
229     ret = meth->create(meth);
230     if (ret == NULL) {
231         CONFerr(CONF_F_NCONF_NEW, ERR_R_MALLOC_FAILURE);
232         return (NULL);
233     }
234
235     return ret;
236 }
237
238 void NCONF_free(CONF *conf)
239 {
240     if (conf == NULL)
241         return;
242     conf->meth->destroy(conf);
243 }
244
245 void NCONF_free_data(CONF *conf)
246 {
247     if (conf == NULL)
248         return;
249     conf->meth->destroy_data(conf);
250 }
251
252 int NCONF_load(CONF *conf, const char *file, long *eline)
253 {
254     if (conf == NULL) {
255         CONFerr(CONF_F_NCONF_LOAD, CONF_R_NO_CONF);
256         return 0;
257     }
258
259     return conf->meth->load(conf, file, eline);
260 }
261
262 #ifndef OPENSSL_NO_FP_API
263 int NCONF_load_fp(CONF *conf, FILE *fp, long *eline)
264 {
265     BIO *btmp;
266     int ret;
267     if (!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) {
268         CONFerr(CONF_F_NCONF_LOAD_FP, ERR_R_BUF_LIB);
269         return 0;
270     }
271     ret = NCONF_load_bio(conf, btmp, eline);
272     BIO_free(btmp);
273     return ret;
274 }
275 #endif
276
277 int NCONF_load_bio(CONF *conf, BIO *bp, long *eline)
278 {
279     if (conf == NULL) {
280         CONFerr(CONF_F_NCONF_LOAD_BIO, CONF_R_NO_CONF);
281         return 0;
282     }
283
284     return conf->meth->load_bio(conf, bp, eline);
285 }
286
287 STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section)
288 {
289     if (conf == NULL) {
290         CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_CONF);
291         return NULL;
292     }
293
294     if (section == NULL) {
295         CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_SECTION);
296         return NULL;
297     }
298
299     return _CONF_get_section_values(conf, section);
300 }
301
302 char *NCONF_get_string(const CONF *conf, const char *group, const char *name)
303 {
304     char *s = _CONF_get_string(conf, group, name);
305
306     /*
307      * Since we may get a value from an environment variable even if conf is
308      * NULL, let's check the value first
309      */
310     if (s)
311         return s;
312
313     if (conf == NULL) {
314         CONFerr(CONF_F_NCONF_GET_STRING,
315                 CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE);
316         return NULL;
317     }
318     CONFerr(CONF_F_NCONF_GET_STRING, CONF_R_NO_VALUE);
319     ERR_add_error_data(4, "group=", group, " name=", name);
320     return NULL;
321 }
322
323 int NCONF_get_number_e(const CONF *conf, const char *group, const char *name,
324                        long *result)
325 {
326     char *str;
327
328     if (result == NULL) {
329         CONFerr(CONF_F_NCONF_GET_NUMBER_E, ERR_R_PASSED_NULL_PARAMETER);
330         return 0;
331     }
332
333     str = NCONF_get_string(conf, group, name);
334
335     if (str == NULL)
336         return 0;
337
338     for (*result = 0; conf->meth->is_number(conf, *str);) {
339         *result = (*result) * 10 + conf->meth->to_int(conf, *str);
340         str++;
341     }
342
343     return 1;
344 }
345
346 #ifndef OPENSSL_NO_FP_API
347 int NCONF_dump_fp(const CONF *conf, FILE *out)
348 {
349     BIO *btmp;
350     int ret;
351     if (!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) {
352         CONFerr(CONF_F_NCONF_DUMP_FP, ERR_R_BUF_LIB);
353         return 0;
354     }
355     ret = NCONF_dump_bio(conf, btmp);
356     BIO_free(btmp);
357     return ret;
358 }
359 #endif
360
361 int NCONF_dump_bio(const CONF *conf, BIO *out)
362 {
363     if (conf == NULL) {
364         CONFerr(CONF_F_NCONF_DUMP_BIO, CONF_R_NO_CONF);
365         return 0;
366     }
367
368     return conf->meth->dump(conf, out);
369 }
370
371 /* This function should be avoided */
372 #if 0
373 long NCONF_get_number(CONF *conf, char *group, char *name)
374 {
375     int status;
376     long ret = 0;
377
378     status = NCONF_get_number_e(conf, group, name, &ret);
379     if (status == 0) {
380         /* This function does not believe in errors... */
381         ERR_get_error();
382     }
383     return ret;
384 }
385 #endif