machine_id.cc (3015B)
1 // Copyright (c) 2012 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 5 #include "rlz/lib/machine_id.h" 6 7 #include <stddef.h> 8 9 #include "rlz/lib/assert.h" 10 #include "rlz/lib/crc8.h" 11 #include "rlz/lib/string_utils.h" 12 13 // Note: The original machine_id.cc code depends on Chromium's sha1 implementation. 14 // Using Mozilla's implmentation as replacement to reduce the dependency of 15 // some external files. 16 #include "mozilla/SHA1.h" 17 18 namespace rlz_lib { 19 20 bool GetMachineId(std::string* machine_id) { 21 if (!machine_id) 22 return false; 23 24 static std::string calculated_id; 25 static bool calculated = false; 26 if (calculated) { 27 *machine_id = calculated_id; 28 return true; 29 } 30 31 std::vector<uint8_t> sid_bytes; 32 int volume_id; 33 if (!GetRawMachineId(&sid_bytes, &volume_id)) 34 return false; 35 36 if (!testing::GetMachineIdImpl(sid_bytes, volume_id, machine_id)) 37 return false; 38 39 calculated = true; 40 calculated_id = *machine_id; 41 return true; 42 } 43 44 namespace testing { 45 46 bool GetMachineIdImpl(const std::vector<uint8_t>& sid_bytes, 47 int volume_id, 48 std::string* machine_id) { 49 machine_id->clear(); 50 51 // The ID should be the SID hash + the Hard Drive SNo. + checksum byte. 52 static const int kSizeWithoutChecksum = mozilla::SHA1Sum::kHashSize + sizeof(int); 53 std::vector<unsigned char> id_binary(kSizeWithoutChecksum + 1, 0); 54 55 if (!sid_bytes.empty()) { 56 // In order to be compatible with the old version of RLZ, the hash of the 57 // SID must be done with all the original bytes from the unicode string. 58 // However, the chromebase SHA1 hash function takes only an std::string as 59 // input, so the unicode string needs to be converted to std::string 60 // "as is". 61 size_t byte_count = sid_bytes.size() * sizeof(std::vector<uint8_t>::value_type); 62 const char* buffer = reinterpret_cast<const char*>(sid_bytes.data()); 63 64 // Note that digest can have embedded nulls. 65 mozilla::SHA1Sum SHA1; 66 mozilla::SHA1Sum::Hash hash; 67 SHA1.update(buffer, byte_count); 68 SHA1.finish(hash); 69 std::string digest(reinterpret_cast<char*>(hash), mozilla::SHA1Sum::kHashSize); 70 VERIFY(digest.size() == mozilla::SHA1Sum::kHashSize); 71 std::copy(digest.begin(), digest.end(), id_binary.begin()); 72 } 73 74 // Convert from int to binary (makes big-endian). 75 for (size_t i = 0; i < sizeof(int); i++) { 76 int shift_bits = 8 * (sizeof(int) - i - 1); 77 id_binary[mozilla::SHA1Sum::kHashSize + i] = static_cast<unsigned char>( 78 (volume_id >> shift_bits) & 0xFF); 79 } 80 81 // Append the checksum byte. 82 if (!sid_bytes.empty() || (0 != volume_id)) 83 rlz_lib::Crc8::Generate(id_binary.data(), 84 kSizeWithoutChecksum, 85 &id_binary[kSizeWithoutChecksum]); 86 87 return rlz_lib::BytesToString( 88 id_binary.data(), kSizeWithoutChecksum + 1, machine_id); 89 } 90 91 } // namespace testing 92 93 } // namespace rlz_lib