OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 "components/variations/variations_seed_store.h" | 5 #include "components/variations/variations_seed_store.h" |
6 | 6 |
| 7 #include <stdint.h> |
| 8 |
7 #include "base/base64.h" | 9 #include "base/base64.h" |
| 10 #include "base/macros.h" |
8 #include "base/metrics/histogram_macros.h" | 11 #include "base/metrics/histogram_macros.h" |
9 #include "base/numerics/safe_math.h" | 12 #include "base/numerics/safe_math.h" |
10 #include "base/prefs/pref_registry_simple.h" | 13 #include "base/prefs/pref_registry_simple.h" |
11 #include "base/prefs/pref_service.h" | 14 #include "base/prefs/pref_service.h" |
12 #include "base/sha1.h" | 15 #include "base/sha1.h" |
13 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
| 17 #include "build/build_config.h" |
14 #include "components/compression/compression_utils.h" | 18 #include "components/compression/compression_utils.h" |
15 #include "components/variations/pref_names.h" | 19 #include "components/variations/pref_names.h" |
16 #include "components/variations/proto/variations_seed.pb.h" | 20 #include "components/variations/proto/variations_seed.pb.h" |
17 #include "crypto/signature_verifier.h" | 21 #include "crypto/signature_verifier.h" |
18 #include "third_party/protobuf/src/google/protobuf/io/coded_stream.h" | 22 #include "third_party/protobuf/src/google/protobuf/io/coded_stream.h" |
19 | 23 |
20 #if defined(OS_ANDROID) | 24 #if defined(OS_ANDROID) |
21 #include "components/variations/android/variations_seed_bridge.h" | 25 #include "components/variations/android/variations_seed_bridge.h" |
22 #endif // OS_ANDROID | 26 #endif // OS_ANDROID |
23 | 27 |
(...skipping 16 matching lines...) Expand all Loading... |
40 // ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2) | 44 // ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2) |
41 // us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 } | 45 // us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 } |
42 // ... | 46 // ... |
43 // When the ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-SHA384, or | 47 // When the ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-SHA384, or |
44 // ecdsa-with-SHA512 algorithm identifier appears in the algorithm field | 48 // ecdsa-with-SHA512 algorithm identifier appears in the algorithm field |
45 // as an AlgorithmIdentifier, the encoding MUST omit the parameters | 49 // as an AlgorithmIdentifier, the encoding MUST omit the parameters |
46 // field. That is, the AlgorithmIdentifier SHALL be a SEQUENCE of one | 50 // field. That is, the AlgorithmIdentifier SHALL be a SEQUENCE of one |
47 // component, the OID ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with- | 51 // component, the OID ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with- |
48 // SHA384, or ecdsa-with-SHA512. | 52 // SHA384, or ecdsa-with-SHA512. |
49 // See also RFC 5480, Appendix A. | 53 // See also RFC 5480, Appendix A. |
50 const uint8 kECDSAWithSHA256AlgorithmID[] = { | 54 const uint8_t kECDSAWithSHA256AlgorithmID[] = { |
51 0x30, 0x0a, | 55 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, |
52 0x06, 0x08, | |
53 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, | |
54 }; | 56 }; |
55 | 57 |
56 // The ECDSA public key of the variations server for verifying variations seed | 58 // The ECDSA public key of the variations server for verifying variations seed |
57 // signatures. | 59 // signatures. |
58 const uint8_t kPublicKey[] = { | 60 const uint8_t kPublicKey[] = { |
59 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, | 61 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, |
60 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, | 62 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, |
61 0x04, 0x51, 0x7c, 0x31, 0x4b, 0x50, 0x42, 0xdd, 0x59, 0xda, 0x0b, 0xfa, 0x43, | 63 0x04, 0x51, 0x7c, 0x31, 0x4b, 0x50, 0x42, 0xdd, 0x59, 0xda, 0x0b, 0xfa, 0x43, |
62 0x44, 0x33, 0x7c, 0x5f, 0xa1, 0x0b, 0xd5, 0x82, 0xf6, 0xac, 0x04, 0x19, 0x72, | 64 0x44, 0x33, 0x7c, 0x5f, 0xa1, 0x0b, 0xd5, 0x82, 0xf6, 0xac, 0x04, 0x19, 0x72, |
63 0x6c, 0x40, 0xd4, 0x3e, 0x56, 0xe2, 0xa0, 0x80, 0xa0, 0x41, 0xb3, 0x23, 0x7b, | 65 0x6c, 0x40, 0xd4, 0x3e, 0x56, 0xe2, 0xa0, 0x80, 0xa0, 0x41, 0xb3, 0x23, 0x7b, |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 RecordSeedStoreHistogram(VARIATIONS_SEED_STORE_FAILED_DELTA_STORE); | 290 RecordSeedStoreHistogram(VARIATIONS_SEED_STORE_FAILED_DELTA_STORE); |
289 } | 291 } |
290 return result; | 292 return result; |
291 } | 293 } |
292 | 294 |
293 void VariationsSeedStore::UpdateSeedDateAndLogDayChange( | 295 void VariationsSeedStore::UpdateSeedDateAndLogDayChange( |
294 const base::Time& server_date_fetched) { | 296 const base::Time& server_date_fetched) { |
295 VariationsSeedDateChangeState date_change = SEED_DATE_NO_OLD_DATE; | 297 VariationsSeedDateChangeState date_change = SEED_DATE_NO_OLD_DATE; |
296 | 298 |
297 if (local_state_->HasPrefPath(prefs::kVariationsSeedDate)) { | 299 if (local_state_->HasPrefPath(prefs::kVariationsSeedDate)) { |
298 const int64 stored_date_value = | 300 const int64_t stored_date_value = |
299 local_state_->GetInt64(prefs::kVariationsSeedDate); | 301 local_state_->GetInt64(prefs::kVariationsSeedDate); |
300 const base::Time stored_date = | 302 const base::Time stored_date = |
301 base::Time::FromInternalValue(stored_date_value); | 303 base::Time::FromInternalValue(stored_date_value); |
302 | 304 |
303 date_change = GetSeedDateChangeState(server_date_fetched, stored_date); | 305 date_change = GetSeedDateChangeState(server_date_fetched, stored_date); |
304 } | 306 } |
305 | 307 |
306 UMA_HISTOGRAM_ENUMERATION("Variations.SeedDateChange", date_change, | 308 UMA_HISTOGRAM_ENUMERATION("Variations.SeedDateChange", date_change, |
307 SEED_DATE_ENUM_SIZE); | 309 SEED_DATE_ENUM_SIZE); |
308 | 310 |
(...skipping 25 matching lines...) Expand all Loading... |
334 if (base64_seed_signature.empty()) | 336 if (base64_seed_signature.empty()) |
335 return VARIATIONS_SEED_SIGNATURE_MISSING; | 337 return VARIATIONS_SEED_SIGNATURE_MISSING; |
336 | 338 |
337 std::string signature; | 339 std::string signature; |
338 if (!base::Base64Decode(base64_seed_signature, &signature)) | 340 if (!base::Base64Decode(base64_seed_signature, &signature)) |
339 return VARIATIONS_SEED_SIGNATURE_DECODE_FAILED; | 341 return VARIATIONS_SEED_SIGNATURE_DECODE_FAILED; |
340 | 342 |
341 crypto::SignatureVerifier verifier; | 343 crypto::SignatureVerifier verifier; |
342 if (!verifier.VerifyInit( | 344 if (!verifier.VerifyInit( |
343 kECDSAWithSHA256AlgorithmID, sizeof(kECDSAWithSHA256AlgorithmID), | 345 kECDSAWithSHA256AlgorithmID, sizeof(kECDSAWithSHA256AlgorithmID), |
344 reinterpret_cast<const uint8*>(signature.data()), signature.size(), | 346 reinterpret_cast<const uint8_t*>(signature.data()), signature.size(), |
345 kPublicKey, arraysize(kPublicKey))) { | 347 kPublicKey, arraysize(kPublicKey))) { |
346 return VARIATIONS_SEED_SIGNATURE_INVALID_SIGNATURE; | 348 return VARIATIONS_SEED_SIGNATURE_INVALID_SIGNATURE; |
347 } | 349 } |
348 | 350 |
349 verifier.VerifyUpdate(reinterpret_cast<const uint8*>(seed_bytes.data()), | 351 verifier.VerifyUpdate(reinterpret_cast<const uint8_t*>(seed_bytes.data()), |
350 seed_bytes.size()); | 352 seed_bytes.size()); |
351 if (verifier.VerifyFinal()) | 353 if (verifier.VerifyFinal()) |
352 return VARIATIONS_SEED_SIGNATURE_VALID; | 354 return VARIATIONS_SEED_SIGNATURE_VALID; |
353 return VARIATIONS_SEED_SIGNATURE_INVALID_SEED; | 355 return VARIATIONS_SEED_SIGNATURE_INVALID_SEED; |
354 } | 356 } |
355 | 357 |
356 void VariationsSeedStore::ClearPrefs() { | 358 void VariationsSeedStore::ClearPrefs() { |
357 local_state_->ClearPref(prefs::kVariationsCompressedSeed); | 359 local_state_->ClearPref(prefs::kVariationsCompressedSeed); |
358 local_state_->ClearPref(prefs::kVariationsSeed); | 360 local_state_->ClearPref(prefs::kVariationsSeed); |
359 local_state_->ClearPref(prefs::kVariationsSeedDate); | 361 local_state_->ClearPref(prefs::kVariationsSeedDate); |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 return true; | 497 return true; |
496 } | 498 } |
497 | 499 |
498 // static | 500 // static |
499 bool VariationsSeedStore::ApplyDeltaPatch(const std::string& existing_data, | 501 bool VariationsSeedStore::ApplyDeltaPatch(const std::string& existing_data, |
500 const std::string& patch, | 502 const std::string& patch, |
501 std::string* output) { | 503 std::string* output) { |
502 output->clear(); | 504 output->clear(); |
503 | 505 |
504 google::protobuf::io::CodedInputStream in( | 506 google::protobuf::io::CodedInputStream in( |
505 reinterpret_cast<const uint8*>(patch.data()), patch.length()); | 507 reinterpret_cast<const uint8_t*>(patch.data()), patch.length()); |
506 // Temporary string declared outside the loop so it can be re-used between | 508 // Temporary string declared outside the loop so it can be re-used between |
507 // different iterations (rather than allocating new ones). | 509 // different iterations (rather than allocating new ones). |
508 std::string temp; | 510 std::string temp; |
509 | 511 |
510 const uint32 existing_data_size = static_cast<uint32>(existing_data.size()); | 512 const uint32_t existing_data_size = |
| 513 static_cast<uint32_t>(existing_data.size()); |
511 while (in.CurrentPosition() != static_cast<int>(patch.length())) { | 514 while (in.CurrentPosition() != static_cast<int>(patch.length())) { |
512 uint32 value; | 515 uint32_t value; |
513 if (!in.ReadVarint32(&value)) | 516 if (!in.ReadVarint32(&value)) |
514 return false; | 517 return false; |
515 | 518 |
516 if (value != 0) { | 519 if (value != 0) { |
517 // A non-zero value indicates the number of bytes to copy from the patch | 520 // A non-zero value indicates the number of bytes to copy from the patch |
518 // stream to the output. | 521 // stream to the output. |
519 | 522 |
520 // No need to guard against bad data (i.e. very large |value|) because the | 523 // No need to guard against bad data (i.e. very large |value|) because the |
521 // call below will fail if |value| is greater than the size of the patch. | 524 // call below will fail if |value| is greater than the size of the patch. |
522 if (!in.ReadString(&temp, value)) | 525 if (!in.ReadString(&temp, value)) |
523 return false; | 526 return false; |
524 output->append(temp); | 527 output->append(temp); |
525 } else { | 528 } else { |
526 // Otherwise, when it's zero, it indicates that it's followed by a pair of | 529 // Otherwise, when it's zero, it indicates that it's followed by a pair of |
527 // numbers - |offset| and |length| that specify a range of data to copy | 530 // numbers - |offset| and |length| that specify a range of data to copy |
528 // from |existing_data|. | 531 // from |existing_data|. |
529 uint32 offset; | 532 uint32_t offset; |
530 uint32 length; | 533 uint32_t length; |
531 if (!in.ReadVarint32(&offset) || !in.ReadVarint32(&length)) | 534 if (!in.ReadVarint32(&offset) || !in.ReadVarint32(&length)) |
532 return false; | 535 return false; |
533 | 536 |
534 // Check for |offset + length| being out of range and for overflow. | 537 // Check for |offset + length| being out of range and for overflow. |
535 base::CheckedNumeric<uint32> end_offset(offset); | 538 base::CheckedNumeric<uint32_t> end_offset(offset); |
536 end_offset += length; | 539 end_offset += length; |
537 if (!end_offset.IsValid() || end_offset.ValueOrDie() > existing_data_size) | 540 if (!end_offset.IsValid() || end_offset.ValueOrDie() > existing_data_size) |
538 return false; | 541 return false; |
539 output->append(existing_data, offset, length); | 542 output->append(existing_data, offset, length); |
540 } | 543 } |
541 } | 544 } |
542 return true; | 545 return true; |
543 } | 546 } |
544 | 547 |
545 void VariationsSeedStore::ReportUnsupportedSeedFormatError() { | 548 void VariationsSeedStore::ReportUnsupportedSeedFormatError() { |
546 RecordSeedStoreHistogram( | 549 RecordSeedStoreHistogram( |
547 VARIATIONS_SEED_STORE_FAILED_UNSUPPORTED_SEED_FORMAT); | 550 VARIATIONS_SEED_STORE_FAILED_UNSUPPORTED_SEED_FORMAT); |
548 } | 551 } |
549 | 552 |
550 } // namespace variations | 553 } // namespace variations |
OLD | NEW |