diff --git a/src/x509.c b/src/x509.c index d9e948fe943..096cead95db 100644 --- a/src/x509.c +++ b/src/x509.c @@ -8640,6 +8640,11 @@ static int x509AddCertDir(WOLFSSL_BY_DIR *ctx, const char *argc, long argl) pathLen = 0; XMEMSET(buf, 0, MAX_FILENAME_SZ); } + if (pathLen >= MAX_FILENAME_SZ) { + WOLFSSL_MSG("Could not write full dir name not enough space"); + WC_FREE_VAR_EX(buf, 0, DYNAMIC_TYPE_OPENSSL); + return 0; + } buf[pathLen++] = *c; } while(*c++ != '\0'); diff --git a/tests/api/test_ossl_x509_lu.c b/tests/api/test_ossl_x509_lu.c index 07213e61369..d89fdd9b12c 100644 --- a/tests/api/test_ossl_x509_lu.c +++ b/tests/api/test_ossl_x509_lu.c @@ -294,6 +294,63 @@ int test_wolfSSL_X509_LOOKUP_ctrl_hash_dir(void) return EXPECT_RESULT(); } +/* Check that a path element longer than the internal MAX_FILENAME_SZ buffer is + * rejected instead of overflowing it. */ +int test_wolfSSL_X509_LOOKUP_ctrl_dir_len(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + X509_STORE* str = NULL; + X509_LOOKUP* lookup = NULL; + char* longPath = NULL; + char maxPath[MAX_FILENAME_SZ + 1]; + + /* one element that does not fit in the buffer - must fail */ + ExpectNotNull(longPath = (char*)XMALLOC(MAX_FILENAME_SZ + 4, NULL, + DYNAMIC_TYPE_TMP_BUFFER)); + if (longPath != NULL) { + XMEMSET(longPath, 'a', MAX_FILENAME_SZ + 3); + longPath[MAX_FILENAME_SZ + 3] = '\0'; + } + + ExpectNotNull((str = wolfSSL_X509_STORE_new())); + ExpectNotNull(lookup = X509_STORE_add_lookup(str, X509_LOOKUP_file())); + ExpectIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_ADD_DIR, longPath, + SSL_FILETYPE_PEM, NULL), 0); + + X509_STORE_free(str); + str = NULL; + + /* oversized element preceded by a valid one - still fails */ + ExpectNotNull((str = wolfSSL_X509_STORE_new())); + ExpectNotNull(lookup = X509_STORE_add_lookup(str, X509_LOOKUP_file())); + if (longPath != NULL) { + longPath[0] = '.'; + longPath[1] = SEPARATOR_CHAR; + } + ExpectIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_ADD_DIR, longPath, + SSL_FILETYPE_PEM, NULL), 0); + + X509_STORE_free(str); + str = NULL; + + XFREE(longPath, NULL, DYNAMIC_TYPE_TMP_BUFFER); + longPath = NULL; + + /* an element that exactly fills the buffer is still accepted */ + XMEMSET(maxPath, 'a', MAX_FILENAME_SZ); + maxPath[MAX_FILENAME_SZ] = '\0'; + + ExpectNotNull((str = wolfSSL_X509_STORE_new())); + ExpectNotNull(lookup = X509_STORE_add_lookup(str, X509_LOOKUP_file())); + ExpectIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_ADD_DIR, maxPath, + SSL_FILETYPE_PEM, NULL), 1); + + X509_STORE_free(str); +#endif + return EXPECT_RESULT(); +} + int test_wolfSSL_X509_load_crl_file(void) { EXPECT_DECLS; diff --git a/tests/api/test_ossl_x509_lu.h b/tests/api/test_ossl_x509_lu.h index 72a7991b1e8..28fffcc3325 100644 --- a/tests/api/test_ossl_x509_lu.h +++ b/tests/api/test_ossl_x509_lu.h @@ -27,6 +27,7 @@ int test_wolfSSL_X509_LOOKUP_load_file(void); int test_wolfSSL_X509_LOOKUP_ctrl_file(void); int test_wolfSSL_X509_LOOKUP_ctrl_hash_dir(void); +int test_wolfSSL_X509_LOOKUP_ctrl_dir_len(void); int test_wolfSSL_X509_load_crl_file(void); int test_X509_LOOKUP_add_dir(void); @@ -34,6 +35,7 @@ int test_X509_LOOKUP_add_dir(void); TEST_DECL_GROUP("ossl_x509_lu", test_wolfSSL_X509_LOOKUP_load_file), \ TEST_DECL_GROUP("ossl_x509_lu", test_wolfSSL_X509_LOOKUP_ctrl_file), \ TEST_DECL_GROUP("ossl_x509_lu", test_wolfSSL_X509_LOOKUP_ctrl_hash_dir), \ + TEST_DECL_GROUP("ossl_x509_lu", test_wolfSSL_X509_LOOKUP_ctrl_dir_len), \ TEST_DECL_GROUP("ossl_x509_lu", test_wolfSSL_X509_load_crl_file), \ TEST_DECL_GROUP("ossl_x509_lu", test_X509_LOOKUP_add_dir)