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