103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#ifndef COMPONENTS_COMPONENT_UPDATER_COMPONENT_UNPACKER_H_ 603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#define COMPONENTS_COMPONENT_UPDATER_COMPONENT_UNPACKER_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <stdint.h> 9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <string> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/callback.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/json/json_file_value_serializer.h" 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/macros.h" 16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/memory/ref_counted.h" 171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/sequenced_task_runner.h" 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace component_updater { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ComponentInstaller; 23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass ComponentPatcher; 245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class OutOfProcessPatcher; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Deserializes the CRX manifest. The top level must be a dictionary. 271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)scoped_ptr<base::DictionaryValue> ReadManifest( 281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const base::FilePath& unpack_path); 291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In charge of unpacking the component CRX package and verifying that it is 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// well formed and the cryptographic signature is correct. If there is no 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// error the component specific installer will be invoked to proceed with 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the component installation or update. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This class should be used only by the component updater. It is inspired by 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and overlaps with code in the extension's SandboxedUnpacker. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The main differences are: 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - The public key hash is full SHA256. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - Does not use a sandboxed unpacker. A valid component is fully trusted. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - The manifest can have different attributes and resources are not 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// transcoded. 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// If the CRX is a delta CRX, the flow is: 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// [ComponentUpdater] [ComponentPatcher] 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Unpack 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// \_ Verify 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// \_ Unzip 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// \_ BeginPatching ---> DifferentialUpdatePatch 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// ... 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// EndPatching <------------ ... 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// \_ Install 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// \_ Finish 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// For a full CRX, the flow is: 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// [ComponentUpdater] 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Unpack 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// \_ Verify 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// \_ Unzip 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// \_ BeginPatching 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// | 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// V 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// EndPatching 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// \_ Install 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// \_ Finish 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// In both cases, if there is an error at any point, the remaining steps will 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// be skipped and Finish will be called. 68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass ComponentUnpacker : public base::RefCountedThreadSafe<ComponentUnpacker> { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Possible error conditions. 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Add only to the bottom of this enum; the order must be kept stable. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum Error { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kNone, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kInvalidParams, 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kInvalidFile, 76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kUnzipPathError, 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kUnzipFailed, 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kNoManifest, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kBadManifest, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kBadExtension, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kInvalidId, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kInstallerError, 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kIoError, 84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kDeltaVerificationFailure, 85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kDeltaBadCommands, 86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kDeltaUnsupportedCommand, 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kDeltaOperationFailure, 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kDeltaPatchProcessFailure, 89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kDeltaMissingExistingFile, 90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kFingerprintWriteFailed, 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch typedef base::Callback<void(Error, int)> Callback; 94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Constructs an unpacker for a specific component unpacking operation. 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // |pk_hash| is the expected/ public key SHA256 hash. |path| is the current 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // location of the CRX. 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ComponentUnpacker(const std::vector<uint8_t>& pk_hash, 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& path, 100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& fingerprint, 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ComponentInstaller* installer, 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<OutOfProcessPatcher> out_of_process_patcher, 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> task_runner); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Begins the actual unpacking of the files. May invoke a patcher if the 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // package is a differential update. Calls |callback| with the result. 107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch void Unpack(const Callback& callback); 108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch friend class base::RefCountedThreadSafe<ComponentUnpacker>; 111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch virtual ~ComponentUnpacker(); 113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool UnpackInternal(); 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The first step of unpacking is to verify the file. Returns false if an 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // error is encountered, the file is malformed, or the file is incorrectly 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // signed. 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool Verify(); 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The second step of unpacking is to unzip. Returns false if an error 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // occurs as part of unzipping. 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool Unzip(); 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The third step is to optionally patch files - this is a no-op for full 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // (non-differential) updates. This step is asynchronous. Returns false if an 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // error is encountered. 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool BeginPatching(); 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // When patching is complete, EndPatching is called before moving on to step 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // four. 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void EndPatching(Error error, int extended_error); 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The fourth step is to install the unpacked component. 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void Install(); 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The final step is to do clean-up for things that can't be tidied as we go. 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If there is an error at any step, the remaining steps are skipped and 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // and Finish is called. 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Finish is responsible for calling the callback provided in Start(). 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void Finish(); 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::vector<uint8_t> pk_hash_; 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::FilePath path_; 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath unpack_path_; 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::FilePath unpack_diff_path_; 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool is_delta_; 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string fingerprint_; 149effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_refptr<ComponentPatcher> patcher_; 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ComponentInstaller* installer_; 151effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch Callback callback_; 1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<OutOfProcessPatcher> out_of_process_patcher_; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Error error_; 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int extended_error_; 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> task_runner_; 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ComponentUnpacker); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace component_updater 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 16203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif // COMPONENTS_COMPONENT_UPDATER_COMPONENT_UNPACKER_H_ 163