Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(767)

Unified Diff: runtime/bin/secure_socket_boringssl.cc

Issue 2346683003: Use OS-provided trusted root certs on Linux (Closed)
Patch Set: Address comments Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/bin/root_certificates_unsupported.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/bin/secure_socket_boringssl.cc
diff --git a/runtime/bin/secure_socket_boringssl.cc b/runtime/bin/secure_socket_boringssl.cc
index e881815796af5c897652ef5f08f09ba3aa652799..132588d31c43de20c08a248057d7a512b1504e16 100644
--- a/runtime/bin/secure_socket_boringssl.cc
+++ b/runtime/bin/secure_socket_boringssl.cc
@@ -28,6 +28,8 @@
#include "bin/builtin.h"
#include "bin/dartutils.h"
+#include "bin/directory.h"
+#include "bin/file.h"
#include "bin/lockers.h"
#include "bin/log.h"
#include "bin/socket.h"
@@ -64,6 +66,10 @@ static const bool SSL_LOG_DATA = false;
static const int SSL_ERROR_MESSAGE_BUFFER_SIZE = 1000;
+const char* commandline_root_certs_file = NULL;
+const char* commandline_root_certs_cache = NULL;
+
+
/* Get the error messages from BoringSSL, and put them in buffer as a
* null-terminated string. */
static void FetchErrorString(char* buffer, int length) {
@@ -788,22 +794,10 @@ void FUNCTION_NAME(SecurityContext_AlpnSupported)(Dart_NativeArguments args) {
}
-void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)(
- Dart_NativeArguments args) {
- SSLContext* context = GetSecurityContext(args);
-#if defined(TARGET_OS_ANDROID)
- // On Android, we don't compile in the trusted root certificates. Insead,
- // we use the directory of trusted certificates already present on the device.
- // This saves ~240KB from the size of the binary. This has the drawback that
- // SSL_do_handshake will synchronously hit the filesystem looking for root
- // certs during its trust evaluation. We call SSL_do_handshake directly from
- // the Dart thread so that Dart code can be invoked from the "bad certificate"
- // callback called by SSL_do_handshake.
- const char* android_cacerts = "/system/etc/security/cacerts";
- int status = SSL_CTX_load_verify_locations(
- context->context(), NULL, android_cacerts);
- CheckStatus(status, "TlsException", "Failure trusting builtint roots");
-#else
+static void AddCompiledInCerts(SSLContext* context) {
+ if (root_certificates_pem == NULL) {
+ return;
+ }
X509_STORE* store = SSL_CTX_get_cert_store(context->context());
BIO* roots_bio =
BIO_new_mem_buf(const_cast<unsigned char*>(root_certificates_pem),
@@ -825,7 +819,90 @@ void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)(
// reading PEM certificates.
ASSERT((ERR_peek_error() == 0) || NoPEMStartLine());
ERR_clear_error();
+}
+
+
+static void LoadRootCertFile(SSLContext* context, const char* file) {
+ if (SSL_LOG_STATUS) {
+ Log::Print("Looking for trusted roots in %s\n", file);
+ }
+ if (!File::Exists(file)) {
+ ThrowIOException(-1, "TlsException", "Failed to find root cert file");
+ }
+ int status = SSL_CTX_load_verify_locations(context->context(), file, NULL);
+ CheckStatus(status, "TlsException", "Failure trusting builtint roots");
+ if (SSL_LOG_STATUS) {
+ Log::Print("Trusting roots from: %s\n", file);
+ }
+}
+
+
+static void LoadRootCertCache(SSLContext* context, const char* cache) {
+ if (SSL_LOG_STATUS) {
+ Log::Print("Looking for trusted roots in %s\n", cache);
+ }
+ if (Directory::Exists(cache) != Directory::EXISTS) {
+ ThrowIOException(-1, "TlsException", "Failed to find root cert cache");
+ }
+ int status = SSL_CTX_load_verify_locations(context->context(), NULL, cache);
+ CheckStatus(status, "TlsException", "Failure trusting builtint roots");
+ if (SSL_LOG_STATUS) {
+ Log::Print("Trusting roots from: %s\n", cache);
+ }
+}
+
+
+void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)(
+ Dart_NativeArguments args) {
+ SSLContext* context = GetSecurityContext(args);
+
+ // First, try to use locations specified on the command line.
+ if (commandline_root_certs_file != NULL) {
+ LoadRootCertFile(context, commandline_root_certs_file);
+ return;
+ }
+
+ if (commandline_root_certs_cache != NULL) {
+ LoadRootCertCache(context, commandline_root_certs_cache);
+ return;
+ }
+
+#if defined(TARGET_OS_ANDROID)
+ // On Android, we don't compile in the trusted root certificates. Insead,
+ // we use the directory of trusted certificates already present on the device.
+ // This saves ~240KB from the size of the binary. This has the drawback that
+ // SSL_do_handshake will synchronously hit the filesystem looking for root
+ // certs during its trust evaluation. We call SSL_do_handshake directly from
+ // the Dart thread so that Dart code can be invoked from the "bad certificate"
+ // callback called by SSL_do_handshake.
+ const char* android_cacerts = "/system/etc/security/cacerts";
+ LoadRootCertCache(context, android_cacerts);
+ return;
+#elif defined(TARGET_OS_LINUX)
+ // 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(bundle)) {
+ LoadRootCertFile(context, bundle);
+ return;
+ }
+
+ if (Directory::Exists(cachedir) == Directory::EXISTS) {
+ LoadRootCertCache(context, cachedir);
+ return;
+ }
#endif // defined(TARGET_OS_ANDROID)
+
+ // Fall back on the compiled-in certs if the standard locations don't exist,
+ // or we aren't on Linux.
+ AddCompiledInCerts(context);
+ if (SSL_LOG_STATUS) {
+ Log::Print("Trusting compiled-in roots\n");
+ }
}
@@ -1494,19 +1571,27 @@ void SSLFilter::Connect(const char* hostname,
// Make the connection:
if (is_server_) {
status = SSL_accept(ssl_);
- if (SSL_LOG_STATUS) Log::Print("SSL_accept status: %d\n", status);
+ if (SSL_LOG_STATUS) {
+ Log::Print("SSL_accept status: %d\n", status);
+ }
if (status != 1) {
// TODO(whesse): expect a needs-data error here. Handle other errors.
error = SSL_get_error(ssl_, status);
- if (SSL_LOG_STATUS) Log::Print("SSL_accept error: %d\n", error);
+ if (SSL_LOG_STATUS) {
+ Log::Print("SSL_accept error: %d\n", error);
+ }
}
} else {
status = SSL_connect(ssl_);
- if (SSL_LOG_STATUS) Log::Print("SSL_connect status: %d\n", status);
+ if (SSL_LOG_STATUS) {
+ Log::Print("SSL_connect status: %d\n", status);
+ }
if (status != 1) {
// TODO(whesse): expect a needs-data error here. Handle other errors.
error = SSL_get_error(ssl_, status);
- if (SSL_LOG_STATUS) Log::Print("SSL_connect error: %d\n", error);
+ if (SSL_LOG_STATUS) {
+ Log::Print("SSL_connect error: %d\n", error);
+ }
}
}
Handshake();
« no previous file with comments | « runtime/bin/root_certificates_unsupported.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698