Greg Kerr | 019d59c | 2016-11-17 14:28:49 -0800 | [diff] [blame] | 1 | // Copyright 2016 The Chromium OS 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 | |
| 5 | // This class abstracts away the details about the layout of the component dir |
| 6 | // and how to verify/copy it. |
| 7 | // |
| 8 | // A component directory contains the following files: |
| 9 | // |
| 10 | // imageloader.json Manifest JSON file |
| 11 | // imageloader.sig.1 Manifest signature |
| 12 | // manifest.fingerprint Fingerprint file (used for delta updates) |
| 13 | // image.squash squashfs image |
| 14 | // table dm-verity table, including parameters |
| 15 | #ifndef IMAGELOADER_COMPONENT_H_ |
| 16 | #define IMAGELOADER_COMPONENT_H_ |
| 17 | |
Eric Caruso | 26a9144 | 2017-10-25 16:05:40 -0700 | [diff] [blame] | 18 | #include <map> |
Eric Caruso | cbe1c5c | 2017-03-15 14:21:08 -0700 | [diff] [blame] | 19 | #include <memory> |
Greg Kerr | 019d59c | 2016-11-17 14:28:49 -0800 | [diff] [blame] | 20 | #include <string> |
| 21 | #include <vector> |
| 22 | |
| 23 | #include <base/files/file.h> |
| 24 | #include <base/files/file_path.h> |
| 25 | #include <base/gtest_prod_util.h> |
| 26 | #include <base/macros.h> |
| 27 | #include <crypto/secure_hash.h> |
| 28 | |
Greg Kerr | 09f06de | 2018-02-16 15:32:07 -0800 | [diff] [blame] | 29 | #include "imageloader/helper_process_proxy.h" |
Ben Chan | 045849f | 2017-12-18 17:27:07 -0800 | [diff] [blame] | 30 | #include "imageloader/imageloader_impl.h" |
Xiaochu Liu | e61e1d6 | 2018-11-12 13:20:09 -0800 | [diff] [blame] | 31 | #include "imageloader/manifest.h" |
Greg Kerr | 019d59c | 2016-11-17 14:28:49 -0800 | [diff] [blame] | 32 | |
| 33 | namespace imageloader { |
| 34 | |
| 35 | // The permissions that the component update directory must use. |
| 36 | constexpr int kComponentDirPerms = 0755; |
| 37 | // The permissions that files in the component should have. |
| 38 | constexpr int kComponentFilePerms = 0644; |
Xiaochu Liu | 83a51ac | 2018-06-22 13:48:37 -0700 | [diff] [blame] | 39 | // The maximum size of any file to read into memory. |
| 40 | constexpr size_t kMaximumFilesize = 4096 * 10; |
Greg Kerr | 019d59c | 2016-11-17 14:28:49 -0800 | [diff] [blame] | 41 | |
| 42 | class Component { |
| 43 | public: |
Eric Caruso | cbe1c5c | 2017-03-15 14:21:08 -0700 | [diff] [blame] | 44 | // Creates a Component. Returns nullptr if initialization and verification |
| 45 | // fails. |
Eric Caruso | 0b79bc8 | 2017-03-21 13:44:34 -0700 | [diff] [blame] | 46 | static std::unique_ptr<Component> Create(const base::FilePath& component_dir, |
| 47 | const Keys& public_keys); |
Greg Kerr | 019d59c | 2016-11-17 14:28:49 -0800 | [diff] [blame] | 48 | |
| 49 | // Copies the component into |dest_dir|. |dest_dir| must already exist. In |
| 50 | // order to be robust against files being modified on disk, this function |
| 51 | // verifies the files it copies against the manifest (which is loaded into |
| 52 | // memory). |
| 53 | bool CopyTo(const base::FilePath& dest_dir); |
| 54 | |
| 55 | // Mounts the component into |mount_point|. |mount_point| must already exist. |
Greg Kerr | 09f06de | 2018-02-16 15:32:07 -0800 | [diff] [blame] | 56 | bool Mount(HelperProcessProxy* proxy, const base::FilePath& mount_point); |
Greg Kerr | 019d59c | 2016-11-17 14:28:49 -0800 | [diff] [blame] | 57 | |
| 58 | // Return a reference to the parsed manifest object, which is stored in |
| 59 | // memory. |
Xiaochu Liu | e61e1d6 | 2018-11-12 13:20:09 -0800 | [diff] [blame] | 60 | const Manifest& manifest(); |
Greg Kerr | 019d59c | 2016-11-17 14:28:49 -0800 | [diff] [blame] | 61 | |
| 62 | private: |
Eric Caruso | cbe1c5c | 2017-03-15 14:21:08 -0700 | [diff] [blame] | 63 | // Constructs a Component. We want to avoid using this where possible since |
| 64 | // you need to load the manifest before doing anything anyway, so use the |
| 65 | // static factory method above. |
Eric Caruso | 089bbff | 2017-03-21 11:34:15 -0700 | [diff] [blame] | 66 | Component(const base::FilePath& component_dir, int key_number); |
Qijiang Fan | 6bc59e1 | 2020-11-11 02:51:06 +0900 | [diff] [blame] | 67 | Component(const Component&) = delete; |
| 68 | Component& operator=(const Component&) = delete; |
Eric Caruso | cbe1c5c | 2017-03-15 14:21:08 -0700 | [diff] [blame] | 69 | |
| 70 | // Loads and verifies the manfiest. Returns false on failure. |public_key| is |
| 71 | // the public key used to check the manifest signature. |
Greg Kerr | 019d59c | 2016-11-17 14:28:49 -0800 | [diff] [blame] | 72 | bool LoadManifest(const std::vector<uint8_t>& public_key); |
Amin Hassani | 17a185b | 2021-02-10 12:07:57 -0800 | [diff] [blame] | 73 | // Same as the above function, but it skips the verification. |
| 74 | bool LoadManifestWithoutVerifyingKeyForTestingOnly(); |
| 75 | |
Colin Howes | ad6271a | 2018-11-21 15:36:05 -0800 | [diff] [blame] | 76 | bool CopyComponentFile(const base::FilePath& src, |
| 77 | const base::FilePath& dest, |
Eric Caruso | 355e37c | 2017-03-15 14:31:41 -0700 | [diff] [blame] | 78 | const std::vector<uint8_t>& expected_hash); |
Greg Kerr | 019d59c | 2016-11-17 14:28:49 -0800 | [diff] [blame] | 79 | // This reads the contents of |file|, hashes it with |sha256|, and if |
| 80 | // |out_file| is not null, copies it into |out_file|. |
Colin Howes | ad6271a | 2018-11-21 15:36:05 -0800 | [diff] [blame] | 81 | bool ReadHashAndCopyFile(base::File* file, |
| 82 | std::vector<uint8_t>* sha256, |
Greg Kerr | 019d59c | 2016-11-17 14:28:49 -0800 | [diff] [blame] | 83 | base::File* out_file); |
| 84 | // Copies the fingerprint file that Chrome users for delta updates. |
| 85 | bool CopyFingerprintFile(const base::FilePath& src, |
| 86 | const base::FilePath& dest); |
Greg Kerr | 04c1cee | 2020-10-15 14:08:44 +0000 | [diff] [blame] | 87 | // Validate the fingerprint file. |
Eric Caruso | cbe1c5c | 2017-03-15 14:21:08 -0700 | [diff] [blame] | 88 | static bool IsValidFingerprintFile(const std::string& contents); |
Greg Kerr | 019d59c | 2016-11-17 14:28:49 -0800 | [diff] [blame] | 89 | |
| 90 | FRIEND_TEST_ALL_PREFIXES(ComponentTest, IsValidFingerprintFile); |
| 91 | FRIEND_TEST_ALL_PREFIXES(ComponentTest, CopyValidImage); |
| 92 | |
Greg Kerr | 019d59c | 2016-11-17 14:28:49 -0800 | [diff] [blame] | 93 | const base::FilePath component_dir_; |
Eric Caruso | 9588e64 | 2017-04-07 15:18:45 -0700 | [diff] [blame] | 94 | size_t key_number_; |
Greg Kerr | 019d59c | 2016-11-17 14:28:49 -0800 | [diff] [blame] | 95 | std::string manifest_raw_; |
| 96 | std::string manifest_sig_; |
Xiaochu Liu | e61e1d6 | 2018-11-12 13:20:09 -0800 | [diff] [blame] | 97 | Manifest manifest_; |
Greg Kerr | 019d59c | 2016-11-17 14:28:49 -0800 | [diff] [blame] | 98 | }; |
| 99 | |
| 100 | } // namespace imageloader |
| 101 | |
| 102 | #endif // IMAGELOADER_COMPONENT_H_ |