1 // Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <openssl/ssl.h>
16
17 #if !defined(OPENSSL_WINDOWS) && !defined(OPENSSL_PNACL) && \
18 !defined(OPENSSL_NO_FILESYSTEM)
19
20 #include <dirent.h>
21 #include <errno.h>
22 #include <string.h>
23
24 #include <openssl/err.h>
25 #include <openssl/mem.h>
26
27
SSL_add_dir_cert_subjects_to_stack(STACK_OF (X509_NAME)* stack,const char * path)28 int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
29 const char *path) {
30 DIR *dir = opendir(path);
31 if (dir == NULL) {
32 OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
33 ERR_add_error_data(3, "opendir('", dir, "')");
34 return 0;
35 }
36
37 int ret = 0;
38 for (;;) {
39 // |readdir| may fail with or without setting |errno|.
40 errno = 0;
41 struct dirent *dirent = readdir(dir);
42 if (dirent == NULL) {
43 if (errno) {
44 OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
45 ERR_add_error_data(3, "readdir('", path, "')");
46 } else {
47 ret = 1;
48 }
49 break;
50 }
51
52 char buf[1024];
53 if (strlen(path) + strlen(dirent->d_name) + 2 > sizeof(buf)) {
54 OPENSSL_PUT_ERROR(SSL, SSL_R_PATH_TOO_LONG);
55 break;
56 }
57
58 int r = snprintf(buf, sizeof(buf), "%s/%s", path, dirent->d_name);
59 if (r <= 0 ||
60 r >= (int)sizeof(buf) ||
61 !SSL_add_file_cert_subjects_to_stack(stack, buf)) {
62 break;
63 }
64 }
65
66 closedir(dir);
67 return ret;
68 }
69
70 #endif // !WINDOWS && !PNACL && !OPENSSL_NO_FILESYSTEM
71