Skip to content

Commit 4f491bf

Browse files
committed
x509storeissuer: add certificates from the provided directories to the store
Signed-off-by: Eugene Syromiatnikov <[email protected]>
1 parent a4c199d commit 4f491bf

File tree

1 file changed

+150
-4
lines changed

1 file changed

+150
-4
lines changed

source/x509storeissuer.c

Lines changed: 150 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@
77
* https://www.openssl.org/source/license.html
88
*/
99

10+
#include <errno.h>
1011
#include <stdbool.h>
1112
#include <stdio.h>
1213
#include <stdlib.h>
1314
#include <string.h>
15+
#include <sys/stat.h>
1416
#ifndef _WIN32
17+
# include <dirent.h>
1518
# include <libgen.h>
1619
# include <unistd.h>
1720
#else
@@ -144,6 +147,146 @@ make_nonce(struct nonce_cfg *cfg)
144147
}
145148
}
146149

150+
static size_t
151+
read_cert(const char * const dir, const char * const name, X509_STORE * const store)
152+
{
153+
X509 *x509 = NULL;
154+
char *path = NULL;
155+
size_t ret = 1;
156+
157+
path = perflib_mk_file_path(dir, name);
158+
if (path == NULL) {
159+
warn("Failed to allocate cert name in directory \"%s\" for file \"%s\"",
160+
dir, name);
161+
goto out;
162+
}
163+
164+
x509 = load_cert_from_file(path);
165+
if (x509 == NULL) {
166+
goto out;
167+
}
168+
169+
if (!X509_STORE_add_cert(store, x509)) {
170+
warnx("Failed to add a certificate from \"%s\" to the store\n", path);
171+
goto out;
172+
}
173+
174+
if (verbosity >= VERBOSITY_DEBUG)
175+
fprintf(stderr, "Successfully added a certificate from \"%s\""
176+
" to the store\n", path);
177+
178+
ret = 1;
179+
180+
out:
181+
X509_free(x509);
182+
OPENSSL_free(path);
183+
184+
return ret;
185+
}
186+
187+
#if defined(_WIN32)
188+
static size_t
189+
read_certsdir(char * const dir, X509_STORE * const store)
190+
{
191+
const size_t dir_len = strlen(dir);
192+
const size_t glob_len = dir_len + sizeof("\\*");
193+
size_t cnt = 0;
194+
char *search_glob = NULL;
195+
HANDLE find_handle = INVALID_HANDLE_VALUE;
196+
WIN32_FIND_DATA find_data;
197+
DWORD last_err;
198+
199+
search_glob = OPENSSL_malloc(glob_len);
200+
if (search_glob == NULL) {
201+
warnx("Error allocating a search glob for \"%s\"", dir);
202+
return 0;
203+
}
204+
205+
if (snprintf(search_glob, glob_len, "%s\\*", dir) != glob_len - 1) {
206+
warnx("Error generating a search glob for \"%s\"", dir);
207+
goto out;
208+
}
209+
210+
find_handle = FindFirstFileA(search_glob, &find_data);
211+
if (find_handle == INVALID_HANDLE_VALUE) {
212+
warnx("Error in FindFirstFile(): %#lx", GetLastError());
213+
goto out;
214+
}
215+
216+
do {
217+
if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
218+
if (verbosity >= VERBOSITY_DEBUG)
219+
warnx("\"%s\\%s\" is a directory file, skipping",
220+
dir, find_data.cFileName);
221+
continue;
222+
}
223+
224+
cnt += read_cert(dir, find_data.cFileName, store);
225+
} while (FindNextFileA(find_handle, &find_data) != 0);
226+
227+
last_err = GetLastError();
228+
if (last_err != ERROR_NO_MORE_FILES)
229+
warnx("Error in FindNextFile(): %#lx", last_err);
230+
231+
out:
232+
if (find_handle != INVALID_HANDLE_VALUE)
233+
FindClose(find_handle);
234+
OPENSSL_free(search_glob);
235+
236+
return cnt;
237+
}
238+
#else /* !defined(_WIN32) */
239+
static size_t
240+
read_certsdir(char * const dir, X509_STORE * const store)
241+
{
242+
struct stat st;
243+
struct dirent *e;
244+
DIR *d = opendir(dir);
245+
size_t cnt = 0;
246+
247+
if (d == NULL) {
248+
warn("Could not open \"%s\"", dir);
249+
250+
return 0;
251+
}
252+
253+
while (1) {
254+
errno = 0;
255+
e = readdir(d);
256+
257+
if (e == NULL) {
258+
if (errno != 0)
259+
warn("An error occurred while reading directory \"%s\"", dir);
260+
261+
break;
262+
}
263+
264+
if (e->d_type != DT_REG && e->d_type != DT_UNKNOWN) {
265+
if (verbosity >= VERBOSITY_DEBUG)
266+
warnx("\"%s/%s\" is not a regular file, skipping",
267+
dir, e->d_name);
268+
continue;
269+
}
270+
271+
cnt += read_cert(dir, e->d_name, store);
272+
}
273+
274+
return cnt;
275+
}
276+
#endif /* defined(_WIN32) */
277+
278+
static size_t
279+
read_certsdirs(char * const * const dirs, const int dir_cnt,
280+
X509_STORE * const store)
281+
{
282+
size_t cnt = 0;
283+
284+
for (int i = 0; i < dir_cnt; i++)
285+
cnt += read_certsdir(dirs[i], store);
286+
287+
return cnt;
288+
}
289+
147290
static void
148291
do_x509storeissuer(size_t num)
149292
{
@@ -256,11 +399,10 @@ main(int argc, char *argv[])
256399
size_t total_count = 0;
257400
size_t total_found = 0;
258401
double avcalltime;
259-
char *cert = NULL;
260402
int ret = EXIT_FAILURE;
261-
BIO *bio = NULL;
262403
int opt;
263404
int dirs_start;
405+
size_t num_certs = 0;
264406
struct nonce_cfg nonce_cfg;
265407

266408
parse_nonce_cfg(NONCE_CFG, &nonce_cfg);
@@ -311,6 +453,12 @@ main(int argc, char *argv[])
311453
if (store == NULL || !X509_STORE_set_default_paths(store))
312454
errx(EXIT_FAILURE, "Failed to create X509_STORE");
313455

456+
num_certs += read_certsdirs(argv + dirs_start, argc - dirs_start - 1,
457+
store);
458+
459+
if (verbosity >= VERBOSITY_DEBUG_STATS)
460+
fprintf(stderr, "Added %zu certificates to the store\n", num_certs);
461+
314462
counts = OPENSSL_malloc(sizeof(size_t) * threadcount);
315463
if (counts == NULL)
316464
errx(EXIT_FAILURE, "Failed to create counts array");
@@ -358,8 +506,6 @@ main(int argc, char *argv[])
358506
err:
359507
X509_free(x509_nonce);
360508
X509_STORE_free(store);
361-
BIO_free(bio);
362-
OPENSSL_free(cert);
363509
OPENSSL_free(founds);
364510
OPENSSL_free(counts);
365511
return ret;

0 commit comments

Comments
 (0)