1 /*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 #include <openssl/ssl.h>
11
12 #if !defined(OPENSSL_WINDOWS) && !defined(OPENSSL_PNACL) && \
13 !defined(OPENSSL_NO_FILESYSTEM)
14
15 #include <dirent.h>
16 #include <errno.h>
17 #include <string.h>
18
19 #include <openssl/err.h>
20 #include <openssl/mem.h>
21
22
SSL_add_dir_cert_subjects_to_stack(STACK_OF (X509_NAME)* stack,const char * path)23 int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
24 const char *path) {
25 DIR *dir = opendir(path);
26 if (dir == NULL) {
27 OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
28 ERR_add_error_data(3, "opendir('", dir, "')");
29 return 0;
30 }
31
32 int ret = 0;
33 for (;;) {
34 // |readdir| may fail with or without setting |errno|.
35 errno = 0;
36 struct dirent *dirent = readdir(dir);
37 if (dirent == NULL) {
38 if (errno) {
39 OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
40 ERR_add_error_data(3, "readdir('", path, "')");
41 } else {
42 ret = 1;
43 }
44 break;
45 }
46
47 char buf[1024];
48 if (strlen(path) + strlen(dirent->d_name) + 2 > sizeof(buf)) {
49 OPENSSL_PUT_ERROR(SSL, SSL_R_PATH_TOO_LONG);
50 break;
51 }
52
53 int r = snprintf(buf, sizeof(buf), "%s/%s", path, dirent->d_name);
54 if (r <= 0 ||
55 r >= (int)sizeof(buf) ||
56 !SSL_add_file_cert_subjects_to_stack(stack, buf)) {
57 break;
58 }
59 }
60
61 closedir(dir);
62 return ret;
63 }
64
65 #endif // !WINDOWS && !PNACL && !OPENSSL_NO_FILESYSTEM
66