Skip to content

Commit fb4b56f

Browse files
committed
x509storeissuer: add limits for certificate file/directory load counts
Signed-off-by: Eugene Syromiatnikov <esyr@openssl.org>
1 parent 4bd0823 commit fb4b56f

File tree

1 file changed

+48
-10
lines changed

1 file changed

+48
-10
lines changed

source/x509storeissuer.c

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
#define RUN_TIME 5
3333
#define QUANTILES 5
3434
#define NONCE_CFG "file:servercert.pem"
35+
#define MAX_LOAD_CERTS INT_MAX
36+
#define MAX_LOAD_CERT_DIRS 0
3537
#define CTX_SHARE_THREADS 1
3638

3739
static size_t timeout_us = RUN_TIME * 1000000;
@@ -226,7 +228,8 @@ read_cert(const char * const dir, const char * const name, X509_STORE * const st
226228

227229
#if defined(_WIN32)
228230
static size_t
229-
read_certsdir(char * const dir, X509_STORE * const store)
231+
read_certsdir(char * const dir, const size_t max_certs,
232+
X509_STORE * const store)
230233
{
231234
const size_t dir_len = strlen(dir);
232235
const size_t glob_len = dir_len + sizeof("\\*");
@@ -236,6 +239,9 @@ read_certsdir(char * const dir, X509_STORE * const store)
236239
WIN32_FIND_DATA find_data;
237240
DWORD last_err;
238241

242+
if (max_certs == 0)
243+
return 0;
244+
239245
search_glob = OPENSSL_malloc(glob_len);
240246
if (search_glob == NULL) {
241247
warnx("Error allocating a search glob for \"%s\"", dir);
@@ -263,6 +269,8 @@ read_certsdir(char * const dir, X509_STORE * const store)
263269

264270
cnt += read_cert(dir, find_data.cFileName, store);
265271

272+
if (cnt >= max_certs)
273+
break;
266274
} while (FindNextFileA(find_handle, &find_data) != 0);
267275

268276
last_err = GetLastError();
@@ -278,13 +286,18 @@ read_certsdir(char * const dir, X509_STORE * const store)
278286
}
279287
#else /* !defined(_WIN32) */
280288
static size_t
281-
read_certsdir(char * const dir, X509_STORE * const store)
289+
read_certsdir(char * const dir, const size_t max_certs,
290+
X509_STORE * const store)
282291
{
283292
struct stat st;
284293
struct dirent *e;
285-
DIR *d = opendir(dir);
294+
DIR *d;
286295
size_t cnt = 0;
287296

297+
if (max_certs == 0)
298+
return 0;
299+
300+
d = opendir(dir);
288301
if (d == NULL) {
289302
warn("Could not open \"%s\"", dir);
290303

@@ -310,6 +323,9 @@ read_certsdir(char * const dir, X509_STORE * const store)
310323
}
311324

312325
cnt += read_cert(dir, e->d_name, store);
326+
327+
if (cnt >= max_certs)
328+
break;
313329
}
314330

315331
closedir(d);
@@ -319,13 +335,17 @@ read_certsdir(char * const dir, X509_STORE * const store)
319335
#endif /* defined(_WIN32) */
320336

321337
static size_t
322-
read_certsdirs(char * const * const dirs, const int dir_cnt,
323-
X509_STORE * const store)
338+
read_certsdirs(char * const * const dirs, const size_t max_certs,
339+
const int dir_cnt, X509_STORE * const store)
324340
{
325341
size_t cnt = 0;
326342

327-
for (int i = 0; i < dir_cnt; i++)
328-
cnt += read_certsdir(dirs[i], store);
343+
for (int i = 0; i < dir_cnt; i++) {
344+
cnt += read_certsdir(dirs[i], max_certs - cnt, store);
345+
346+
if (cnt >= max_certs)
347+
break;
348+
}
329349

330350
return cnt;
331351
}
@@ -525,7 +545,8 @@ usage(char * const argv[])
525545
{
526546
fprintf(stderr,
527547
"Usage: %s [-t] [-v] [-q N] [-T time] [-n nonce_type:type_args]"
528-
" [-C threads] [-V] certsdir [certsdir...] threadcount\n"
548+
" [-l max_certs] [-L max_cert_dirs] [-C threads]"
549+
" [-V] certsdir [certsdir...] threadcount\n"
529550
"\t-t\tTerse output\n"
530551
"\t-v\tVerbose output. Multiple usage increases verbosity.\n"
531552
"\t-q\tGather information about temporal N-quantiles.\n"
@@ -538,6 +559,10 @@ usage(char * const argv[])
538559
"\t\t\tfile:PATH - load nonce certificate from PATH;\n"
539560
"\t\t\tif PATH is relative, the provided certsdir's are searched.\n"
540561
"\t\tDefault: " NONCE_CFG "\n"
562+
"\t-l\tLimit on the number of initially loaded certificates.\n"
563+
"\t\tDefault: " OPENSSL_MSTR(MAX_LOAD_CERTS) "\n"
564+
"\t-L\tLimit on the number of initially loaded certificate\n"
565+
"\t\tdirectories. Default: " OPENSSL_MSTR(MAX_LOAD_CERT_DIRS) "\n"
541566
"\t-C\tNumber of threads that share the same X.509\n"
542567
"\t\tstore context object. Default: "
543568
OPENSSL_MSTR(CTX_SHARE_THREADS) "\n"
@@ -608,11 +633,13 @@ main(int argc, char *argv[])
608633
int opt;
609634
int dirs_start;
610635
size_t num_certs = 0;
636+
size_t max_load_certs = MAX_LOAD_CERTS;
637+
int max_load_cert_dirs = MAX_LOAD_CERT_DIRS;
611638
struct nonce_cfg nonce_cfg;
612639

613640
parse_nonce_cfg(NONCE_CFG, &nonce_cfg);
614641

615-
while ((opt = getopt(argc, argv, "tvq:T:n:C:V")) != -1) {
642+
while ((opt = getopt(argc, argv, "tvq:T:n:l:L:C:V")) != -1) {
616643
switch (opt) {
617644
case 't': /* terse */
618645
verbosity = VERBOSITY_TERSE;
@@ -635,6 +662,15 @@ main(int argc, char *argv[])
635662
case 'n': /* nonce */
636663
parse_nonce_cfg(optarg, &nonce_cfg);
637664
break;
665+
case 'l': /* max certs to load */
666+
max_load_certs = parse_int(optarg, 0, INT_MAX,
667+
"maximum certificate load count");
668+
break;
669+
case 'L': /* max certs dirs to load*/
670+
max_load_cert_dirs = parse_int(optarg, 0, INT_MAX,
671+
"maximum certificate directories"
672+
" load count");
673+
break;
638674
case 'C': /* how many threads share X509_STORE_CTX */
639675
ctx_share_cnt = parse_int(optarg, 1, INT_MAX,
640676
"X509_STORE_CTX share degree");
@@ -684,7 +720,9 @@ main(int argc, char *argv[])
684720
if (store == NULL || !X509_STORE_set_default_paths(store))
685721
errx(EXIT_FAILURE, "Failed to create X509_STORE");
686722

687-
num_certs += read_certsdirs(argv + dirs_start, argc - dirs_start - 1,
723+
num_certs += read_certsdirs(argv + dirs_start, max_load_certs,
724+
OSSL_MIN(argc - dirs_start - 1,
725+
max_load_cert_dirs),
688726
store);
689727

690728
if (verbosity >= VERBOSITY_DEBUG_STATS)

0 commit comments

Comments
 (0)