Coverage Report

Created: 2023-06-29 07:23

/src/boringssl/crypto/conf/conf.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2
 * All rights reserved.
3
 *
4
 * This package is an SSL implementation written
5
 * by Eric Young (eay@cryptsoft.com).
6
 * The implementation was written so as to conform with Netscapes SSL.
7
 *
8
 * This library is free for commercial and non-commercial use as long as
9
 * the following conditions are aheared to.  The following conditions
10
 * apply to all code found in this distribution, be it the RC4, RSA,
11
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12
 * included with this distribution is covered by the same copyright terms
13
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14
 *
15
 * Copyright remains Eric Young's, and as such any Copyright notices in
16
 * the code are not to be removed.
17
 * If this package is used in a product, Eric Young should be given attribution
18
 * as the author of the parts of the library used.
19
 * This can be in the form of a textual message at program startup or
20
 * in documentation (online or textual) provided with the package.
21
 *
22
 * Redistribution and use in source and binary forms, with or without
23
 * modification, are permitted provided that the following conditions
24
 * are met:
25
 * 1. Redistributions of source code must retain the copyright
26
 *    notice, this list of conditions and the following disclaimer.
27
 * 2. Redistributions in binary form must reproduce the above copyright
28
 *    notice, this list of conditions and the following disclaimer in the
29
 *    documentation and/or other materials provided with the distribution.
30
 * 3. All advertising materials mentioning features or use of this software
31
 *    must display the following acknowledgement:
32
 *    "This product includes cryptographic software written by
33
 *     Eric Young (eay@cryptsoft.com)"
34
 *    The word 'cryptographic' can be left out if the rouines from the library
35
 *    being used are not cryptographic related :-).
36
 * 4. If you include any Windows specific code (or a derivative thereof) from
37
 *    the apps directory (application code) you must include an acknowledgement:
38
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39
 *
40
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50
 * SUCH DAMAGE.
51
 *
52
 * The licence and distribution terms for any publically available version or
53
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
54
 * copied and put under another distribution licence
55
 * [including the GNU Public Licence.] */
