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