1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file. 4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/extensions/install_verifier.h" 6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <algorithm> 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <string> 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/bind.h" 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/command_line.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/metrics/field_trial.h" 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/metrics/histogram.h" 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/prefs/pref_service.h" 15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/stl_util.h" 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/extensions/extension_management.h" 17effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "chrome/browser/extensions/extension_service.h" 18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/extensions/install_signer.h" 19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/common/chrome_switches.h" 20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/common/extensions/manifest_url_handler.h" 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/common/pref_names.h" 2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/grit/generated_resources.h" 23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/public/browser/browser_context.h" 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/common/content_switches.h" 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_prefs.h" 26effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "extensions/browser/extension_registry.h" 27effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "extensions/browser/extension_system.h" 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/pref_names.h" 29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "extensions/common/extension_set.h" 30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest.h" 31effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "extensions/common/one_shot_event.h" 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace extensions { 35effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace { 37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)enum VerifyStatus { 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NONE = 0, // Do not request install signatures, and do not enforce them. 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BOOTSTRAP, // Request install signatures, but do not enforce them. 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ENFORCE, // Request install signatures, and enforce them. 42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ENFORCE_STRICT, // Same as ENFORCE, but hard fail if we can't fetch 43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // signatures. 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This is used in histograms - do not remove or reorder entries above! Also 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the "MAX" item below should always be the last element. 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VERIFY_STATUS_MAX 48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}; 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(GOOGLE_CHROME_BUILD) 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kExperimentName[] = "ExtensionInstallVerification"; 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif // defined(GOOGLE_CHROME_BUILD) 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)VerifyStatus GetExperimentStatus() { 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(GOOGLE_CHROME_BUILD) 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string group = base::FieldTrialList::FindFullName( 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kExperimentName); 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string forced_trials = CommandLine::ForCurrentProcess()-> 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetSwitchValueASCII(switches::kForceFieldTrials); 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (forced_trials.find(kExperimentName) != std::string::npos) { 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // We don't want to allow turning off enforcement by forcing the field 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // trial group to something other than enforcement. 64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return ENFORCE_STRICT; 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VerifyStatus default_status = NONE; 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (group == "EnforceStrict") 70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return ENFORCE_STRICT; 71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) else if (group == "Enforce") 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return ENFORCE; 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else if (group == "Bootstrap") 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return BOOTSTRAP; 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else if (group == "None" || group == "Control") 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return NONE; 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return default_status; 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif // defined(GOOGLE_CHROME_BUILD) 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return NONE; 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)VerifyStatus GetCommandLineStatus() { 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const CommandLine* cmdline = CommandLine::ForCurrentProcess(); 86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!InstallSigner::GetForcedNotFromWebstore().empty()) 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return ENFORCE; 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (cmdline->HasSwitch(switches::kExtensionsInstallVerification)) { 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string value = cmdline->GetSwitchValueASCII( 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) switches::kExtensionsInstallVerification); 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (value == "bootstrap") 93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return BOOTSTRAP; 94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) else if (value == "enforce_strict") 95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return ENFORCE_STRICT; 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) else 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return ENFORCE; 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return NONE; 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)VerifyStatus GetStatus() { 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return std::max(GetExperimentStatus(), GetCommandLineStatus()); 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool ShouldFetchSignature() { 108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return GetStatus() >= BOOTSTRAP; 109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool ShouldEnforce() { 112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return GetStatus() >= ENFORCE; 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)enum InitResult { 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) INIT_NO_PREF = 0, 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) INIT_UNPARSEABLE_PREF, 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) INIT_INVALID_SIGNATURE, 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) INIT_VALID_SIGNATURE, 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This is used in histograms - do not remove or reorder entries above! Also 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the "MAX" item below should always be the last element. 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) INIT_RESULT_MAX 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void LogInitResultHistogram(InitResult result) { 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("ExtensionInstallVerifier.InitResult", 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result, INIT_RESULT_MAX); 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool CanUseExtensionApis(const Extension& extension) { 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return extension.is_extension() || extension.is_legacy_packaged_app(); 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 136effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochenum VerifyAllSuccess { 137effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch VERIFY_ALL_BOOTSTRAP_SUCCESS = 0, 138effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch VERIFY_ALL_BOOTSTRAP_FAILURE, 139effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch VERIFY_ALL_NON_BOOTSTRAP_SUCCESS, 140effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch VERIFY_ALL_NON_BOOTSTRAP_FAILURE, 141effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 142effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Used in histograms. Do not remove/reorder any entries above, and the below 143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // MAX entry should always come last. 144effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch VERIFY_ALL_SUCCESS_MAX 145effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}; 146effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 147effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Record the success or failure of verifying all extensions, and whether or 148effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// not it was a bootstrapping. 149effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid LogVerifyAllSuccessHistogram(bool bootstrap, bool success) { 150effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch VerifyAllSuccess result; 151effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (bootstrap && success) 152effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch result = VERIFY_ALL_BOOTSTRAP_SUCCESS; 153effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch else if (bootstrap && !success) 154effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch result = VERIFY_ALL_BOOTSTRAP_FAILURE; 155effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch else if (!bootstrap && success) 156effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch result = VERIFY_ALL_NON_BOOTSTRAP_SUCCESS; 157effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch else 158effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch result = VERIFY_ALL_NON_BOOTSTRAP_FAILURE; 159effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 160effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // This used to be part of ExtensionService, but moved here. In order to keep 161effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // our histograms accurate, the name is unchanged. 162effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch UMA_HISTOGRAM_ENUMERATION( 163effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch "ExtensionService.VerifyAllSuccess", result, VERIFY_ALL_SUCCESS_MAX); 164effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 165effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 166effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Record the success or failure of a single verification. 167effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid LogAddVerifiedSuccess(bool success) { 168effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // This used to be part of ExtensionService, but moved here. In order to keep 169effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // our histograms accurate, the name is unchanged. 170effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch UMA_HISTOGRAM_BOOLEAN("ExtensionService.AddVerified", success); 171effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 172effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 175effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochInstallVerifier::InstallVerifier(ExtensionPrefs* prefs, 176effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch content::BrowserContext* context) 177f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) : prefs_(prefs), 178f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) context_(context), 179f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bootstrap_check_complete_(false), 180f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) weak_factory_(this) { 181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 182effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 183effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochInstallVerifier::~InstallVerifier() {} 184effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool InstallVerifier::NeedsVerification(const Extension& extension) { 1876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return IsFromStore(extension) && CanUseExtensionApis(extension); 1886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 1896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// static 1936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool InstallVerifier::IsFromStore(const Extension& extension) { 1946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (extension.from_webstore() || ManifestURL::UpdatesFromGallery(&extension)) 1956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return true; 1966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // If an extension has no update url, our autoupdate code will ask the 1986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // webstore about it (to aid in migrating to the webstore from self-hosting 1996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // or sideloading based installs). So we want to do verification checks on 2006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // such extensions too so that we don't accidentally disable old installs of 2016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // extensions that did migrate to the webstore. 2026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return (ManifestURL::GetUpdateURL(&extension).is_empty() && 2036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Manifest::IsAutoUpdateableLocation(extension.location())); 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InstallVerifier::Init() { 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("ExtensionInstallVerifier.ExperimentStatus", 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetExperimentStatus(), VERIFY_STATUS_MAX); 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("ExtensionInstallVerifier.ActualStatus", 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetStatus(), VERIFY_STATUS_MAX); 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::DictionaryValue* pref = prefs_->GetInstallSignature(); 213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (pref) { 214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<InstallSignature> signature_from_prefs = 215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InstallSignature::FromValue(*pref); 216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!signature_from_prefs.get()) { 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LogInitResultHistogram(INIT_UNPARSEABLE_PREF); 218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else if (!InstallSigner::VerifySignature(*signature_from_prefs.get())) { 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LogInitResultHistogram(INIT_INVALID_SIGNATURE); 220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "Init - ignoring invalid signature"; 221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) signature_ = signature_from_prefs.Pass(); 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LogInitResultHistogram(INIT_VALID_SIGNATURE); 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_COUNTS_100("ExtensionInstallVerifier.InitSignatureCount", 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) signature_->ids.size()); 226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GarbageCollect(); 227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LogInitResultHistogram(INIT_NO_PREF); 230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 231effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 232effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ExtensionSystem::Get(context_)->ready().Post( 233effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch FROM_HERE, 234effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Bind(&InstallVerifier::MaybeBootstrapSelf, 235effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch weak_factory_.GetWeakPtr())); 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 238effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid InstallVerifier::VerifyAllExtensions() { 239effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch AddMany(GetExtensionsToVerify(), ADD_ALL); 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::Time InstallVerifier::SignatureTimestamp() { 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (signature_.get()) 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return signature_->timestamp; 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return base::Time(); 247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool InstallVerifier::IsKnownId(const std::string& id) const { 250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return signature_.get() && (ContainsKey(signature_->ids, id) || 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ContainsKey(signature_->invalid_ids, id)); 252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool InstallVerifier::IsInvalid(const std::string& id) const { 2556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return ((signature_.get() && ContainsKey(signature_->invalid_ids, id))); 2566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 2576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 258effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid InstallVerifier::VerifyExtension(const std::string& extension_id) { 259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionIdSet ids; 260effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ids.insert(extension_id); 261effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch AddMany(ids, ADD_SINGLE); 262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 264effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid InstallVerifier::AddMany(const ExtensionIdSet& ids, OperationType type) { 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!ShouldFetchSignature()) { 266effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch OnVerificationComplete(true, type); // considered successful. 267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (signature_.get()) { 271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionIdSet not_allowed_yet = 272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::STLSetDifference<ExtensionIdSet>(ids, signature_->ids); 273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (not_allowed_yet.empty()) { 274effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch OnVerificationComplete(true, type); // considered successful. 275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InstallVerifier::PendingOperation* operation = 280effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch new InstallVerifier::PendingOperation(type); 281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) operation->ids.insert(ids.begin(), ids.end()); 282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) operation_queue_.push(linked_ptr<PendingOperation>(operation)); 284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If there are no ongoing pending requests, we need to kick one off. 286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (operation_queue_.size() == 1) 287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BeginFetch(); 288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InstallVerifier::AddProvisional(const ExtensionIdSet& ids) { 291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) provisional_.insert(ids.begin(), ids.end()); 292effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch AddMany(ids, ADD_PROVISIONAL); 293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InstallVerifier::Remove(const std::string& id) { 296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionIdSet ids; 297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ids.insert(id); 298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RemoveMany(ids); 299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InstallVerifier::RemoveMany(const ExtensionIdSet& ids) { 302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!signature_.get() || !ShouldFetchSignature()) 303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool found_any = false; 306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (ExtensionIdSet::const_iterator i = ids.begin(); i != ids.end(); ++i) { 307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (ContainsKey(signature_->ids, *i) || 308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ContainsKey(signature_->invalid_ids, *i)) { 309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) found_any = true; 310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!found_any) 314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InstallVerifier::PendingOperation* operation = 317effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch new InstallVerifier::PendingOperation(InstallVerifier::REMOVE); 318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) operation->ids = ids; 319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) operation_queue_.push(linked_ptr<PendingOperation>(operation)); 321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (operation_queue_.size() == 1) 322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BeginFetch(); 323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool InstallVerifier::AllowedByEnterprisePolicy(const std::string& id) const { 3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return ExtensionManagementFactory::GetForBrowserContext(context_) 3271675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch ->IsInstallationExplicitlyAllowed(id); 3286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 3296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)std::string InstallVerifier::GetDebugPolicyProviderName() const { 331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return std::string("InstallVerifier"); 332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)enum MustRemainDisabledOutcome { 3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VERIFIED = 0, 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOT_EXTENSION, 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UNPACKED, 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ENTERPRISE_POLICY_ALLOWED, 3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FORCED_NOT_VERIFIED, 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOT_FROM_STORE, 3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NO_SIGNATURE, 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOT_VERIFIED_BUT_NOT_ENFORCING, 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOT_VERIFIED, 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOT_VERIFIED_BUT_INSTALL_TIME_NEWER_THAN_SIGNATURE, 347a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NOT_VERIFIED_BUT_UNKNOWN_ID, 348a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) COMPONENT, 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This is used in histograms - do not remove or reorder entries above! Also 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the "MAX" item below should always be the last element. 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MUST_REMAIN_DISABLED_OUTCOME_MAX 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MustRemainDisabledHistogram(MustRemainDisabledOutcome outcome) { 3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("ExtensionInstallVerifier.MustRemainDisabled", 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) outcome, MUST_REMAIN_DISABLED_OUTCOME_MAX); 358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool InstallVerifier::MustRemainDisabled(const Extension* extension, 363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Extension::DisableReason* reason, 364a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16* error) const { 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CHECK(extension); 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!CanUseExtensionApis(*extension)) { 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MustRemainDisabledHistogram(NOT_EXTENSION); 368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (Manifest::IsUnpackedLocation(extension->location())) { 3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MustRemainDisabledHistogram(UNPACKED); 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 374a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (extension->location() == Manifest::COMPONENT) { 375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MustRemainDisabledHistogram(COMPONENT); 376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 377a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (AllowedByEnterprisePolicy(extension->id())) { 3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MustRemainDisabledHistogram(ENTERPRISE_POLICY_ALLOWED); 3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool verified = true; 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MustRemainDisabledOutcome outcome = VERIFIED; 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ContainsKey(InstallSigner::GetForcedNotFromWebstore(), extension->id())) { 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) verified = false; 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) outcome = FORCED_NOT_VERIFIED; 3886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } else if (!IsFromStore(*extension)) { 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) verified = false; 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) outcome = NOT_FROM_STORE; 391f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else if (signature_.get() == NULL && 392f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) (!bootstrap_check_complete_ || GetStatus() < ENFORCE_STRICT)) { 3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If we don't have a signature yet, we'll temporarily consider every 3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // extension from the webstore verified to avoid false positives on existing 395effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // profiles hitting this code for the first time. The InstallVerifier 396effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // will bootstrap itself once the ExtensionsSystem is ready. 3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) outcome = NO_SIGNATURE; 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (!IsVerified(extension->id())) { 399f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (signature_.get() && 400f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) !ContainsKey(signature_->invalid_ids, extension->id())) { 401a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) outcome = NOT_VERIFIED_BUT_UNKNOWN_ID; 4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) verified = false; 4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) outcome = NOT_VERIFIED; 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!verified && !ShouldEnforce()) { 4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) verified = true; 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) outcome = NOT_VERIFIED_BUT_NOT_ENFORCING; 4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MustRemainDisabledHistogram(outcome); 412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!verified) { 414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (reason) 415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *reason = Extension::DISABLE_NOT_VERIFIED; 416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (error) 417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *error = l10n_util::GetStringFUTF16( 418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IDS_EXTENSIONS_ADDED_WITHOUT_KNOWLEDGE, 419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE)); 420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return !verified; 422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 424effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochInstallVerifier::PendingOperation::PendingOperation(OperationType type) 425effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch : type(type) {} 426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)InstallVerifier::PendingOperation::~PendingOperation() { 428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 430effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochExtensionIdSet InstallVerifier::GetExtensionsToVerify() const { 431effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ExtensionIdSet result; 432effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_ptr<ExtensionSet> extensions = 433effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ExtensionRegistry::Get(context_)->GenerateInstalledExtensionsSet(); 434effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch for (ExtensionSet::const_iterator iter = extensions->begin(); 435effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch iter != extensions->end(); 436effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ++iter) { 4371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (NeedsVerification(*iter->get())) 438effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch result.insert((*iter)->id()); 439effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 440effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return result; 441effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 442effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 443effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid InstallVerifier::MaybeBootstrapSelf() { 444effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch bool needs_bootstrap = false; 445effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 446effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ExtensionIdSet extension_ids = GetExtensionsToVerify(); 447effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (signature_.get() == NULL && ShouldFetchSignature()) { 448effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch needs_bootstrap = true; 449effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } else { 450effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch for (ExtensionIdSet::const_iterator iter = extension_ids.begin(); 451effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch iter != extension_ids.end(); 452effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ++iter) { 453effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!IsKnownId(*iter)) { 454effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch needs_bootstrap = true; 455effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch break; 456effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 457effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 458effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 459effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 460effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (needs_bootstrap) 461effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch AddMany(extension_ids, ADD_ALL_BOOTSTRAP); 462f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) else 463f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bootstrap_check_complete_ = true; 464effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 465effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 466f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void InstallVerifier::OnVerificationComplete(bool success, OperationType type) { 467effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch switch (type) { 468effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch case ADD_SINGLE: 469effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch LogAddVerifiedSuccess(success); 470effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch break; 471effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch case ADD_ALL: 472effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch case ADD_ALL_BOOTSTRAP: 473effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch LogVerifyAllSuccessHistogram(type == ADD_ALL_BOOTSTRAP, success); 474f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bootstrap_check_complete_ = true; 475effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (success) { 476effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Iterate through the extensions and, if any are newly-verified and 477effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // should have the DISABLE_NOT_VERIFIED reason lifted, do so. 478effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const ExtensionSet& disabled_extensions = 479effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ExtensionRegistry::Get(context_)->disabled_extensions(); 480effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch for (ExtensionSet::const_iterator iter = disabled_extensions.begin(); 481effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch iter != disabled_extensions.end(); 482effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ++iter) { 483effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch int disable_reasons = prefs_->GetDisableReasons((*iter)->id()); 484effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (disable_reasons & Extension::DISABLE_NOT_VERIFIED && 4851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci !MustRemainDisabled(iter->get(), NULL, NULL)) { 486effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch prefs_->RemoveDisableReason((*iter)->id(), 487effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch Extension::DISABLE_NOT_VERIFIED); 488effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 489effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 490f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 491f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (success || GetStatus() == ENFORCE_STRICT) { 492effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ExtensionSystem::Get(context_) 493effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ->extension_service() 494effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ->CheckManagementPolicy(); 495effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 496effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch break; 497effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // We don't need to check disable reasons or report UMA stats for 498effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // provisional adds or removals. 499effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch case ADD_PROVISIONAL: 500effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch case REMOVE: 501effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch break; 502effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 503effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 504effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InstallVerifier::GarbageCollect() { 506f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!ShouldFetchSignature()) { 507f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 508f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 509f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CHECK(signature_.get()); 510f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionIdSet leftovers = signature_->ids; 511a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leftovers.insert(signature_->invalid_ids.begin(), 512a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) signature_->invalid_ids.end()); 513f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionIdList all_ids; 514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) prefs_->GetExtensions(&all_ids); 515f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (ExtensionIdList::const_iterator i = all_ids.begin(); 516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) i != all_ids.end(); ++i) { 517f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionIdSet::iterator found = leftovers.find(*i); 518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (found != leftovers.end()) 519f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) leftovers.erase(found); 520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!leftovers.empty()) { 522f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RemoveMany(leftovers); 523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 524f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 525f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 526f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool InstallVerifier::IsVerified(const std::string& id) const { 527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return ((signature_.get() && ContainsKey(signature_->ids, id)) || 528f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ContainsKey(provisional_, id)); 529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 531f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InstallVerifier::BeginFetch() { 532f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(ShouldFetchSignature()); 533f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 534f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(asargent) - It would be possible to coalesce all operations in the 535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // queue into one fetch - we'd probably just need to change the queue to 536effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // hold (set of ids, list of operation type) pairs. 537f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CHECK(!operation_queue_.empty()); 538f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const PendingOperation& operation = *operation_queue_.front(); 539f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 540f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionIdSet ids_to_sign; 541f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (signature_.get()) { 542f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ids_to_sign.insert(signature_->ids.begin(), signature_->ids.end()); 543f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 544effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (operation.type == InstallVerifier::REMOVE) { 545f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (ExtensionIdSet::const_iterator i = operation.ids.begin(); 546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) i != operation.ids.end(); ++i) { 547f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (ContainsKey(ids_to_sign, *i)) 548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ids_to_sign.erase(*i); 549f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 550effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } else { // All other operation types are some form of "ADD". 551effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ids_to_sign.insert(operation.ids.begin(), operation.ids.end()); 552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 553f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 554effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch signer_.reset(new InstallSigner(context_->GetRequestContext(), ids_to_sign)); 555f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) signer_->GetSignature(base::Bind(&InstallVerifier::SignatureCallback, 556effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch weak_factory_.GetWeakPtr())); 557f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 558f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 559f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InstallVerifier::SaveToPrefs() { 560f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (signature_.get()) 561f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(InstallSigner::VerifySignature(*signature_)); 562f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 563f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!signature_.get() || signature_->ids.empty()) { 564f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "SaveToPrefs - saving NULL"; 565f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) prefs_->SetInstallSignature(NULL); 566f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue pref; 568f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) signature_->ToValue(&pref); 569f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (VLOG_IS_ON(1)) { 570f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "SaveToPrefs - saving"; 571f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 572f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(InstallSigner::VerifySignature(*signature_.get())); 573f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<InstallSignature> rehydrated = 574f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InstallSignature::FromValue(pref); 575f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(InstallSigner::VerifySignature(*rehydrated.get())); 576f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 577f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) prefs_->SetInstallSignature(&pref); 578f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 579f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 580f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 5825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)enum CallbackResult { 5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CALLBACK_NO_SIGNATURE = 0, 5855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CALLBACK_INVALID_SIGNATURE, 5865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CALLBACK_VALID_SIGNATURE, 5875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This is used in histograms - do not remove or reorder entries above! Also 5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the "MAX" item below should always be the last element. 5905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CALLBACK_RESULT_MAX 5925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 5935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void GetSignatureResultHistogram(CallbackResult result) { 5955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("ExtensionInstallVerifier.GetSignatureResult", 5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result, CALLBACK_RESULT_MAX); 5975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 5985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 6005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 601f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InstallVerifier::SignatureCallback( 602f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<InstallSignature> signature) { 603f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 604f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) linked_ptr<PendingOperation> operation = operation_queue_.front(); 605f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) operation_queue_.pop(); 606f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 607f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool success = false; 608f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!signature.get()) { 6095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetSignatureResultHistogram(CALLBACK_NO_SIGNATURE); 610f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else if (!InstallSigner::VerifySignature(*signature)) { 6115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetSignatureResultHistogram(CALLBACK_INVALID_SIGNATURE); 612f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 6135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetSignatureResultHistogram(CALLBACK_VALID_SIGNATURE); 614f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) success = true; 615f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 616f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 617f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!success) { 618effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch OnVerificationComplete(false, operation->type); 619f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 620f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(asargent) - if this was something like a network error, we need to 621f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // do retries with exponential back off. 622f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 623f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) signature_ = signature.Pass(); 624f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SaveToPrefs(); 625f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 626f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!provisional_.empty()) { 627f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Update |provisional_| to remove ids that were successfully signed. 628f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) provisional_ = base::STLSetDifference<ExtensionIdSet>( 629f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) provisional_, signature_->ids); 630f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 631f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 632effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch OnVerificationComplete(success, operation->type); 633f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 634f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 635f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!operation_queue_.empty()) 636f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BeginFetch(); 637f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 638f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 639f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace extensions 640