OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/install_signer.h" | 5 #include "chrome/browser/extensions/install_signer.h" |
6 | 6 |
7 #include "base/base64.h" | 7 #include "base/base64.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
(...skipping 30 matching lines...) Expand all Loading... | |
41 using extensions::ExtensionIdSet; | 41 using extensions::ExtensionIdSet; |
42 | 42 |
43 const char kExpireDateKey[] = "expire_date"; | 43 const char kExpireDateKey[] = "expire_date"; |
44 const char kExpiryKey[] = "expiry"; | 44 const char kExpiryKey[] = "expiry"; |
45 const char kHashKey[] = "hash"; | 45 const char kHashKey[] = "hash"; |
46 const char kIdsKey[] = "ids"; | 46 const char kIdsKey[] = "ids"; |
47 const char kInvalidIdsKey[] = "invalid_ids"; | 47 const char kInvalidIdsKey[] = "invalid_ids"; |
48 const char kProtocolVersionKey[] = "protocol_version"; | 48 const char kProtocolVersionKey[] = "protocol_version"; |
49 const char kSaltKey[] = "salt"; | 49 const char kSaltKey[] = "salt"; |
50 const char kSignatureKey[] = "signature"; | 50 const char kSignatureKey[] = "signature"; |
51 const char kTimestampKey[] = "timestamp"; | |
51 | 52 |
52 const size_t kSaltBytes = 32; | 53 const size_t kSaltBytes = 32; |
53 | 54 |
54 const char kBackendUrl[] = | 55 const char kBackendUrl[] = |
55 "https://www.googleapis.com/chromewebstore/v1.1/items/verify"; | 56 "https://www.googleapis.com/chromewebstore/v1.1/items/verify"; |
56 | 57 |
57 const char kPublicKeyPEM[] = \ | 58 const char kPublicKeyPEM[] = \ |
58 "-----BEGIN PUBLIC KEY-----" \ | 59 "-----BEGIN PUBLIC KEY-----" \ |
59 "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj/u/XDdjlDyw7gHEtaaa" \ | 60 "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj/u/XDdjlDyw7gHEtaaa" \ |
60 "sZ9GdG8WOKAyJzXd8HFrDtz2Jcuy7er7MtWvHgNDA0bwpznbI5YdZeV4UfCEsA4S" \ | 61 "sZ9GdG8WOKAyJzXd8HFrDtz2Jcuy7er7MtWvHgNDA0bwpznbI5YdZeV4UfCEsA4S" \ |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
126 id_list->AppendString(*i); | 127 id_list->AppendString(*i); |
127 | 128 |
128 value->Set(kIdsKey, id_list); | 129 value->Set(kIdsKey, id_list); |
129 value->SetString(kExpireDateKey, expire_date); | 130 value->SetString(kExpireDateKey, expire_date); |
130 std::string salt_base64; | 131 std::string salt_base64; |
131 std::string signature_base64; | 132 std::string signature_base64; |
132 base::Base64Encode(salt, &salt_base64); | 133 base::Base64Encode(salt, &salt_base64); |
133 base::Base64Encode(signature, &signature_base64); | 134 base::Base64Encode(signature, &signature_base64); |
134 value->SetString(kSaltKey, salt_base64); | 135 value->SetString(kSaltKey, salt_base64); |
135 value->SetString(kSignatureKey, signature_base64); | 136 value->SetString(kSignatureKey, signature_base64); |
137 value->SetString(kTimestampKey, | |
138 base::Int64ToString(timestamp.ToInternalValue())); | |
136 } | 139 } |
137 | 140 |
138 // static | 141 // static |
139 scoped_ptr<InstallSignature> InstallSignature::FromValue( | 142 scoped_ptr<InstallSignature> InstallSignature::FromValue( |
140 const base::DictionaryValue& value) { | 143 const base::DictionaryValue& value) { |
141 | 144 |
142 scoped_ptr<InstallSignature> result(new InstallSignature); | 145 scoped_ptr<InstallSignature> result(new InstallSignature); |
143 | 146 |
144 std::string salt_base64; | 147 std::string salt_base64; |
145 std::string signature_base64; | 148 std::string signature_base64; |
146 if (!value.GetString(kExpireDateKey, &result->expire_date) || | 149 if (!value.GetString(kExpireDateKey, &result->expire_date) || |
147 !value.GetString(kSaltKey, &salt_base64) || | 150 !value.GetString(kSaltKey, &salt_base64) || |
148 !value.GetString(kSignatureKey, &signature_base64) || | 151 !value.GetString(kSignatureKey, &signature_base64) || |
149 !base::Base64Decode(salt_base64, &result->salt) || | 152 !base::Base64Decode(salt_base64, &result->salt) || |
150 !base::Base64Decode(signature_base64, &result->signature)) { | 153 !base::Base64Decode(signature_base64, &result->signature)) { |
151 result.reset(); | 154 result.reset(); |
152 return result.Pass(); | 155 return result.Pass(); |
153 } | 156 } |
154 | 157 |
158 // Note: earlier versions of the code did not write out a timestamp value | |
159 // so older entries will not necessarily have this. | |
160 if (value.HasKey(kTimestampKey)) { | |
161 std::string timestamp; | |
162 int64 timestamp_value = 0; | |
163 if (!value.GetString(kTimestampKey, ×tamp) || | |
164 !base::StringToInt64(timestamp, ×tamp_value)) { | |
165 result.reset(); | |
166 return result.Pass(); | |
167 } | |
168 result->timestamp = base::Time::FromInternalValue(timestamp_value); | |
169 } | |
170 | |
155 const base::ListValue* ids = NULL; | 171 const base::ListValue* ids = NULL; |
156 if (!value.GetList(kIdsKey, &ids)) { | 172 if (!value.GetList(kIdsKey, &ids)) { |
157 result.reset(); | 173 result.reset(); |
158 return result.Pass(); | 174 return result.Pass(); |
159 } | 175 } |
160 | 176 |
161 for (base::ListValue::const_iterator i = ids->begin(); i != ids->end(); ++i) { | 177 for (base::ListValue::const_iterator i = ids->begin(); i != ids->end(); ++i) { |
162 std::string id; | 178 std::string id; |
163 if (!(*i)->GetAsString(&id)) { | 179 if (!(*i)->GetAsString(&id)) { |
164 result.reset(); | 180 result.reset(); |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
430 ExtensionIdSet valid_ids = | 446 ExtensionIdSet valid_ids = |
431 base::STLSetDifference<ExtensionIdSet>(ids_, invalid_ids); | 447 base::STLSetDifference<ExtensionIdSet>(ids_, invalid_ids); |
432 | 448 |
433 scoped_ptr<InstallSignature> result; | 449 scoped_ptr<InstallSignature> result; |
434 if (!signature.empty()) { | 450 if (!signature.empty()) { |
435 result.reset(new InstallSignature); | 451 result.reset(new InstallSignature); |
436 result->ids = valid_ids; | 452 result->ids = valid_ids; |
437 result->salt = salt_; | 453 result->salt = salt_; |
438 result->signature = signature; | 454 result->signature = signature; |
439 result->expire_date = expire_date; | 455 result->expire_date = expire_date; |
456 result->timestamp = base::Time::Now(); | |
Finnur
2014/02/12 13:54:57
The timestamp you want is when you sent the reques
asargent_no_longer_on_chrome
2014/02/12 16:27:56
This is technically correct about the timestamp, a
| |
440 bool verified = VerifySignature(*result); | 457 bool verified = VerifySignature(*result); |
441 UMA_HISTOGRAM_BOOLEAN("ExtensionInstallSigner.ResultWasValid", verified); | 458 UMA_HISTOGRAM_BOOLEAN("ExtensionInstallSigner.ResultWasValid", verified); |
442 UMA_HISTOGRAM_COUNTS_100("ExtensionInstallSigner.InvalidCount", | 459 UMA_HISTOGRAM_COUNTS_100("ExtensionInstallSigner.InvalidCount", |
443 invalid_ids.size()); | 460 invalid_ids.size()); |
444 if (!verified) | 461 if (!verified) |
445 result.reset(); | 462 result.reset(); |
446 } | 463 } |
447 | 464 |
448 if (!callback_.is_null()) | 465 if (!callback_.is_null()) |
449 callback_.Run(result.Pass()); | 466 callback_.Run(result.Pass()); |
450 } | 467 } |
451 | 468 |
452 | 469 |
453 } // namespace extensions | 470 } // namespace extensions |
OLD | NEW |