OLD | NEW |
| (Empty) |
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 | |
5 #ifndef COMPONENTS_CRX_FILE_CRX_FILE_H_ | |
6 #define COMPONENTS_CRX_FILE_CRX_FILE_H_ | |
7 | |
8 #include <stddef.h> | |
9 #include <stdint.h> | |
10 #include <sys/types.h> | |
11 | |
12 #include <memory> | |
13 #include <string> | |
14 #include <vector> | |
15 | |
16 namespace base { | |
17 class FilePath; | |
18 } | |
19 | |
20 namespace crx_file { | |
21 | |
22 // CRX files have a header that includes a magic key, version number, and | |
23 // some signature sizing information. Use CrxFile object to validate whether | |
24 // the header is valid or not. | |
25 class CrxFile { | |
26 public: | |
27 // The size of the magic character sequence at the beginning of each crx | |
28 // file, in bytes. This should be a multiple of 4. | |
29 static const size_t kCrxFileHeaderMagicSize = 4; | |
30 | |
31 // This header is the first data at the beginning of an extension. Its | |
32 // contents are purposely 32-bit aligned so that it can just be slurped into | |
33 // a struct without manual parsing. | |
34 struct Header { | |
35 char magic[kCrxFileHeaderMagicSize]; | |
36 uint32_t version; | |
37 uint32_t key_size; // The size of the public key, in bytes. | |
38 uint32_t signature_size; // The size of the signature, in bytes. | |
39 // An ASN.1-encoded PublicKeyInfo structure follows. | |
40 // The signature follows. | |
41 }; | |
42 | |
43 enum Error { | |
44 kWrongMagic, | |
45 kInvalidVersion, | |
46 kInvalidKeyTooLarge, | |
47 kInvalidKeyTooSmall, | |
48 kInvalidSignatureTooLarge, | |
49 kInvalidSignatureTooSmall, | |
50 }; | |
51 | |
52 // Construct a new CRX file header object with bytes of a header | |
53 // read from a CRX file. If a null scoped_ptr is returned, |error| | |
54 // contains an error code with additional information. | |
55 static std::unique_ptr<CrxFile> Parse(const Header& header, Error* error); | |
56 | |
57 // Construct a new header for the given key and signature sizes. | |
58 // Returns a null scoped_ptr if erroneous values of |key_size| and/or | |
59 // |signature_size| are provided. |error| contains an error code with | |
60 // additional information. | |
61 // Use this constructor and then .header() to obtain the Header | |
62 // for writing out to a CRX file. | |
63 static std::unique_ptr<CrxFile> Create(const uint32_t key_size, | |
64 const uint32_t signature_size, | |
65 Error* error); | |
66 | |
67 // Returns the header structure for writing out to a CRX file. | |
68 const Header& header() const { return header_; } | |
69 | |
70 // Checks a valid |header| to determine whether or not the CRX represents a | |
71 // differential CRX. | |
72 static bool HeaderIsDelta(const Header& header); | |
73 | |
74 enum class ValidateError { | |
75 NONE, | |
76 CRX_FILE_NOT_READABLE, | |
77 CRX_HEADER_INVALID, | |
78 CRX_MAGIC_NUMBER_INVALID, | |
79 CRX_VERSION_NUMBER_INVALID, | |
80 CRX_EXCESSIVELY_LARGE_KEY_OR_SIGNATURE, | |
81 CRX_ZERO_KEY_LENGTH, | |
82 CRX_ZERO_SIGNATURE_LENGTH, | |
83 CRX_PUBLIC_KEY_INVALID, | |
84 CRX_SIGNATURE_INVALID, | |
85 CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED, | |
86 CRX_SIGNATURE_VERIFICATION_FAILED, | |
87 CRX_HASH_VERIFICATION_FAILED, | |
88 }; | |
89 | |
90 // Validates that the .crx file at |crx_path| is properly signed. If | |
91 // |expected_hash| is non-empty, it should specify a hex-encoded SHA256 hash | |
92 // for the entire .crx file which will be checked as we read it, and any | |
93 // mismatch will cause a CRX_HASH_VERIFICATION_FAILED result. The | |
94 // |public_key| argument can be provided to receive a copy of the | |
95 // base64-encoded public key pem bytes extracted from the .crx. The | |
96 // |extension_id| argument can be provided to receive the extension id (which | |
97 // is computed as a hash of the public key provided in the .crx). The | |
98 // |header| argument can be provided to receive a copy of the crx header. | |
99 static ValidateError ValidateSignature(const base::FilePath& crx_path, | |
100 const std::string& expected_hash, | |
101 std::string* public_key, | |
102 std::string* extension_id, | |
103 CrxFile::Header* header); | |
104 | |
105 private: | |
106 Header header_; | |
107 | |
108 // Constructor is private. Clients should use static factory methods above. | |
109 explicit CrxFile(const Header& header); | |
110 | |
111 // Checks the |header| for validity and returns true if the values are valid. | |
112 // If false is returned, more detailed error code is returned in |error|. | |
113 static bool HeaderIsValid(const Header& header, Error* error); | |
114 }; | |
115 | |
116 } // namespace crx_file | |
117 | |
118 #endif // COMPONENTS_CRX_FILE_CRX_FILE_H_ | |
OLD | NEW |