summaryrefslogtreecommitdiffstats
path: root/content/browser/browser_main_runner.cc
diff options
context:
space:
mode:
authorrsleevi <rsleevi@chromium.org>2014-09-23 20:12:55 -0700
committerCommit bot <commit-bot@chromium.org>2014-09-24 03:13:10 +0000
commit25e2bc0a95354727342757ba71582bf4de638fe8 (patch)
tree769e510b3a3566a92e098baecd86bc272fef3b67 /content/browser/browser_main_runner.cc
parent6fb1f2e798c05bc01f3feeb8ae17dbb34f482f86 (diff)
downloadchromium_src-25e2bc0a95354727342757ba71582bf4de638fe8.zip
chromium_src-25e2bc0a95354727342757ba71582bf4de638fe8.tar.gz
chromium_src-25e2bc0a95354727342757ba71582bf4de638fe8.tar.bz2
Use sidestep to detour CertVerifyCertificateSignatureEx on Windows versions earlier than Vista (excluding XP SP3), adding in SHA-256 support by deferring to NSS.
The canonical path to supporting SHA-256 is to install XP SP3 or the appropriate hotfixes for XP x64 / Windows Server 2003. However, as not all users may do so, and there's enough of a usability hurdle, provide an interception hook until we fully drop support for these systems. XP is already outside of MSFT EOL (April 2014). Windows Server 2003 is EOL'd July 2015. BUG=401365 Review URL: https://codereview.chromium.org/561613002 Cr-Commit-Position: refs/heads/master@{#296335}
Diffstat (limited to 'content/browser/browser_main_runner.cc')
-rw-r--r--content/browser/browser_main_runner.cc87
1 files changed, 87 insertions, 0 deletions
diff --git a/content/browser/browser_main_runner.cc b/content/browser/browser_main_runner.cc
index a06f18a..7acd62d 100644
--- a/content/browser/browser_main_runner.cc
+++ b/content/browser/browser_main_runner.cc
@@ -20,7 +20,10 @@
#include "ui/base/ime/input_method_initializer.h"
#if defined(OS_WIN)
+#include "base/win/win_util.h"
#include "base/win/windows_version.h"
+#include "net/cert/sha256_legacy_support_win.h"
+#include "sandbox/win/src/sidestep/preamble_patcher.h"
#include "ui/base/win/scoped_ole_initializer.h"
#endif
@@ -28,6 +31,89 @@ bool g_exited_main_message_loop = false;
namespace content {
+#if defined(OS_WIN)
+namespace {
+
+// Pointer to the original CryptVerifyCertificateSignatureEx function.
+net::sha256_interception::CryptVerifyCertificateSignatureExFunc
+ g_real_crypt_verify_signature_stub = NULL;
+
+// Stub function that is called whenever the Crypt32 function
+// CryptVerifyCertificateSignatureEx is called. It just defers to net to perform
+// the actual verification.
+BOOL WINAPI CryptVerifyCertificateSignatureExStub(
+ HCRYPTPROV_LEGACY provider,
+ DWORD encoding_type,
+ DWORD subject_type,
+ void* subject_data,
+ DWORD issuer_type,
+ void* issuer_data,
+ DWORD flags,
+ void* extra) {
+ return net::sha256_interception::CryptVerifyCertificateSignatureExHook(
+ g_real_crypt_verify_signature_stub, provider, encoding_type, subject_type,
+ subject_data, issuer_type, issuer_data, flags, extra);
+}
+
+// If necessary, install an interception
+void InstallSha256LegacyHooks() {
+#if defined(_WIN64)
+ // Interception on x64 is not supported.
+ return;
+#else
+ if (base::win::MaybeHasSHA256Support())
+ return;
+
+ net::sha256_interception::CryptVerifyCertificateSignatureExFunc
+ cert_verify_signature_ptr = reinterpret_cast<
+ net::sha256_interception::CryptVerifyCertificateSignatureExFunc>(
+ ::GetProcAddress(::GetModuleHandle(L"crypt32.dll"),
+ "CryptVerifyCertificateSignatureEx"));
+ CHECK(cert_verify_signature_ptr);
+
+ DWORD old_protect = 0;
+ if (!::VirtualProtect(cert_verify_signature_ptr, 5, PAGE_EXECUTE_READWRITE,
+ &old_protect)) {
+ return;
+ }
+
+ g_real_crypt_verify_signature_stub =
+ reinterpret_cast<
+ net::sha256_interception::CryptVerifyCertificateSignatureExFunc>(
+ VirtualAllocEx(::GetCurrentProcess(), NULL,
+ sidestep::kMaxPreambleStubSize, MEM_COMMIT,
+ PAGE_EXECUTE_READWRITE));
+ if (g_real_crypt_verify_signature_stub == NULL) {
+ CHECK(::VirtualProtect(cert_verify_signature_ptr, 5, old_protect,
+ &old_protect));
+ return;
+ }
+
+ sidestep::SideStepError patch_result =
+ sidestep::PreamblePatcher::Patch(
+ cert_verify_signature_ptr, CryptVerifyCertificateSignatureExStub,
+ g_real_crypt_verify_signature_stub, sidestep::kMaxPreambleStubSize);
+ if (patch_result != sidestep::SIDESTEP_SUCCESS) {
+ CHECK(::VirtualFreeEx(::GetCurrentProcess(),
+ g_real_crypt_verify_signature_stub, 0,
+ MEM_RELEASE));
+ CHECK(::VirtualProtect(cert_verify_signature_ptr, 5, old_protect,
+ &old_protect));
+ return;
+ }
+
+ DWORD dummy = 0;
+ CHECK(::VirtualProtect(cert_verify_signature_ptr, 5, old_protect, &dummy));
+ CHECK(::VirtualProtect(g_real_crypt_verify_signature_stub,
+ sidestep::kMaxPreambleStubSize, old_protect,
+ &old_protect));
+#endif // _WIN64
+}
+
+} // namespace
+
+#endif // OS_WIN
+
class BrowserMainRunnerImpl : public BrowserMainRunner {
public:
BrowserMainRunnerImpl()
@@ -64,6 +150,7 @@ class BrowserMainRunnerImpl : public BrowserMainRunner {
// Win32 API here directly.
ImmDisableTextFrameService(static_cast<DWORD>(-1));
}
+ InstallSha256LegacyHooks();
#endif // OS_WIN
base::StatisticsRecorder::Initialize();