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