puffin_component_unpacker.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // Copyright 2022 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_PUFFIN_COMPONENT_UNPACKER_H_
  5. #define COMPONENTS_UPDATE_CLIENT_PUFFIN_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 "base/sequence_checker.h"
  14. #include "components/update_client/update_client_errors.h"
  15. namespace crx_file {
  16. enum class VerifierFormat;
  17. }
  18. namespace update_client {
  19. class Unzipper;
  20. // Unpacks the component CRX package and verifies that it is
  21. // well formed and the cryptographic signature is correct.
  22. //
  23. // This class is only used by the component updater. It is inspired by
  24. // and overlaps with code in the extension's SandboxedUnpacker.
  25. // The main differences are:
  26. // - The public key hash is SHA256.
  27. // - Does not use a sandboxed unpacker. A valid component is fully trusted.
  28. // - The manifest can have different attributes and resources are not
  29. // transcoded.
  30. //
  31. // This is an updated version of ComponentUnpacker that leverages the new
  32. // Puffin-based puffpatch CRX-diff format, rather than the legacy
  33. // courgette/bsdiff per-file CRXD format. Puffin patches the CRX before
  34. // unpacking, changing the order of operations such that patching needs to occur
  35. // before verifying and unpacking. Unlike the original implementation, by the
  36. // time we unpack, the patching has already occurred.
  37. class PuffinComponentUnpacker
  38. : public base::RefCountedThreadSafe<PuffinComponentUnpacker> {
  39. public:
  40. // Contains the result of the unpacking.
  41. struct Result {
  42. Result();
  43. // Unpack error: 0 indicates success.
  44. UnpackerError error = UnpackerError::kNone;
  45. // Additional error information, such as errno or last error.
  46. int extended_error = 0;
  47. // Path of the unpacked files if the unpacking was successful.
  48. base::FilePath unpack_path;
  49. // The extracted public key of the package if the unpacking was successful.
  50. std::string public_key;
  51. };
  52. PuffinComponentUnpacker(const PuffinComponentUnpacker&) = delete;
  53. PuffinComponentUnpacker& operator=(const PuffinComponentUnpacker&) = delete;
  54. // Begins the actual unpacking of the files. Calls `callback` with the result.
  55. static void Unpack(const std::vector<uint8_t>& pk_hash,
  56. const base::FilePath& path,
  57. std::unique_ptr<Unzipper> unzipper,
  58. crx_file::VerifierFormat crx_format,
  59. base::OnceCallback<void(const Result& result)> callback);
  60. private:
  61. friend class base::RefCountedThreadSafe<PuffinComponentUnpacker>;
  62. // Constructs an unpacker for a specific component unpacking operation.
  63. // `pk_hash` is the expected public developer key's SHA256 hash. If empty,
  64. // the unpacker accepts any developer key. `path` is the current location
  65. // of the CRX.
  66. PuffinComponentUnpacker(
  67. const std::vector<uint8_t>& pk_hash,
  68. const base::FilePath& path,
  69. std::unique_ptr<Unzipper> unzipper,
  70. crx_file::VerifierFormat crx_format,
  71. base::OnceCallback<void(const Result& result)> callback);
  72. virtual ~PuffinComponentUnpacker();
  73. // The first step of unpacking is to verify the file. Triggers
  74. // `BeginUnzipping` if successful. Triggers `EndUnpacking` if an early error
  75. // is encountered.
  76. void Verify();
  77. // The next step of unpacking is to unzip. Triggers `EndUnzipping` if
  78. // successful. Triggers `EndUnpacking` if an early error is encountered.
  79. void BeginUnzipping();
  80. void EndUnzipping(bool error);
  81. // The final step is to do clean-up for things that can't be tidied as we go.
  82. // If there is an error at any step, the remaining steps are skipped and
  83. // `EndUnpacking` is called. `EndUnpacking` is responsible for calling the
  84. // callback provided in `Unpack`.
  85. void EndUnpacking(UnpackerError error, int extended_error);
  86. std::vector<uint8_t> pk_hash_;
  87. base::FilePath path_;
  88. std::unique_ptr<Unzipper> unzipper_;
  89. crx_file::VerifierFormat crx_format_;
  90. base::OnceCallback<void(const Result& result)> callback_;
  91. base::FilePath unpack_path_;
  92. std::string public_key_;
  93. SEQUENCE_CHECKER(sequence_checker_);
  94. };
  95. } // namespace update_client
  96. #endif // COMPONENTS_UPDATE_CLIENT_PUFFIN_COMPONENT_UNPACKER_H_