File: unpacker.h

package info (click to toggle)
chromium 140.0.7339.127-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 6,192,880 kB
  • sloc: cpp: 35,093,808; ansic: 7,161,670; javascript: 4,199,694; python: 1,441,797; asm: 949,904; xml: 747,503; pascal: 187,748; perl: 88,691; sh: 88,248; objc: 79,953; sql: 52,714; cs: 44,599; fortran: 24,137; makefile: 22,114; tcl: 15,277; php: 13,980; yacc: 9,000; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (133 lines) | stat: -rw-r--r-- 4,905 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_UPDATE_CLIENT_UNPACKER_H_
#define COMPONENTS_UPDATE_CLIENT_UNPACKER_H_

#include <stdint.h>

#include <memory>
#include <string>
#include <vector>

#include "base/files/file_path.h"
#include "base/functional/callback.h"
#include "base/memory/ref_counted.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "components/update_client/update_client_errors.h"

namespace crx_file {
enum class VerifierFormat;
}

namespace update_client {

class Unzipper;

// Unpacks the component CRX package and verifies that it is
// well formed and the cryptographic signature is correct.
//
// This class is only used by the component updater. It is inspired by
// and overlaps with code in the extension's SandboxedUnpacker.
// The main differences are:
// - The public key hash is SHA256.
// - Does not use a sandboxed unpacker. A valid component is fully trusted.
// - The manifest can have different attributes and resources are not
//   transcoded.
//
// This is an updated version of Unpacker that leverages the new
// Puffin-based puffpatch CRX-diff format, rather than the legacy
// courgette/bsdiff per-file CRXD format. Puffin patches the CRX before
// unpacking, changing the order of operations such that patching needs to occur
// before verifying and unpacking. Unlike the original implementation, by the
// time we unpack, the patching has already occurred.
//
// Note: During unzip step we also check for verified_contents.json in the
// header of crx file and unpack it to metadata_ folder if it doesn't already
// contain verified_contents file.
class Unpacker : public base::RefCountedThreadSafe<Unpacker> {
 public:
  // Contains the result of the unpacking.
  struct Result {
    Result();

    // Unpack error: 0 indicates success.
    UnpackerError error = UnpackerError::kNone;

    // Additional error information, such as errno or last error.
    int extended_error = 0;

    // Path of the unpacked files if the unpacking was successful.
    base::FilePath unpack_path;

    // The extracted public key of the package if the unpacking was successful.
    std::string public_key;
  };

  Unpacker(const Unpacker&) = delete;
  Unpacker& operator=(const Unpacker&) = delete;

  // Begins the actual unpacking of the files. Calls `callback` with the result.
  static void Unpack(const std::string& app_id,
                     const std::vector<uint8_t>& pk_hash,
                     const base::FilePath& path,
                     std::unique_ptr<Unzipper> unzipper,
                     crx_file::VerifierFormat crx_format,
                     base::OnceCallback<void(const Result& result)> callback);

 private:
  friend class base::RefCountedThreadSafe<Unpacker>;

  // Constructs an unpacker for a specific component unpacking operation.
  // `pk_hash` is the expected public developer key's SHA256 hash. If empty,
  // the unpacker accepts any developer key. `path` is the current location
  // of the CRX.
  Unpacker(const std::string& app_id,
           const base::FilePath& path,
           std::unique_ptr<Unzipper> unzipper,
           base::OnceCallback<void(const Result& result)> callback);

  virtual ~Unpacker();

  // The first step of unpacking is to verify the file. Triggers
  // `BeginUnzipping` if successful. Triggers `EndUnpacking` if an early error
  // is encountered.
  void Verify(const std::vector<uint8_t>& pk_hash,
              crx_file::VerifierFormat crx_format);

  // The next step of unpacking is to unzip. Triggers `EndUnzipping` if
  // successful. Triggers `EndUnpacking` if an early error is encountered.
  void BeginUnzipping();
  void EndUnzipping(bool error);

  // Decompresses verified contents fetched from the header of CRX.
  void UncompressVerifiedContents();

  // Stores the decompressed verified contents fetched from the header of CRX.
  void StoreVerifiedContentsInExtensionDir(
      const std::string& verified_contents);

  // The final step is to do clean-up for things that can't be tidied as we go.
  // If there is an error at any step, the remaining steps are skipped and
  // `EndUnpacking` is called. `EndUnpacking` is responsible for calling the
  // callback provided in `Unpack`.
  void EndUnpacking(UnpackerError error, int extended_error = 0);

  const std::string app_id_;
  base::FilePath path_;
  std::unique_ptr<Unzipper> unzipper_;
  base::OnceCallback<void(const Result& result)> callback_;
  base::FilePath unpack_path_;
  std::string public_key_;
  base::TimeTicks unzip_begin_time_;

  // The compressed verified contents extracted from the CRX header.
  std::vector<uint8_t> compressed_verified_contents_;
  SEQUENCE_CHECKER(sequence_checker_);
};

}  // namespace update_client

#endif  // COMPONENTS_UPDATE_CLIENT_UNPACKER_H_