| 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 |