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