56
57
#include <openssl/conf.h>
58
59
#include <string.h>
60
#include <ctype.h>
61
62
#include <openssl/bio.h>
63
#include <openssl/buf.h>
64
#include <openssl/err.h>
65
#include <openssl/lhash.h>
66
#include <openssl/mem.h>
67
68
#include "conf_def.h"
69
#include "internal.h"
70
#include "../internal.h"
71
72
73
static const char kDefaultSectionName[] = "default";
74
75
0
static uint32_t conf_value_hash(const CONF_VALUE *v) {
76
0
  const uint32_t section_hash = v->section ? OPENSSL_strhash(v->section) : 0;
77
0
  const uint32_t name_hash = v->name ? OPENSSL_strhash(v->name) : 0;
78
0
  return (section_hash << 2) ^ name_hash;
79
0
}
80
81
0
static int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b) {
82
0
  int i;
83
84
0
  if (a->section != b->section) {
85
0
    i = strcmp(a->section, b->section);
86
0
    if (i) {
87
0
      return i;
88
0
    }
89
0
  }
90
91
0
  if (a->name != NULL && b->name != NULL) {
92
0
    return strcmp(a->name, b->name);
93
0
  } else if (a->name == b->name) {
94
0
    return 0;
95
0
  } else {
96
0
    return (a->name == NULL) ? -1 : 1;
97
0
  }
98
0
}
99
100
0
CONF *NCONF_new(void *method) {
101
0
  CONF *conf;
102
103
0
  if (method != NULL) {
104
0
    return NULL;
105
0
  }
106
107
0
  conf = OPENSSL_malloc(sizeof(CONF));
108
0
  if (conf == NULL) {
109
0
    return NULL;
110
0
  }
111
112
0
  conf->data = lh_CONF_VALUE_new(conf_value_hash, conf_value_cmp);
113
0
  if (conf->data == NULL) {
114
0
    OPENSSL_free(conf);
115
0
    return NULL;
116
0
  }
117
118
0
  return conf;
119
0
}
120
121
0
CONF_VALUE *CONF_VALUE_new(void) {
122
0
  CONF_VALUE *v = OPENSSL_malloc(sizeof(CONF_VALUE));
123
0
  if (!v) {
124
0
    return NULL;
125
0
  }
126
0
  OPENSSL_memset(v, 0, sizeof(CONF_VALUE));
127
0
  return v;
128
0
}
129
130
0
static void value_free_contents(CONF_VALUE *value) {
131
0
  OPENSSL_free(value->section);
132
0
  if (value->name) {
133
0
    OPENSSL_free(value->name);
134
0
    OPENSSL_free(value->value);
135
0
  } else {
136
    // TODO(davidben): When |value->name| is NULL, |CONF_VALUE| is actually an
137
    // entirely different structure. This is fragile and confusing. Make a
138
    // proper |CONF_SECTION| type that doesn't require this.
139
0
    sk_CONF_VALUE_free((STACK_OF(CONF_VALUE) *)value->value);
140
0
  }
141
0
}
142
143
0
static void value_free(CONF_VALUE *value) {
144
0
  if (value != NULL) {
145
0
    value_free_contents(value);
146
0
    OPENSSL_free(value);
147
0
  }
148
0
}
149
150
0
static void value_free_arg(CONF_VALUE *value, void *arg) { value_free(value); }
151
152
0
void NCONF_free(CONF *conf) {
153
0
  if (conf == NULL || conf->data == NULL) {
154
0
    return;
155
0
  }
156
157
0
  lh_CONF_VALUE_doall_arg(conf->data, value_free_arg, NULL);
158
0
  lh_CONF_VALUE_free(conf->data);
159
0
  OPENSSL_free(conf);
160
0
}
161
162
0
static CONF_VALUE *NCONF_new_section(const CONF *conf, const char *section) {
163
0
  STACK_OF(CONF_VALUE) *sk = NULL;
164
0
  int ok = 0;
165
0
  CONF_VALUE *v = NULL, *old_value;
166
167
0
  sk = sk_CONF_VALUE_new_null();
168
0
  v = CONF_VALUE_new();
169
0
  if (sk == NULL || v == NULL) {
170
0
    goto err;
171
0
  }
172
0
  v->section = OPENSSL_strdup(section);
173
0
  if (v->section == NULL) {
174
0
    goto err;
175
0
  }
176
177
0
  v->name = NULL;
178
0
  v->value = (char *)sk;
179
180
0
  if (!lh_CONF_VALUE_insert(conf->data, &old_value, v)) {
181
0
    goto err;
182
0
  }
183
0
  value_free(old_value);
184
0
  ok = 1;
185
186
0
err:
187
0
  if (!ok) {
188
0
    sk_CONF_VALUE_free(sk);
189
0
    OPENSSL_free(v);
190
0
    v = NULL;
191
0
  }
192
0
  return v;
193
0
}
194
195
0
static int str_copy(CONF *conf, char *section, char **pto, char *from) {
196
0
  int q, to = 0, len = 0;
197
0
  char v;
198
0
  BUF_MEM *buf;
199
200
0
  buf = BUF_MEM_new();
201
0
  if (buf == NULL) {
202
0
    return 0;
203
0
  }
204
205
0
  len = strlen(from) + 1;
206
0
  if (!BUF_MEM_grow(buf, len)) {
207
0
    goto err;
208
0
  }
209
210
0
  for (;;) {
211
0
    if (IS_QUOTE(conf, *from)) {
212
0
      q = *from;
213
0
      from++;
214
0
      while (!IS_EOF(conf, *from) && (*from != q)) {
215
0
        if (IS_ESC(conf, *from)) {
216
0
          from++;
217
0
          if (IS_EOF(conf, *from)) {
218
0
            break;
219
0
          }
220
0
        }
221
0
        buf->data[to++] = *(from++);
222
0
      }
223
0
      if (*from == q) {
224
0
        from++;
225
0
      }
226
0
    } else if (IS_ESC(conf, *from)) {
227
0
      from++;
228
0
      v = *(from++);
229
0
      if (IS_EOF(conf, v)) {
230
0
        break;
231
0
      } else if (v == 'r') {
232
0
        v = '\r';
233
0
      } else if (v == 'n') {
234
0
        v = '\n';
235
0
      } else if (v == 'b') {
236
0
        v = '\b';
237
0
      } else if (v == 't') {
238
0
        v = '\t';
239
0
      }
240
0
      buf->data[to++] = v;
241
0
    } else if (IS_EOF(conf, *from)) {
242
0
      break;
243
0
    } else if (*from == '$') {
244
      // Historically, $foo would expand to a previously-parsed value. This
245
      // feature has been removed as it was unused and is a DoS vector.
246
0
      OPENSSL_PUT_ERROR(CONF, CONF_R_VARIABLE_EXPANSION_NOT_SUPPORTED);
247
0
      goto err;
248
0
    } else {
249
0
      buf->data[to++] = *(from++);
250
0
    }
251
0
  }
252
253
0
  buf->data[to] = '\0';
254
0
  OPENSSL_free(*pto);
255
0
  *pto = buf->data;
256
0
  OPENSSL_free(buf);
257
0
  return 1;
258
259
0
err:
260
0
  BUF_MEM_free(buf);
261
0
  return 0;
262
0
}
263
264
0
static CONF_VALUE *get_section(const CONF *conf, const char *section) {
265
0
  CONF_VALUE template;
266
267
0
  OPENSSL_memset(&template, 0, sizeof(template));
268
0
  template.section = (char *) section;
269
0
  return lh_CONF_VALUE_retrieve(conf->data, &template);
270
0
}
271
272
const STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf,
273
0
                                              const char *section) {
274
0
  const CONF_VALUE *section_value = get_section(conf, section);
275
0
  if (section_value == NULL) {
276
0
    return NULL;
277
0
  }
278
0
  return (STACK_OF(CONF_VALUE)*) section_value->value;
279
0
}
280
281
const char *NCONF_get_string(const CONF *conf, const char *section,
282
0
                             const char *name) {
283
0
  CONF_VALUE template, *value;
284
285
0
  if (section == NULL) {
286
0
    section = kDefaultSectionName;
287
0
  }
288
289
0
  OPENSSL_memset(&template, 0, sizeof(template));
290
0
  template.section = (char *) section;
291
0
  template.name = (char *) name;
292
0
  value = lh_CONF_VALUE_retrieve(conf->data, &template);
293
0
  if (value == NULL) {
294
0
    return NULL;
295
0
  }
296
0
  return value->value;
297
0
}
298
299
static int add_string(const CONF *conf, CONF_VALUE *section,
300
0
                      CONF_VALUE *value) {
301
0
  STACK_OF(CONF_VALUE) *section_stack = (STACK_OF(CONF_VALUE)*) section->value;
302
0
  CONF_VALUE *old_value;
303
304
0
  value->section = OPENSSL_strdup(section->section);
305
0
  if (!sk_CONF_VALUE_push(section_stack, value)) {
306
0
    return 0;
307
0
  }
308
309
0
  if (!lh_CONF_VALUE_insert(conf->data, &old_value, value)) {
310
0
    return 0;
311
0
  }
312
0
  if (old_value != NULL) {
313
0
    (void)sk_CONF_VALUE_delete_ptr(section_stack, old_value);
314
0
    value_free(old_value);
315
0
  }
316
317
0
  return 1;
318
0
}
319
320
0
static char *eat_ws(CONF *conf, char *p) {
321
0
  while (IS_WS(conf, *p) && !IS_EOF(conf, *p)) {
322
0
    p++;
323
0
  }
324
0
  return p;
325
0
}
326
327
0
#define scan_esc(conf, p) (((IS_EOF((conf), (p)[1])) ? ((p) + 1) : ((p) + 2)))
328
329
0
static char *eat_alpha_numeric(CONF *conf, char *p) {
330
0
  for (;;) {
331
0
    if (IS_ESC(conf, *p)) {
332
0
      p = scan_esc(conf, p);
333
0
      continue;
334
0
    }
335
0
    if (!IS_ALPHA_NUMERIC_PUNCT(conf, *p)) {
336
0
      return p;
337
0
    }
338
0
    p++;
339
0
  }
340
0
}
341
342
0
static char *scan_quote(CONF *conf, char *p) {
343
0
  int q = *p;
344
345
0
  p++;
346
0
  while (!IS_EOF(conf, *p) && *p != q) {
347
0
    if (IS_ESC(conf, *p)) {
348
0
      p++;
349
0
      if (IS_EOF(conf, *p)) {
350
0
        return p;
351
0
      }
352
0
    }
353
0
    p++;
354
0
  }
355
0
  if (*p == q) {
356
0
    p++;
357
0
  }
358
0
  return p;
359
0
}
360
361
0
static void clear_comments(CONF *conf, char *p) {
362
0
  for (;;) {
363
0
    if (!IS_WS(conf, *p)) {
364
0
      break;
365
0
    }
366
0
    p++;
367
0
  }
368
369
0
  for (;;) {
370
0
    if (IS_COMMENT(conf, *p)) {
371
0
      *p = '\0';
372
0
      return;
373
0
    }
374
0
    if (IS_QUOTE(conf, *p)) {
375
0
      p = scan_quote(conf, p);
376
0
      continue;
377
0
    }
378
0
    if (IS_ESC(conf, *p)) {
379
0
      p = scan_esc(conf, p);
380
0
      continue;
381
0
    }
382
0
    if (IS_EOF(conf, *p)) {
383
0
      return;
384
0
    } else {
385
0
      p++;
386
0
    }
387
0
  }
388
0
}
389
390
0
static int def_load_bio(CONF *conf, BIO *in, long *out_error_line) {
391
0
  static const size_t CONFBUFSIZE = 512;
392
0
  int bufnum = 0, i, ii;
393
0
  BUF_MEM *buff = NULL;
394
0
  char *s, *p, *end;
395
0
  int again;
396
0
  long eline = 0;
397
0
  char btmp[DECIMAL_SIZE(eline) + 1];
398
0
  CONF_VALUE *v = NULL, *tv;
399
0
  CONF_VALUE *sv = NULL;
400
0
  char *section = NULL, *buf;
401
0
  char *start, *psection, *pname;
402
403
0
  if ((buff = BUF_MEM_new()) == NULL) {
404
0
    OPENSSL_PUT_ERROR(CONF, ERR_R_BUF_LIB);
405
0
    goto err;
406
0
  }
407
408
0
  section = OPENSSL_strdup(kDefaultSectionName);
409
0
  if (section == NULL) {
410
0
    goto err;
411
0
  }
412
413
0
  sv = NCONF_new_section(conf, section);
414
0
  if (sv == NULL) {
415
0
    OPENSSL_PUT_ERROR(CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
416
0
    goto err;
417
0
  }
418
419
0
  bufnum = 0;
420
0
  again = 0;
421
0
  for (;;) {
422
0
    if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) {
423
0
      OPENSSL_PUT_ERROR(CONF, ERR_R_BUF_LIB);
424
0
      goto err;
425
0
    }
426
0
    p = &(buff->data[bufnum]);
427
0
    *p = '\0';
428
0
    BIO_gets(in, p, CONFBUFSIZE - 1);
429
0
    p[CONFBUFSIZE - 1] = '\0';
430
0
    ii = i = strlen(p);
431
0
    if (i == 0 && !again) {
432
0
      break;
433
0
    }
434
0
    again = 0;
435
0
    while (i > 0) {
436
0
      if ((p[i - 1] != '\r') && (p[i - 1] != '\n')) {
437
0
        break;
438
0
      } else {
439
0
        i--;
440
0
      }
441
0
    }
442
    // we removed some trailing stuff so there is a new
443
    // line on the end.
444
0
    if (ii && i == ii) {
445
0
      again = 1;  // long line
446
0
    } else {
447
0
      p[i] = '\0';
448
0
      eline++;  // another input line
449
0
    }
450
451
    // we now have a line with trailing \r\n removed
452
453
    // i is the number of bytes
454
0
    bufnum += i;
455
456
0
    v = NULL;
457
    // check for line continuation
458
0
    if (bufnum >= 1) {
459
      // If we have bytes and the last char '\\' and
460
      // second last char is not '\\'
461
0
      p = &(buff->data[bufnum - 1]);
462
0
      if (IS_ESC(conf, p[0]) && ((bufnum <= 1) || !IS_ESC(conf, p[-1]))) {
463
0
        bufnum--;
464
0
        again = 1;
465
0
      }
466
0
    }
467
0
    if (again) {
468
0
      continue;
469
0
    }
470
0
    bufnum = 0;
471
0
    buf = buff->data;
472
473
0
    clear_comments(conf, buf);
474
0
    s = eat_ws(conf, buf);
475
0
    if (IS_EOF(conf, *s)) {
476
0
      continue;  // blank line
477
0
    }
478
0
    if (*s == '[') {
479
0
      char *ss;
480
481
0
      s++;
482
0
      start = eat_ws(conf, s);
483
0
      ss = start;
484
0
    again:
485
0
      end = eat_alpha_numeric(conf, ss);
486
0
      p = eat_ws(conf, end);
487
0
      if (*p != ']') {
488
0
        if (*p != '\0' && ss != p) {
489
0
          ss = p;
490
0
          goto again;
491
0
        }
492
0
        OPENSSL_PUT_ERROR(CONF, CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
493
0
        goto err;
494
0
      }
495
0
      *end = '\0';
496
0
      if (!str_copy(conf, NULL, &section, start)) {
497
0
        goto err;
498
0
      }
499
0
      if ((sv = get_section(conf, section)) == NULL) {
500
0
        sv = NCONF_new_section(conf, section);
501
0
      }
502
0
      if (sv == NULL) {
503
0
        OPENSSL_PUT_ERROR(CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
504
0
        goto err;
505
0
      }
506
0
      continue;
507
0
    } else {
508
0
      pname = s;
509
0
      psection = NULL;
510
0
      end = eat_alpha_numeric(conf, s);
511
0
      if ((end[0] == ':') && (end[1] == ':')) {
512
0
        *end = '\0';
513
0
        end += 2;
514
0
        psection = pname;
515
0
        pname = end;
516
0
        end = eat_alpha_numeric(conf, end);
517
0
      }
518
0
      p = eat_ws(conf, end);
519
0
      if (*p != '=') {
520
0
        OPENSSL_PUT_ERROR(CONF, CONF_R_MISSING_EQUAL_SIGN);
521
0
        goto err;
522
0
      }
523
0
      *end = '\0';
524
0
      p++;
525
0
      start = eat_ws(conf, p);
526
0
      while (!IS_EOF(conf, *p)) {
527
0
        p++;
528
0
      }
529
0
      p--;
530
0
      while ((p != start) && (IS_WS(conf, *p))) {
531
0
        p--;
532
0
      }
533
0
      p++;
534
0
      *p = '\0';
535
536
0
      if (!(v = CONF_VALUE_new())) {
537
0
        goto err;
538
0
      }
539
0
      if (psection == NULL) {
540
0
        psection = section;
541
0
      }
542
0
      v->name = OPENSSL_strdup(pname);
543
0
      if (v->name == NULL) {
544
0
        goto err;
545
0
      }
546
0
      if (!str_copy(conf, psection, &(v->value), start)) {
547
0
        goto err;
548
0
      }
549
550
0
      if (strcmp(psection, section) != 0) {
551
0
        if ((tv = get_section(conf, psection)) == NULL) {
552
0
          tv = NCONF_new_section(conf, psection);
553
0
        }
554
0
        if (tv == NULL) {
555
0
          OPENSSL_PUT_ERROR(CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
556
0
          goto err;
557
0
        }
558
0
      } else {
559
0
        tv = sv;
560
0
      }
561
0
      if (add_string(conf, tv, v) == 0) {
562
0
        goto err;
563
0
      }
564
0
      v = NULL;
565
0
    }
566
0
  }
567
0
  BUF_MEM_free(buff);
568
0
  OPENSSL_free(section);
569
0
  return 1;
570
571
0
err:
572
0
  BUF_MEM_free(buff);
573
0
  OPENSSL_free(section);
574
0
  if (out_error_line != NULL) {
575
0
    *out_error_line = eline;
576
0
  }
577
0
  BIO_snprintf(btmp, sizeof btmp, "%ld", eline);
578
0
  ERR_add_error_data(2, "line ", btmp);
579
580
0
  if (v != NULL) {
581
0
    OPENSSL_free(v->name);
582
0
    OPENSSL_free(v->value);
583
0
    OPENSSL_free(v);
584
0
  }
585
0
  return 0;
586
0
}
587
588
0
int NCONF_load(CONF *conf, const char *filename, long *out_error_line) {
589
0
  BIO *in = BIO_new_file(filename, "rb");
590
0
  int ret;
591
592
0
  if (in == NULL) {
593
0
    OPENSSL_PUT_ERROR(CONF, ERR_R_SYS_LIB);
594
0
    return 0;
595
0
  }
596
597
0
  ret = def_load_bio(conf, in, out_error_line);
598
0
  BIO_free(in);
599
600
0
  return ret;
601
0
}
602
603
0
int NCONF_load_bio(CONF *conf, BIO *bio, long *out_error_line) {
604
0
  return def_load_bio(conf, bio, out_error_line);
605
0
}
606
607
int CONF_parse_list(const char *list, char sep, int remove_whitespace,
608
                    int (*list_cb)(const char *elem, size_t len, void *usr),
609
0
                    void *arg) {
610
0
  int ret;
611
0
  const char *lstart, *tmpend, *p;
612
613
0
  if (list == NULL) {
614
0
    OPENSSL_PUT_ERROR(CONF, CONF_R_LIST_CANNOT_BE_NULL);
615
0
    return 0;
616
0
  }
617
618
0
  lstart = list;
619
0
  for (;;) {
620
0
    if (remove_whitespace) {
621
0
      while (*lstart && OPENSSL_isspace((unsigned char)*lstart)) {
622
0
        lstart++;
623
0
      }
624
0
    }
625
0
    p = strchr(lstart, sep);
626
0
    if (p == lstart || !*lstart) {
627
0
      ret = list_cb(NULL, 0, arg);
628
0
    } else {
629
0
      if (p) {
630
0
        tmpend = p - 1;
631
0
      } else {
632
0
        tmpend = lstart + strlen(lstart) - 1;
633
0
      }
634
0
      if (remove_whitespace) {
635
0
        while (OPENSSL_isspace((unsigned char)*tmpend)) {
636
0
          tmpend--;
637
0
        }
638
0
      }
639
0
      ret = list_cb(lstart, tmpend - lstart + 1, arg);
640
0
    }
641
0
    if (ret <= 0) {
642
0
      return ret;
643
0
    }
644
0
    if (p == NULL) {
645
0
      return 1;
646
0
    }
647
0
    lstart = p + 1;
648
0
  }
649
0
}
650
651
int CONF_modules_load_file(const char *filename, const char *appname,
652
0
                           unsigned long flags) {
653
0
  return 1;
654
0
}
655
656
0
void CONF_modules_free(void) {}
657
658
0
void OPENSSL_config(const char *config_name) {}
659
660
0
void OPENSSL_no_config(void) {}