Index: content/browser/browser_main_runner.cc |
diff --git a/content/browser/browser_main_runner.cc b/content/browser/browser_main_runner.cc |
index a06f18af30dfe3d2a6c4342124c87e6507177daf..3faba5b3a0e71f75207f844806a8cec9d669e4e1 100644 |
--- a/content/browser/browser_main_runner.cc |
+++ b/content/browser/browser_main_runner.cc |
@@ -21,6 +21,8 @@ |
#if defined(OS_WIN) |
#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 +30,86 @@ 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. |
jam
2014/09/12 04:13:08
nit: move this to net::sha256_interception::IsNeed
Ryan Sleevi
2014/09/12 08:34:35
The logic behind this is that the function would t
|
+ return; |
+#else |
+ if (!net::sha256_interception::IsNeeded()) |
+ 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) |
+ return; |
davidben
2014/09/12 22:51:17
If this return fires, we'll leave cert_verify_sign
|
+ |
+ 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)); |
jam
2014/09/12 04:13:08
that's a lot of lines to patch the method. can you
Ryan Sleevi
2014/09/12 08:34:35
Nope. I worked with Carlos and Shrikant on this. B
|
+#endif // _WIN64 |
+} |
+ |
+} // namespace |
+ |
+#endif // OS_WIN |
+ |
class BrowserMainRunnerImpl : public BrowserMainRunner { |
public: |
BrowserMainRunnerImpl() |
@@ -64,6 +146,7 @@ class BrowserMainRunnerImpl : public BrowserMainRunner { |
// Win32 API here directly. |
ImmDisableTextFrameService(static_cast<DWORD>(-1)); |
} |
+ InstallSha256LegacyHooks(); |
davidben
2014/09/12 22:51:17
Perhaps add tests the exercise the patched version
Ryan Sleevi
2014/09/23 21:59:58
Considering that the XP bots we have are SP3, I do
|
#endif // OS_WIN |
base::StatisticsRecorder::Initialize(); |