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