Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / music_manager_private / device_id.cc
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.
4
5 #include "chrome/browser/extensions/api/music_manager_private/device_id.h"
6
7 #include "base/bind.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"
12
13 namespace {
14
15 using extensions::api::DeviceId;
16
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());
26   if (result) {
27     *signature_return = StringToLowerASCII(base::HexEncode(digest.data(),
28                                                            digest.size()));
29   }
30   return result;
31 }
32
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);
37
38   if (raw_device_id.empty()) {
39     callback.Run("");
40     return;
41   }
42
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.";
46     callback.Run("");
47     return;
48   }
49   callback.Run(device_id);
50 }
51
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 {
56       size_t size;
57       unsigned char address[MAC_LENGTH];
58   };
59
60   // VPN, virtualization, tethering, bluetooth, etc.
61   static InvalidMacEntry invalidAddresses[] = {
62     // Empty address
63     {MAC_LENGTH, {0, 0, 0, 0, 0, 0}},
64     // VMware
65     {OUI_LENGTH, {0x00, 0x50, 0x56}},
66     {OUI_LENGTH, {0x00, 0x05, 0x69}},
67     {OUI_LENGTH, {0x00, 0x0c, 0x29}},
68     {OUI_LENGTH, {0x00, 0x1c, 0x14}},
69     // VirtualBox
70     {OUI_LENGTH, {0x08, 0x00, 0x27}},
71     // PdaNet
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.
81     {2, {0x00, 0xff}},
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}},
86     // RAS Async Adapter
87     {MAC_LENGTH, {0x20, 0x41, 0x53, 0x59, 0x4e, 0xff}},
88     // Qualcomm USB ethernet adapter
89     {MAC_LENGTH, {0x00, 0xa0, 0xc6, 0x00, 0x00, 0x00}},
90     // Windows VPN
91     {MAC_LENGTH, {0x00, 0x53, 0x45, 0x00, 0x00, 0x00}},
92     // Bluetooth
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}},
99     // Ceton TV tuner
100     {MAC_LENGTH, {0x00, 0x22, 0x2c, 0xff, 0xff, 0xff}},
101     // Check Point VPN
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}},
105     // Cisco VPN
106     {MAC_LENGTH, {0x00, 0x05, 0x9a, 0x3c, 0x7a, 0x00}},
107     // Cisco VPN
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}},
113     // Nortel VPN
114     {MAC_LENGTH, {0x44, 0x45, 0x53, 0x54, 0x42, 0x00}},
115     // AEP VPN
116     {MAC_LENGTH, {0x00, 0x30, 0x70, 0x00, 0x00, 0x01}},
117     // Positive VPN
118     {MAC_LENGTH, {0x00, 0x02, 0x03, 0x04, 0x05, 0x06}},
119     // Bluetooth
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}},
125     // FRITZ!web DSL
126     {MAC_LENGTH, {0x00, 0x04, 0x0E, 0xFF, 0xFF, 0xFF}},
127     // VirtualPC
128     {MAC_LENGTH, {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}},
129     // Bluetooth
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}},
134     // Huawei cell modem
135     {MAC_LENGTH, {0x58, 0x2C, 0x80, 0x13, 0x92, 0x63}},
136     // Fortinet VPN
137     {OUI_LENGTH, {0x00, 0x09, 0x0F}},
138     // Realtek
139     {MAC_LENGTH, {0x00, 0x00, 0x00, 0x00, 0x00, 0x30}},
140     // Other rare dupes.
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
152   };
153
154   if (size != MAC_LENGTH) {
155     return false;
156   }
157
158   if (static_cast<const unsigned char *>(bytes)[0] & 0x02) {
159     // Locally administered.
160     return false;
161   }
162
163   // Note: Use ARRAYSIZE_UNSAFE() instead of arraysize() because InvalidMacEntry
164   // is declared inside this function.
165   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(invalidAddresses); ++i) {
166     size_t count = invalidAddresses[i].size;
167     if (memcmp(invalidAddresses[i].address, bytes, count) == 0) {
168         return false;
169     }
170   }
171   return true;
172 }
173
174 }  // namespace
175
176 namespace extensions {
177 namespace api {
178
179 // static
180 void DeviceId::GetDeviceId(const std::string& extension_id,
181                            const IdCallback& callback) {
182   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
183   CHECK(!extension_id.empty());
184
185   // Forward call to platform specific implementation, then compute the HMAC
186   // in the callback.
187   GetRawDeviceId(base::Bind(&GetRawDeviceIdCallback, extension_id, callback));
188 }
189
190 // static
191 bool DeviceId::IsValidMacAddress(const void* bytes, size_t size) {
192   return IsValidMacAddressImpl(bytes, size);
193 }
194
195 }  // namespace api
196 }  // namespace extensions