| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |  | 
| 2 // Use of this source code is governed by a BSD-style license that can be |  | 
| 3 // found in the LICENSE file. |  | 
| 4 |  | 
| 5 #include "chrome/browser/safe_browsing/binary_feature_extractor.h" |  | 
| 6 |  | 
| 7 #include <windows.h> |  | 
| 8 #include <softpub.h> |  | 
| 9 #include <wintrust.h> |  | 
| 10 |  | 
| 11 #include "base/files/file_path.h" |  | 
| 12 #include "base/files/memory_mapped_file.h" |  | 
| 13 #include "base/logging.h" |  | 
| 14 #include "chrome/browser/safe_browsing/pe_image_reader_win.h" |  | 
| 15 #include "chrome/common/safe_browsing/csd.pb.h" |  | 
| 16 |  | 
| 17 #pragma comment(lib, "wintrust.lib") |  | 
| 18 |  | 
| 19 namespace safe_browsing { |  | 
| 20 |  | 
| 21 BinaryFeatureExtractor::BinaryFeatureExtractor() {} |  | 
| 22 |  | 
| 23 BinaryFeatureExtractor::~BinaryFeatureExtractor() {} |  | 
| 24 |  | 
| 25 void BinaryFeatureExtractor::CheckSignature( |  | 
| 26     const base::FilePath& file_path, |  | 
| 27     ClientDownloadRequest_SignatureInfo* signature_info) { |  | 
| 28   DVLOG(2) << "Checking signature for " << file_path.value(); |  | 
| 29 |  | 
| 30   WINTRUST_FILE_INFO file_info = {0}; |  | 
| 31   file_info.cbStruct = sizeof(file_info); |  | 
| 32   file_info.pcwszFilePath = file_path.value().c_str(); |  | 
| 33   file_info.hFile = NULL; |  | 
| 34   file_info.pgKnownSubject = NULL; |  | 
| 35 |  | 
| 36   WINTRUST_DATA wintrust_data = {0}; |  | 
| 37   wintrust_data.cbStruct = sizeof(wintrust_data); |  | 
| 38   wintrust_data.pPolicyCallbackData = NULL; |  | 
| 39   wintrust_data.pSIPClientData = NULL; |  | 
| 40   wintrust_data.dwUIChoice = WTD_UI_NONE; |  | 
| 41   wintrust_data.fdwRevocationChecks = WTD_REVOKE_NONE; |  | 
| 42   wintrust_data.dwUnionChoice = WTD_CHOICE_FILE; |  | 
| 43   wintrust_data.pFile = &file_info; |  | 
| 44   wintrust_data.dwStateAction = WTD_STATEACTION_VERIFY; |  | 
| 45   wintrust_data.hWVTStateData = NULL; |  | 
| 46   wintrust_data.pwszURLReference = NULL; |  | 
| 47   // Disallow revocation checks over the network. |  | 
| 48   wintrust_data.dwProvFlags = WTD_CACHE_ONLY_URL_RETRIEVAL; |  | 
| 49   wintrust_data.dwUIContext = WTD_UICONTEXT_EXECUTE; |  | 
| 50 |  | 
| 51   // The WINTRUST_ACTION_GENERIC_VERIFY_V2 policy verifies that the certificate |  | 
| 52   // chains up to a trusted root CA, and that it has appropriate permission to |  | 
| 53   // sign code. |  | 
| 54   GUID policy_guid = WINTRUST_ACTION_GENERIC_VERIFY_V2; |  | 
| 55 |  | 
| 56   LONG result = WinVerifyTrust(static_cast<HWND>(INVALID_HANDLE_VALUE), |  | 
| 57                                &policy_guid, |  | 
| 58                                &wintrust_data); |  | 
| 59 |  | 
| 60   CRYPT_PROVIDER_DATA* prov_data = WTHelperProvDataFromStateData( |  | 
| 61       wintrust_data.hWVTStateData); |  | 
| 62   if (prov_data) { |  | 
| 63     if (prov_data->csSigners > 0) { |  | 
| 64       signature_info->set_trusted(result == ERROR_SUCCESS); |  | 
| 65     } |  | 
| 66     for (DWORD i = 0; i < prov_data->csSigners; ++i) { |  | 
| 67       const CERT_CHAIN_CONTEXT* cert_chain_context = |  | 
| 68           prov_data->pasSigners[i].pChainContext; |  | 
| 69       if (!cert_chain_context) |  | 
| 70         break; |  | 
| 71       for (DWORD j = 0; j < cert_chain_context->cChain; ++j) { |  | 
| 72         CERT_SIMPLE_CHAIN* simple_chain = cert_chain_context->rgpChain[j]; |  | 
| 73         ClientDownloadRequest_CertificateChain* chain = |  | 
| 74             signature_info->add_certificate_chain(); |  | 
| 75         if (!simple_chain) |  | 
| 76           break; |  | 
| 77         for (DWORD k = 0; k < simple_chain->cElement; ++k) { |  | 
| 78           CERT_CHAIN_ELEMENT* element = simple_chain->rgpElement[k]; |  | 
| 79           chain->add_element()->set_certificate( |  | 
| 80               element->pCertContext->pbCertEncoded, |  | 
| 81               element->pCertContext->cbCertEncoded); |  | 
| 82         } |  | 
| 83       } |  | 
| 84     } |  | 
| 85 |  | 
| 86     // Free the provider data. |  | 
| 87     wintrust_data.dwStateAction = WTD_STATEACTION_CLOSE; |  | 
| 88     WinVerifyTrust(static_cast<HWND>(INVALID_HANDLE_VALUE), |  | 
| 89                    &policy_guid, &wintrust_data); |  | 
| 90   } |  | 
| 91 } |  | 
| 92 |  | 
| 93 bool BinaryFeatureExtractor::ExtractImageHeaders( |  | 
| 94     const base::FilePath& file_path, |  | 
| 95     ExtractHeadersOption options, |  | 
| 96     ClientDownloadRequest_ImageHeaders* image_headers) { |  | 
| 97   // Map the file into memory. |  | 
| 98   base::MemoryMappedFile file; |  | 
| 99   if (!file.Initialize(file_path)) |  | 
| 100     return false; |  | 
| 101 |  | 
| 102   PeImageReader pe_image; |  | 
| 103   if (!pe_image.Initialize(file.data(), file.length())) |  | 
| 104     return false; |  | 
| 105 |  | 
| 106   // Copy the headers. |  | 
| 107   ClientDownloadRequest_PEImageHeaders* pe_headers = |  | 
| 108       image_headers->mutable_pe_headers(); |  | 
| 109   pe_headers->set_dos_header(pe_image.GetDosHeader(), sizeof(IMAGE_DOS_HEADER)); |  | 
| 110   pe_headers->set_file_header(pe_image.GetCoffFileHeader(), |  | 
| 111                               sizeof(IMAGE_FILE_HEADER)); |  | 
| 112   size_t optional_header_size = 0; |  | 
| 113   const uint8_t* optional_header_data = |  | 
| 114       pe_image.GetOptionalHeaderData(&optional_header_size); |  | 
| 115   if (pe_image.GetWordSize() == PeImageReader::WORD_SIZE_32) { |  | 
| 116     pe_headers->set_optional_headers32(optional_header_data, |  | 
| 117                                        optional_header_size); |  | 
| 118   } else { |  | 
| 119     pe_headers->set_optional_headers64(optional_header_data, |  | 
| 120                                        optional_header_size); |  | 
| 121   } |  | 
| 122   const size_t number_of_sections = pe_image.GetNumberOfSections(); |  | 
| 123   for (size_t i = 0; i != number_of_sections; ++i) { |  | 
| 124     pe_headers->add_section_header(pe_image.GetSectionHeaderAt(i), |  | 
| 125                                    sizeof(IMAGE_SECTION_HEADER)); |  | 
| 126   } |  | 
| 127   if (!(options & kOmitExports)) { |  | 
| 128     size_t export_size = 0; |  | 
| 129     const uint8_t* export_section = pe_image.GetExportSection(&export_size); |  | 
| 130     if (export_section) |  | 
| 131       pe_headers->set_export_section_data(export_section, export_size); |  | 
| 132   } |  | 
| 133   size_t number_of_debug_entries = pe_image.GetNumberOfDebugEntries(); |  | 
| 134   for (size_t i = 0; i != number_of_debug_entries; ++i) { |  | 
| 135     const uint8_t* raw_data = NULL; |  | 
| 136     size_t raw_data_size = 0; |  | 
| 137     const IMAGE_DEBUG_DIRECTORY* directory_entry = |  | 
| 138         pe_image.GetDebugEntry(i, &raw_data, &raw_data_size); |  | 
| 139     if (directory_entry) { |  | 
| 140       ClientDownloadRequest_PEImageHeaders_DebugData* debug_data = |  | 
| 141           pe_headers->add_debug_data(); |  | 
| 142       debug_data->set_directory_entry(directory_entry, |  | 
| 143                                       sizeof(*directory_entry)); |  | 
| 144       if (raw_data) |  | 
| 145         debug_data->set_raw_data(raw_data, raw_data_size); |  | 
| 146     } |  | 
| 147   } |  | 
| 148 |  | 
| 149   return true; |  | 
| 150 } |  | 
| 151 |  | 
| 152 }  // namespace safe_browsing |  | 
| OLD | NEW | 
|---|