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 <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 // |result|. | 85 // |result|. |
86 bool HashWithMachineId(const std::string& salt, std::string* result) { | 86 bool HashWithMachineId(const std::string& salt, std::string* result) { |
87 std::string machine_id; | 87 std::string machine_id; |
88 #if defined(ENABLE_RLZ) | 88 #if defined(ENABLE_RLZ) |
89 if (!rlz_lib::GetMachineId(&machine_id)) | 89 if (!rlz_lib::GetMachineId(&machine_id)) |
90 return false; | 90 return false; |
91 #else | 91 #else |
92 machine_id = "unknown"; | 92 machine_id = "unknown"; |
93 #endif | 93 #endif |
94 | 94 |
95 scoped_ptr<crypto::SecureHash> hash( | 95 std::unique_ptr<crypto::SecureHash> hash( |
96 crypto::SecureHash::Create(crypto::SecureHash::SHA256)); | 96 crypto::SecureHash::Create(crypto::SecureHash::SHA256)); |
97 | 97 |
98 hash->Update(machine_id.data(), machine_id.size()); | 98 hash->Update(machine_id.data(), machine_id.size()); |
99 hash->Update(salt.data(), salt.size()); | 99 hash->Update(salt.data(), salt.size()); |
100 | 100 |
101 std::string result_bytes(crypto::kSHA256Length, 0); | 101 std::string result_bytes(crypto::kSHA256Length, 0); |
102 hash->Finish(string_as_array(&result_bytes), result_bytes.size()); | 102 hash->Finish(string_as_array(&result_bytes), result_bytes.size()); |
103 | 103 |
104 base::Base64Encode(result_bytes, result); | 104 base::Base64Encode(result_bytes, result); |
105 return true; | 105 return true; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 std::string signature_base64; | 174 std::string signature_base64; |
175 base::Base64Encode(salt, &salt_base64); | 175 base::Base64Encode(salt, &salt_base64); |
176 base::Base64Encode(signature, &signature_base64); | 176 base::Base64Encode(signature, &signature_base64); |
177 value->SetString(kSaltKey, salt_base64); | 177 value->SetString(kSaltKey, salt_base64); |
178 value->SetString(kSignatureKey, signature_base64); | 178 value->SetString(kSignatureKey, signature_base64); |
179 value->SetString(kTimestampKey, | 179 value->SetString(kTimestampKey, |
180 base::Int64ToString(timestamp.ToInternalValue())); | 180 base::Int64ToString(timestamp.ToInternalValue())); |
181 } | 181 } |
182 | 182 |
183 // static | 183 // static |
184 scoped_ptr<InstallSignature> InstallSignature::FromValue( | 184 std::unique_ptr<InstallSignature> InstallSignature::FromValue( |
185 const base::DictionaryValue& value) { | 185 const base::DictionaryValue& value) { |
186 | 186 std::unique_ptr<InstallSignature> result(new InstallSignature); |
187 scoped_ptr<InstallSignature> result(new InstallSignature); | |
188 | 187 |
189 // For now we don't want to support any backwards compability, but in the | 188 // For now we don't want to support any backwards compability, but in the |
190 // future if we do, we would want to put the migration code here. | 189 // future if we do, we would want to put the migration code here. |
191 int format_version = 0; | 190 int format_version = 0; |
192 if (!value.GetInteger(kSignatureFormatVersionKey, &format_version) || | 191 if (!value.GetInteger(kSignatureFormatVersionKey, &format_version) || |
193 format_version != kSignatureFormatVersion) { | 192 format_version != kSignatureFormatVersion) { |
194 result.reset(); | 193 result.reset(); |
195 return result; | 194 return result; |
196 } | 195 } |
197 | 196 |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 void InstallSigner::GetSignature(const SignatureCallback& callback) { | 343 void InstallSigner::GetSignature(const SignatureCallback& callback) { |
345 CHECK(!url_fetcher_.get()); | 344 CHECK(!url_fetcher_.get()); |
346 CHECK(callback_.is_null()); | 345 CHECK(callback_.is_null()); |
347 CHECK(salt_.empty()); | 346 CHECK(salt_.empty()); |
348 callback_ = callback; | 347 callback_ = callback; |
349 | 348 |
350 // If the set of ids is empty, just return an empty signature and skip the | 349 // If the set of ids is empty, just return an empty signature and skip the |
351 // call to the server. | 350 // call to the server. |
352 if (ids_.empty()) { | 351 if (ids_.empty()) { |
353 if (!callback_.is_null()) | 352 if (!callback_.is_null()) |
354 callback_.Run(scoped_ptr<InstallSignature>(new InstallSignature())); | 353 callback_.Run(std::unique_ptr<InstallSignature>(new InstallSignature())); |
355 return; | 354 return; |
356 } | 355 } |
357 | 356 |
358 salt_ = std::string(kSaltBytes, 0); | 357 salt_ = std::string(kSaltBytes, 0); |
359 DCHECK_EQ(kSaltBytes, salt_.size()); | 358 DCHECK_EQ(kSaltBytes, salt_.size()); |
360 crypto::RandBytes(string_as_array(&salt_), salt_.size()); | 359 crypto::RandBytes(string_as_array(&salt_), salt_.size()); |
361 | 360 |
362 std::string hash_base64; | 361 std::string hash_base64; |
363 if (!HashWithMachineId(salt_, &hash_base64)) { | 362 if (!HashWithMachineId(salt_, &hash_base64)) { |
364 ReportErrorViaCallback(); | 363 ReportErrorViaCallback(); |
(...skipping 15 matching lines...) Expand all Loading... |
380 | 379 |
381 // The request protocol is JSON of the form: | 380 // The request protocol is JSON of the form: |
382 // { | 381 // { |
383 // "protocol_version": "1", | 382 // "protocol_version": "1", |
384 // "hash": "<base64-encoded hash value here>", | 383 // "hash": "<base64-encoded hash value here>", |
385 // "ids": [ "<id1>", "id2" ] | 384 // "ids": [ "<id1>", "id2" ] |
386 // } | 385 // } |
387 base::DictionaryValue dictionary; | 386 base::DictionaryValue dictionary; |
388 dictionary.SetInteger(kProtocolVersionKey, 1); | 387 dictionary.SetInteger(kProtocolVersionKey, 1); |
389 dictionary.SetString(kHashKey, hash_base64); | 388 dictionary.SetString(kHashKey, hash_base64); |
390 scoped_ptr<base::ListValue> id_list(new base::ListValue); | 389 std::unique_ptr<base::ListValue> id_list(new base::ListValue); |
391 for (ExtensionIdSet::const_iterator i = ids_.begin(); i != ids_.end(); ++i) { | 390 for (ExtensionIdSet::const_iterator i = ids_.begin(); i != ids_.end(); ++i) { |
392 id_list->AppendString(*i); | 391 id_list->AppendString(*i); |
393 } | 392 } |
394 dictionary.Set(kIdsKey, id_list.release()); | 393 dictionary.Set(kIdsKey, id_list.release()); |
395 std::string json; | 394 std::string json; |
396 base::JSONWriter::Write(dictionary, &json); | 395 base::JSONWriter::Write(dictionary, &json); |
397 if (json.empty()) { | 396 if (json.empty()) { |
398 ReportErrorViaCallback(); | 397 ReportErrorViaCallback(); |
399 return; | 398 return; |
400 } | 399 } |
401 url_fetcher_->SetUploadData("application/json", json); | 400 url_fetcher_->SetUploadData("application/json", json); |
402 LogRequestStartHistograms(); | 401 LogRequestStartHistograms(); |
403 request_start_time_ = base::Time::Now(); | 402 request_start_time_ = base::Time::Now(); |
404 VLOG(1) << "Sending request: " << json; | 403 VLOG(1) << "Sending request: " << json; |
405 url_fetcher_->Start(); | 404 url_fetcher_->Start(); |
406 } | 405 } |
407 | 406 |
408 void InstallSigner::ReportErrorViaCallback() { | 407 void InstallSigner::ReportErrorViaCallback() { |
409 InstallSignature* null_signature = NULL; | 408 InstallSignature* null_signature = NULL; |
410 if (!callback_.is_null()) | 409 if (!callback_.is_null()) |
411 callback_.Run(scoped_ptr<InstallSignature>(null_signature)); | 410 callback_.Run(std::unique_ptr<InstallSignature>(null_signature)); |
412 } | 411 } |
413 | 412 |
414 void InstallSigner::ParseFetchResponse() { | 413 void InstallSigner::ParseFetchResponse() { |
415 bool fetch_success = url_fetcher_->GetStatus().is_success(); | 414 bool fetch_success = url_fetcher_->GetStatus().is_success(); |
416 UMA_HISTOGRAM_BOOLEAN("ExtensionInstallSigner.FetchSuccess", fetch_success); | 415 UMA_HISTOGRAM_BOOLEAN("ExtensionInstallSigner.FetchSuccess", fetch_success); |
417 | 416 |
418 std::string response; | 417 std::string response; |
419 if (fetch_success) { | 418 if (fetch_success) { |
420 if (!url_fetcher_->GetResponseAsString(&response)) | 419 if (!url_fetcher_->GetResponseAsString(&response)) |
421 response.clear(); | 420 response.clear(); |
(...skipping 10 matching lines...) Expand all Loading... |
432 // { | 431 // { |
433 // "protocol_version": "1", | 432 // "protocol_version": "1", |
434 // "signature": "<base64-encoded signature>", | 433 // "signature": "<base64-encoded signature>", |
435 // "expiry": "<date in YYYY-MM-DD form>", | 434 // "expiry": "<date in YYYY-MM-DD form>", |
436 // "invalid_ids": [ "<id3>", "<id4>" ] | 435 // "invalid_ids": [ "<id3>", "<id4>" ] |
437 // } | 436 // } |
438 // where |invalid_ids| is a list of ids from the original request that | 437 // where |invalid_ids| is a list of ids from the original request that |
439 // could not be verified to be in the webstore. | 438 // could not be verified to be in the webstore. |
440 | 439 |
441 base::DictionaryValue* dictionary = NULL; | 440 base::DictionaryValue* dictionary = NULL; |
442 scoped_ptr<base::Value> parsed = base::JSONReader::Read(response); | 441 std::unique_ptr<base::Value> parsed = base::JSONReader::Read(response); |
443 bool json_success = parsed.get() && parsed->GetAsDictionary(&dictionary); | 442 bool json_success = parsed.get() && parsed->GetAsDictionary(&dictionary); |
444 UMA_HISTOGRAM_BOOLEAN("ExtensionInstallSigner.ParseJsonSuccess", | 443 UMA_HISTOGRAM_BOOLEAN("ExtensionInstallSigner.ParseJsonSuccess", |
445 json_success); | 444 json_success); |
446 if (!json_success) { | 445 if (!json_success) { |
447 ReportErrorViaCallback(); | 446 ReportErrorViaCallback(); |
448 return; | 447 return; |
449 } | 448 } |
450 | 449 |
451 int protocol_version = 0; | 450 int protocol_version = 0; |
452 std::string signature_base64; | 451 std::string signature_base64; |
(...skipping 30 matching lines...) Expand all Loading... |
483 | 482 |
484 HandleSignatureResult(signature, expire_date, invalid_ids); | 483 HandleSignatureResult(signature, expire_date, invalid_ids); |
485 } | 484 } |
486 | 485 |
487 void InstallSigner::HandleSignatureResult(const std::string& signature, | 486 void InstallSigner::HandleSignatureResult(const std::string& signature, |
488 const std::string& expire_date, | 487 const std::string& expire_date, |
489 const ExtensionIdSet& invalid_ids) { | 488 const ExtensionIdSet& invalid_ids) { |
490 ExtensionIdSet valid_ids = | 489 ExtensionIdSet valid_ids = |
491 base::STLSetDifference<ExtensionIdSet>(ids_, invalid_ids); | 490 base::STLSetDifference<ExtensionIdSet>(ids_, invalid_ids); |
492 | 491 |
493 scoped_ptr<InstallSignature> result; | 492 std::unique_ptr<InstallSignature> result; |
494 if (!signature.empty()) { | 493 if (!signature.empty()) { |
495 result.reset(new InstallSignature); | 494 result.reset(new InstallSignature); |
496 result->ids = valid_ids; | 495 result->ids = valid_ids; |
497 result->invalid_ids = invalid_ids; | 496 result->invalid_ids = invalid_ids; |
498 result->salt = salt_; | 497 result->salt = salt_; |
499 result->signature = signature; | 498 result->signature = signature; |
500 result->expire_date = expire_date; | 499 result->expire_date = expire_date; |
501 result->timestamp = request_start_time_; | 500 result->timestamp = request_start_time_; |
502 bool verified = VerifySignature(*result); | 501 bool verified = VerifySignature(*result); |
503 UMA_HISTOGRAM_BOOLEAN("ExtensionInstallSigner.ResultWasValid", verified); | 502 UMA_HISTOGRAM_BOOLEAN("ExtensionInstallSigner.ResultWasValid", verified); |
504 UMA_HISTOGRAM_COUNTS_100("ExtensionInstallSigner.InvalidCount", | 503 UMA_HISTOGRAM_COUNTS_100("ExtensionInstallSigner.InvalidCount", |
505 invalid_ids.size()); | 504 invalid_ids.size()); |
506 if (!verified) | 505 if (!verified) |
507 result.reset(); | 506 result.reset(); |
508 } | 507 } |
509 | 508 |
510 if (!callback_.is_null()) | 509 if (!callback_.is_null()) |
511 callback_.Run(std::move(result)); | 510 callback_.Run(std::move(result)); |
512 } | 511 } |
513 | 512 |
514 | 513 |
515 } // namespace extensions | 514 } // namespace extensions |
OLD | NEW |