[io/ssl] Add an option to bypass trusting system cert roots.
Fixes https://github.com/dart-lang/sdk/issues/45912
TEST=manually remove root certificate for pub.dev, confirm that dart is not able to establish https connection in default configuration to pub.dev, confirm that it can connect with the flag.
Change-Id: I51af7994d7cd7371a17877844dc1bf39cd5e54ca
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/198442
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Zach Anderson <zra@google.com>
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index e60f6c8..b002ab8 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -470,6 +470,8 @@
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 658cea3..a0fc972 100644
--- a/runtime/bin/main_options.h
+++ b/runtime/bin/main_options.h
@@ -48,7 +48,8 @@
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 f5d3a00..4ea0f10 100644
--- a/runtime/bin/security_context.cc
+++ b/runtime/bin/security_context.cc
@@ -35,6 +35,7 @@
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 5090cdb..e8800e2 100644
--- a/runtime/bin/security_context.h
+++ b/runtime/bin/security_context.h
@@ -93,6 +93,14 @@
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 @@
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 e4a9312..b251a0a 100644
--- a/runtime/bin/security_context_linux.cc
+++ b/runtime/bin/security_context_linux.cc
@@ -40,21 +40,27 @@
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 950f4be..6b19a89 100644
--- a/runtime/bin/security_context_win.cc
+++ b/runtime/bin/security_context_win.cc
@@ -190,12 +190,18 @@
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.