diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc index e60f6c82ae7..b002ab8bfef 100644 --- a/runtime/bin/main_options.cc +++ b/runtime/bin/main_options.cc @@ -470,6 +470,8 @@ bool Options::ParseArguments(int argc, SSLCertContext::set_root_certs_cache(Options::root_certs_cache()); SSLCertContext::set_long_ssl_cert_evaluation( Options::long_ssl_cert_evaluation()); + SSLCertContext::set_bypass_trusting_system_roots( + Options::bypass_trusting_system_roots()); #endif // !defined(DART_IO_SECURE_SOCKET_DISABLED) // The arguments to the VM are at positions 1 through i-1 in argv. diff --git a/runtime/bin/main_options.h b/runtime/bin/main_options.h index 658cea3fd3d..a0fc972575a 100644 --- a/runtime/bin/main_options.h +++ b/runtime/bin/main_options.h @@ -48,7 +48,8 @@ namespace bin { V(suppress_core_dump, suppress_core_dump) \ V(enable_service_port_fallback, enable_service_port_fallback) \ V(disable_dart_dev, disable_dart_dev) \ - V(long_ssl_cert_evaluation, long_ssl_cert_evaluation) + V(long_ssl_cert_evaluation, long_ssl_cert_evaluation) \ + V(bypass_trusting_system_roots, bypass_trusting_system_roots) // Boolean flags that have a short form. #define SHORT_BOOL_OPTIONS_LIST(V) \ diff --git a/runtime/bin/security_context.cc b/runtime/bin/security_context.cc index f5d3a007c31..4ea0f1086ea 100644 --- a/runtime/bin/security_context.cc +++ b/runtime/bin/security_context.cc @@ -35,6 +35,7 @@ namespace bin { const char* SSLCertContext::root_certs_file_ = NULL; const char* SSLCertContext::root_certs_cache_ = NULL; bool SSLCertContext::long_ssl_cert_evaluation_ = false; +bool SSLCertContext::bypass_trusting_system_roots_ = false; int SSLCertContext::CertificateCallback(int preverify_ok, X509_STORE_CTX* store_ctx) { diff --git a/runtime/bin/security_context.h b/runtime/bin/security_context.h index 5090cdb14e3..e8800e2e7c2 100644 --- a/runtime/bin/security_context.h +++ b/runtime/bin/security_context.h @@ -93,6 +93,14 @@ class SSLCertContext : public ReferenceCounted { long_ssl_cert_evaluation_ = long_ssl_cert_evaluation; } + static bool bypass_trusting_system_roots() { + return bypass_trusting_system_roots_; + } + static void set_bypass_trusting_system_roots( + bool bypass_trusting_system_roots) { + bypass_trusting_system_roots_ = bypass_trusting_system_roots; + } + private: void AddCompiledInCerts(); void LoadRootCertFile(const char* file); @@ -107,6 +115,7 @@ class SSLCertContext : public ReferenceCounted { bool trust_builtin_; static bool long_ssl_cert_evaluation_; + static bool bypass_trusting_system_roots_; DISALLOW_COPY_AND_ASSIGN(SSLCertContext); }; diff --git a/runtime/bin/security_context_linux.cc b/runtime/bin/security_context_linux.cc index e4a9312d3e8..b251a0a3861 100644 --- a/runtime/bin/security_context_linux.cc +++ b/runtime/bin/security_context_linux.cc @@ -40,21 +40,27 @@ void SSLCertContext::TrustBuiltinRoots() { return; } - // On Linux, we use the compiled-in trusted certs as a last resort. First, - // we try to find the trusted certs in various standard locations. A good - // discussion of the complexities of this endeavor can be found here: - // - // https://www.happyassassin.net/2015/01/12/a-note-about-ssltls-trusted-certificate-stores-and-platforms/ - const char* bundle = "/etc/pki/tls/certs/ca-bundle.crt"; - const char* cachedir = "/etc/ssl/certs"; - if (File::Exists(NULL, bundle)) { - LoadRootCertFile(bundle); - return; - } + if (bypass_trusting_system_roots()) { + if (SSL_LOG_STATUS) { + Syslog::Print("Bypass trusting Linux built-in roots\n"); + } + } else { + // On Linux, we use the compiled-in trusted certs as a last resort. First, + // we try to find the trusted certs in various standard locations. A good + // discussion of the complexities of this endeavor can be found here: + // + // https://www.happyassassin.net/2015/01/12/a-note-about-ssltls-trusted-certificate-stores-and-platforms/ + const char* bundle = "/etc/pki/tls/certs/ca-bundle.crt"; + const char* cachedir = "/etc/ssl/certs"; + if (File::Exists(NULL, bundle)) { + LoadRootCertFile(bundle); + return; + } - if (Directory::Exists(NULL, cachedir) == Directory::EXISTS) { - LoadRootCertCache(cachedir); - return; + if (Directory::Exists(NULL, cachedir) == Directory::EXISTS) { + LoadRootCertCache(cachedir); + return; + } } // Fall back on the compiled-in certs if the standard locations don't exist, diff --git a/runtime/bin/security_context_win.cc b/runtime/bin/security_context_win.cc index 950f4be4238..6b19a89e15e 100644 --- a/runtime/bin/security_context_win.cc +++ b/runtime/bin/security_context_win.cc @@ -190,12 +190,18 @@ void SSLCertContext::TrustBuiltinRoots() { return; } - if (SSL_LOG_STATUS) { - Syslog::Print("Trusting Windows built-in roots\n"); - } - X509_STORE* store = SSL_CTX_get_cert_store(context()); - if (AddCertificatesFromRootStore(store)) { - return; + if (bypass_trusting_system_roots()) { + if (SSL_LOG_STATUS) { + Syslog::Print("Bypass trusting Windows built-in roots\n"); + } + } else { + if (SSL_LOG_STATUS) { + Syslog::Print("Trusting Windows built-in roots\n"); + } + X509_STORE* store = SSL_CTX_get_cert_store(context()); + if (AddCertificatesFromRootStore(store)) { + return; + } } // Reset store. SSL_CTX_set_cert_store will take ownership of store. A manual // free is not needed.