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
3 // found in the LICENSE file.
5 #include "chrome/browser/extensions/api/music_manager_private/device_id.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "base/strings/string_util.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "crypto/hmac.h"
15 using extensions::api::DeviceId
;
17 // Compute HMAC-SHA256(|key|, |text|) as a string.
18 bool ComputeHmacSha256(const std::string
& key
,
19 const std::string
& text
,
20 std::string
* signature_return
) {
21 crypto::HMAC
hmac(crypto::HMAC::SHA256
);
22 const size_t digest_length
= hmac
.DigestLength();
23 std::vector
<uint8
> digest(digest_length
);
24 bool result
= hmac
.Init(key
) &&
25 hmac
.Sign(text
, &digest
[0], digest
.size());
27 *signature_return
= base::ToLowerASCII(
28 base::HexEncode(digest
.data(), digest
.size()));
33 void GetRawDeviceIdCallback(const std::string
& extension_id
,
34 const DeviceId::IdCallback
& callback
,
35 const std::string
& raw_device_id
) {
36 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
38 if (raw_device_id
.empty()) {
43 std::string device_id
;
44 if (!ComputeHmacSha256(raw_device_id
, extension_id
, &device_id
)) {
45 DLOG(ERROR
) << "Error while computing HMAC-SHA256 of device id.";
49 callback
.Run(device_id
);
52 bool IsValidMacAddressImpl(const void* bytes
, size_t size
) {
53 const size_t MAC_LENGTH
= 6;
54 const size_t OUI_LENGTH
= 3;
55 struct InvalidMacEntry
{
57 unsigned char address
[MAC_LENGTH
];
60 // VPN, virtualization, tethering, bluetooth, etc.
61 static InvalidMacEntry invalidAddresses
[] = {
63 {MAC_LENGTH
, {0, 0, 0, 0, 0, 0}},
65 {OUI_LENGTH
, {0x00, 0x50, 0x56}},
66 {OUI_LENGTH
, {0x00, 0x05, 0x69}},
67 {OUI_LENGTH
, {0x00, 0x0c, 0x29}},
68 {OUI_LENGTH
, {0x00, 0x1c, 0x14}},
70 {OUI_LENGTH
, {0x08, 0x00, 0x27}},
72 {MAC_LENGTH
, {0x00, 0x26, 0x37, 0xbd, 0x39, 0x42}},
73 // Cisco AnyConnect VPN
74 {MAC_LENGTH
, {0x00, 0x05, 0x9a, 0x3c, 0x7a, 0x00}},
75 // Marvell sometimes uses this as a dummy address
76 {MAC_LENGTH
, {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}},
77 // Apple uses this across machines for Bluetooth ethernet adapters.
78 {MAC_LENGTH
-1, {0x65, 0x90, 0x07, 0x42, 0xf1}},
79 // Juniper uses this for their Virtual Adapter, the other 4 bytes are
80 // reassigned at every boot. 00-ff-xx is not assigned to anyone.
82 // T-Mobile Wireless Ethernet
83 {MAC_LENGTH
, {0x00, 0xa0, 0xc6, 0x00, 0x00, 0x00}},
84 // Generic Bluetooth device
85 {MAC_LENGTH
, {0x00, 0x15, 0x83, 0x3d, 0x0a, 0x57}},
87 {MAC_LENGTH
, {0x20, 0x41, 0x53, 0x59, 0x4e, 0xff}},
88 // Qualcomm USB ethernet adapter
89 {MAC_LENGTH
, {0x00, 0xa0, 0xc6, 0x00, 0x00, 0x00}},
91 {MAC_LENGTH
, {0x00, 0x53, 0x45, 0x00, 0x00, 0x00}},
93 {MAC_LENGTH
, {0x00, 0x1f, 0x81, 0x00, 0x08, 0x30}},
94 {MAC_LENGTH
, {0x00, 0x1b, 0x10, 0x00, 0x2a, 0xec}},
95 {MAC_LENGTH
, {0x00, 0x15, 0x83, 0x15, 0xa3, 0x10}},
96 {MAC_LENGTH
, {0x00, 0x15, 0x83, 0x07, 0xC6, 0x5A}},
97 {MAC_LENGTH
, {0x00, 0x1f, 0x81, 0x00, 0x02, 0x00}},
98 {MAC_LENGTH
, {0x00, 0x1f, 0x81, 0x00, 0x02, 0xdd}},
100 {MAC_LENGTH
, {0x00, 0x22, 0x2c, 0xff, 0xff, 0xff}},
102 {MAC_LENGTH
, {0x54, 0x55, 0x43, 0x44, 0x52, 0x09}},
103 {MAC_LENGTH
, {0x54, 0xEF, 0x14, 0x71, 0xE4, 0x0E}},
104 {MAC_LENGTH
, {0x54, 0xBA, 0xC6, 0xFF, 0x74, 0x10}},
106 {MAC_LENGTH
, {0x00, 0x05, 0x9a, 0x3c, 0x7a, 0x00}},
108 {MAC_LENGTH
, {0x00, 0x05, 0x9a, 0x3c, 0x78, 0x00}},
109 // Intel USB cell modem
110 {MAC_LENGTH
, {0x00, 0x1e, 0x10, 0x1f, 0x00, 0x01}},
111 // Microsoft tethering
112 {MAC_LENGTH
, {0x80, 0x00, 0x60, 0x0f, 0xe8, 0x00}},
114 {MAC_LENGTH
, {0x44, 0x45, 0x53, 0x54, 0x42, 0x00}},
116 {MAC_LENGTH
, {0x00, 0x30, 0x70, 0x00, 0x00, 0x01}},
118 {MAC_LENGTH
, {0x00, 0x02, 0x03, 0x04, 0x05, 0x06}},
120 {MAC_LENGTH
, {0x00, 0x15, 0x83, 0x0B, 0x13, 0xC0}},
121 // Kerio Virtual Network Adapter
122 {MAC_LENGTH
, {0x44, 0x45, 0x53, 0x54, 0x4f, 0x53}},
123 // Sierra Wireless cell modems.
124 {OUI_LENGTH
, {0x00, 0xA0, 0xD5}},
126 {MAC_LENGTH
, {0x00, 0x04, 0x0E, 0xFF, 0xFF, 0xFF}},
128 {MAC_LENGTH
, {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}},
130 {MAC_LENGTH
, {0x00, 0x1F, 0x81, 0x00, 0x01, 0x00}},
131 {MAC_LENGTH
, {0x00, 0x30, 0x91, 0x10, 0x00, 0x26}},
132 {MAC_LENGTH
, {0x00, 0x25, 0x00, 0x5A, 0xC3, 0xD0}},
133 {MAC_LENGTH
, {0x00, 0x15, 0x83, 0x0C, 0xBF, 0xEB}},
135 {MAC_LENGTH
, {0x58, 0x2C, 0x80, 0x13, 0x92, 0x63}},
137 {OUI_LENGTH
, {0x00, 0x09, 0x0F}},
139 {MAC_LENGTH
, {0x00, 0x00, 0x00, 0x00, 0x00, 0x30}},
141 {MAC_LENGTH
, {0x00, 0x11, 0xf5, 0x0d, 0x8a, 0xe8}}, // Atheros
142 {MAC_LENGTH
, {0x00, 0x20, 0x07, 0x01, 0x16, 0x06}}, // Atheros
143 {MAC_LENGTH
, {0x0d, 0x0b, 0x00, 0x00, 0xe0, 0x00}}, // Atheros
144 {MAC_LENGTH
, {0x90, 0x4c, 0xe5, 0x0b, 0xc8, 0x8e}}, // Atheros
145 {MAC_LENGTH
, {0x00, 0x1c, 0x23, 0x38, 0x49, 0xa4}}, // Broadcom
146 {MAC_LENGTH
, {0x00, 0x12, 0x3f, 0x82, 0x7c, 0x32}}, // Broadcom
147 {MAC_LENGTH
, {0x00, 0x11, 0x11, 0x32, 0xc3, 0x77}}, // Broadcom
148 {MAC_LENGTH
, {0x00, 0x24, 0xd6, 0xae, 0x3e, 0x39}}, // Microsoft
149 {MAC_LENGTH
, {0x00, 0x0f, 0xb0, 0x3a, 0xb4, 0x80}}, // Realtek
150 {MAC_LENGTH
, {0x08, 0x10, 0x74, 0xa1, 0xda, 0x1b}}, // Realtek
151 {MAC_LENGTH
, {0x00, 0x21, 0x9b, 0x2a, 0x0a, 0x9c}}, // Realtek
154 if (size
!= MAC_LENGTH
) {
158 if (static_cast<const unsigned char *>(bytes
)[0] & 0x02) {
159 // Locally administered.
163 for (size_t i
= 0; i
< arraysize(invalidAddresses
); ++i
) {
164 size_t count
= invalidAddresses
[i
].size
;
165 if (memcmp(invalidAddresses
[i
].address
, bytes
, count
) == 0) {
174 namespace extensions
{
178 void DeviceId::GetDeviceId(const std::string
& extension_id
,
179 const IdCallback
& callback
) {
180 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
181 CHECK(!extension_id
.empty());
183 // Forward call to platform specific implementation, then compute the HMAC
185 GetRawDeviceId(base::Bind(&GetRawDeviceIdCallback
, extension_id
, callback
));
189 bool DeviceId::IsValidMacAddress(const void* bytes
, size_t size
) {
190 return IsValidMacAddressImpl(bytes
, size
);
194 } // namespace extensions