diff options
author | kerrnel <kerrnel@chromium.org> | 2015-11-02 15:40:53 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-11-02 23:41:44 +0000 |
commit | 2b08c52ad7d79322756e93b7fb4dfb0a00f402e4 (patch) | |
tree | 9eeefc257bf01d001d694b496043b01b3109266e | |
parent | 42d9e3744b46e0fa1f555818273216e18094eeca (diff) | |
download | chromium_src-2b08c52ad7d79322756e93b7fb4dfb0a00f402e4.zip chromium_src-2b08c52ad7d79322756e93b7fb4dfb0a00f402e4.tar.gz chromium_src-2b08c52ad7d79322756e93b7fb4dfb0a00f402e4.tar.bz2 |
Implement anonymous, opt-in, collection of OS X binary integrity incidents.
This change implements anonymous collection of data about binary integrity
incidents on OS X. A binary integrity incident means that Chrome's application
bundle was modified on disk by some unauthorized source. This change collects
information about modified files. The checks are enabled on a sampling of user's
browsers and run at browser startup if enabled.
BUG=530314
Review URL: https://codereview.chromium.org/1363613004
Cr-Commit-Position: refs/heads/master@{#357469}
56 files changed, 2143 insertions, 62 deletions
diff --git a/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.cc b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.cc index d12d770..1768187 100644 --- a/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.cc +++ b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.cc @@ -18,32 +18,35 @@ #include "chrome/browser/safe_browsing/incident_reporting/binary_integrity_incident.h" #include "chrome/browser/safe_browsing/incident_reporting/incident_receiver.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" -#include "chrome/common/safe_browsing/binary_feature_extractor.h" #include "chrome/common/safe_browsing/csd.pb.h" namespace safe_browsing { -namespace { - void RecordSignatureVerificationTime(size_t file_index, - const base::TimeDelta& verification_time) { + const base::TimeDelta& verification_time) { static const char kHistogramName[] = "SBIRS.VerifyBinaryIntegrity."; base::HistogramBase* signature_verification_time_histogram = base::Histogram::FactoryTimeGet( std::string(kHistogramName) + base::SizeTToString(file_index), base::TimeDelta::FromMilliseconds(1), - base::TimeDelta::FromSeconds(20), - 50, + base::TimeDelta::FromSeconds(20), 50, base::Histogram::kUmaTargetedHistogramFlag); - signature_verification_time_histogram->AddTime(verification_time); + signature_verification_time_histogram->AddTime(verification_time); } -} // namespace +void ClearBinaryIntegrityForFile(IncidentReceiver* incident_receiver, + const std::string& basename) { + scoped_ptr<ClientIncidentReport_IncidentData_BinaryIntegrityIncident> + incident(new ClientIncidentReport_IncidentData_BinaryIntegrityIncident()); + incident->set_file_basename(basename); + incident_receiver->ClearIncidentForProcess( + make_scoped_ptr(new BinaryIntegrityIncident(incident.Pass()))); +} void RegisterBinaryIntegrityAnalysis() { -#if defined(OS_WIN) +#if defined(OS_WIN) || defined(OS_MACOSX) scoped_refptr<SafeBrowsingService> safe_browsing_service( g_browser_process->safe_browsing_service()); @@ -52,52 +55,4 @@ void RegisterBinaryIntegrityAnalysis() { #endif } -void VerifyBinaryIntegrity(scoped_ptr<IncidentReceiver> incident_receiver) { - scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor( - new BinaryFeatureExtractor()); - - std::vector<base::FilePath> critical_binaries = GetCriticalBinariesPath(); - for (size_t i = 0; i < critical_binaries.size(); ++i) { - base::FilePath binary_path(critical_binaries[i]); - if (!base::PathExists(binary_path)) - continue; - - scoped_ptr<ClientDownloadRequest_SignatureInfo> signature_info( - new ClientDownloadRequest_SignatureInfo()); - - base::TimeTicks time_before = base::TimeTicks::Now(); - binary_feature_extractor->CheckSignature(binary_path, signature_info.get()); - RecordSignatureVerificationTime(i, base::TimeTicks::Now() - time_before); - - // Only create a report if the signature is untrusted. - if (!signature_info->trusted()) { - scoped_ptr<ClientIncidentReport_IncidentData_BinaryIntegrityIncident> - incident( - new ClientIncidentReport_IncidentData_BinaryIntegrityIncident()); - - incident->set_file_basename(binary_path.BaseName().AsUTF8Unsafe()); - incident->set_allocated_signature(signature_info.release()); - - // Send the report. - incident_receiver->AddIncidentForProcess( - make_scoped_ptr(new BinaryIntegrityIncident(incident.Pass()))); - } else { - // The binary is integral, remove previous report so that next incidents - // for the binary will be reported. - scoped_ptr<ClientIncidentReport_IncidentData_BinaryIntegrityIncident> - incident( - new ClientIncidentReport_IncidentData_BinaryIntegrityIncident()); - incident->set_file_basename(binary_path.BaseName().AsUTF8Unsafe()); - incident_receiver->ClearIncidentForProcess( - make_scoped_ptr(new BinaryIntegrityIncident(incident.Pass()))); - } - } -} - -#if !defined(OS_WIN) -std::vector<base::FilePath> GetCriticalBinariesPath() { - return std::vector<base::FilePath>(); -} -#endif // !defined(OS_WIN) - } // namespace safe_browsing diff --git a/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.h b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.h index 6ac4532..0d1efe7 100644 --- a/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.h +++ b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.h @@ -5,12 +5,13 @@ #ifndef CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_BINARY_INTEGRITY_ANALYZER_H_ #define CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_BINARY_INTEGRITY_ANALYZER_H_ -#include <vector> +#include <string> #include "base/memory/scoped_ptr.h" namespace base { class FilePath; +class TimeDelta; } // namespace base namespace safe_browsing { @@ -26,8 +27,14 @@ void RegisterBinaryIntegrityAnalysis(); // service will decide when to start the analysis. void VerifyBinaryIntegrity(scoped_ptr<IncidentReceiver> incident_receiver); -// Returns a vector containing the paths to all the binaries to verify. -std::vector<base::FilePath> GetCriticalBinariesPath(); +// Record how long the signature verification took. +void RecordSignatureVerificationTime(size_t file_index, + const base::TimeDelta& verification_time); + +// Clear past incident reports for a file or bundle. This is used if the code +// object is now integral, as it will allow future incidents to be reported. +void ClearBinaryIntegrityForFile(IncidentReceiver* incident_receiver, + const std::string& basename); } // namespace safe_browsing diff --git a/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_mac.cc b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_mac.cc new file mode 100644 index 0000000..b6da848 --- /dev/null +++ b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_mac.cc @@ -0,0 +1,77 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_mac.h" + +#include "base/files/file_util.h" +#include "base/mac/bundle_locations.h" +#include "chrome/browser/safe_browsing/incident_reporting/binary_integrity_incident.h" +#include "chrome/browser/safe_browsing/incident_reporting/incident_receiver.h" +#include "chrome/browser/safe_browsing/signature_evaluator_mac.h" +#include "chrome/common/safe_browsing/csd.pb.h" + +#define DEVELOPER_ID_APPLICATION_OID "field.1.2.840.113635.100.6.1.13" +#define DEVELOPER_ID_INTERMEDIATE_OID "field.1.2.840.113635.100.6.2.6" + +namespace safe_browsing { + +namespace { + +void VerifyBinaryIntegrityHelper(IncidentReceiver* incident_receiver, + const base::FilePath& path, + const std::string& requirement) { + MacSignatureEvaluator evaluator(path, requirement); + if (!evaluator.Initialize()) { + LOG(ERROR) << "Could not initialize mac signature evaluator"; + return; + } + + scoped_ptr<ClientIncidentReport_IncidentData_BinaryIntegrityIncident> + incident(new ClientIncidentReport_IncidentData_BinaryIntegrityIncident()); + if (!evaluator.PerformEvaluation(incident.get())) { + incident_receiver->AddIncidentForProcess( + make_scoped_ptr(new BinaryIntegrityIncident(incident.Pass()))); + } else { + // Clear past incidents involving this bundle if the signature is + // now valid. + ClearBinaryIntegrityForFile(incident_receiver, path.BaseName().value()); + } +} + +} // namespace + +std::vector<PathAndRequirement> GetCriticalPathsAndRequirements() { + // Get the path to the main executable. + std::vector<PathAndRequirement> critical_binaries; + // This requirement describes a developer ID signed application, + // with Google's team identifier, and the com.Google.Chrome[.canary] + // identifier. + std::string requirement = + "anchor apple generic and certificate 1[" DEVELOPER_ID_INTERMEDIATE_OID + "] exists and certificate leaf[" DEVELOPER_ID_APPLICATION_OID + "] exists and certificate leaf[subject.OU]=\"EQHXZ8M8AV\" and " + "(identifier=\"com.google.Chrome\" or " + "identifier=\"com.google.Chrome.canary\")"; + critical_binaries.push_back( + PathAndRequirement(base::mac::OuterBundlePath(), requirement)); + // TODO(kerrnel): eventually add Adobe Flash Player to this list. + return critical_binaries; +} + +void VerifyBinaryIntegrityForTesting(IncidentReceiver* incident_receiver, + const base::FilePath& path, + const std::string& requirement) { + VerifyBinaryIntegrityHelper(incident_receiver, path, requirement); +} + +void VerifyBinaryIntegrity(scoped_ptr<IncidentReceiver> incident_receiver) { + size_t i = 0; + for (const auto& p : GetCriticalPathsAndRequirements()) { + base::TimeTicks time_before = base::TimeTicks::Now(); + VerifyBinaryIntegrityHelper(incident_receiver.get(), p.path, p.requirement); + RecordSignatureVerificationTime(i++, base::TimeTicks::Now() - time_before); + } +} + +} // namespace diff --git a/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_mac.h b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_mac.h new file mode 100644 index 0000000..05ecec2 --- /dev/null +++ b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_mac.h @@ -0,0 +1,40 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_BINARY_INTEGRITY_ANALYZER_MAC_H_ +#define CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_BINARY_INTEGRITY_ANALYZER_MAC_H_ + +#include "chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.h" + +#include <string> +#include <vector> + +#include "base/files/file_path.h" + +namespace safe_browsing { + +class IncidentReceiver; + +// Wraps a path to a code object and its specified code requirement. +struct PathAndRequirement { + PathAndRequirement(const base::FilePath& o_path, + const std::string& o_requirement) + : path(o_path), requirement(o_requirement) {} + base::FilePath path; + std::string requirement; +}; + +// Returns a vector of pairs, each of which contains the paths to the binaries +// to verify, and the codesign requirement to use when verifying. +std::vector<PathAndRequirement> GetCriticalPathsAndRequirements(); + +// This is a helper stub to allow the signature checking code to be tested with +// custom requirements and files. +void VerifyBinaryIntegrityForTesting(IncidentReceiver* incident_receiver, + const base::FilePath& path, + const std::string& requirement); + +} // namespace safe_browsing + +#endif // CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_BINARY_INTEGRITY_ANALYZER_MAC_H_ diff --git a/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_mac_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_mac_unittest.cc new file mode 100644 index 0000000..8d3c00a --- /dev/null +++ b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_mac_unittest.cc @@ -0,0 +1,139 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_mac.h" + +#include "base/files/file.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/mac/bundle_locations.h" +#include "base/memory/scoped_ptr.h" +#include "base/path_service.h" +#include "chrome/browser/safe_browsing/incident_reporting/incident.h" +#include "chrome/browser/safe_browsing/incident_reporting/mock_incident_receiver.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/common/safe_browsing/csd.pb.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::_; +using ::testing::StrictMock; + +namespace safe_browsing { + +namespace { + +const char kBundleBase[] = "test-bundle.app"; +const char kBundleURL[] = "test-bundle.app/Contents/MacOS/test-bundle"; + +// Helper function to corrupt the content of a binary to make sure the signature +// verification will fail. +bool CorruptFileContent(const base::FilePath& file_path) { + // This is the hard coded position of the TEXT segment in the mach-o file. + static const uint64_t text_pos = 0x1F90; + base::File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_WRITE); + if (!file.IsValid()) + return false; + char vec[] = {0xAA}; + return file.Write(text_pos, vec, sizeof(vec)) == sizeof(vec); +} + +} // namespace + +class BinaryIntegrityAnalyzerMacTest : public ::testing::Test { + public: + void SetUp() override; + + protected: + base::FilePath test_data_dir_; + base::ScopedTempDir temp_dir_; +}; + +void BinaryIntegrityAnalyzerMacTest::SetUp() { + ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_)); + test_data_dir_ = test_data_dir_.Append("safe_browsing/mach_o/"); + + // Set up the temp directory to copy the bundle to. + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); + + // Copy the signed bundle to the temp directory. + base::FilePath signed_bundle_path = + base::FilePath(test_data_dir_).Append(kBundleBase); + base::FilePath copied_bundle_path = + base::FilePath(temp_dir_.path()).Append(kBundleBase); + ASSERT_TRUE( + base::CopyDirectory(signed_bundle_path, copied_bundle_path, true)); +} + +TEST_F(BinaryIntegrityAnalyzerMacTest, GetCriticalPathsAndRequirements) { + // Expected paths and requirement strings. + std::vector<PathAndRequirement> paths_and_requirements_expected; + + std::string expected_req = + "anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] " + "exists and certificate leaf[field.1.2.840.113635.100.6.1.13] exists and " + "certificate leaf[subject.OU]=\"EQHXZ8M8AV\" and " + "(identifier=\"com.google.Chrome\" or " + "identifier=\"com.google.Chrome.canary\")"; + paths_and_requirements_expected.push_back( + PathAndRequirement(base::mac::OuterBundlePath(), expected_req)); + + std::vector<PathAndRequirement> paths_and_requirements = + GetCriticalPathsAndRequirements(); + ASSERT_EQ(1u, paths_and_requirements.size()); + EXPECT_EQ(paths_and_requirements[0].path, + paths_and_requirements_expected[0].path); + EXPECT_EQ(paths_and_requirements[0].requirement, + paths_and_requirements_expected[0].requirement); +} + +TEST_F(BinaryIntegrityAnalyzerMacTest, VerifyBinaryIntegrityForTesting) { + scoped_ptr<MockIncidentReceiver> mock_receiver( + new StrictMock<MockIncidentReceiver>()); + base::FilePath bundle = temp_dir_.path().Append(kBundleBase); + std::string requirement( + "certificate leaf[subject.CN]=\"untrusted@goat.local\""); + + // Run check on valid bundle. + scoped_ptr<Incident> incident_to_clear; + EXPECT_CALL(*mock_receiver, DoClearIncidentForProcess(_)) + .WillOnce(TakeIncident(&incident_to_clear)); + VerifyBinaryIntegrityForTesting(mock_receiver.get(), bundle, requirement); + + ASSERT_TRUE(incident_to_clear); + ASSERT_EQ(IncidentType::BINARY_INTEGRITY, incident_to_clear->GetType()); + ASSERT_EQ(incident_to_clear->GetKey(), "test-bundle.app"); + + base::FilePath exe_path = temp_dir_.path().Append(kBundleURL); + ASSERT_TRUE(CorruptFileContent(exe_path)); + + scoped_ptr<Incident> incident; + EXPECT_CALL(*mock_receiver, DoAddIncidentForProcess(_)) + .WillOnce(TakeIncident(&incident)); + + VerifyBinaryIntegrityForTesting(mock_receiver.get(), bundle, requirement); + + // Verify that the incident report contains the expected data. + scoped_ptr<ClientIncidentReport_IncidentData> incident_data( + incident->TakePayload()); + + ASSERT_TRUE(incident_data->has_binary_integrity()); + EXPECT_TRUE(incident_data->binary_integrity().has_file_basename()); + EXPECT_EQ("test-bundle.app", + incident_data->binary_integrity().file_basename()); + EXPECT_TRUE(incident_data->binary_integrity().has_sec_error()); + EXPECT_EQ(-67061, incident_data->binary_integrity().sec_error()); + EXPECT_FALSE(incident_data->binary_integrity().has_signature()); + EXPECT_EQ(0, + incident_data->binary_integrity().signature().signed_data_size()); + EXPECT_EQ(1, incident_data->binary_integrity().contained_file_size()); + + const auto& contained_file = + incident_data->binary_integrity().contained_file(0); + EXPECT_EQ(contained_file.relative_path(), "Contents/MacOS/test-bundle"); + EXPECT_TRUE(contained_file.has_signature()); + EXPECT_TRUE(contained_file.has_image_headers()); +} + +} // namespace safe_browsing diff --git a/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win.cc b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win.cc index e2013cb..54148e3 100644 --- a/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win.cc +++ b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win.cc @@ -2,12 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.h" +#include "chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win.h" #include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/logging.h" #include "base/path_service.h" +#include "chrome/browser/safe_browsing/incident_reporting/binary_integrity_incident.h" +#include "chrome/browser/safe_browsing/incident_reporting/incident_receiver.h" #include "chrome/common/chrome_version.h" +#include "chrome/common/safe_browsing/binary_feature_extractor.h" +#include "chrome/common/safe_browsing/csd.pb.h" namespace safe_browsing { @@ -43,4 +48,42 @@ std::vector<base::FilePath> GetCriticalBinariesPath() { return critical_binaries; } +void VerifyBinaryIntegrity(scoped_ptr<IncidentReceiver> incident_receiver) { + scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor( + new BinaryFeatureExtractor()); + + std::vector<base::FilePath> critical_binaries = GetCriticalBinariesPath(); + for (size_t i = 0; i < critical_binaries.size(); ++i) { + base::FilePath binary_path(critical_binaries[i]); + if (!base::PathExists(binary_path)) + continue; + + scoped_ptr<ClientDownloadRequest_SignatureInfo> signature_info( + new ClientDownloadRequest_SignatureInfo()); + + base::TimeTicks time_before = base::TimeTicks::Now(); + binary_feature_extractor->CheckSignature(binary_path, signature_info.get()); + RecordSignatureVerificationTime(i, base::TimeTicks::Now() - time_before); + + // Only create a report if the signature is untrusted. + if (!signature_info->trusted()) { + scoped_ptr<ClientIncidentReport_IncidentData_BinaryIntegrityIncident> + incident( + new ClientIncidentReport_IncidentData_BinaryIntegrityIncident()); + + incident->set_file_basename(binary_path.BaseName().AsUTF8Unsafe()); + incident->set_allocated_signature(signature_info.release()); + + // Send the report. + incident_receiver->AddIncidentForProcess( + make_scoped_ptr(new BinaryIntegrityIncident(incident.Pass()))); + } else { + // The binary is integral, remove previous report so that next incidents + // for the binary will be reported. + ClearBinaryIntegrityForFile(incident_receiver.get(), + binary_path.BaseName().AsUTF8Unsafe()); + } + } +} + } // namespace safe_browsing diff --git a/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win.h b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win.h new file mode 100644 index 0000000..6405ead --- /dev/null +++ b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win.h @@ -0,0 +1,23 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_BINARY_INTEGRITY_ANALYZER_WIN_H_ +#define CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_BINARY_INTEGRITY_ANALYZER_WIN_H_ + +#include "chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.h" + +#include <vector> + +namespace base { +class FilePath; +} // namespace base + +namespace safe_browsing { + +// Returns a vector containing the paths to all the binaries to verify. +std::vector<base::FilePath> GetCriticalBinariesPath(); + +} // namespace safe_browsing + +#endif // CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_BINARY_INTEGRITY_ANALYZER_WIN_H_ diff --git a/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win_unittest.cc index b2055f1..dc7c9a3 100644 --- a/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win_unittest.cc +++ b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win_unittest.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.h" +#include "chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win.h" #include "base/bind.h" #include "base/files/file_util.h" diff --git a/chrome/browser/safe_browsing/signature_evaluator_mac.h b/chrome/browser/safe_browsing/signature_evaluator_mac.h new file mode 100644 index 0000000..d14ba14 --- /dev/null +++ b/chrome/browser/safe_browsing/signature_evaluator_mac.h @@ -0,0 +1,71 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_COMMON_SAFE_BROWSING_SIGNATURE_EVALUATOR_MAC_H_ +#define CHROME_COMMON_SAFE_BROWSING_SIGNATURE_EVALUATOR_MAC_H_ + +#include <Security/Security.h> + +#include <string> + +#include "base/files/file_path.h" +#include "base/mac/scoped_cftyperef.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "chrome/browser/safe_browsing/incident_reporting/binary_integrity_incident.h" + +namespace safe_browsing { + +// Wraps the OS X SecStaticCode API, to evaluate a given file object +// with a given code requirement, and produce a list of incident reports +// for files that fail code signature validity checks. +class MacSignatureEvaluator { + public: + explicit MacSignatureEvaluator(const base::FilePath& signed_object_path); + + // The requirement string must be a valid "Code Signing Requirement Language + // string, which describes the identity of the signer. + MacSignatureEvaluator(const base::FilePath& signed_object_path, + const std::string& requirement); + + ~MacSignatureEvaluator(); + + // Creates the static code object and requirement string, and returns + // true if the object creation succeeds, else false. + bool Initialize(); + + // Evaluate the signature and return a list of any binary integrity incident + // reports. Returns true if and only if the signed code object is valid. + bool PerformEvaluation( + ClientIncidentReport_IncidentData_BinaryIntegrityIncident* incident); + + // Returns relative path component between a parent and a child. + // For example, /foo/bar and /foo/bar/y returns y. Note that + // this knows nothing about symlinks. Exposed for testing. + static bool GetRelativePathComponent(const base::FilePath& parent, + const base::FilePath& child, + std::string* out); + + private: + // The path to the code object on disk. + base::FilePath path_; + + // A Code Signing Requirement string. + std::string requirement_str_; + + // Records whether or not a requirement string was specified. + bool has_requirement_; + + // The static code object constructed from the code object on disk. + base::ScopedCFTypeRef<SecStaticCodeRef> code_; + + // The requirement object constructed from the requirement string. + base::ScopedCFTypeRef<SecRequirementRef> requirement_; + + DISALLOW_COPY_AND_ASSIGN(MacSignatureEvaluator); +}; + +} // namespace safe_browsing + +#endif // CHROME_COMMON_SAFE_BROWSING_SIGNATURE_EVALUATOR_MAC_H_ diff --git a/chrome/browser/safe_browsing/signature_evaluator_mac.mm b/chrome/browser/safe_browsing/signature_evaluator_mac.mm new file mode 100644 index 0000000..3189619 --- /dev/null +++ b/chrome/browser/safe_browsing/signature_evaluator_mac.mm @@ -0,0 +1,235 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/safe_browsing/signature_evaluator_mac.h" + +#include <CoreFoundation/CoreFoundation.h> +#include <Foundation/Foundation.h> +#include <Security/Security.h> +#include <sys/xattr.h> + +#include "base/mac/foundation_util.h" +#include "base/mac/mac_util.h" +#include "base/mac/scoped_cftyperef.h" +#include "base/mac/scoped_nsobject.h" +#include "base/strings/sys_string_conversions.h" +#include "chrome/common/safe_browsing/binary_feature_extractor.h" +#include "chrome/common/safe_browsing/csd.pb.h" +#include "chrome/common/safe_browsing/mach_o_image_reader_mac.h" + +namespace safe_browsing { + +namespace { + +// OS X code signing data can be stored in extended attributes as well. This is +// a list of the extended attributes slots currently used in Security.framework, +// from codesign.h (see the kSecCS_* constants). +const char* const xattrs[] = { + "com.apple.cs.CodeDirectory", + "com.apple.cs.CodeSignature", + "com.apple.cs.CodeRequirements", + "com.apple.cs.CodeResources", + "com.apple.cs.CodeApplication", + "com.apple.cs.CodeEntitlements", +}; + +// Convenience function to get the appropriate path from a variety of NSObject +// types. For resources, code signing seems to give back an NSURL in which +// the path is relative to the bundle root. So in this case, we take the +// relative component, otherwise we take the entire path. +bool GetPathFromNSObject(id obj, std::string* output) { + if (NSString* str = base::mac::ObjCCast<NSString>(obj)) { + output->assign([str fileSystemRepresentation]); + return true; + } + if (NSURL* url = base::mac::ObjCCast<NSURL>(obj)) { + output->assign([[url path] fileSystemRepresentation]); + return true; + } + if (NSBundle* bundle = base::mac::ObjCCast<NSBundle>(obj)) { + output->assign([[bundle bundlePath] fileSystemRepresentation]); + return true; + } + return false; +} + +// Extract the signature information from the mach-o or extended attributes. +void ExtractSignatureInfo(const base::FilePath& path, + ClientDownloadRequest_ImageHeaders* image_headers, + ClientDownloadRequest_SignatureInfo* signature) { + scoped_refptr<BinaryFeatureExtractor> bfe = new BinaryFeatureExtractor(); + + // TODO(kerrnel): if Chrome ever opts into the OS X "kill" semantics, this + // call has to change. `ExtractImageFeatures` maps the file, which will + // cause Chrome to be killed before it can report on the invalid file. + // This call will need to read(2) the binary into a buffer. + if (!bfe->ExtractImageFeatures(path, BinaryFeatureExtractor::kDefaultOptions, + image_headers, + signature->mutable_signed_data())) { + // If this is not a mach-o file, search inside the extended attributes. + for (const char* attr : xattrs) { + ssize_t size = getxattr(path.value().c_str(), attr, nullptr, 0, 0, 0); + if (size >= 0) { + std::vector<uint8_t> xattr_data(size); + ssize_t post_size = getxattr(path.value().c_str(), attr, &xattr_data[0], + xattr_data.size(), 0, 0); + if (post_size >= 0) { + xattr_data.resize(post_size); + ClientDownloadRequest_ExtendedAttr* xattr_msg = + signature->add_xattr(); + xattr_msg->set_key(attr); + xattr_msg->set_value(xattr_data.data(), xattr_data.size()); + } + } + } + } +} + +// Process the NSError information about any files that were altered. +void ReportAlteredFiles( + id detail, + const base::FilePath& bundle_path, + ClientIncidentReport_IncidentData_BinaryIntegrityIncident* incident) { + if (NSArray* arr = base::mac::ObjCCast<NSArray>(detail)) { + for (id obj in arr) + ReportAlteredFiles(obj, bundle_path, incident); + } else { + std::string path_str; + if (!GetPathFromNSObject(detail, &path_str)) + return; + std::string relative_path; + base::FilePath path(path_str); + // If the relative path calculation fails, at least take the basename. + if (!MacSignatureEvaluator::GetRelativePathComponent(bundle_path, path, + &relative_path)) { + relative_path = path.BaseName().value(); + } + + ClientIncidentReport_IncidentData_BinaryIntegrityIncident_ContainedFile* + contained_file = incident->add_contained_file(); + contained_file->set_relative_path(relative_path); + ExtractSignatureInfo(base::FilePath(path_str), + contained_file->mutable_image_headers(), + contained_file->mutable_signature()); + } +} + +} // namespace + +MacSignatureEvaluator::MacSignatureEvaluator( + const base::FilePath& signed_object_path) + : path_(signed_object_path), + requirement_str_(), + has_requirement_(false), + code_(nullptr), + requirement_(nullptr) {} + +MacSignatureEvaluator::MacSignatureEvaluator( + const base::FilePath& signed_object_path, + const std::string& requirement) + : path_(signed_object_path), + requirement_str_(requirement), + has_requirement_(true), + code_(nullptr), + requirement_(nullptr) {} + +MacSignatureEvaluator::~MacSignatureEvaluator() {} + +bool MacSignatureEvaluator::GetRelativePathComponent( + const base::FilePath& parent, + const base::FilePath& child, + std::string* out) { + if (!parent.IsParent(child)) + return false; + + std::vector<base::FilePath::StringType> parent_components; + std::vector<base::FilePath::StringType> child_components; + parent.GetComponents(&parent_components); + child.GetComponents(&child_components); + + size_t i = 0; + while (i < parent_components.size() && + child_components[i] == parent_components[i]) { + ++i; + } + + while (i < child_components.size()) { + out->append(child_components[i]); + if (++i < child_components.size()) + out->append("/"); + } + return true; +} + +bool MacSignatureEvaluator::Initialize() { + base::scoped_nsobject<NSURL> code_url([[NSURL alloc] + initFileURLWithPath:base::SysUTF8ToNSString(path_.value())]); + if (!code_url) + return false; + + if (SecStaticCodeCreateWithPath(base::mac::NSToCFCast(code_url.get()), + kSecCSDefaultFlags, + code_.InitializeInto()) != errSecSuccess) { + return false; + } + + if (has_requirement_) { + if (SecRequirementCreateWithString( + base::mac::NSToCFCast(base::SysUTF8ToNSString(requirement_str_)), + kSecCSDefaultFlags, + requirement_.InitializeInto()) != errSecSuccess) { + return false; + } + } + return true; +} + +bool MacSignatureEvaluator::PerformEvaluation( + ClientIncidentReport_IncidentData_BinaryIntegrityIncident* incident) { + DCHECK(incident->contained_file_size() == 0); + base::ScopedCFTypeRef<CFErrorRef> errors; + OSStatus err = SecStaticCodeCheckValidityWithErrors( + code_, kSecCSCheckAllArchitectures, requirement_, + errors.InitializeInto()); + if (err == errSecSuccess) + return true; + // Add the signature of the main binary to the incident report. + incident->set_file_basename(path_.BaseName().value()); + incident->set_sec_error(err); + // We heuristically detect if we are in a bundle or not by checking if + // the main executable is different from the path_. + base::ScopedCFTypeRef<CFDictionaryRef> info_dict; + if (SecCodeCopySigningInformation(code_, kSecCSDefaultFlags, + info_dict.InitializeInto()) == + errSecSuccess) { + CFURLRef exec_url = base::mac::CFCastStrict<CFURLRef>( + CFDictionaryGetValue(info_dict, kSecCodeInfoMainExecutable)); + if (!exec_url) + return false; + + base::FilePath exec_path( + [[base::mac::CFToNSCast(exec_url) path] fileSystemRepresentation]); + if (exec_path != path_) { + ReportAlteredFiles(base::mac::CFToNSCast(exec_url), path_, incident); + } else { + // We may be examing a flat executable file, so extract any signature. + ExtractSignatureInfo(path_, incident->mutable_image_headers(), + incident->mutable_signature()); + } + } + + if (errors) { + NSDictionary* info = [base::mac::CFToNSCast(errors.get()) userInfo]; + static const CFStringRef keys[] = { + kSecCFErrorResourceAltered, kSecCFErrorResourceMissing, + }; + for (CFStringRef key : keys) { + if (id detail = [info objectForKey:base::mac::CFToNSCast(key)]) + ReportAlteredFiles(detail, path_, incident); + } + } + return false; +} + +} // namespace safe_browsing diff --git a/chrome/browser/safe_browsing/signature_evaluator_mac_unittest.cc b/chrome/browser/safe_browsing/signature_evaluator_mac_unittest.cc new file mode 100644 index 0000000..4b3fad3 --- /dev/null +++ b/chrome/browser/safe_browsing/signature_evaluator_mac_unittest.cc @@ -0,0 +1,328 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/safe_browsing/signature_evaluator_mac.h" + +#include <CoreFoundation/CoreFoundation.h> +#include <sys/xattr.h> + +#include <string> +#include <vector> + +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/mac/mac_util.h" +#include "base/mac/scoped_cftyperef.h" +#include "base/path_service.h" +#include "base/strings/sys_string_conversions.h" +#include "base/test/scoped_path_override.h" +#include "chrome/browser/safe_browsing/incident_reporting/incident.h" +#include "chrome/browser/safe_browsing/incident_reporting/mock_incident_receiver.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/common/safe_browsing/csd.pb.h" +#include "testing/gmock/include/gmock/gmock-matchers.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::_; +using ::testing::StrictMock; + +namespace safe_browsing { + +namespace { + +const char* const xattrs[] = { + "com.apple.cs.CodeDirectory", + "com.apple.cs.CodeSignature", + "com.apple.cs.CodeRequirements", + "com.apple.cs.CodeResources", + "com.apple.cs.CodeApplication", + "com.apple.cs.CodeEntitlements", +}; + +} // namespace + +class MacSignatureEvaluatorTest : public testing::Test { + protected: + void SetUp() override { + base::FilePath source_path; + ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_path)); + testdata_path_ = + source_path.AppendASCII("safe_browsing").AppendASCII("mach_o"); + + base::FilePath dir_exe; + ASSERT_TRUE(PathService::Get(base::DIR_EXE, &dir_exe)); + base::FilePath file_exe; + ASSERT_TRUE(PathService::Get(base::FILE_EXE, &file_exe)); + + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); + } + + bool SetupXattrs(const base::FilePath& path) { + char sentinel = 'A'; + for (const auto& xattr : xattrs) { + std::vector<uint8_t> buf(10); + memset(&buf[0], sentinel++, buf.size()); + if (setxattr(path.value().c_str(), xattr, &buf[0], buf.size(), 0, 0) != 0) + return false; + } + return true; + } + + base::FilePath testdata_path_; + base::ScopedTempDir temp_dir_; +}; + +TEST_F(MacSignatureEvaluatorTest, RelativePathComponentTest) { + EXPECT_FALSE(MacSignatureEvaluator::GetRelativePathComponent( + base::FilePath("/foo"), base::FilePath("/bar"), nullptr)); + EXPECT_FALSE(MacSignatureEvaluator::GetRelativePathComponent( + base::FilePath("/foo/bar"), base::FilePath("/bar/baz"), nullptr)); + EXPECT_FALSE(MacSignatureEvaluator::GetRelativePathComponent( + base::FilePath("/foo/x"), base::FilePath("/foo/y"), nullptr)); + + std::string output1; + EXPECT_TRUE(MacSignatureEvaluator::GetRelativePathComponent( + base::FilePath("/foo/bar"), base::FilePath("/foo/bar/y"), &output1)); + EXPECT_EQ(output1, "y"); + + std::string output2; + EXPECT_TRUE(MacSignatureEvaluator::GetRelativePathComponent( + base::FilePath("/Applications/Google Chrome.app"), + base::FilePath("/Applications/Google Chrome.app/Contents/MacOS/foo"), + &output2)); + EXPECT_EQ(output2, "Contents/MacOS/foo"); +} + +TEST_F(MacSignatureEvaluatorTest, SimpleTest) { + // This is a simple test that checks the validity of a signed executable. + // There is no designated requirement: we only check the embedded signature. + base::FilePath path = testdata_path_.AppendASCII("signedexecutablefat"); + safe_browsing::MacSignatureEvaluator evaluator(path); + ASSERT_TRUE(evaluator.Initialize()); + + ClientIncidentReport_IncidentData_BinaryIntegrityIncident incident; + EXPECT_TRUE(evaluator.PerformEvaluation(&incident)); + EXPECT_EQ(0, incident.contained_file_size()); +} + +TEST_F(MacSignatureEvaluatorTest, SimpleTestWithDR) { + // This test checks the signer against a designated requirement description. + base::FilePath path = testdata_path_.AppendASCII("signedexecutablefat"); + std::string requirement( + "certificate leaf[subject.CN]=\"untrusted@goat.local\""); + safe_browsing::MacSignatureEvaluator evaluator(path, requirement); + ASSERT_TRUE(evaluator.Initialize()); + + ClientIncidentReport_IncidentData_BinaryIntegrityIncident incident; + EXPECT_TRUE(evaluator.PerformEvaluation(&incident)); + EXPECT_EQ(0, incident.contained_file_size()); +} + +TEST_F(MacSignatureEvaluatorTest, SimpleTestWithBadDR) { + // Now test with a designated requirement that does not describe the signer. + base::FilePath path = testdata_path_.AppendASCII("signedexecutablefat"); + safe_browsing::MacSignatureEvaluator evaluator(path, "anchor apple"); + ASSERT_TRUE(evaluator.Initialize()); + + ClientIncidentReport_IncidentData_BinaryIntegrityIncident incident; + EXPECT_FALSE(evaluator.PerformEvaluation(&incident)); + EXPECT_EQ(-67050, incident.sec_error()); + EXPECT_TRUE(incident.has_signature()); + ASSERT_TRUE(incident.has_file_basename()); + EXPECT_EQ("signedexecutablefat", incident.file_basename()); +} + +TEST_F(MacSignatureEvaluatorTest, SimpleBundleTest) { + // Now test a simple, validly signed bundle. + base::FilePath path = testdata_path_.AppendASCII("test-bundle.app"); + + std::string requirement( + "certificate leaf[subject.CN]=\"untrusted@goat.local\""); + safe_browsing::MacSignatureEvaluator evaluator(path, requirement); + ASSERT_TRUE(evaluator.Initialize()); + + ClientIncidentReport_IncidentData_BinaryIntegrityIncident incident; + EXPECT_TRUE(evaluator.PerformEvaluation(&incident)); + EXPECT_EQ(0, incident.contained_file_size()); +} + +TEST_F(MacSignatureEvaluatorTest, ModifiedMainExecTest32) { + // Now to a test modified, signed bundle. + base::FilePath path = testdata_path_.AppendASCII("modified-main-exec32.app"); + + std::string requirement( + "certificate leaf[subject.CN]=\"untrusted@goat.local\""); + safe_browsing::MacSignatureEvaluator evaluator(path, requirement); + ASSERT_TRUE(evaluator.Initialize()); + + ClientIncidentReport_IncidentData_BinaryIntegrityIncident incident; + EXPECT_FALSE(evaluator.PerformEvaluation(&incident)); + EXPECT_EQ(-67061, incident.sec_error()); + EXPECT_EQ(path.BaseName().value(), incident.file_basename()); + EXPECT_FALSE(incident.has_signature()); + EXPECT_FALSE(incident.has_image_headers()); + ASSERT_EQ(1, incident.contained_file_size()); + + const ClientIncidentReport_IncidentData_BinaryIntegrityIncident_ContainedFile& + contained_file = incident.contained_file(0); + EXPECT_EQ(contained_file.relative_path(), "Contents/MacOS/test-bundle"); + EXPECT_TRUE(contained_file.has_signature()); + EXPECT_TRUE(contained_file.has_image_headers()); +} + +TEST_F(MacSignatureEvaluatorTest, ModifiedMainExecTest64) { + // Snow Leopard does not know about the 64-bit slice so this test is + // irrelevant. + if (!base::mac::IsOSLionOrLater()) + return; + + // Now to a test modified, signed bundle. + base::FilePath path = testdata_path_.AppendASCII("modified-main-exec64.app"); + + std::string requirement( + "certificate leaf[subject.CN]=\"untrusted@goat.local\""); + safe_browsing::MacSignatureEvaluator evaluator(path, requirement); + ASSERT_TRUE(evaluator.Initialize()); + + ClientIncidentReport_IncidentData_BinaryIntegrityIncident incident; + EXPECT_FALSE(evaluator.PerformEvaluation(&incident)); + + EXPECT_EQ(-67061, incident.sec_error()); + EXPECT_EQ(path.BaseName().value(), incident.file_basename()); + EXPECT_FALSE(incident.has_signature()); + EXPECT_FALSE(incident.has_image_headers()); + ASSERT_EQ(1, incident.contained_file_size()); + + const ClientIncidentReport_IncidentData_BinaryIntegrityIncident_ContainedFile& + contained_file = incident.contained_file(0); + EXPECT_EQ(contained_file.relative_path(), "Contents/MacOS/test-bundle"); + EXPECT_TRUE(contained_file.has_signature()); + EXPECT_TRUE(contained_file.has_image_headers()); +} + +TEST_F(MacSignatureEvaluatorTest, ModifiedBundleAndExecTest) { + // Now test a modified, signed bundle with resources added and the main + // executable modified. + base::FilePath path = + testdata_path_.AppendASCII("modified-bundle-and-exec.app"); + + std::string requirement( + "certificate leaf[subject.CN]=\"untrusted@goat.local\""); + safe_browsing::MacSignatureEvaluator evaluator(path, requirement); + ASSERT_TRUE(evaluator.Initialize()); + + ClientIncidentReport_IncidentData_BinaryIntegrityIncident incident; + EXPECT_FALSE(evaluator.PerformEvaluation(&incident)); + EXPECT_EQ(-67061, incident.sec_error()); + EXPECT_FALSE(incident.has_signature()); + EXPECT_FALSE(incident.has_image_headers()); + EXPECT_EQ(path.BaseName().value(), incident.file_basename()); + ASSERT_EQ(1, incident.contained_file_size()); + + const ClientIncidentReport_IncidentData_BinaryIntegrityIncident_ContainedFile& + contained_file = incident.contained_file(0); + EXPECT_EQ(contained_file.relative_path(), "Contents/MacOS/test-bundle"); + EXPECT_TRUE(contained_file.has_signature()); + EXPECT_TRUE(contained_file.has_image_headers()); +} + +TEST_F(MacSignatureEvaluatorTest, ModifiedBundleTest) { + // Now test a modified, signed bundle. This bundle has + // the following problems: + // 1) A file was added (This should not be reported) + // 2) libsigned64.dylib was modified + // 3) executable32 was modified + + base::FilePath orig_path = testdata_path_.AppendASCII("modified-bundle.app"); + base::FilePath copied_path = + temp_dir_.path().AppendASCII("modified-bundle.app"); + CHECK(base::CopyDirectory(orig_path, copied_path, true)); + + // Setup the extended attributes, which don't persist in the git repo. + ASSERT_TRUE(SetupXattrs( + copied_path.AppendASCII("Contents/Resources/Base.lproj/MainMenu.nib"))); + + std::string requirement( + "certificate leaf[subject.CN]=\"untrusted@goat.local\""); + safe_browsing::MacSignatureEvaluator evaluator(copied_path, requirement); + ASSERT_TRUE(evaluator.Initialize()); + + ClientIncidentReport_IncidentData_BinaryIntegrityIncident incident; + EXPECT_FALSE(evaluator.PerformEvaluation(&incident)); + + EXPECT_TRUE(incident.has_file_basename()); + EXPECT_EQ(copied_path.BaseName().value(), incident.file_basename()); + EXPECT_FALSE(incident.has_signature()); + EXPECT_FALSE(incident.has_image_headers()); + EXPECT_EQ(-67054, incident.sec_error()); + ASSERT_EQ(4, incident.contained_file_size()); + + const ClientIncidentReport_IncidentData_BinaryIntegrityIncident_ContainedFile* + main_exec = nullptr; + const ClientIncidentReport_IncidentData_BinaryIntegrityIncident_ContainedFile* + libsigned64 = nullptr; + const ClientIncidentReport_IncidentData_BinaryIntegrityIncident_ContainedFile* + executable32 = nullptr; + const ClientIncidentReport_IncidentData_BinaryIntegrityIncident_ContainedFile* + mainmenunib = nullptr; + const ClientIncidentReport_IncidentData_BinaryIntegrityIncident_ContainedFile* + codesign_cfg = nullptr; + + for (const auto& contained_file : incident.contained_file()) { + if (contained_file.relative_path() == "Contents/MacOS/test-bundle") { + main_exec = &contained_file; + } else if (contained_file.relative_path() == + "Contents/Frameworks/libsigned64.dylib") { + libsigned64 = &contained_file; + } else if (contained_file.relative_path() == + "Contents/Resources/executable32") { + executable32 = &contained_file; + } else if (contained_file.relative_path() == + "Contents/Resources/Base.lproj/MainMenu.nib") { + mainmenunib = &contained_file; + } else if (contained_file.relative_path() == + "Contents/Resources/codesign.cfg") { + codesign_cfg = &contained_file; + } + } + + ASSERT_NE(main_exec, nullptr); + ASSERT_NE(mainmenunib, nullptr); + ASSERT_NE(libsigned64, nullptr); + ASSERT_NE(executable32, nullptr); + // This is important. Do not collect information on extra files added. + EXPECT_EQ(codesign_cfg, nullptr); + + EXPECT_TRUE(libsigned64->has_relative_path()); + EXPECT_EQ("Contents/Frameworks/libsigned64.dylib", + libsigned64->relative_path()); + EXPECT_TRUE(libsigned64->has_signature()); + + EXPECT_TRUE(executable32->has_relative_path()); + EXPECT_EQ("Contents/Resources/executable32", executable32->relative_path()); + EXPECT_TRUE(executable32->has_signature()); + EXPECT_TRUE(executable32->has_image_headers()); + + EXPECT_TRUE(mainmenunib->has_relative_path()); + EXPECT_EQ("Contents/Resources/Base.lproj/MainMenu.nib", + mainmenunib->relative_path()); + EXPECT_TRUE(mainmenunib->has_signature()); + EXPECT_EQ(6, mainmenunib->signature().xattr_size()); + // Manually convert the global xattrs array to a vector + std::vector<std::string> xattrs_known; + for (const auto& xattr : xattrs) + xattrs_known.push_back(xattr); + + std::vector<std::string> xattrs_seen; + for (const auto& xattr : mainmenunib->signature().xattr()) { + ASSERT_TRUE(xattr.has_key()); + EXPECT_TRUE(xattr.has_value()); + xattrs_seen.push_back(xattr.key()); + } + EXPECT_THAT(xattrs_known, ::testing::ContainerEq(xattrs_seen)); +} + +} // namespace safe_browsing diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 6c31d11..b1922db9 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2496,6 +2496,7 @@ 'browser/safe_browsing/download_protection_service.h', 'browser/safe_browsing/incident_reporting/binary_integrity_analyzer.cc', 'browser/safe_browsing/incident_reporting/binary_integrity_analyzer.h', + 'browser/safe_browsing/incident_reporting/binary_integrity_analyzer_mac.cc', 'browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win.cc', 'browser/safe_browsing/incident_reporting/binary_integrity_incident.cc', 'browser/safe_browsing/incident_reporting/binary_integrity_incident.h', @@ -2567,6 +2568,8 @@ 'browser/safe_browsing/sandboxed_dmg_analyzer_mac.h', 'browser/safe_browsing/sandboxed_zip_analyzer.cc', 'browser/safe_browsing/sandboxed_zip_analyzer.h', + 'browser/safe_browsing/signature_evaluator_mac.h', + 'browser/safe_browsing/signature_evaluator_mac.mm', 'browser/safe_browsing/two_phase_uploader.cc', 'browser/safe_browsing/two_phase_uploader.h', 'browser/safe_browsing/unverified_download_field_trial.cc', diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index 0219be7..1f179ff 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -963,6 +963,7 @@ 'browser/safe_browsing/download_feedback_service_unittest.cc', 'browser/safe_browsing/download_feedback_unittest.cc', 'browser/safe_browsing/download_protection_service_unittest.cc', + 'browser/safe_browsing/incident_reporting/binary_integrity_analyzer_mac_unittest.cc', 'browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win_unittest.cc', 'browser/safe_browsing/incident_reporting/binary_integrity_incident_unittest.cc', 'browser/safe_browsing/incident_reporting/blacklist_load_analyzer_win_unittest.cc', @@ -998,6 +999,7 @@ 'browser/safe_browsing/safe_browsing_util_unittest.cc', 'browser/safe_browsing/sandboxed_dmg_analyzer_mac_unittest.cc', 'browser/safe_browsing/sandboxed_zip_analyzer_unittest.cc', + 'browser/safe_browsing/signature_evaluator_mac_unittest.cc', 'browser/safe_browsing/test_database_manager.cc', 'browser/safe_browsing/test_database_manager.h', 'browser/safe_browsing/two_phase_uploader_unittest.cc', diff --git a/chrome/common/safe_browsing/csd.proto b/chrome/common/safe_browsing/csd.proto index 3058e4c..db2a1f9 100644 --- a/chrome/common/safe_browsing/csd.proto +++ b/chrome/common/safe_browsing/csd.proto @@ -208,6 +208,16 @@ message ClientDownloadRequest { repeated Element element = 1; } + // This is an OS X only message to report extended attribute informations. + // Extended attributes on OS X are used for various security mechanisms, + // which makes them interesting to Chrome. + message ExtendedAttr { + // This is the name of the extended attribute. + required string key = 1; + // This is the value of the extended attribute. + optional bytes value = 2; + } + message SignatureInfo { // All certificate chains for each of the binary's signers. Multiple chains // may be present if the binary or any certificate has multiple signers. @@ -225,6 +235,11 @@ message ClientDownloadRequest { // On Mac, this is the code signature blob referenced by the // LC_CODE_SIGNATURE load command. repeated bytes signed_data = 3; + + // On OS X, code signing data can be contained in the extended attributes of + // a file. As Gatekeeper respects this signature, we look for it and collect + // it. + repeated ExtendedAttr xattr = 4; } // This field will only be set if the binary is signed. @@ -421,10 +436,21 @@ message ClientIncidentReport { repeated string split_key = 3; optional ValueState value_state = 4; } + message BinaryIntegrityIncident { optional string file_basename = 1; optional ClientDownloadRequest.SignatureInfo signature = 2; + optional ClientDownloadRequest.ImageHeaders image_headers = 3; + optional int32 sec_error = 4; + + message ContainedFile { + optional string relative_path = 1; + optional ClientDownloadRequest.SignatureInfo signature = 2; + optional ClientDownloadRequest.ImageHeaders image_headers = 3; + } + repeated ContainedFile contained_file = 5; } + message BlacklistLoadIncident { optional string path = 1; optional ClientDownloadRequest.Digests digest = 2; diff --git a/chrome/test/data/safe_browsing/mach_o/Makefile b/chrome/test/data/safe_browsing/mach_o/Makefile index faa2fec..7b11582 100644 --- a/chrome/test/data/safe_browsing/mach_o/Makefile +++ b/chrome/test/data/safe_browsing/mach_o/Makefile @@ -57,3 +57,47 @@ signedexecutablefat: executablefat codesign.keychain $(PWD)/codesign.keychain codesign -s $(KEYCHAIN_IDENTITY) --keychain $(PWD)/codesign.keychain \ $@ --all-architectures + +.PHONY: test-bundle.app +test-bundle.app: signedexecutablefat libsigned64.dylib executable32 + ditto base-bundle.app $@ + ditto $< $@/Contents/MacOS/test-bundle + ditto $(word 2,$^) $@/Contents/Frameworks/$(word 2,$^) + ditto $(word 3,$^) $@/Contents/Resources/$(word 3,$^) + security unlock-keychain -p $(KEYCHAIN_PASSWORD) \ + $(PWD)/codesign.keychain + codesign -f -s $(KEYCHAIN_IDENTITY) --keychain $(PWD)/codesign.keychain \ + $@ --all-architectures --resource-rules ResourceRules + +.PHONY: modified-bundle.app +modified-bundle.app: test-bundle.app lib32.dylib executable64 + ditto $< $@ + touch $@/Contents/Resources/codesign.cfg + ditto $(word 2,$^) $@/Contents/Frameworks/libsigned64.dylib + ditto $(word 3,$^) $@/Contents/Resources/executable32 + echo "foo" >> $@/Contents/Resources/Base.lproj/MainMenu.nib + security unlock-keychain -p $(KEYCHAIN_PASSWORD) \ + $(PWD)/codesign.keychain + codesign -f -s $(KEYCHAIN_IDENTITY) --keychain $(PWD)/codesign.keychain \ + $@/Contents/Resources/Base.lproj/MainMenu.nib + +.PHONY: modified-bundle-and-exec.app +modified-bundle-and-exec.app: test-bundle.app lib32.dylib executable64 + ditto $< $@ + touch $@/Contents/Resources/codesign.cfg + ditto $(word 2,$^) $@/Contents/Frameworks/libsigned64.dylib + ditto $(word 3,$^) $@/Contents/Resources/executable32 + printf '\x31' | dd bs=1 seek=8097 count=1 conv=notrunc \ + of=$@/Contents/MacOS/test-bundle + +.PHONY: modified-main-exec32.app +modified-main-exec32.app: test-bundle.app + ditto $< $@ + printf '\x31' | dd bs=1 seek=8097 count=1 conv=notrunc \ + of=$@/Contents/MacOS/test-bundle + +.PHONY: modified-main-exec64.app +modified-main-exec64.app: test-bundle.app + ditto $< $@ + printf '\x31' | dd bs=1 seek=24448 count=1 conv=notrunc \ + of=$@/Contents/MacOS/test-bundle diff --git a/chrome/test/data/safe_browsing/mach_o/ResourceRules b/chrome/test/data/safe_browsing/mach_o/ResourceRules new file mode 100644 index 0000000..d780895 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/ResourceRules @@ -0,0 +1,99 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>rules</key> + <dict> + <key>^Resources/</key> + <true/> + <key>^Frameworks</key> + <true/> + <key>^Resources/.*\.lproj/</key> + <dict> + <key>optional</key> + <true/> + <key>weight</key> + <real>1000</real> + </dict> + <key>^Resources/.*\.lproj/locversion.plist$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>1100</real> + </dict> + <key>^version.plist$</key> + <true/> + </dict> + <key>rules2</key> + <dict> + <key>.*\.dSYM($|/)</key> + <dict> + <key>weight</key> + <real>11</real> + </dict> + <key>^(.*/)?\.DS_Store$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>2000</real> + </dict> + <key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key> + <dict> + <key>weight</key> + <real>10</real> + </dict> + <key>^.*</key> + <true/> + <key>^Info\.plist$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>20</real> + </dict> + <key>^PkgInfo$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>20</real> + </dict> + <key>^Resources/</key> + <dict> + <key>weight</key> + <real>20</real> + </dict> + <key>^Resources/.*\.lproj/</key> + <dict> + <key>optional</key> + <true/> + <key>weight</key> + <real>1000</real> + </dict> + <key>^Resources/.*\.lproj/locversion.plist$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>1100</real> + </dict> + <key>^[^/]+$</key> + <dict> + <key>weight</key> + <real>10</real> + </dict> + <key>^embedded\.provisionprofile$</key> + <dict> + <key>weight</key> + <real>20</real> + </dict> + <key>^version\.plist$</key> + <dict> + <key>weight</key> + <real>20</real> + </dict> + </dict> +</dict> +</plist> diff --git a/chrome/test/data/safe_browsing/mach_o/base-bundle.app/Contents/Info.plist b/chrome/test/data/safe_browsing/mach_o/base-bundle.app/Contents/Info.plist new file mode 100644 index 0000000..a6082b8 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/base-bundle.app/Contents/Info.plist @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>BuildMachineOSBuild</key> + <string>14F27</string> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>test-bundle</string> + <key>CFBundleIdentifier</key> + <string>google-test.test-bundle</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>test-bundle</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>DTCompiler</key> + <string>com.apple.compilers.llvm.clang.1_0</string> + <key>DTPlatformBuild</key> + <string>6D2105</string> + <key>DTPlatformVersion</key> + <string>GM</string> + <key>DTSDKBuild</key> + <string>14D125</string> + <key>DTSDKName</key> + <string>macosx10.10</string> + <key>DTXcode</key> + <string>0632</string> + <key>DTXcodeBuild</key> + <string>6D2105</string> + <key>LSMinimumSystemVersion</key> + <string>10.10</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright © 2015 test-bundle. All rights reserved.</string> + <key>NSMainNibFile</key> + <string>MainMenu</string> + <key>NSPrincipalClass</key> + <string>NSApplication</string> +</dict> +</plist> diff --git a/chrome/test/data/safe_browsing/mach_o/base-bundle.app/Contents/PkgInfo b/chrome/test/data/safe_browsing/mach_o/base-bundle.app/Contents/PkgInfo new file mode 100644 index 0000000..bd04210 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/base-bundle.app/Contents/PkgInfo @@ -0,0 +1 @@ +APPL????
\ No newline at end of file diff --git a/chrome/test/data/safe_browsing/mach_o/base-bundle.app/Contents/Resources/Base.lproj/MainMenu.nib b/chrome/test/data/safe_browsing/mach_o/base-bundle.app/Contents/Resources/Base.lproj/MainMenu.nib Binary files differnew file mode 100644 index 0000000..483099c --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/base-bundle.app/Contents/Resources/Base.lproj/MainMenu.nib diff --git a/chrome/test/data/safe_browsing/mach_o/modified-bundle-and-exec.app/Contents/Frameworks/libsigned64.dylib b/chrome/test/data/safe_browsing/mach_o/modified-bundle-and-exec.app/Contents/Frameworks/libsigned64.dylib Binary files differnew file mode 100644 index 0000000..d5a79af --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-bundle-and-exec.app/Contents/Frameworks/libsigned64.dylib diff --git a/chrome/test/data/safe_browsing/mach_o/modified-bundle-and-exec.app/Contents/Info.plist b/chrome/test/data/safe_browsing/mach_o/modified-bundle-and-exec.app/Contents/Info.plist new file mode 100644 index 0000000..a6082b8 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-bundle-and-exec.app/Contents/Info.plist @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>BuildMachineOSBuild</key> + <string>14F27</string> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>test-bundle</string> + <key>CFBundleIdentifier</key> + <string>google-test.test-bundle</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>test-bundle</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>DTCompiler</key> + <string>com.apple.compilers.llvm.clang.1_0</string> + <key>DTPlatformBuild</key> + <string>6D2105</string> + <key>DTPlatformVersion</key> + <string>GM</string> + <key>DTSDKBuild</key> + <string>14D125</string> + <key>DTSDKName</key> + <string>macosx10.10</string> + <key>DTXcode</key> + <string>0632</string> + <key>DTXcodeBuild</key> + <string>6D2105</string> + <key>LSMinimumSystemVersion</key> + <string>10.10</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright © 2015 test-bundle. All rights reserved.</string> + <key>NSMainNibFile</key> + <string>MainMenu</string> + <key>NSPrincipalClass</key> + <string>NSApplication</string> +</dict> +</plist> diff --git a/chrome/test/data/safe_browsing/mach_o/modified-bundle-and-exec.app/Contents/MacOS/test-bundle b/chrome/test/data/safe_browsing/mach_o/modified-bundle-and-exec.app/Contents/MacOS/test-bundle Binary files differnew file mode 100644 index 0000000..48b0e84 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-bundle-and-exec.app/Contents/MacOS/test-bundle diff --git a/chrome/test/data/safe_browsing/mach_o/modified-bundle-and-exec.app/Contents/PkgInfo b/chrome/test/data/safe_browsing/mach_o/modified-bundle-and-exec.app/Contents/PkgInfo new file mode 100644 index 0000000..bd04210 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-bundle-and-exec.app/Contents/PkgInfo @@ -0,0 +1 @@ +APPL????
\ No newline at end of file diff --git a/chrome/test/data/safe_browsing/mach_o/modified-bundle-and-exec.app/Contents/Resources/Base.lproj/MainMenu.nib b/chrome/test/data/safe_browsing/mach_o/modified-bundle-and-exec.app/Contents/Resources/Base.lproj/MainMenu.nib Binary files differnew file mode 100644 index 0000000..483099c --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-bundle-and-exec.app/Contents/Resources/Base.lproj/MainMenu.nib diff --git a/chrome/test/data/safe_browsing/mach_o/modified-bundle-and-exec.app/Contents/Resources/codesign.cfg b/chrome/test/data/safe_browsing/mach_o/modified-bundle-and-exec.app/Contents/Resources/codesign.cfg new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-bundle-and-exec.app/Contents/Resources/codesign.cfg diff --git a/chrome/test/data/safe_browsing/mach_o/modified-bundle-and-exec.app/Contents/Resources/executable32 b/chrome/test/data/safe_browsing/mach_o/modified-bundle-and-exec.app/Contents/Resources/executable32 Binary files differnew file mode 100644 index 0000000..7191667 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-bundle-and-exec.app/Contents/Resources/executable32 diff --git a/chrome/test/data/safe_browsing/mach_o/modified-bundle-and-exec.app/Contents/_CodeSignature/CodeResources b/chrome/test/data/safe_browsing/mach_o/modified-bundle-and-exec.app/Contents/_CodeSignature/CodeResources new file mode 100644 index 0000000..aa06c23 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-bundle-and-exec.app/Contents/_CodeSignature/CodeResources @@ -0,0 +1,139 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>files</key> + <dict> + <key>Frameworks/libsigned64.dylib</key> + <data> + eD0Asf8/OXa6v2aNFp33nh5bsGw= + </data> + <key>Resources/Base.lproj/MainMenu.nib</key> + <dict> + <key>hash</key> + <data> + 36VmRur+3AKfYrTxgwnd4cqqjvY= + </data> + <key>optional</key> + <true/> + </dict> + <key>Resources/executable32</key> + <data> + 8UYv2Wx4Y+rmOojWWLGJj+o5iqU= + </data> + </dict> + <key>files2</key> + <dict> + <key>Frameworks/libsigned64.dylib</key> + <data> + eD0Asf8/OXa6v2aNFp33nh5bsGw= + </data> + <key>Resources/Base.lproj/MainMenu.nib</key> + <dict> + <key>hash</key> + <data> + 36VmRur+3AKfYrTxgwnd4cqqjvY= + </data> + <key>optional</key> + <true/> + </dict> + <key>Resources/executable32</key> + <data> + 8UYv2Wx4Y+rmOojWWLGJj+o5iqU= + </data> + </dict> + <key>rules</key> + <dict> + <key>^Frameworks</key> + <true/> + <key>^Resources/</key> + <true/> + <key>^Resources/.*\.lproj/</key> + <dict> + <key>optional</key> + <true/> + <key>weight</key> + <real>1000</real> + </dict> + <key>^Resources/.*\.lproj/locversion.plist$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>1100</real> + </dict> + <key>^version.plist$</key> + <true/> + </dict> + <key>rules2</key> + <dict> + <key>.*\.dSYM($|/)</key> + <dict> + <key>weight</key> + <real>11</real> + </dict> + <key>^(.*/)?\.DS_Store$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>2000</real> + </dict> + <key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key> + <dict> + <key>weight</key> + <real>10</real> + </dict> + <key>^.*</key> + <true/> + <key>^Info\.plist$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>20</real> + </dict> + <key>^PkgInfo$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>20</real> + </dict> + <key>^Resources/</key> + <dict> + <key>weight</key> + <real>20</real> + </dict> + <key>^Resources/.*\.lproj/</key> + <dict> + <key>optional</key> + <true/> + <key>weight</key> + <real>1000</real> + </dict> + <key>^Resources/.*\.lproj/locversion.plist$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>1100</real> + </dict> + <key>^[^/]+$</key> + <dict> + <key>weight</key> + <real>10</real> + </dict> + <key>^embedded\.provisionprofile$</key> + <dict> + <key>weight</key> + <real>20</real> + </dict> + <key>^version\.plist$</key> + <dict> + <key>weight</key> + <real>20</real> + </dict> + </dict> +</dict> +</plist> diff --git a/chrome/test/data/safe_browsing/mach_o/modified-bundle.app/Contents/Frameworks/libsigned64.dylib b/chrome/test/data/safe_browsing/mach_o/modified-bundle.app/Contents/Frameworks/libsigned64.dylib Binary files differnew file mode 100644 index 0000000..d5a79af --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-bundle.app/Contents/Frameworks/libsigned64.dylib diff --git a/chrome/test/data/safe_browsing/mach_o/modified-bundle.app/Contents/Info.plist b/chrome/test/data/safe_browsing/mach_o/modified-bundle.app/Contents/Info.plist new file mode 100644 index 0000000..a6082b8 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-bundle.app/Contents/Info.plist @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>BuildMachineOSBuild</key> + <string>14F27</string> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>test-bundle</string> + <key>CFBundleIdentifier</key> + <string>google-test.test-bundle</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>test-bundle</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>DTCompiler</key> + <string>com.apple.compilers.llvm.clang.1_0</string> + <key>DTPlatformBuild</key> + <string>6D2105</string> + <key>DTPlatformVersion</key> + <string>GM</string> + <key>DTSDKBuild</key> + <string>14D125</string> + <key>DTSDKName</key> + <string>macosx10.10</string> + <key>DTXcode</key> + <string>0632</string> + <key>DTXcodeBuild</key> + <string>6D2105</string> + <key>LSMinimumSystemVersion</key> + <string>10.10</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright © 2015 test-bundle. All rights reserved.</string> + <key>NSMainNibFile</key> + <string>MainMenu</string> + <key>NSPrincipalClass</key> + <string>NSApplication</string> +</dict> +</plist> diff --git a/chrome/test/data/safe_browsing/mach_o/modified-bundle.app/Contents/MacOS/test-bundle b/chrome/test/data/safe_browsing/mach_o/modified-bundle.app/Contents/MacOS/test-bundle Binary files differnew file mode 100644 index 0000000..4acc277 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-bundle.app/Contents/MacOS/test-bundle diff --git a/chrome/test/data/safe_browsing/mach_o/modified-bundle.app/Contents/PkgInfo b/chrome/test/data/safe_browsing/mach_o/modified-bundle.app/Contents/PkgInfo new file mode 100644 index 0000000..bd04210 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-bundle.app/Contents/PkgInfo @@ -0,0 +1 @@ +APPL????
\ No newline at end of file diff --git a/chrome/test/data/safe_browsing/mach_o/modified-bundle.app/Contents/Resources/Base.lproj/MainMenu.nib b/chrome/test/data/safe_browsing/mach_o/modified-bundle.app/Contents/Resources/Base.lproj/MainMenu.nib Binary files differnew file mode 100644 index 0000000..a8a2953 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-bundle.app/Contents/Resources/Base.lproj/MainMenu.nib diff --git a/chrome/test/data/safe_browsing/mach_o/modified-bundle.app/Contents/Resources/codesign.cfg b/chrome/test/data/safe_browsing/mach_o/modified-bundle.app/Contents/Resources/codesign.cfg new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-bundle.app/Contents/Resources/codesign.cfg diff --git a/chrome/test/data/safe_browsing/mach_o/modified-bundle.app/Contents/Resources/executable32 b/chrome/test/data/safe_browsing/mach_o/modified-bundle.app/Contents/Resources/executable32 Binary files differnew file mode 100644 index 0000000..7191667 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-bundle.app/Contents/Resources/executable32 diff --git a/chrome/test/data/safe_browsing/mach_o/modified-bundle.app/Contents/_CodeSignature/CodeResources b/chrome/test/data/safe_browsing/mach_o/modified-bundle.app/Contents/_CodeSignature/CodeResources new file mode 100644 index 0000000..aa06c23 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-bundle.app/Contents/_CodeSignature/CodeResources @@ -0,0 +1,139 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>files</key> + <dict> + <key>Frameworks/libsigned64.dylib</key> + <data> + eD0Asf8/OXa6v2aNFp33nh5bsGw= + </data> + <key>Resources/Base.lproj/MainMenu.nib</key> + <dict> + <key>hash</key> + <data> + 36VmRur+3AKfYrTxgwnd4cqqjvY= + </data> + <key>optional</key> + <true/> + </dict> + <key>Resources/executable32</key> + <data> + 8UYv2Wx4Y+rmOojWWLGJj+o5iqU= + </data> + </dict> + <key>files2</key> + <dict> + <key>Frameworks/libsigned64.dylib</key> + <data> + eD0Asf8/OXa6v2aNFp33nh5bsGw= + </data> + <key>Resources/Base.lproj/MainMenu.nib</key> + <dict> + <key>hash</key> + <data> + 36VmRur+3AKfYrTxgwnd4cqqjvY= + </data> + <key>optional</key> + <true/> + </dict> + <key>Resources/executable32</key> + <data> + 8UYv2Wx4Y+rmOojWWLGJj+o5iqU= + </data> + </dict> + <key>rules</key> + <dict> + <key>^Frameworks</key> + <true/> + <key>^Resources/</key> + <true/> + <key>^Resources/.*\.lproj/</key> + <dict> + <key>optional</key> + <true/> + <key>weight</key> + <real>1000</real> + </dict> + <key>^Resources/.*\.lproj/locversion.plist$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>1100</real> + </dict> + <key>^version.plist$</key> + <true/> + </dict> + <key>rules2</key> + <dict> + <key>.*\.dSYM($|/)</key> + <dict> + <key>weight</key> + <real>11</real> + </dict> + <key>^(.*/)?\.DS_Store$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>2000</real> + </dict> + <key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key> + <dict> + <key>weight</key> + <real>10</real> + </dict> + <key>^.*</key> + <true/> + <key>^Info\.plist$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>20</real> + </dict> + <key>^PkgInfo$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>20</real> + </dict> + <key>^Resources/</key> + <dict> + <key>weight</key> + <real>20</real> + </dict> + <key>^Resources/.*\.lproj/</key> + <dict> + <key>optional</key> + <true/> + <key>weight</key> + <real>1000</real> + </dict> + <key>^Resources/.*\.lproj/locversion.plist$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>1100</real> + </dict> + <key>^[^/]+$</key> + <dict> + <key>weight</key> + <real>10</real> + </dict> + <key>^embedded\.provisionprofile$</key> + <dict> + <key>weight</key> + <real>20</real> + </dict> + <key>^version\.plist$</key> + <dict> + <key>weight</key> + <real>20</real> + </dict> + </dict> +</dict> +</plist> diff --git a/chrome/test/data/safe_browsing/mach_o/modified-main-exec32.app/Contents/Frameworks/libsigned64.dylib b/chrome/test/data/safe_browsing/mach_o/modified-main-exec32.app/Contents/Frameworks/libsigned64.dylib Binary files differnew file mode 100644 index 0000000..77b77db --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-main-exec32.app/Contents/Frameworks/libsigned64.dylib diff --git a/chrome/test/data/safe_browsing/mach_o/modified-main-exec32.app/Contents/Info.plist b/chrome/test/data/safe_browsing/mach_o/modified-main-exec32.app/Contents/Info.plist new file mode 100644 index 0000000..a6082b8 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-main-exec32.app/Contents/Info.plist @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>BuildMachineOSBuild</key> + <string>14F27</string> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>test-bundle</string> + <key>CFBundleIdentifier</key> + <string>google-test.test-bundle</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>test-bundle</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>DTCompiler</key> + <string>com.apple.compilers.llvm.clang.1_0</string> + <key>DTPlatformBuild</key> + <string>6D2105</string> + <key>DTPlatformVersion</key> + <string>GM</string> + <key>DTSDKBuild</key> + <string>14D125</string> + <key>DTSDKName</key> + <string>macosx10.10</string> + <key>DTXcode</key> + <string>0632</string> + <key>DTXcodeBuild</key> + <string>6D2105</string> + <key>LSMinimumSystemVersion</key> + <string>10.10</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright © 2015 test-bundle. All rights reserved.</string> + <key>NSMainNibFile</key> + <string>MainMenu</string> + <key>NSPrincipalClass</key> + <string>NSApplication</string> +</dict> +</plist> diff --git a/chrome/test/data/safe_browsing/mach_o/modified-main-exec32.app/Contents/MacOS/test-bundle b/chrome/test/data/safe_browsing/mach_o/modified-main-exec32.app/Contents/MacOS/test-bundle Binary files differnew file mode 100644 index 0000000..48b0e84 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-main-exec32.app/Contents/MacOS/test-bundle diff --git a/chrome/test/data/safe_browsing/mach_o/modified-main-exec32.app/Contents/PkgInfo b/chrome/test/data/safe_browsing/mach_o/modified-main-exec32.app/Contents/PkgInfo new file mode 100644 index 0000000..bd04210 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-main-exec32.app/Contents/PkgInfo @@ -0,0 +1 @@ +APPL????
\ No newline at end of file diff --git a/chrome/test/data/safe_browsing/mach_o/modified-main-exec32.app/Contents/Resources/Base.lproj/MainMenu.nib b/chrome/test/data/safe_browsing/mach_o/modified-main-exec32.app/Contents/Resources/Base.lproj/MainMenu.nib Binary files differnew file mode 100644 index 0000000..483099c --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-main-exec32.app/Contents/Resources/Base.lproj/MainMenu.nib diff --git a/chrome/test/data/safe_browsing/mach_o/modified-main-exec32.app/Contents/Resources/executable32 b/chrome/test/data/safe_browsing/mach_o/modified-main-exec32.app/Contents/Resources/executable32 Binary files differnew file mode 100644 index 0000000..9337b20 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-main-exec32.app/Contents/Resources/executable32 diff --git a/chrome/test/data/safe_browsing/mach_o/modified-main-exec32.app/Contents/_CodeSignature/CodeResources b/chrome/test/data/safe_browsing/mach_o/modified-main-exec32.app/Contents/_CodeSignature/CodeResources new file mode 100644 index 0000000..aa06c23 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-main-exec32.app/Contents/_CodeSignature/CodeResources @@ -0,0 +1,139 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>files</key> + <dict> + <key>Frameworks/libsigned64.dylib</key> + <data> + eD0Asf8/OXa6v2aNFp33nh5bsGw= + </data> + <key>Resources/Base.lproj/MainMenu.nib</key> + <dict> + <key>hash</key> + <data> + 36VmRur+3AKfYrTxgwnd4cqqjvY= + </data> + <key>optional</key> + <true/> + </dict> + <key>Resources/executable32</key> + <data> + 8UYv2Wx4Y+rmOojWWLGJj+o5iqU= + </data> + </dict> + <key>files2</key> + <dict> + <key>Frameworks/libsigned64.dylib</key> + <data> + eD0Asf8/OXa6v2aNFp33nh5bsGw= + </data> + <key>Resources/Base.lproj/MainMenu.nib</key> + <dict> + <key>hash</key> + <data> + 36VmRur+3AKfYrTxgwnd4cqqjvY= + </data> + <key>optional</key> + <true/> + </dict> + <key>Resources/executable32</key> + <data> + 8UYv2Wx4Y+rmOojWWLGJj+o5iqU= + </data> + </dict> + <key>rules</key> + <dict> + <key>^Frameworks</key> + <true/> + <key>^Resources/</key> + <true/> + <key>^Resources/.*\.lproj/</key> + <dict> + <key>optional</key> + <true/> + <key>weight</key> + <real>1000</real> + </dict> + <key>^Resources/.*\.lproj/locversion.plist$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>1100</real> + </dict> + <key>^version.plist$</key> + <true/> + </dict> + <key>rules2</key> + <dict> + <key>.*\.dSYM($|/)</key> + <dict> + <key>weight</key> + <real>11</real> + </dict> + <key>^(.*/)?\.DS_Store$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>2000</real> + </dict> + <key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key> + <dict> + <key>weight</key> + <real>10</real> + </dict> + <key>^.*</key> + <true/> + <key>^Info\.plist$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>20</real> + </dict> + <key>^PkgInfo$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>20</real> + </dict> + <key>^Resources/</key> + <dict> + <key>weight</key> + <real>20</real> + </dict> + <key>^Resources/.*\.lproj/</key> + <dict> + <key>optional</key> + <true/> + <key>weight</key> + <real>1000</real> + </dict> + <key>^Resources/.*\.lproj/locversion.plist$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>1100</real> + </dict> + <key>^[^/]+$</key> + <dict> + <key>weight</key> + <real>10</real> + </dict> + <key>^embedded\.provisionprofile$</key> + <dict> + <key>weight</key> + <real>20</real> + </dict> + <key>^version\.plist$</key> + <dict> + <key>weight</key> + <real>20</real> + </dict> + </dict> +</dict> +</plist> diff --git a/chrome/test/data/safe_browsing/mach_o/modified-main-exec64.app/Contents/Frameworks/libsigned64.dylib b/chrome/test/data/safe_browsing/mach_o/modified-main-exec64.app/Contents/Frameworks/libsigned64.dylib Binary files differnew file mode 100644 index 0000000..77b77db --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-main-exec64.app/Contents/Frameworks/libsigned64.dylib diff --git a/chrome/test/data/safe_browsing/mach_o/modified-main-exec64.app/Contents/Info.plist b/chrome/test/data/safe_browsing/mach_o/modified-main-exec64.app/Contents/Info.plist new file mode 100644 index 0000000..a6082b8 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-main-exec64.app/Contents/Info.plist @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>BuildMachineOSBuild</key> + <string>14F27</string> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>test-bundle</string> + <key>CFBundleIdentifier</key> + <string>google-test.test-bundle</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>test-bundle</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>DTCompiler</key> + <string>com.apple.compilers.llvm.clang.1_0</string> + <key>DTPlatformBuild</key> + <string>6D2105</string> + <key>DTPlatformVersion</key> + <string>GM</string> + <key>DTSDKBuild</key> + <string>14D125</string> + <key>DTSDKName</key> + <string>macosx10.10</string> + <key>DTXcode</key> + <string>0632</string> + <key>DTXcodeBuild</key> + <string>6D2105</string> + <key>LSMinimumSystemVersion</key> + <string>10.10</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright © 2015 test-bundle. All rights reserved.</string> + <key>NSMainNibFile</key> + <string>MainMenu</string> + <key>NSPrincipalClass</key> + <string>NSApplication</string> +</dict> +</plist> diff --git a/chrome/test/data/safe_browsing/mach_o/modified-main-exec64.app/Contents/MacOS/test-bundle b/chrome/test/data/safe_browsing/mach_o/modified-main-exec64.app/Contents/MacOS/test-bundle Binary files differnew file mode 100644 index 0000000..a425014 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-main-exec64.app/Contents/MacOS/test-bundle diff --git a/chrome/test/data/safe_browsing/mach_o/modified-main-exec64.app/Contents/PkgInfo b/chrome/test/data/safe_browsing/mach_o/modified-main-exec64.app/Contents/PkgInfo new file mode 100644 index 0000000..bd04210 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-main-exec64.app/Contents/PkgInfo @@ -0,0 +1 @@ +APPL????
\ No newline at end of file diff --git a/chrome/test/data/safe_browsing/mach_o/modified-main-exec64.app/Contents/Resources/Base.lproj/MainMenu.nib b/chrome/test/data/safe_browsing/mach_o/modified-main-exec64.app/Contents/Resources/Base.lproj/MainMenu.nib Binary files differnew file mode 100644 index 0000000..483099c --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-main-exec64.app/Contents/Resources/Base.lproj/MainMenu.nib diff --git a/chrome/test/data/safe_browsing/mach_o/modified-main-exec64.app/Contents/Resources/executable32 b/chrome/test/data/safe_browsing/mach_o/modified-main-exec64.app/Contents/Resources/executable32 Binary files differnew file mode 100644 index 0000000..9337b20 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-main-exec64.app/Contents/Resources/executable32 diff --git a/chrome/test/data/safe_browsing/mach_o/modified-main-exec64.app/Contents/_CodeSignature/CodeResources b/chrome/test/data/safe_browsing/mach_o/modified-main-exec64.app/Contents/_CodeSignature/CodeResources new file mode 100644 index 0000000..aa06c23 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/modified-main-exec64.app/Contents/_CodeSignature/CodeResources @@ -0,0 +1,139 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>files</key> + <dict> + <key>Frameworks/libsigned64.dylib</key> + <data> + eD0Asf8/OXa6v2aNFp33nh5bsGw= + </data> + <key>Resources/Base.lproj/MainMenu.nib</key> + <dict> + <key>hash</key> + <data> + 36VmRur+3AKfYrTxgwnd4cqqjvY= + </data> + <key>optional</key> + <true/> + </dict> + <key>Resources/executable32</key> + <data> + 8UYv2Wx4Y+rmOojWWLGJj+o5iqU= + </data> + </dict> + <key>files2</key> + <dict> + <key>Frameworks/libsigned64.dylib</key> + <data> + eD0Asf8/OXa6v2aNFp33nh5bsGw= + </data> + <key>Resources/Base.lproj/MainMenu.nib</key> + <dict> + <key>hash</key> + <data> + 36VmRur+3AKfYrTxgwnd4cqqjvY= + </data> + <key>optional</key> + <true/> + </dict> + <key>Resources/executable32</key> + <data> + 8UYv2Wx4Y+rmOojWWLGJj+o5iqU= + </data> + </dict> + <key>rules</key> + <dict> + <key>^Frameworks</key> + <true/> + <key>^Resources/</key> + <true/> + <key>^Resources/.*\.lproj/</key> + <dict> + <key>optional</key> + <true/> + <key>weight</key> + <real>1000</real> + </dict> + <key>^Resources/.*\.lproj/locversion.plist$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>1100</real> + </dict> + <key>^version.plist$</key> + <true/> + </dict> + <key>rules2</key> + <dict> + <key>.*\.dSYM($|/)</key> + <dict> + <key>weight</key> + <real>11</real> + </dict> + <key>^(.*/)?\.DS_Store$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>2000</real> + </dict> + <key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key> + <dict> + <key>weight</key> + <real>10</real> + </dict> + <key>^.*</key> + <true/> + <key>^Info\.plist$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>20</real> + </dict> + <key>^PkgInfo$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>20</real> + </dict> + <key>^Resources/</key> + <dict> + <key>weight</key> + <real>20</real> + </dict> + <key>^Resources/.*\.lproj/</key> + <dict> + <key>optional</key> + <true/> + <key>weight</key> + <real>1000</real> + </dict> + <key>^Resources/.*\.lproj/locversion.plist$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>1100</real> + </dict> + <key>^[^/]+$</key> + <dict> + <key>weight</key> + <real>10</real> + </dict> + <key>^embedded\.provisionprofile$</key> + <dict> + <key>weight</key> + <real>20</real> + </dict> + <key>^version\.plist$</key> + <dict> + <key>weight</key> + <real>20</real> + </dict> + </dict> +</dict> +</plist> diff --git a/chrome/test/data/safe_browsing/mach_o/test-bundle.app/Contents/Frameworks/libsigned64.dylib b/chrome/test/data/safe_browsing/mach_o/test-bundle.app/Contents/Frameworks/libsigned64.dylib Binary files differnew file mode 100644 index 0000000..77b77db --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/test-bundle.app/Contents/Frameworks/libsigned64.dylib diff --git a/chrome/test/data/safe_browsing/mach_o/test-bundle.app/Contents/Info.plist b/chrome/test/data/safe_browsing/mach_o/test-bundle.app/Contents/Info.plist new file mode 100644 index 0000000..a6082b8 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/test-bundle.app/Contents/Info.plist @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>BuildMachineOSBuild</key> + <string>14F27</string> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>test-bundle</string> + <key>CFBundleIdentifier</key> + <string>google-test.test-bundle</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>test-bundle</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>DTCompiler</key> + <string>com.apple.compilers.llvm.clang.1_0</string> + <key>DTPlatformBuild</key> + <string>6D2105</string> + <key>DTPlatformVersion</key> + <string>GM</string> + <key>DTSDKBuild</key> + <string>14D125</string> + <key>DTSDKName</key> + <string>macosx10.10</string> + <key>DTXcode</key> + <string>0632</string> + <key>DTXcodeBuild</key> + <string>6D2105</string> + <key>LSMinimumSystemVersion</key> + <string>10.10</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright © 2015 test-bundle. All rights reserved.</string> + <key>NSMainNibFile</key> + <string>MainMenu</string> + <key>NSPrincipalClass</key> + <string>NSApplication</string> +</dict> +</plist> diff --git a/chrome/test/data/safe_browsing/mach_o/test-bundle.app/Contents/MacOS/test-bundle b/chrome/test/data/safe_browsing/mach_o/test-bundle.app/Contents/MacOS/test-bundle Binary files differnew file mode 100644 index 0000000..4acc277 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/test-bundle.app/Contents/MacOS/test-bundle diff --git a/chrome/test/data/safe_browsing/mach_o/test-bundle.app/Contents/PkgInfo b/chrome/test/data/safe_browsing/mach_o/test-bundle.app/Contents/PkgInfo new file mode 100644 index 0000000..bd04210 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/test-bundle.app/Contents/PkgInfo @@ -0,0 +1 @@ +APPL????
\ No newline at end of file diff --git a/chrome/test/data/safe_browsing/mach_o/test-bundle.app/Contents/Resources/Base.lproj/MainMenu.nib b/chrome/test/data/safe_browsing/mach_o/test-bundle.app/Contents/Resources/Base.lproj/MainMenu.nib Binary files differnew file mode 100644 index 0000000..483099c --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/test-bundle.app/Contents/Resources/Base.lproj/MainMenu.nib diff --git a/chrome/test/data/safe_browsing/mach_o/test-bundle.app/Contents/Resources/executable32 b/chrome/test/data/safe_browsing/mach_o/test-bundle.app/Contents/Resources/executable32 Binary files differnew file mode 100644 index 0000000..9337b20 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/test-bundle.app/Contents/Resources/executable32 diff --git a/chrome/test/data/safe_browsing/mach_o/test-bundle.app/Contents/_CodeSignature/CodeResources b/chrome/test/data/safe_browsing/mach_o/test-bundle.app/Contents/_CodeSignature/CodeResources new file mode 100644 index 0000000..aa06c23 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/test-bundle.app/Contents/_CodeSignature/CodeResources @@ -0,0 +1,139 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>files</key> + <dict> + <key>Frameworks/libsigned64.dylib</key> + <data> + eD0Asf8/OXa6v2aNFp33nh5bsGw= + </data> + <key>Resources/Base.lproj/MainMenu.nib</key> + <dict> + <key>hash</key> + <data> + 36VmRur+3AKfYrTxgwnd4cqqjvY= + </data> + <key>optional</key> + <true/> + </dict> + <key>Resources/executable32</key> + <data> + 8UYv2Wx4Y+rmOojWWLGJj+o5iqU= + </data> + </dict> + <key>files2</key> + <dict> + <key>Frameworks/libsigned64.dylib</key> + <data> + eD0Asf8/OXa6v2aNFp33nh5bsGw= + </data> + <key>Resources/Base.lproj/MainMenu.nib</key> + <dict> + <key>hash</key> + <data> + 36VmRur+3AKfYrTxgwnd4cqqjvY= + </data> + <key>optional</key> + <true/> + </dict> + <key>Resources/executable32</key> + <data> + 8UYv2Wx4Y+rmOojWWLGJj+o5iqU= + </data> + </dict> + <key>rules</key> + <dict> + <key>^Frameworks</key> + <true/> + <key>^Resources/</key> + <true/> + <key>^Resources/.*\.lproj/</key> + <dict> + <key>optional</key> + <true/> + <key>weight</key> + <real>1000</real> + </dict> + <key>^Resources/.*\.lproj/locversion.plist$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>1100</real> + </dict> + <key>^version.plist$</key> + <true/> + </dict> + <key>rules2</key> + <dict> + <key>.*\.dSYM($|/)</key> + <dict> + <key>weight</key> + <real>11</real> + </dict> + <key>^(.*/)?\.DS_Store$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>2000</real> + </dict> + <key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key> + <dict> + <key>weight</key> + <real>10</real> + </dict> + <key>^.*</key> + <true/> + <key>^Info\.plist$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>20</real> + </dict> + <key>^PkgInfo$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>20</real> + </dict> + <key>^Resources/</key> + <dict> + <key>weight</key> + <real>20</real> + </dict> + <key>^Resources/.*\.lproj/</key> + <dict> + <key>optional</key> + <true/> + <key>weight</key> + <real>1000</real> + </dict> + <key>^Resources/.*\.lproj/locversion.plist$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>1100</real> + </dict> + <key>^[^/]+$</key> + <dict> + <key>weight</key> + <real>10</real> + </dict> + <key>^embedded\.provisionprofile$</key> + <dict> + <key>weight</key> + <real>20</real> + </dict> + <key>^version\.plist$</key> + <dict> + <key>weight</key> + <real>20</real> + </dict> + </dict> +</dict> +</plist> |