component_unpacker.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // Copyright 2014 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef COMPONENTS_UPDATE_CLIENT_COMPONENT_UNPACKER_H_
  5. #define COMPONENTS_UPDATE_CLIENT_COMPONENT_UNPACKER_H_
  6. #include <stdint.h>
  7. #include <memory>
  8. #include <string>
  9. #include <vector>
  10. #include "base/callback.h"
  11. #include "base/files/file_path.h"
  12. #include "base/memory/ref_counted.h"
  13. #include "components/update_client/update_client_errors.h"
  14. // TODO(crbug.com/1349158): Remove this class once Puffin patches are fully
  15. // implemented.
  16. namespace crx_file {
  17. enum class VerifierFormat;
  18. }
  19. namespace update_client {
  20. class CrxInstaller;
  21. class ComponentPatcher;
  22. class Patcher;
  23. class Unzipper;
  24. // In charge of unpacking the component CRX package and verifying that it is
  25. // well formed and the cryptographic signature is correct.
  26. //
  27. // This class should be used only by the component updater. It is inspired by
  28. // and overlaps with code in the extension's SandboxedUnpacker.
  29. // The main differences are:
  30. // - The public key hash is full SHA256.
  31. // - Does not use a sandboxed unpacker. A valid component is fully trusted.
  32. // - The manifest can have different attributes and resources are not
  33. // transcoded.
  34. //
  35. // If the CRX is a delta CRX, the flow is:
  36. // [ComponentUpdater] [ComponentPatcher]
  37. // Unpack
  38. // \_ Verify
  39. // \_ Unzip
  40. // \_ BeginPatching ---> DifferentialUpdatePatch
  41. // ...
  42. // EndPatching <------------ ...
  43. // \_ EndUnpacking
  44. //
  45. // For a full CRX, the flow is:
  46. // [ComponentUpdater]
  47. // Unpack
  48. // \_ Verify
  49. // \_ Unzip
  50. // \_ BeginPatching
  51. // |
  52. // V
  53. // EndPatching
  54. // \_ EndUnpacking
  55. //
  56. // In both cases, if there is an error at any point, the remaining steps will
  57. // be skipped and EndUnpacking will be called.
  58. class ComponentUnpacker : public base::RefCountedThreadSafe<ComponentUnpacker> {
  59. public:
  60. // Contains the result of the unpacking.
  61. struct Result {
  62. Result();
  63. // Unpack error: 0 indicates success.
  64. UnpackerError error = UnpackerError::kNone;
  65. // Additional error information, such as errno or last error.
  66. int extended_error = 0;
  67. // Path of the unpacked files if the unpacking was successful.
  68. base::FilePath unpack_path;
  69. // The extracted public key of the package if the unpacking was successful.
  70. std::string public_key;
  71. };
  72. using Callback = base::OnceCallback<void(const Result& result)>;
  73. // Constructs an unpacker for a specific component unpacking operation.
  74. // |pk_hash| is the expected public developer key's SHA256 hash. If empty,
  75. // the unpacker accepts any developer key. |path| is the current location
  76. // of the CRX.
  77. ComponentUnpacker(const std::vector<uint8_t>& pk_hash,
  78. const base::FilePath& path,
  79. scoped_refptr<CrxInstaller> installer,
  80. std::unique_ptr<Unzipper> unzipper,
  81. scoped_refptr<Patcher> patcher,
  82. crx_file::VerifierFormat crx_format);
  83. ComponentUnpacker(const ComponentUnpacker&) = delete;
  84. ComponentUnpacker& operator=(const ComponentUnpacker&) = delete;
  85. // Begins the actual unpacking of the files. May invoke a patcher and the
  86. // component installer if the package is a differential update.
  87. // Calls |callback| with the result.
  88. void Unpack(Callback callback);
  89. private:
  90. friend class base::RefCountedThreadSafe<ComponentUnpacker>;
  91. virtual ~ComponentUnpacker();
  92. // The first step of unpacking is to verify the file. Returns false if an
  93. // error is encountered, the file is malformed, or the file is incorrectly
  94. // signed.
  95. bool Verify();
  96. // The second step of unpacking is to unzip. Returns false if an early error
  97. // is encountered.
  98. bool BeginUnzipping();
  99. void EndUnzipping(bool error);
  100. // The third step is to optionally patch files - this is a no-op for full
  101. // (non-differential) updates. This step is asynchronous.
  102. void BeginPatching();
  103. void EndPatching(UnpackerError error, int extended_error);
  104. // The final step is to do clean-up for things that can't be tidied as we go.
  105. // If there is an error at any step, the remaining steps are skipped and
  106. // EndUnpacking is called. EndUnpacking is responsible for calling the
  107. // callback provided in Unpack().
  108. void EndUnpacking();
  109. std::vector<uint8_t> pk_hash_;
  110. base::FilePath path_;
  111. base::FilePath unpack_path_;
  112. base::FilePath unpack_diff_path_;
  113. bool is_delta_;
  114. scoped_refptr<ComponentPatcher> patcher_;
  115. scoped_refptr<CrxInstaller> installer_;
  116. Callback callback_;
  117. std::unique_ptr<Unzipper> unzipper_;
  118. scoped_refptr<Patcher> patcher_tool_;
  119. crx_file::VerifierFormat crx_format_;
  120. UnpackerError error_;
  121. int extended_error_;
  122. std::string public_key_;
  123. };
  124. } // namespace update_client
  125. #endif // COMPONENTS_UPDATE_CLIENT_COMPONENT_UNPACKER_H_