| // Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // https://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include <openssl/ssl.h> |
| |
| #if !defined(OPENSSL_WINDOWS) && !defined(OPENSSL_PNACL) && \ |
| !defined(OPENSSL_NO_FILESYSTEM) |
| |
| #include <dirent.h> |
| #include <errno.h> |
| #include <string.h> |
| |
| #include <openssl/err.h> |
| #include <openssl/mem.h> |
| |
| |
| int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, |
| const char *path) { |
| DIR *dir = opendir(path); |
| if (dir == NULL) { |
| OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); |
| ERR_add_error_data(3, "opendir('", dir, "')"); |
| return 0; |
| } |
| |
| int ret = 0; |
| for (;;) { |
| // |readdir| may fail with or without setting |errno|. |
| errno = 0; |
| struct dirent *dirent = readdir(dir); |
| if (dirent == NULL) { |
| if (errno) { |
| OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); |
| ERR_add_error_data(3, "readdir('", path, "')"); |
| } else { |
| ret = 1; |
| } |
| break; |
| } |
| |
| char buf[1024]; |
| if (strlen(path) + strlen(dirent->d_name) + 2 > sizeof(buf)) { |
| OPENSSL_PUT_ERROR(SSL, SSL_R_PATH_TOO_LONG); |
| break; |
| } |
| |
| int r = snprintf(buf, sizeof(buf), "%s/%s", path, dirent->d_name); |
| if (r <= 0 || |
| r >= (int)sizeof(buf) || |
| !SSL_add_file_cert_subjects_to_stack(stack, buf)) { |
| break; |
| } |
| } |
| |
| closedir(dir); |
| return ret; |
| } |
| |
| #endif // !WINDOWS && !PNACL && !OPENSSL_NO_FILESYSTEM |