Home | History | Annotate | Line # | Download | only in test
      1  1.1  christos /*
      2  1.2  christos  * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
      3  1.1  christos  *
      4  1.2  christos  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  1.1  christos  * this file except in compliance with the License.  You can obtain a copy
      6  1.1  christos  * in the file LICENSE in the source distribution or at
      7  1.1  christos  * https://www.openssl.org/source/license.html
      8  1.1  christos  */
      9  1.1  christos 
     10  1.1  christos #include <stdlib.h>
     11  1.1  christos #include <string.h>
     12  1.1  christos #include <openssl/conf.h>
     13  1.1  christos #include <openssl/err.h>
     14  1.1  christos #include "testutil.h"
     15  1.1  christos 
     16  1.1  christos #ifdef _WIN32
     17  1.1  christos # include <direct.h>
     18  1.1  christos # define DIRSEP "/\\"
     19  1.2  christos # ifndef __BORLANDC__
     20  1.2  christos #  define chdir _chdir
     21  1.2  christos # endif
     22  1.1  christos # define DIRSEP_PRESERVE 0
     23  1.1  christos #elif !defined(OPENSSL_NO_POSIX_IO)
     24  1.1  christos # include <unistd.h>
     25  1.1  christos # ifndef OPENSSL_SYS_VMS
     26  1.1  christos #  define DIRSEP "/"
     27  1.1  christos #  define DIRSEP_PRESERVE 0
     28  1.1  christos # else
     29  1.1  christos #  define DIRSEP "/]:"
     30  1.1  christos #  define DIRSEP_PRESERVE 1
     31  1.1  christos # endif
     32  1.1  christos #else
     33  1.1  christos /* the test does not work without chdir() */
     34  1.1  christos # define chdir(x) (-1);
     35  1.1  christos # define DIRSEP "/"
     36  1.1  christos #  define DIRSEP_PRESERVE 0
     37  1.1  christos #endif
     38  1.1  christos 
     39  1.1  christos /* changes path to that of the filename */
     40  1.1  christos static int change_path(const char *file)
     41  1.1  christos {
     42  1.1  christos     char *s = OPENSSL_strdup(file);
     43  1.1  christos     char *p = s;
     44  1.1  christos     char *last = NULL;
     45  1.2  christos     int ret = 0;
     46  1.1  christos 
     47  1.1  christos     if (s == NULL)
     48  1.1  christos         return -1;
     49  1.1  christos 
     50  1.1  christos     while ((p = strpbrk(p, DIRSEP)) != NULL) {
     51  1.1  christos         last = p++;
     52  1.1  christos     }
     53  1.1  christos     if (last == NULL)
     54  1.2  christos         goto err;
     55  1.1  christos     last[DIRSEP_PRESERVE] = 0;
     56  1.1  christos 
     57  1.1  christos     TEST_note("changing path to %s", s);
     58  1.1  christos     ret = chdir(s);
     59  1.2  christos  err:
     60  1.1  christos     OPENSSL_free(s);
     61  1.1  christos     return ret;
     62  1.1  christos }
     63  1.1  christos 
     64  1.1  christos /*
     65  1.1  christos  * This test program checks the operation of the .include directive.
     66  1.1  christos  */
     67  1.1  christos 
     68  1.1  christos static CONF *conf;
     69  1.1  christos static BIO *in;
     70  1.1  christos static int expect_failure = 0;
     71  1.1  christos 
     72  1.1  christos static int test_load_config(void)
     73  1.1  christos {
     74  1.1  christos     long errline;
     75  1.1  christos     long val;
     76  1.1  christos     char *str;
     77  1.1  christos     long err;
     78  1.1  christos 
     79  1.1  christos     if (!TEST_int_gt(NCONF_load_bio(conf, in, &errline), 0)
     80  1.1  christos         || !TEST_int_eq(err = ERR_peek_error(), 0)) {
     81  1.1  christos         if (expect_failure)
     82  1.1  christos             return 1;
     83  1.1  christos         TEST_note("Failure loading the configuration at line %ld", errline);
     84  1.1  christos         return 0;
     85  1.1  christos     }
     86  1.1  christos     if (expect_failure) {
     87  1.1  christos         TEST_note("Failure expected but did not happen");
     88  1.1  christos         return 0;
     89  1.1  christos     }
     90  1.1  christos 
     91  1.1  christos     if (!TEST_int_gt(CONF_modules_load(conf, NULL, 0), 0)) {
     92  1.1  christos         TEST_note("Failed in CONF_modules_load");
     93  1.1  christos         return 0;
     94  1.1  christos     }
     95  1.1  christos 
     96  1.1  christos     /* verify whether CA_default/default_days is set */
     97  1.1  christos     val = 0;
     98  1.1  christos     if (!TEST_int_eq(NCONF_get_number(conf, "CA_default", "default_days", &val), 1)
     99  1.1  christos         || !TEST_int_eq(val, 365)) {
    100  1.1  christos         TEST_note("default_days incorrect");
    101  1.1  christos         return 0;
    102  1.1  christos     }
    103  1.1  christos 
    104  1.1  christos     /* verify whether req/default_bits is set */
    105  1.1  christos     val = 0;
    106  1.1  christos     if (!TEST_int_eq(NCONF_get_number(conf, "req", "default_bits", &val), 1)
    107  1.1  christos         || !TEST_int_eq(val, 2048)) {
    108  1.1  christos         TEST_note("default_bits incorrect");
    109  1.1  christos         return 0;
    110  1.1  christos     }
    111  1.1  christos 
    112  1.1  christos     /* verify whether countryName_default is set correctly */
    113  1.1  christos     str = NCONF_get_string(conf, "req_distinguished_name", "countryName_default");
    114  1.1  christos     if (!TEST_ptr(str) || !TEST_str_eq(str, "AU")) {
    115  1.1  christos         TEST_note("countryName_default incorrect");
    116  1.1  christos         return 0;
    117  1.1  christos     }
    118  1.1  christos 
    119  1.1  christos     return 1;
    120  1.1  christos }
    121  1.1  christos 
    122  1.1  christos static int test_check_null_numbers(void)
    123  1.1  christos {
    124  1.1  christos #if defined(_BSD_SOURCE) \
    125  1.1  christos         || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) \
    126  1.1  christos         || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600)
    127  1.1  christos     long val = 0;
    128  1.1  christos 
    129  1.1  christos     /* Verify that a NULL config with a present environment variable returns
    130  1.1  christos      * success and the value.
    131  1.1  christos      */
    132  1.1  christos     if (!TEST_int_eq(setenv("FNORD", "123", 1), 0)
    133  1.1  christos             || !TEST_true(NCONF_get_number(NULL, "missing", "FNORD", &val))
    134  1.1  christos             || !TEST_long_eq(val, 123)) {
    135  1.1  christos         TEST_note("environment variable with NULL conf failed");
    136  1.1  christos         return 0;
    137  1.1  christos     }
    138  1.1  christos 
    139  1.1  christos     /*
    140  1.2  christos      * Verify that a NULL config with a missing environment variable returns
    141  1.1  christos      * a failure code.
    142  1.1  christos      */
    143  1.1  christos     if (!TEST_int_eq(unsetenv("FNORD"), 0)
    144  1.1  christos             || !TEST_false(NCONF_get_number(NULL, "missing", "FNORD", &val))) {
    145  1.1  christos         TEST_note("missing environment variable with NULL conf failed");
    146  1.1  christos         return 0;
    147  1.1  christos     }
    148  1.1  christos #endif
    149  1.1  christos     return 1;
    150  1.1  christos }
    151  1.1  christos 
    152  1.1  christos static int test_check_overflow(void)
    153  1.1  christos {
    154  1.1  christos #if defined(_BSD_SOURCE) \
    155  1.1  christos         || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) \
    156  1.1  christos         || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600)
    157  1.1  christos     long val = 0;
    158  1.1  christos     char max[(sizeof(long) * 8) / 3 + 3];
    159  1.1  christos     char *p;
    160  1.1  christos 
    161  1.3  christos     p = max + BIO_snprintf(max, sizeof(max), "0%ld", LONG_MAX) - 1;
    162  1.1  christos     setenv("FNORD", max, 1);
    163  1.1  christos     if (!TEST_true(NCONF_get_number(NULL, "missing", "FNORD", &val))
    164  1.1  christos             || !TEST_long_eq(val, LONG_MAX))
    165  1.1  christos         return 0;
    166  1.1  christos 
    167  1.1  christos     while (++*p > '9')
    168  1.1  christos         *p-- = '0';
    169  1.1  christos 
    170  1.1  christos     setenv("FNORD", max, 1);
    171  1.1  christos     if (!TEST_false(NCONF_get_number(NULL, "missing", "FNORD", &val)))
    172  1.1  christos         return 0;
    173  1.1  christos #endif
    174  1.1  christos     return 1;
    175  1.1  christos }
    176  1.1  christos 
    177  1.2  christos typedef enum OPTION_choice {
    178  1.2  christos     OPT_ERR = -1,
    179  1.2  christos     OPT_EOF = 0,
    180  1.2  christos     OPT_FAIL,
    181  1.2  christos     OPT_TEST_ENUM
    182  1.2  christos } OPTION_CHOICE;
    183  1.2  christos 
    184  1.2  christos const OPTIONS *test_get_options(void)
    185  1.2  christos {
    186  1.2  christos     static const OPTIONS test_options[] = {
    187  1.2  christos         OPT_TEST_OPTIONS_WITH_EXTRA_USAGE("conf_file\n"),
    188  1.2  christos         { "f", OPT_FAIL, '-', "A failure is expected" },
    189  1.2  christos         { NULL }
    190  1.2  christos     };
    191  1.2  christos     return test_options;
    192  1.2  christos }
    193  1.2  christos 
    194  1.1  christos int setup_tests(void)
    195  1.1  christos {
    196  1.1  christos     const char *conf_file;
    197  1.2  christos     OPTION_CHOICE o;
    198  1.1  christos 
    199  1.1  christos     if (!TEST_ptr(conf = NCONF_new(NULL)))
    200  1.1  christos         return 0;
    201  1.1  christos 
    202  1.2  christos     while ((o = opt_next()) != OPT_EOF) {
    203  1.2  christos         switch (o) {
    204  1.2  christos         case OPT_FAIL:
    205  1.2  christos             expect_failure = 1;
    206  1.2  christos             break;
    207  1.2  christos         case OPT_TEST_CASES:
    208  1.2  christos             break;
    209  1.2  christos         default:
    210  1.2  christos             return 0;
    211  1.2  christos         }
    212  1.2  christos     }
    213  1.2  christos 
    214  1.1  christos     conf_file = test_get_argument(0);
    215  1.1  christos     if (!TEST_ptr(conf_file)
    216  1.1  christos         || !TEST_ptr(in = BIO_new_file(conf_file, "r"))) {
    217  1.1  christos         TEST_note("Unable to open the file argument");
    218  1.1  christos         return 0;
    219  1.1  christos     }
    220  1.1  christos 
    221  1.1  christos     /*
    222  1.1  christos      * For this test we need to chdir as we use relative
    223  1.1  christos      * path names in the config files.
    224  1.1  christos      */
    225  1.1  christos     change_path(conf_file);
    226  1.1  christos 
    227  1.1  christos     ADD_TEST(test_load_config);
    228  1.1  christos     ADD_TEST(test_check_null_numbers);
    229  1.1  christos     ADD_TEST(test_check_overflow);
    230  1.1  christos     return 1;
    231  1.1  christos }
    232  1.1  christos 
    233  1.1  christos void cleanup_tests(void)
    234  1.1  christos {
    235  1.1  christos     BIO_vfree(in);
    236  1.1  christos     NCONF_free(conf);
    237  1.1  christos     CONF_modules_unload(1);
    238  1.1  christos }
    239