Chromium Code Reviews| Index: runtime/bin/security_context_boringssl.cc |
| diff --git a/runtime/bin/security_context_boringssl.cc b/runtime/bin/security_context_boringssl.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..74dc028eb490429fa7afe38afb4577e3dd9d7753 |
| --- /dev/null |
| +++ b/runtime/bin/security_context_boringssl.cc |
| @@ -0,0 +1,129 @@ |
| +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +#if !defined(DART_IO_DISABLED) && !defined(DART_IO_SECURE_SOCKET_DISABLED) |
| + |
| +#include "platform/globals.h" |
| +#if defined(HOST_OS_ANDROID) || defined(HOST_OS_LINUX) || \ |
| + defined(HOST_OS_WINDOWS) || defined(HOST_OS_FUCHSIA) |
| + |
| +#include "bin/security_context.h" |
| + |
| +#include <openssl/bio.h> |
| +#include <openssl/ssl.h> |
| +#include <openssl/x509.h> |
| + |
| +#include "bin/directory.h" |
| +#include "bin/file.h" |
| +#include "bin/log.h" |
| +#include "bin/secure_socket.h" |
| +#include "bin/secure_socket_utils.h" |
| + |
| +namespace dart { |
| +namespace bin { |
| + |
| +// The security context won't necessarily use the compiled-in root certificates, |
| +// but since there is no way to update the size of the allocation after creating |
| +// the weak persistent handle, we assume that it will. Note that when the |
| +// root certs aren't compiled in, |root_certificates_pem_length| is 0. |
| +const intptr_t SSLCertContext::kApproximateSize = |
| + sizeof(SSLCertContext) + root_certificates_pem_length; |
| + |
| +const char* commandline_root_certs_file = NULL; |
| +const char* commandline_root_certs_cache = NULL; |
| + |
| +static void AddCompiledInCerts(SSLCertContext* context) { |
| + if (root_certificates_pem == NULL) { |
| + if (SSL_LOG_STATUS) { |
| + Log::Print("Missing compiled-in roots\n"); |
| + } |
| + 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), |
| + root_certificates_pem_length); |
| + X509* root_cert; |
| + // PEM_read_bio_X509 reads PEM-encoded certificates from a bio (in our case, |
| + // backed by a memory buffer), and returns X509 objects, one by one. |
| + // When the end of the bio is reached, it returns null. |
| + while ((root_cert = PEM_read_bio_X509(roots_bio, NULL, NULL, NULL)) != NULL) { |
| + int status = X509_STORE_add_cert(store, root_cert); |
| + // X509_STORE_add_cert increments the reference count of cert on success. |
| + X509_free(root_cert); |
| + if (status == 0) { |
| + break; |
| + } |
| + } |
| + BIO_free(roots_bio); |
| + // If there is an error here, it must be the error indicating that we are done |
| + // reading PEM certificates. |
| + ASSERT((ERR_peek_error() == 0) || SecureSocketUtils::NoPEMStartLine()); |
| + ERR_clear_error(); |
| +} |
| + |
| + |
| +void SSLCertContext::TrustBuiltinRoots() { |
| + // First, try to use locations specified on the command line. |
| + if (commandline_root_certs_file != NULL) { |
| + LoadRootCertFile(commandline_root_certs_file); |
| + return; |
| + } |
| + |
| + if (commandline_root_certs_cache != NULL) { |
| + LoadRootCertCache(commandline_root_certs_cache); |
| + return; |
| + } |
| + |
| +#if defined(HOST_OS_ANDROID) |
|
zra
2017/06/02 22:56:24
This is looking really good.
At this point I thin
bkonyi
2017/06/05 20:25:52
Done.
|
| + // 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(android_cacerts); |
| + return; |
| +#elif defined(HOST_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(bundle); |
| + return; |
| + } |
| + |
| + if (Directory::Exists(cachedir) == Directory::EXISTS) { |
| + LoadRootCertCache(cachedir); |
| + return; |
| + } |
| +#endif // defined(HOST_OS_ANDROID) |
| + |
| + // Fall back on the compiled-in certs if the standard locations don't exist, |
| + // or we aren't on Linux. |
| + if (SSL_LOG_STATUS) { |
| + Log::Print("Trusting compiled-in roots\n"); |
| + } |
| + AddCompiledInCerts(this); |
| +} |
| + |
| + |
| +void SSLFilter::RegisterCallbacks(SSLCertContext* cert_ctx) { |
| + // No callbacks to register for implementations using BoringSSL's built-in |
| + // verification mechanism. |
| +} |
| + |
| +} // namespace bin |
| +} // namespace dart |
| + |
| +#endif // defined(HOST_OS_LINUX) |
| + |
| +#endif // !defined(DART_IO_DISABLED) && |
| + // !defined(DART_IO_SECURE_SOCKET_DISABLED) |