xref: /freebsd/crypto/openssl/crypto/conf/conf_api.c (revision dea77ea6)
1ddd58736SKris Kennaway /* conf_api.c */
2ddd58736SKris Kennaway /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3ddd58736SKris Kennaway  * All rights reserved.
4ddd58736SKris Kennaway  *
5ddd58736SKris Kennaway  * This package is an SSL implementation written
6ddd58736SKris Kennaway  * by Eric Young (eay@cryptsoft.com).
7ddd58736SKris Kennaway  * The implementation was written so as to conform with Netscapes SSL.
8ddd58736SKris Kennaway  *
9ddd58736SKris Kennaway  * This library is free for commercial and non-commercial use as long as
10ddd58736SKris Kennaway  * the following conditions are aheared to.  The following conditions
11ddd58736SKris Kennaway  * apply to all code found in this distribution, be it the RC4, RSA,
12ddd58736SKris Kennaway  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13ddd58736SKris Kennaway  * included with this distribution is covered by the same copyright terms
14ddd58736SKris Kennaway  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15ddd58736SKris Kennaway  *
16ddd58736SKris Kennaway  * Copyright remains Eric Young's, and as such any Copyright notices in
17ddd58736SKris Kennaway  * the code are not to be removed.
18ddd58736SKris Kennaway  * If this package is used in a product, Eric Young should be given attribution
19ddd58736SKris Kennaway  * as the author of the parts of the library used.
20ddd58736SKris Kennaway  * This can be in the form of a textual message at program startup or
21ddd58736SKris Kennaway  * in documentation (online or textual) provided with the package.
22ddd58736SKris Kennaway  *
23ddd58736SKris Kennaway  * Redistribution and use in source and binary forms, with or without
24ddd58736SKris Kennaway  * modification, are permitted provided that the following conditions
25ddd58736SKris Kennaway  * are met:
26ddd58736SKris Kennaway  * 1. Redistributions of source code must retain the copyright
27ddd58736SKris Kennaway  *    notice, this list of conditions and the following disclaimer.
28ddd58736SKris Kennaway  * 2. Redistributions in binary form must reproduce the above copyright
29ddd58736SKris Kennaway  *    notice, this list of conditions and the following disclaimer in the
30ddd58736SKris Kennaway  *    documentation and/or other materials provided with the distribution.
31ddd58736SKris Kennaway  * 3. All advertising materials mentioning features or use of this software
32ddd58736SKris Kennaway  *    must display the following acknowledgement:
33ddd58736SKris Kennaway  *    "This product includes cryptographic software written by
34ddd58736SKris Kennaway  *     Eric Young (eay@cryptsoft.com)"
35ddd58736SKris Kennaway  *    The word 'cryptographic' can be left out if the rouines from the library
36ddd58736SKris Kennaway  *    being used are not cryptographic related :-).
37ddd58736SKris Kennaway  * 4. If you include any Windows specific code (or a derivative thereof) from
38ddd58736SKris Kennaway  *    the apps directory (application code) you must include an acknowledgement:
39ddd58736SKris Kennaway  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40ddd58736SKris Kennaway  *
41ddd58736SKris Kennaway  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42ddd58736SKris Kennaway  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43ddd58736SKris Kennaway  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44ddd58736SKris Kennaway  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45ddd58736SKris Kennaway  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46ddd58736SKris Kennaway  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47ddd58736SKris Kennaway  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48ddd58736SKris Kennaway  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49ddd58736SKris Kennaway  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50ddd58736SKris Kennaway  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51ddd58736SKris Kennaway  * SUCH DAMAGE.
52ddd58736SKris Kennaway  *
53ddd58736SKris Kennaway  * The licence and distribution terms for any publically available version or
54ddd58736SKris Kennaway  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55ddd58736SKris Kennaway  * copied and put under another distribution licence
56ddd58736SKris Kennaway  * [including the GNU Public Licence.]
57ddd58736SKris Kennaway  */
58ddd58736SKris Kennaway 
59ddd58736SKris Kennaway /* Part of the code in here was originally in conf.c, which is now removed */
60ddd58736SKris Kennaway 
61ddd58736SKris Kennaway #ifndef CONF_DEBUG
62ddd58736SKris Kennaway # undef NDEBUG                  /* avoid conflicting definitions */
63ddd58736SKris Kennaway # define NDEBUG
64ddd58736SKris Kennaway #endif
65ddd58736SKris Kennaway 
66ddd58736SKris Kennaway #include <assert.h>
6712de4ed2SJung-uk Kim #include <stdlib.h>
68ddd58736SKris Kennaway #include <string.h>
69ddd58736SKris Kennaway #include <openssl/conf.h>
70ddd58736SKris Kennaway #include <openssl/conf_api.h>
715c87c606SMark Murray #include "e_os.h"
72ddd58736SKris Kennaway 
731f13597dSJung-uk Kim static void value_free_hash_doall_arg(CONF_VALUE *a,
741f13597dSJung-uk Kim                                       LHASH_OF(CONF_VALUE) *conf);
751f13597dSJung-uk Kim static void value_free_stack_doall(CONF_VALUE *a);
761f13597dSJung-uk Kim static IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_hash, CONF_VALUE,
771f13597dSJung-uk Kim                                     LHASH_OF(CONF_VALUE))
781f13597dSJung-uk Kim static IMPLEMENT_LHASH_DOALL_FN(value_free_stack, CONF_VALUE)
79ddd58736SKris Kennaway 
80ddd58736SKris Kennaway /* Up until OpenSSL 0.9.5a, this was get_section */
815c87c606SMark Murray CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section)
82ddd58736SKris Kennaway {
83ddd58736SKris Kennaway     CONF_VALUE *v, vv;
84ddd58736SKris Kennaway 
856f9291ceSJung-uk Kim     if ((conf == NULL) || (section == NULL))
866f9291ceSJung-uk Kim         return (NULL);
87ddd58736SKris Kennaway     vv.name = NULL;
885c87c606SMark Murray     vv.section = (char *)section;
891f13597dSJung-uk Kim     v = lh_CONF_VALUE_retrieve(conf->data, &vv);
90ddd58736SKris Kennaway     return (v);
91ddd58736SKris Kennaway }
92ddd58736SKris Kennaway 
93ddd58736SKris Kennaway /* Up until OpenSSL 0.9.5a, this was CONF_get_section */
945c87c606SMark Murray STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf,
955c87c606SMark Murray                                                const char *section)
96ddd58736SKris Kennaway {
97ddd58736SKris Kennaway     CONF_VALUE *v;
98ddd58736SKris Kennaway 
99ddd58736SKris Kennaway     v = _CONF_get_section(conf, section);
100ddd58736SKris Kennaway     if (v != NULL)
101ddd58736SKris Kennaway         return ((STACK_OF(CONF_VALUE) *)v->value);
102ddd58736SKris Kennaway     else
103ddd58736SKris Kennaway         return (NULL);
104ddd58736SKris Kennaway }
105ddd58736SKris Kennaway 
106ddd58736SKris Kennaway int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value)
107ddd58736SKris Kennaway {
108ddd58736SKris Kennaway     CONF_VALUE *v = NULL;
109ddd58736SKris Kennaway     STACK_OF(CONF_VALUE) *ts;
110ddd58736SKris Kennaway 
111ddd58736SKris Kennaway     ts = (STACK_OF(CONF_VALUE) *)section->value;
112ddd58736SKris Kennaway 
113ddd58736SKris Kennaway     value->section = section->section;
1146f9291ceSJung-uk Kim     if (!sk_CONF_VALUE_push(ts, value)) {
115ddd58736SKris Kennaway         return 0;
116ddd58736SKris Kennaway     }
117ddd58736SKris Kennaway 
1181f13597dSJung-uk Kim     v = lh_CONF_VALUE_insert(conf->data, value);
1196f9291ceSJung-uk Kim     if (v != NULL) {
120db522d3aSSimon L. B. Nielsen         (void)sk_CONF_VALUE_delete_ptr(ts, v);
121ddd58736SKris Kennaway         OPENSSL_free(v->name);
122ddd58736SKris Kennaway         OPENSSL_free(v->value);
123ddd58736SKris Kennaway         OPENSSL_free(v);
124ddd58736SKris Kennaway     }
125ddd58736SKris Kennaway     return 1;
126ddd58736SKris Kennaway }
127ddd58736SKris Kennaway 
1286f9291ceSJung-uk Kim char *_CONF_get_string(const CONF *conf, const char *section,
1296f9291ceSJung-uk Kim                        const char *name)
130ddd58736SKris Kennaway {
131ddd58736SKris Kennaway     CONF_VALUE *v, vv;
132ddd58736SKris Kennaway     char *p;
133ddd58736SKris Kennaway 
1346f9291ceSJung-uk Kim     if (name == NULL)
1356f9291ceSJung-uk Kim         return (NULL);
1366f9291ceSJung-uk Kim     if (conf != NULL) {
1376f9291ceSJung-uk Kim         if (section != NULL) {
1385c87c606SMark Murray             vv.name = (char *)name;
1395c87c606SMark Murray             vv.section = (char *)section;
1401f13597dSJung-uk Kim             v = lh_CONF_VALUE_retrieve(conf->data, &vv);
1416f9291ceSJung-uk Kim             if (v != NULL)
1426f9291ceSJung-uk Kim                 return (v->value);
1436f9291ceSJung-uk Kim             if (strcmp(section, "ENV") == 0) {
1441f13597dSJung-uk Kim                 p = getenv(name);
1456f9291ceSJung-uk Kim                 if (p != NULL)
1466f9291ceSJung-uk Kim                     return (p);
147ddd58736SKris Kennaway             }
148ddd58736SKris Kennaway         }
149ddd58736SKris Kennaway         vv.section = "default";
1505c87c606SMark Murray         vv.name = (char *)name;
1511f13597dSJung-uk Kim         v = lh_CONF_VALUE_retrieve(conf->data, &vv);
152ddd58736SKris Kennaway         if (v != NULL)
153ddd58736SKris Kennaway             return (v->value);
154ddd58736SKris Kennaway         else
155ddd58736SKris Kennaway             return (NULL);
1566f9291ceSJung-uk Kim     } else
1571f13597dSJung-uk Kim         return (getenv(name));
158ddd58736SKris Kennaway }
159ddd58736SKris Kennaway 
1606f9291ceSJung-uk Kim #if 0                           /* There's no way to provide error checking
1616f9291ceSJung-uk Kim                                  * with this function, so force implementors
1626f9291ceSJung-uk Kim                                  * of the higher levels to get a string and
1636f9291ceSJung-uk Kim                                  * read the number themselves. */
164ddd58736SKris Kennaway long _CONF_get_number(CONF *conf, char *section, char *name)
165ddd58736SKris Kennaway {
166ddd58736SKris Kennaway     char *str;
167ddd58736SKris Kennaway     long ret = 0;
168ddd58736SKris Kennaway 
169ddd58736SKris Kennaway     str = _CONF_get_string(conf, section, name);
1706f9291ceSJung-uk Kim     if (str == NULL)
1716f9291ceSJung-uk Kim         return (0);
1726f9291ceSJung-uk Kim     for (;;) {
173ddd58736SKris Kennaway         if (conf->meth->is_number(conf, *str))
174ddd58736SKris Kennaway             ret = ret * 10 + conf->meth->to_int(conf, *str);
175ddd58736SKris Kennaway         else
176ddd58736SKris Kennaway             return (ret);
177ddd58736SKris Kennaway         str++;
178ddd58736SKris Kennaway     }
179ddd58736SKris Kennaway }
1805c87c606SMark Murray #endif
181ddd58736SKris Kennaway 
1821f13597dSJung-uk Kim static unsigned long conf_value_hash(const CONF_VALUE *v)
183ddd58736SKris Kennaway {
1841f13597dSJung-uk Kim     return (lh_strhash(v->section) << 2) ^ lh_strhash(v->name);
185ddd58736SKris Kennaway }
1866f9291ceSJung-uk Kim 
1871f13597dSJung-uk Kim static IMPLEMENT_LHASH_HASH_FN(conf_value, CONF_VALUE)
188ddd58736SKris Kennaway 
1891f13597dSJung-uk Kim static int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b)
190ddd58736SKris Kennaway {
191ddd58736SKris Kennaway     int i;
192ddd58736SKris Kennaway 
1936f9291ceSJung-uk Kim     if (a->section != b->section) {
194ddd58736SKris Kennaway         i = strcmp(a->section, b->section);
1956f9291ceSJung-uk Kim         if (i)
196ddd58736SKris Kennaway             return (i);
197ddd58736SKris Kennaway     }
1986f9291ceSJung-uk Kim 
1996f9291ceSJung-uk Kim     if ((a->name != NULL) && (b->name != NULL)) {
2006f9291ceSJung-uk Kim         i = strcmp(a->name, b->name);
2016f9291ceSJung-uk Kim         return (i);
2026f9291ceSJung-uk Kim     } else if (a->name == b->name)
203ddd58736SKris Kennaway         return (0);
204ddd58736SKris Kennaway     else
205ddd58736SKris Kennaway         return ((a->name == NULL) ? -1 : 1);
206ddd58736SKris Kennaway }
2076f9291ceSJung-uk Kim 
2081f13597dSJung-uk Kim static IMPLEMENT_LHASH_COMP_FN(conf_value, CONF_VALUE)
2091f13597dSJung-uk Kim 
2101f13597dSJung-uk Kim int _CONF_new_data(CONF *conf)
2111f13597dSJung-uk Kim {
2126f9291ceSJung-uk Kim     if (conf == NULL) {
2131f13597dSJung-uk Kim         return 0;
2141f13597dSJung-uk Kim     }
2151f13597dSJung-uk Kim     if (conf->data == NULL)
2166f9291ceSJung-uk Kim         if ((conf->data = lh_CONF_VALUE_new()) == NULL) {
2171f13597dSJung-uk Kim             return 0;
2181f13597dSJung-uk Kim         }
2191f13597dSJung-uk Kim     return 1;
2201f13597dSJung-uk Kim }
2211f13597dSJung-uk Kim 
2221f13597dSJung-uk Kim void _CONF_free_data(CONF *conf)
2231f13597dSJung-uk Kim {
2246f9291ceSJung-uk Kim     if (conf == NULL || conf->data == NULL)
2256f9291ceSJung-uk Kim         return;
2261f13597dSJung-uk Kim 
2276f9291ceSJung-uk Kim     lh_CONF_VALUE_down_load(conf->data) = 0; /* evil thing to make * sure the
2286f9291ceSJung-uk Kim                                               * 'OPENSSL_free()' works as *
2291f13597dSJung-uk Kim                                               * expected */
2301f13597dSJung-uk Kim     lh_CONF_VALUE_doall_arg(conf->data,
2311f13597dSJung-uk Kim                             LHASH_DOALL_ARG_FN(value_free_hash),
2321f13597dSJung-uk Kim                             LHASH_OF(CONF_VALUE), conf->data);
2331f13597dSJung-uk Kim 
2346f9291ceSJung-uk Kim     /*
2356f9291ceSJung-uk Kim      * We now have only 'section' entries in the hash table. Due to problems
2366f9291ceSJung-uk Kim      * with
2376f9291ceSJung-uk Kim      */
2381f13597dSJung-uk Kim 
2391f13597dSJung-uk Kim     lh_CONF_VALUE_doall(conf->data, LHASH_DOALL_FN(value_free_stack));
2401f13597dSJung-uk Kim     lh_CONF_VALUE_free(conf->data);
2411f13597dSJung-uk Kim }
2421f13597dSJung-uk Kim 
2436f9291ceSJung-uk Kim static void value_free_hash_doall_arg(CONF_VALUE *a,
2446f9291ceSJung-uk Kim                                       LHASH_OF(CONF_VALUE) *conf)
2451f13597dSJung-uk Kim {
2461f13597dSJung-uk Kim     if (a->name != NULL)
2471f13597dSJung-uk Kim         (void)lh_CONF_VALUE_delete(conf, a);
2481f13597dSJung-uk Kim }
2491f13597dSJung-uk Kim 
2501f13597dSJung-uk Kim static void value_free_stack_doall(CONF_VALUE *a)
2511f13597dSJung-uk Kim {
2521f13597dSJung-uk Kim     CONF_VALUE *vv;
2531f13597dSJung-uk Kim     STACK_OF(CONF_VALUE) *sk;
2541f13597dSJung-uk Kim     int i;
2551f13597dSJung-uk Kim 
2566f9291ceSJung-uk Kim     if (a->name != NULL)
2576f9291ceSJung-uk Kim         return;
2581f13597dSJung-uk Kim 
2591f13597dSJung-uk Kim     sk = (STACK_OF(CONF_VALUE) *)a->value;
2606f9291ceSJung-uk Kim     for (i = sk_CONF_VALUE_num(sk) - 1; i >= 0; i--) {
2611f13597dSJung-uk Kim         vv = sk_CONF_VALUE_value(sk, i);
2621f13597dSJung-uk Kim         OPENSSL_free(vv->value);
2631f13597dSJung-uk Kim         OPENSSL_free(vv->name);
2641f13597dSJung-uk Kim         OPENSSL_free(vv);
2651f13597dSJung-uk Kim     }
2666f9291ceSJung-uk Kim     if (sk != NULL)
2676f9291ceSJung-uk Kim         sk_CONF_VALUE_free(sk);
2681f13597dSJung-uk Kim     OPENSSL_free(a->section);
2691f13597dSJung-uk Kim     OPENSSL_free(a);
2701f13597dSJung-uk Kim }
271ddd58736SKris Kennaway 
272ddd58736SKris Kennaway /* Up until OpenSSL 0.9.5a, this was new_section */
2735c87c606SMark Murray CONF_VALUE *_CONF_new_section(CONF *conf, const char *section)
274ddd58736SKris Kennaway {
2751f13597dSJung-uk Kim     STACK_OF(CONF_VALUE) *sk = NULL;
276ddd58736SKris Kennaway     int ok = 0, i;
277ddd58736SKris Kennaway     CONF_VALUE *v = NULL, *vv;
278ddd58736SKris Kennaway 
2791f13597dSJung-uk Kim     if ((sk = sk_CONF_VALUE_new_null()) == NULL)
280ddd58736SKris Kennaway         goto err;
2811f13597dSJung-uk Kim     if ((v = OPENSSL_malloc(sizeof(CONF_VALUE))) == NULL)
282ddd58736SKris Kennaway         goto err;
283ddd58736SKris Kennaway     i = strlen(section) + 1;
2841f13597dSJung-uk Kim     if ((v->section = OPENSSL_malloc(i)) == NULL)
285ddd58736SKris Kennaway         goto err;
286ddd58736SKris Kennaway 
287ddd58736SKris Kennaway     memcpy(v->section, section, i);
288ddd58736SKris Kennaway     v->name = NULL;
289ddd58736SKris Kennaway     v->value = (char *)sk;
290ddd58736SKris Kennaway 
2911f13597dSJung-uk Kim     vv = lh_CONF_VALUE_insert(conf->data, v);
2921f13597dSJung-uk Kim     OPENSSL_assert(vv == NULL);
293dea77ea6SJung-uk Kim     if (lh_CONF_VALUE_error(conf->data) > 0)
294dea77ea6SJung-uk Kim         goto err;
295ddd58736SKris Kennaway     ok = 1;
296ddd58736SKris Kennaway  err:
2976f9291ceSJung-uk Kim     if (!ok) {
2986f9291ceSJung-uk Kim         if (sk != NULL)
2996f9291ceSJung-uk Kim             sk_CONF_VALUE_free(sk);
3006f9291ceSJung-uk Kim         if (v != NULL)
3016f9291ceSJung-uk Kim             OPENSSL_free(v);
302ddd58736SKris Kennaway         v = NULL;
303ddd58736SKris Kennaway     }
304ddd58736SKris Kennaway     return (v);
305ddd58736SKris Kennaway }
306ddd58736SKris Kennaway 
307ddd58736SKris Kennaway IMPLEMENT_STACK_OF(CONF_VALUE)
308