[email protected] | 1df24d0a | 2014-01-20 21:29:59 | [diff] [blame] | 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 | |
blundell | 0b2305c | 2015-08-25 15:54:42 | [diff] [blame^] | 5 | #ifndef COMPONENTS_VARIATIONS_VARIATIONS_SEED_STORE_H_ |
| 6 | #define COMPONENTS_VARIATIONS_VARIATIONS_SEED_STORE_H_ |
[email protected] | 1df24d0a | 2014-01-20 21:29:59 | [diff] [blame] | 7 | |
| 8 | #include <string> |
| 9 | |
| 10 | #include "base/compiler_specific.h" |
[email protected] | c69b6c1 | 2014-03-07 20:32:36 | [diff] [blame] | 11 | #include "base/gtest_prod_util.h" |
[email protected] | 1df24d0a | 2014-01-20 21:29:59 | [diff] [blame] | 12 | #include "base/time/time.h" |
| 13 | |
| 14 | class PrefService; |
| 15 | class PrefRegistrySimple; |
| 16 | |
[email protected] | 59b6f67 | 2014-07-26 18:35:47 | [diff] [blame] | 17 | namespace variations { |
[email protected] | 24afce1 | 2014-07-25 21:00:31 | [diff] [blame] | 18 | class VariationsSeed; |
[email protected] | 59b6f67 | 2014-07-26 18:35:47 | [diff] [blame] | 19 | } |
| 20 | |
| 21 | namespace chrome_variations { |
[email protected] | 24afce1 | 2014-07-25 21:00:31 | [diff] [blame] | 22 | |
[email protected] | 1df24d0a | 2014-01-20 21:29:59 | [diff] [blame] | 23 | // VariationsSeedStore is a helper class for reading and writing the variations |
| 24 | // seed from Local State. |
| 25 | class VariationsSeedStore { |
| 26 | public: |
| 27 | explicit VariationsSeedStore(PrefService* local_state); |
| 28 | virtual ~VariationsSeedStore(); |
| 29 | |
| 30 | // Loads the variations seed data from local state into |seed|. If there is a |
| 31 | // problem with loading, the pref value is cleared and false is returned. If |
| 32 | // successful, |seed| will contain the loaded data and true is returned. |
[email protected] | 59b6f67 | 2014-07-26 18:35:47 | [diff] [blame] | 33 | bool LoadSeed(variations::VariationsSeed* seed); |
[email protected] | 1df24d0a | 2014-01-20 21:29:59 | [diff] [blame] | 34 | |
asvitkine | b24f4559 | 2015-08-07 02:57:25 | [diff] [blame] | 35 | // Stores the given seed |data| (serialized protobuf) to local state, along |
[email protected] | 54af732e | 2014-01-23 22:20:39 | [diff] [blame] | 36 | // with a base64-encoded digital signature for seed and the date when it was |
asvitkine | b24f4559 | 2015-08-07 02:57:25 | [diff] [blame] | 37 | // fetched. If |is_delta_compressed| is true, treats |data| as being delta |
| 38 | // compressed and attempts to decode it first using the store's seed data. |
| 39 | // The actual seed data will be base64 encoded for storage. If the string |
| 40 | // is invalid, the existing prefs are untouched and false is returned. |
| 41 | // Additionally, stores the |country_code| that was received with the seed in |
| 42 | // a separate pref. On success and if |parsed_seed| is not NULL, |parsed_seed| |
| 43 | // will be filled with the de-serialized decoded protobuf. |
| 44 | bool StoreSeedData(const std::string& data, |
[email protected] | 54af732e | 2014-01-23 22:20:39 | [diff] [blame] | 45 | const std::string& base64_seed_signature, |
asvitkine | b24f4559 | 2015-08-07 02:57:25 | [diff] [blame] | 46 | const std::string& country_code, |
[email protected] | 6839813b | 2014-05-12 22:49:40 | [diff] [blame] | 47 | const base::Time& date_fetched, |
asvitkine | b24f4559 | 2015-08-07 02:57:25 | [diff] [blame] | 48 | bool is_delta_compressed, |
[email protected] | 59b6f67 | 2014-07-26 18:35:47 | [diff] [blame] | 49 | variations::VariationsSeed* parsed_seed); |
[email protected] | 1df24d0a | 2014-01-20 21:29:59 | [diff] [blame] | 50 | |
[email protected] | 344c623a | 2014-03-11 20:29:39 | [diff] [blame] | 51 | // Updates |kVariationsSeedDate| and logs when previous date was from a |
| 52 | // different day. |
| 53 | void UpdateSeedDateAndLogDayChange(const base::Time& server_date_fetched); |
| 54 | |
[email protected] | 1df24d0a | 2014-01-20 21:29:59 | [diff] [blame] | 55 | // Returns the serial number of the last loaded or stored seed. |
| 56 | const std::string& variations_serial_number() const { |
| 57 | return variations_serial_number_; |
| 58 | } |
| 59 | |
asvitkine | b24f4559 | 2015-08-07 02:57:25 | [diff] [blame] | 60 | // Returns whether the last loaded or stored seed has the country field set. |
| 61 | bool seed_has_country_code() const { |
| 62 | return seed_has_country_code_; |
| 63 | } |
[email protected] | 1df24d0a | 2014-01-20 21:29:59 | [diff] [blame] | 64 | |
grt | 7d52139 | 2014-12-15 18:04:29 | [diff] [blame] | 65 | // Returns the invalid signature in base64 format, or an empty string if the |
| 66 | // signature was valid, missing, or if signature verification is disabled. |
| 67 | std::string GetInvalidSignature() const; |
| 68 | |
asvitkine | b24f4559 | 2015-08-07 02:57:25 | [diff] [blame] | 69 | // Registers Local State prefs used by this class. |
| 70 | static void RegisterPrefs(PrefRegistrySimple* registry); |
| 71 | |
[email protected] | c69b6c1 | 2014-03-07 20:32:36 | [diff] [blame] | 72 | protected: |
| 73 | // Note: UMA histogram enum - don't re-order or remove entries. |
| 74 | enum VerifySignatureResult { |
| 75 | VARIATIONS_SEED_SIGNATURE_MISSING, |
| 76 | VARIATIONS_SEED_SIGNATURE_DECODE_FAILED, |
| 77 | VARIATIONS_SEED_SIGNATURE_INVALID_SIGNATURE, |
| 78 | VARIATIONS_SEED_SIGNATURE_INVALID_SEED, |
| 79 | VARIATIONS_SEED_SIGNATURE_VALID, |
| 80 | VARIATIONS_SEED_SIGNATURE_ENUM_SIZE, |
| 81 | }; |
| 82 | |
| 83 | // Verifies a variations seed (the serialized proto bytes) with the specified |
| 84 | // base-64 encoded signature that was received from the server and returns the |
| 85 | // result. The signature is assumed to be an "ECDSA with SHA-256" signature |
| 86 | // (see kECDSAWithSHA256AlgorithmID in the .cc file). Returns the result of |
| 87 | // signature verification or VARIATIONS_SEED_SIGNATURE_ENUM_SIZE if signature |
| 88 | // verification is not enabled. |
| 89 | virtual VariationsSeedStore::VerifySignatureResult VerifySeedSignature( |
| 90 | const std::string& seed_bytes, |
| 91 | const std::string& base64_seed_signature); |
| 92 | |
[email protected] | 1df24d0a | 2014-01-20 21:29:59 | [diff] [blame] | 93 | private: |
[email protected] | c69b6c1 | 2014-03-07 20:32:36 | [diff] [blame] | 94 | FRIEND_TEST_ALL_PREFIXES(VariationsSeedStoreTest, VerifySeedSignature); |
asvitkine | b24f4559 | 2015-08-07 02:57:25 | [diff] [blame] | 95 | FRIEND_TEST_ALL_PREFIXES(VariationsSeedStoreTest, ApplyDeltaPatch); |
[email protected] | c69b6c1 | 2014-03-07 20:32:36 | [diff] [blame] | 96 | |
[email protected] | 54af732e | 2014-01-23 22:20:39 | [diff] [blame] | 97 | // Clears all prefs related to variations seed storage. |
| 98 | void ClearPrefs(); |
| 99 | |
asvitkine | 5ea32c5 | 2015-02-12 01:23:11 | [diff] [blame] | 100 | // Reads the variations seed data from prefs; returns true on success. |
| 101 | bool ReadSeedData(std::string* seed_data); |
| 102 | |
asvitkine | b24f4559 | 2015-08-07 02:57:25 | [diff] [blame] | 103 | // Internal version of |StoreSeedData()| that assumes |seed_data| is not delta |
| 104 | // compressed. |
| 105 | bool StoreSeedDataNoDelta( |
| 106 | const std::string& seed_data, |
| 107 | const std::string& base64_seed_signature, |
| 108 | const std::string& country_code, |
| 109 | const base::Time& date_fetched, |
| 110 | variations::VariationsSeed* parsed_seed); |
| 111 | |
| 112 | // Applies a delta-compressed |patch| to |existing_data|, producing the result |
| 113 | // in |output|. Returns whether the operation was successful. |
| 114 | static bool ApplyDeltaPatch(const std::string& existing_data, |
| 115 | const std::string& patch, |
| 116 | std::string* output); |
| 117 | |
[email protected] | 1df24d0a | 2014-01-20 21:29:59 | [diff] [blame] | 118 | // The pref service used to persist the variations seed. |
| 119 | PrefService* local_state_; |
| 120 | |
| 121 | // Cached serial number from the most recently fetched variations seed. |
| 122 | std::string variations_serial_number_; |
| 123 | |
asvitkine | b24f4559 | 2015-08-07 02:57:25 | [diff] [blame] | 124 | // Whether the most recently fetched variations seed has the country code |
| 125 | // field set. |
| 126 | bool seed_has_country_code_; |
| 127 | |
grt | 7d52139 | 2014-12-15 18:04:29 | [diff] [blame] | 128 | // Keeps track of an invalid signature. |
| 129 | std::string invalid_base64_signature_; |
| 130 | |
[email protected] | 1df24d0a | 2014-01-20 21:29:59 | [diff] [blame] | 131 | DISALLOW_COPY_AND_ASSIGN(VariationsSeedStore); |
| 132 | }; |
| 133 | |
| 134 | } // namespace chrome_variations |
| 135 | |
blundell | 0b2305c | 2015-08-25 15:54:42 | [diff] [blame^] | 136 | #endif // COMPONENTS_VARIATIONS_VARIATIONS_SEED_STORE_H_ |