@@ -221,15 +221,15 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
221
221
issuer);
222
222
}
223
223
224
- unsigned long LoadCertsFromFile ( // NOLINT(runtime/int)
224
+ static unsigned long LoadCertsFromFile ( // NOLINT(runtime/int)
225
225
std::vector<X509*>* certs,
226
226
const char * file) {
227
227
MarkPopErrorOnReturn mark_pop_error_on_return;
228
228
229
229
auto bio = BIOPointer::NewFile (file, " r" );
230
230
if (!bio) return ERR_get_error ();
231
231
232
- while (X509* x509 = PEM_read_bio_X509 (
232
+ while (X509* x509 = PEM_read_bio_X509_AUX (
233
233
bio.get (), nullptr , NoPasswordCallback, nullptr )) {
234
234
certs->push_back (x509);
235
235
}
@@ -244,6 +244,19 @@ unsigned long LoadCertsFromFile( // NOLINT(runtime/int)
244
244
}
245
245
}
246
246
247
+ static void LoadCertsFromFileOrWarn (std::vector<X509*>* certs,
248
+ const char * file) {
249
+ unsigned long err = LoadCertsFromFile (certs, file); // NOLINT(runtime/int)
250
+ if (err) {
251
+ char buf[256 ];
252
+ ERR_error_string_n (err, buf, sizeof (buf));
253
+ fprintf (stderr,
254
+ " Warning: Ignoring extra certs from `%s`, load failed: %s\n " ,
255
+ extra_root_certs_file.c_str (),
256
+ buf);
257
+ }
258
+ }
259
+
247
260
// Indicates the trust status of a certificate.
248
261
enum class TrustStatus {
249
262
// Trust status is unknown / uninitialized.
@@ -643,6 +656,73 @@ void ReadWindowsCertificates(
643
656
}
644
657
#endif
645
658
659
+ void LoadCertsFromDir (std::vector<X509*>* certs, std::string_view cert_dir) {
660
+ uv_fs_t dir_req;
661
+ auto cleanup = OnScopeLeave ([&dir_req]() { uv_fs_req_cleanup (&dir_req); });
662
+ int err = uv_fs_scandir (nullptr , &dir_req, cert_dir.data (), 0 , nullptr );
663
+ if (err < 0 ) {
664
+ fprintf (stderr,
665
+ " Cannot open directory %s to load OpenSSL certificates.\n " ,
666
+ cert_dir.data ());
667
+ return ;
668
+ }
669
+
670
+ uv_fs_t stats_req;
671
+ auto cleanup_stats =
672
+ OnScopeLeave ([&stats_req]() { uv_fs_req_cleanup (&stats_req); });
673
+ for (;;) {
674
+ uv_dirent_t ent;
675
+
676
+ int r = uv_fs_scandir_next (&dir_req, &ent);
677
+ if (r == UV_EOF) {
678
+ break ;
679
+ }
680
+ if (r < 0 ) {
681
+ char message[64 ];
682
+ uv_strerror_r (r, message, sizeof (message));
683
+ fprintf (stderr,
684
+ " Cannot scan directory %s to load OpenSSL certificates.\n " ,
685
+ cert_dir.data ());
686
+ return ;
687
+ }
688
+
689
+ std::string file_path = std::string (cert_dir) + " /" + ent.name ;
690
+ int stats_r = uv_fs_stat (nullptr , &stats_req, file_path.c_str (), nullptr );
691
+ if (stats_r == 0 &&
692
+ (static_cast <uv_stat_t *>(stats_req.ptr )->st_mode & S_IFREG)) {
693
+ LoadCertsFromFile (certs, file_path.c_str ());
694
+ }
695
+ }
696
+ }
697
+
698
+ // Loads CA certificates from the default certificate paths respected by
699
+ // OpenSSL.
700
+ void GetOpenSSLSystemCertificates (std::vector<X509*>* system_store_certs) {
701
+ std::string cert_file;
702
+ // While configurable when OpenSSL is built, this is usually SSL_CERT_FILE.
703
+ if (!credentials::SafeGetenv (X509_get_default_cert_file_env (), &cert_file)) {
704
+ // This is usually /etc/ssl/cert.pem if we are using the OpenSSL statically
705
+ // linked and built with default configurations.
706
+ cert_file = X509_get_default_cert_file ();
707
+ }
708
+
709
+ std::string cert_dir;
710
+ // While configurable when OpenSSL is built, this is usually SSL_CERT_DIR.
711
+ if (!credentials::SafeGetenv (X509_get_default_cert_dir_env (), &cert_dir)) {
712
+ // This is usually /etc/ssl/certs if we are using the OpenSSL statically
713
+ // linked and built with default configurations.
714
+ cert_dir = X509_get_default_cert_dir ();
715
+ }
716
+
717
+ if (!cert_file.empty ()) {
718
+ LoadCertsFromFile (system_store_certs, cert_file.c_str ());
719
+ }
720
+
721
+ if (!cert_dir.empty ()) {
722
+ LoadCertsFromDir (system_store_certs, cert_dir.c_str ());
723
+ }
724
+ }
725
+
646
726
static std::vector<X509*> InitializeBundledRootCertificates () {
647
727
// Read the bundled certificates in node_root_certs.h into
648
728
// bundled_root_certs_vector.
@@ -682,6 +762,9 @@ static std::vector<X509*> InitializeSystemStoreCertificates() {
682
762
#endif
683
763
#ifdef _WIN32
684
764
ReadWindowsCertificates (&system_store_certs);
765
+ #endif
766
+ #if !defined(__APPLE__) && !defined(_WIN32)
767
+ GetOpenSSLSystemCertificates (&system_store_certs);
685
768
#endif
686
769
return system_store_certs;
687
770
}
@@ -696,17 +779,7 @@ static std::vector<X509*>& GetSystemStoreRootCertificates() {
696
779
697
780
static std::vector<X509*> InitializeExtraCACertificates () {
698
781
std::vector<X509*> extra_certs;
699
- unsigned long err = LoadCertsFromFile ( // NOLINT(runtime/int)
700
- &extra_certs,
701
- extra_root_certs_file.c_str ());
702
- if (err) {
703
- char buf[256 ];
704
- ERR_error_string_n (err, buf, sizeof (buf));
705
- fprintf (stderr,
706
- " Warning: Ignoring extra certs from `%s`, load failed: %s\n " ,
707
- extra_root_certs_file.c_str (),
708
- buf);
709
- }
782
+ LoadCertsFromFileOrWarn (&extra_certs, extra_root_certs_file.c_str ());
710
783
return extra_certs;
711
784
}
712
785
0 commit comments