[email protected] | ffd2f79e | 2013-11-14 00:11:46 | [diff] [blame] | 1 | // Copyright 2013 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 CHROME_BROWSER_EXTENSIONS_INSTALL_SIGNER_H_ |
| 6 | #define CHROME_BROWSER_EXTENSIONS_INSTALL_SIGNER_H_ |
| 7 | |
dcheng | c963c714 | 2016-04-08 03:55:22 | [diff] [blame] | 8 | #include <memory> |
[email protected] | ffd2f79e | 2013-11-14 00:11:46 | [diff] [blame] | 9 | #include <set> |
| 10 | #include <string> |
| 11 | #include <vector> |
| 12 | |
[email protected] | ffd2f79e | 2013-11-14 00:11:46 | [diff] [blame] | 13 | #include "base/callback.h" |
avi | a2f4804a | 2015-12-24 23:11:13 | [diff] [blame] | 14 | #include "base/macros.h" |
Devlin Cronin | 06087655 | 2020-01-06 22:20:39 | [diff] [blame] | 15 | #include "extensions/common/extension_id.h" |
[email protected] | ffd2f79e | 2013-11-14 00:11:46 | [diff] [blame] | 16 | |
| 17 | namespace base { |
| 18 | class DictionaryValue; |
| 19 | } |
| 20 | |
Antonio Gomes | cfd0d89 | 2018-05-12 12:58:25 | [diff] [blame] | 21 | namespace network { |
| 22 | class SimpleURLLoader; |
| 23 | class SharedURLLoaderFactory; |
| 24 | } // namespace network |
[email protected] | ffd2f79e | 2013-11-14 00:11:46 | [diff] [blame] | 25 | |
| 26 | namespace extensions { |
| 27 | |
| 28 | // This represents a list of ids signed with a private key using an algorithm |
| 29 | // that includes some salt bytes. |
| 30 | struct InstallSignature { |
| 31 | // The set of ids that have been signed. |
| 32 | ExtensionIdSet ids; |
| 33 | |
| 34 | // Both of these are just arrays of bytes, NOT base64-encoded. |
| 35 | std::string salt; |
| 36 | std::string signature; |
| 37 | |
| 38 | // The date that the signature should expire, in YYYY-MM-DD format. |
| 39 | std::string expire_date; |
| 40 | |
[email protected] | 8abef23 | 2014-03-07 08:54:37 | [diff] [blame] | 41 | // The time this signature was obtained from the server. Note that this |
| 42 | // is computed locally and *not* signed by the server key. |
[email protected] | 33dc0c6 | 2014-02-13 00:00:38 | [diff] [blame] | 43 | base::Time timestamp; |
| 44 | |
[email protected] | 8abef23 | 2014-03-07 08:54:37 | [diff] [blame] | 45 | // The set of ids that the server indicated were invalid (ie not signed). |
| 46 | // Note that this is computed locally and *not* signed by the signature. |
| 47 | ExtensionIdSet invalid_ids; |
| 48 | |
[email protected] | ffd2f79e | 2013-11-14 00:11:46 | [diff] [blame] | 49 | InstallSignature(); |
vmpstr | b8aacbe | 2016-02-26 02:00:48 | [diff] [blame] | 50 | InstallSignature(const InstallSignature& other); |
[email protected] | ffd2f79e | 2013-11-14 00:11:46 | [diff] [blame] | 51 | ~InstallSignature(); |
| 52 | |
| 53 | // Helper methods for serialization to/from a base::DictionaryValue. |
| 54 | void ToValue(base::DictionaryValue* value) const; |
| 55 | |
dcheng | c963c714 | 2016-04-08 03:55:22 | [diff] [blame] | 56 | static std::unique_ptr<InstallSignature> FromValue( |
[email protected] | ffd2f79e | 2013-11-14 00:11:46 | [diff] [blame] | 57 | const base::DictionaryValue& value); |
| 58 | }; |
| 59 | |
| 60 | // Objects of this class encapsulate an operation to get a signature proving |
| 61 | // that a set of ids are hosted in the webstore. |
| 62 | class InstallSigner { |
| 63 | public: |
Devlin Cronin | efd14a1 | 2019-01-04 00:51:49 | [diff] [blame] | 64 | using SignatureCallback = |
| 65 | base::OnceCallback<void(std::unique_ptr<InstallSignature>)>; |
[email protected] | ffd2f79e | 2013-11-14 00:11:46 | [diff] [blame] | 66 | |
| 67 | // IMPORTANT NOTE: It is possible that only some, but not all, of the entries |
| 68 | // in |ids| will be successfully signed by the backend. Callers should always |
| 69 | // check the set of ids in the InstallSignature passed to their callback, as |
| 70 | // it may contain only a subset of the ids they passed in. |
Antonio Gomes | cfd0d89 | 2018-05-12 12:58:25 | [diff] [blame] | 71 | InstallSigner( |
| 72 | scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, |
| 73 | const ExtensionIdSet& ids); |
[email protected] | ffd2f79e | 2013-11-14 00:11:46 | [diff] [blame] | 74 | ~InstallSigner(); |
| 75 | |
| 76 | // Returns a set of ids that are forced to be considered not from webstore, |
| 77 | // e.g. by a command line flag used for testing. |
| 78 | static ExtensionIdSet GetForcedNotFromWebstore(); |
| 79 | |
| 80 | // Begins the process of fetching a signature from the backend. This should |
| 81 | // only be called once! If you want to get another signature, make another |
| 82 | // instance of this class. |
Devlin Cronin | efd14a1 | 2019-01-04 00:51:49 | [diff] [blame] | 83 | void GetSignature(SignatureCallback callback); |
[email protected] | ffd2f79e | 2013-11-14 00:11:46 | [diff] [blame] | 84 | |
| 85 | // Returns whether the signature in InstallSignature is properly signed with a |
| 86 | // known public key. |
| 87 | static bool VerifySignature(const InstallSignature& signature); |
| 88 | |
| 89 | private: |
[email protected] | ffd2f79e | 2013-11-14 00:11:46 | [diff] [blame] | 90 | |
[email protected] | 76f569d | 2013-12-11 21:37:20 | [diff] [blame] | 91 | // A helper function that calls |callback_| with an indication that an error |
| 92 | // happened (currently done by passing an empty pointer). |
| 93 | void ReportErrorViaCallback(); |
| 94 | |
Antonio Gomes | cfd0d89 | 2018-05-12 12:58:25 | [diff] [blame] | 95 | // Called when |simple_loader_| has returned a result to parse the response, |
[email protected] | 76f569d | 2013-12-11 21:37:20 | [diff] [blame] | 96 | // and then call HandleSignatureResult with structured data. |
Antonio Gomes | cfd0d89 | 2018-05-12 12:58:25 | [diff] [blame] | 97 | void ParseFetchResponse(std::unique_ptr<std::string> response_body); |
[email protected] | 76f569d | 2013-12-11 21:37:20 | [diff] [blame] | 98 | |
[email protected] | ffd2f79e | 2013-11-14 00:11:46 | [diff] [blame] | 99 | // Handles the result from a backend fetch. |
| 100 | void HandleSignatureResult(const std::string& signature, |
| 101 | const std::string& expire_date, |
| 102 | const ExtensionIdSet& invalid_ids); |
| 103 | |
| 104 | // The final callback for when we're done. |
| 105 | SignatureCallback callback_; |
| 106 | |
| 107 | // The current set of ids we're trying to verify. This may contain fewer ids |
| 108 | // than we started with. |
| 109 | ExtensionIdSet ids_; |
| 110 | |
| 111 | // An array of random bytes used as an input to hash with the machine id, |
| 112 | // which will need to be persisted in the eventual InstallSignature we get. |
| 113 | std::string salt_; |
| 114 | |
| 115 | // These are used to make the call to a backend server for a signature. |
Antonio Gomes | cfd0d89 | 2018-05-12 12:58:25 | [diff] [blame] | 116 | scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; |
| 117 | // The underlying SimpleURLLoader which does the actual load. |
| 118 | std::unique_ptr<network::SimpleURLLoader> simple_loader_; |
[email protected] | ffd2f79e | 2013-11-14 00:11:46 | [diff] [blame] | 119 | |
[email protected] | 33dc0c6 | 2014-02-13 00:00:38 | [diff] [blame] | 120 | // The time the request to the server was started. |
| 121 | base::Time request_start_time_; |
| 122 | |
[email protected] | ffd2f79e | 2013-11-14 00:11:46 | [diff] [blame] | 123 | DISALLOW_COPY_AND_ASSIGN(InstallSigner); |
| 124 | }; |
| 125 | |
| 126 | } // namespace extensions |
| 127 | |
| 128 | #endif // CHROME_BROWSER_EXTENSIONS_INSTALL_SIGNER_H_ |