1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file.
4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/extensions/api/networking_private/networking_private_credentials_getter.h"
6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/base64.h"
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/bind.h"
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/message_loop/message_loop.h"
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/threading/sequenced_worker_pool.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/common/extensions/api/networking_private/networking_private_crypto.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/common/extensions/chrome_utility_extensions_messages.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/browser/utility_process_host.h"
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using content::BrowserThread;
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using content::UtilityProcessHost;
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using extensions::NetworkingPrivateCredentialsGetter;
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace {
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class CredentialsGetterHostClient : public content::UtilityProcessHostClient {
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public:
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  explicit CredentialsGetterHostClient(const std::string& public_key);
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual ~CredentialsGetterHostClient();
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // UtilityProcessHostClient
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void OnProcessCrashed(int exit_code) OVERRIDE;
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void OnProcessLaunchFailed() OVERRIDE;
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // IPC message handlers.
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void OnGotCredentials(const std::string& key_data, bool success);
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Starts the utility process that gets wifi passphrase from system.
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void StartProcessOnIOThread(
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const std::string& network_guid,
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const extensions::NetworkingPrivateServiceClient::CryptoVerify::
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          VerifyAndEncryptCredentialsCallback& callback);
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private:
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Public key used to encrypt results
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<uint8> public_key_;
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Callback for reporting the result.
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  extensions::NetworkingPrivateServiceClient::CryptoVerify::
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      VerifyAndEncryptCredentialsCallback callback_;
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CredentialsGetterHostClient);
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciCredentialsGetterHostClient::CredentialsGetterHostClient(
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string& public_key)
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : public_key_(public_key.begin(), public_key.end()) {
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)CredentialsGetterHostClient::~CredentialsGetterHostClient() {}
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool CredentialsGetterHostClient::OnMessageReceived(
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const IPC::Message& message) {
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool handled = true;
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(CredentialsGetterHostClient, message)
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_GotWiFiCredentials, OnGotCredentials)
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  IPC_MESSAGE_UNHANDLED(handled = false)
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return handled;
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void CredentialsGetterHostClient::OnProcessCrashed(int exit_code) {
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  callback_.Run("", "Process Crashed");
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void CredentialsGetterHostClient::OnProcessLaunchFailed() {
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  callback_.Run("", "Process Launch Failed");
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid CredentialsGetterHostClient::OnGotCredentials(const std::string& key_data,
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                   bool success) {
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (success) {
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::vector<uint8> ciphertext;
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!networking_private_crypto::EncryptByteString(
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            public_key_, key_data, &ciphertext)) {
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      callback_.Run("", "Encrypt Credentials Failed");
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return;
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    std::string base64_encoded_key_data;
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::Base64Encode(std::string(ciphertext.begin(), ciphertext.end()),
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       &base64_encoded_key_data);
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    callback_.Run(base64_encoded_key_data, "");
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else {
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    callback_.Run("", "Get Credentials Failed");
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void CredentialsGetterHostClient::StartProcessOnIOThread(
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& network_guid,
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const extensions::NetworkingPrivateServiceClient::CryptoVerify::
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        VerifyAndEncryptCredentialsCallback& callback) {
101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::IO);
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  UtilityProcessHost* host =
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      UtilityProcessHost::Create(this, base::MessageLoopProxy::current());
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  callback_ = callback;
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  host->ElevatePrivileges();
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  host->Send(new ChromeUtilityHostMsg_GetWiFiCredentials(network_guid));
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace extensions {
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class NetworkingPrivateCredentialsGetterWin
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : public NetworkingPrivateCredentialsGetter {
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public:
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NetworkingPrivateCredentialsGetterWin();
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void Start(
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const std::string& network_guid,
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const std::string& public_key,
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const extensions::NetworkingPrivateServiceClient::CryptoVerify::
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          VerifyAndEncryptCredentialsCallback& callback) OVERRIDE;
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private:
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual ~NetworkingPrivateCredentialsGetterWin();
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NetworkingPrivateCredentialsGetterWin);
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)NetworkingPrivateCredentialsGetterWin::NetworkingPrivateCredentialsGetterWin() {
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void NetworkingPrivateCredentialsGetterWin::Start(
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& network_guid,
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& public_key,
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const extensions::NetworkingPrivateServiceClient::CryptoVerify::
137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        VerifyAndEncryptCredentialsCallback& callback) {
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BrowserThread::PostTask(
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      BrowserThread::IO,
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FROM_HERE,
141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&CredentialsGetterHostClient::StartProcessOnIOThread,
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 new CredentialsGetterHostClient(public_key),
143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 network_guid,
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 callback));
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)NetworkingPrivateCredentialsGetterWin::
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ~NetworkingPrivateCredentialsGetterWin() {}
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)NetworkingPrivateCredentialsGetter*
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)NetworkingPrivateCredentialsGetter::Create() {
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return new NetworkingPrivateCredentialsGetterWin();
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace extensions
156