@@ -221,17 +221,23 @@ 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
- const char * file) {
226
+ const char * file,
227
+ bool check_usage) {
227
228
MarkPopErrorOnReturn mark_pop_error_on_return;
228
229
229
230
auto bio = BIOPointer::NewFile (file, " r" );
230
231
if (!bio) return ERR_get_error ();
231
232
232
- while (X509* x509 = PEM_read_bio_X509 (
233
+ while (X509* x509 = PEM_read_bio_X509_AUX (
233
234
bio.get (), nullptr , NoPasswordCallback, nullptr )) {
234
- certs->push_back (x509);
235
+ if (!check_usage ||
236
+ X509_check_purpose (x509, X509_PURPOSE_SSL_SERVER, 0 ) == 1 ) {
237
+ certs->push_back (x509);
238
+ } else {
239
+ X509_free (x509);
240
+ }
235
241
}
236
242
237
243
unsigned long err = ERR_peek_last_error (); // NOLINT(runtime/int)
@@ -643,6 +649,75 @@ void ReadWindowsCertificates(
643
649
}
644
650
#endif
645
651
652
+ void LoadCertsFromDir (std::vector<X509*>* certs,
653
+ std::string_view cert_dir,
654
+ bool check_usage) {
655
+ uv_fs_t dir_req;
656
+ auto cleanup = OnScopeLeave ([&dir_req]() { uv_fs_req_cleanup (&dir_req); });
657
+ int err = uv_fs_scandir (nullptr , &dir_req, cert_dir.data (), 0 , nullptr );
658
+ if (err < 0 ) {
659
+ fprintf (stderr,
660
+ " Cannot open directory %s to load OpenSSL certificates.\n " ,
661
+ cert_dir.data ());
662
+ return ;
663
+ }
664
+
665
+ uv_fs_t stats_req;
666
+ auto cleanup_stats =
667
+ OnScopeLeave ([&stats_req]() { uv_fs_req_cleanup (&stats_req); });
668
+ for (;;) {
669
+ uv_dirent_t ent;
670
+
671
+ int r = uv_fs_scandir_next (&dir_req, &ent);
672
+ if (r == UV_EOF) {
673
+ break ;
674
+ }
675
+ if (r < 0 ) {
676
+ char message[64 ];
677
+ uv_strerror_r (r, message, sizeof (message));
678
+ fprintf (stderr,
679
+ " Cannot scan directory %s to load OpenSSL certificates.\n " ,
680
+ cert_dir.data ());
681
+ return ;
682
+ }
683
+
684
+ std::string file_path = std::string (cert_dir) + " /" + ent.name ;
685
+ int stats_r = uv_fs_stat (nullptr , &stats_req, file_path.c_str (), nullptr );
686
+ if (stats_r == 0 &&
687
+ (static_cast <uv_stat_t *>(stats_req.ptr )->st_mode & S_IFREG)) {
688
+ LoadCertsFromFile (certs, file_path.c_str (), check_usage);
689
+ }
690
+ }
691
+ }
692
+
693
+ // Loads CA certificates from the default certificate paths respected by
694
+ // OpenSSL.
695
+ void GetOpenSSLSystemCertificates (std::vector<X509*>* system_store_certs) {
696
+ std::string cert_file;
697
+ // While configurable when OpenSSL is built, this is usually SSL_CERT_FILE.
698
+ if (!credentials::SafeGetenv (X509_get_default_cert_file_env (), &cert_file)) {
699
+ // This is usually /etc/ssl/cert.pem if we are using the OpenSSL statically
700
+ // linked and built with default configurations.
701
+ cert_file = X509_get_default_cert_file ();
702
+ }
703
+
704
+ std::string cert_dir;
705
+ // While configurable when OpenSSL is built, this is usually SSL_CERT_DIR.
706
+ if (!credentials::SafeGetenv (X509_get_default_cert_dir_env (), &cert_dir)) {
707
+ // This is usually /etc/ssl/certs if we are using the OpenSSL statically
708
+ // linked and built with default configurations.
709
+ cert_dir = X509_get_default_cert_dir ();
710
+ }
711
+
712
+ if (!cert_file.empty ()) {
713
+ LoadCertsFromFile (system_store_certs, cert_file.c_str (), true );
714
+ }
715
+
716
+ if (!cert_dir.empty ()) {
717
+ LoadCertsFromDir (system_store_certs, cert_dir.c_str (), true );
718
+ }
719
+ }
720
+
646
721
static std::vector<X509*> InitializeBundledRootCertificates () {
647
722
// Read the bundled certificates in node_root_certs.h into
648
723
// bundled_root_certs_vector.
@@ -683,6 +758,9 @@ static std::vector<X509*> InitializeSystemStoreCertificates() {
683
758
#endif
684
759
#ifdef _WIN32
685
760
ReadWindowsCertificates (&system_store_certs);
761
+ #endif
762
+ #if !defined(__APPLE__) && !defined(_WIN32)
763
+ GetOpenSSLSystemCertificates (&system_store_certs);
686
764
#endif
687
765
return system_store_certs;
688
766
}
@@ -699,7 +777,8 @@ static std::vector<X509*> InitializeExtraCACertificates() {
699
777
std::vector<X509*> extra_certs;
700
778
unsigned long err = LoadCertsFromFile ( // NOLINT(runtime/int)
701
779
&extra_certs,
702
- extra_root_certs_file.c_str ());
780
+ extra_root_certs_file.c_str (),
781
+ false );
703
782
if (err) {
704
783
char buf[256 ];
705
784
ERR_error_string_n (err, buf, sizeof (buf));
0 commit comments