+ if (CHECK_AND_SKIP_PREFIX(pname, ".pragma")
+ && (p != pname || *p == '=')) {
+ char *pval;
+
+ if (*p == '=') {
+ p++;
+ p = eat_ws(conf, p);
+ }
+ trim_ws(conf, p);
+
+ /* Pragma values take the form keyword:value */
+ pval = strchr(p, ':');
+ if (pval == NULL || pval == p || pval[1] == '\0') {
+ ERR_raise(ERR_LIB_CONF, CONF_R_INVALID_PRAGMA);
+ goto err;
+ }
+
+ *pval++ = '\0';
+ trim_ws(conf, p);
+ pval = eat_ws(conf, pval);
+
+ /*
+ * Known pragmas:
+ *
+ * dollarid takes "on", "true or "off", "false"
+ * abspath takes "on", "true or "off", "false"
+ * includedir directory prefix
+ */
+ if (strcmp(p, "dollarid") == 0) {
+ if (!parsebool(pval, &conf->flag_dollarid))
+ goto err;
+ } else if (strcmp(p, "abspath") == 0) {
+ if (!parsebool(pval, &conf->flag_abspath))
+ goto err;
+ } else if (strcmp(p, "includedir") == 0) {
+ OPENSSL_free(conf->includedir);
+ if ((conf->includedir = OPENSSL_strdup(pval)) == NULL)
+ goto err;
+ }
+
+ /*
+ * We *ignore* any unknown pragma.
+ */
+ continue;
+ } else if (CHECK_AND_SKIP_PREFIX(pname, ".include")
+ && (p != pname || *p == '=')) {
+ char *include = NULL;
+ BIO *next;
+ const char *include_dir = ossl_safe_getenv("OPENSSL_CONF_INCLUDE");
+ char *include_path = NULL;
+
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ /*
+ * The include processing below can cause the "conf" fuzzer to
+ * timeout due to the fuzzer inserting large and complicated
+ * includes - with a large amount of time spent in
+ * OPENSSL_strlcat/OPENSSL_strcpy. This is not a security
+ * concern because config files should never come from untrusted
+ * sources. We just set an arbitrary limit on the allowed
+ * number of includes when fuzzing to prevent this timeout.
+ */
+ if (numincludes++ > 10)
+ goto err;
+#endif
+
+ if (include_dir == NULL)
+ include_dir = conf->includedir;
+
+ if (*p == '=') {
+ p++;
+ p = eat_ws(conf, p);
+ }
+ trim_ws(conf, p);
+ if (!str_copy(conf, psection, &include, p))
+ goto err;
+
+ if (include_dir != NULL && !ossl_is_absolute_path(include)) {
+ size_t newlen = strlen(include_dir) + strlen(include) + 2;
+
+ include_path = OPENSSL_malloc(newlen);
+ if (include_path == NULL) {
+ OPENSSL_free(include);
+ goto err;
+ }
+
+ OPENSSL_strlcpy(include_path, include_dir, newlen);
+ if (!ossl_ends_with_dirsep(include_path))
+ OPENSSL_strlcat(include_path, "/", newlen);
+ OPENSSL_strlcat(include_path, include, newlen);
+ OPENSSL_free(include);
+ } else {
+ include_path = include;
+ }
+
+ if (conf->flag_abspath
+ && !ossl_is_absolute_path(include_path)) {
+ ERR_raise(ERR_LIB_CONF, CONF_R_RELATIVE_PATH);
+ OPENSSL_free(include_path);
+ goto err;
+ }
+
+ /* get the BIO of the included file */
+#ifndef OPENSSL_NO_POSIX_IO
+ next = process_include(include_path, &dirctx, &dirpath);
+ if (include_path != dirpath) {
+ /* dirpath will contain include in case of a directory */
+ OPENSSL_free(include_path);
+ }
+#else
+ next = BIO_new_file(include_path, "r");
+ OPENSSL_free(include_path);
+#endif
+
+ if (next != NULL) {
+ /* push the currently processing BIO onto stack */
+ if (biosk == NULL) {
+ if ((biosk = sk_BIO_new_null()) == NULL) {
+ ERR_raise(ERR_LIB_CONF, ERR_R_CRYPTO_LIB);
+ BIO_free(next);
+ goto err;
+ }
+ }
+ if (!sk_BIO_push(biosk, in)) {
+ ERR_raise(ERR_LIB_CONF, ERR_R_CRYPTO_LIB);
+ BIO_free(next);
+ goto err;
+ }
+ /* continue with reading from the included BIO */
+ in = next;
+ }
+ continue;
+ } else if (*p != '=') {
+ ERR_raise_data(ERR_LIB_CONF, CONF_R_MISSING_EQUAL_SIGN,
+ "HERE-->%s", p);