Revert of Refactoring of Cast-related crypto code (patchset #19 id:350001 of https...
[chromium-blink-merge.git] / chrome / browser / extensions / api / networking_private / crypto_verify_impl.cc
blobda34f3fed41a808aeb91af2df02247dd8de6f01f
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
3 // found in the LICENSE file.
5 #include "chrome/browser/extensions/api/networking_private/crypto_verify_impl.h"
7 #include "base/base64.h"
8 #include "base/bind.h"
9 #include "base/bind_helpers.h"
10 #include "base/sequenced_task_runner.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_util.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "base/threading/sequenced_worker_pool.h"
15 #include "chrome/browser/extensions/api/networking_private/networking_private_api.h"
16 #include "chrome/browser/extensions/api/networking_private/networking_private_credentials_getter.h"
17 #include "chrome/browser/extensions/api/networking_private/networking_private_service_client.h"
18 #include "chrome/common/extensions/api/networking_private.h"
19 #include "chrome/common/extensions/api/networking_private/networking_private_crypto.h"
20 #include "content/public/browser/browser_thread.h"
22 namespace extensions {
24 namespace {
26 const char kCryptoVerifySequenceTokenName[] = "CryptoVerify";
28 // Called from a blocking pool task runner. Returns true and sets |verified| if
29 // able to decode the credentials, otherwise sets |verified| to false and
30 // returns false.
31 bool DecodeAndVerifyCredentials(
32 const CryptoVerifyImpl::Credentials& credentials,
33 bool* verified) {
34 std::string decoded_signed_data;
35 if (!base::Base64Decode(credentials.signed_data, &decoded_signed_data)) {
36 LOG(ERROR) << "Failed to decode signed data";
37 *verified = false;
38 return false;
40 *verified = networking_private_crypto::VerifyCredentials(
41 credentials.certificate, decoded_signed_data, credentials.unsigned_data,
42 credentials.device_bssid);
43 return true;
46 void VerifyDestinationCompleted(
47 const CryptoVerifyImpl::BoolCallback& success_callback,
48 const CryptoVerifyImpl::FailureCallback& failure_callback,
49 bool* verified,
50 bool success) {
51 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
52 if (!success)
53 failure_callback.Run(networking_private::kErrorEncryptionError);
54 else
55 success_callback.Run(*verified);
58 // Called from a blocking pool task runner. Returns |data| encoded using
59 // |credentials| on success, or an empty string on failure.
60 std::string DoVerifyAndEncryptData(
61 const CryptoVerifyImpl::Credentials& credentials,
62 const std::string& data) {
63 bool verified;
64 if (!DecodeAndVerifyCredentials(credentials, &verified) || !verified)
65 return std::string();
67 std::string decoded_public_key;
68 if (!base::Base64Decode(credentials.public_key, &decoded_public_key)) {
69 LOG(ERROR) << "Failed to decode public key";
70 return std::string();
73 std::vector<uint8_t> public_key_data(decoded_public_key.begin(),
74 decoded_public_key.end());
75 std::vector<uint8_t> ciphertext;
76 if (!networking_private_crypto::EncryptByteString(public_key_data, data,
77 &ciphertext)) {
78 LOG(ERROR) << "Failed to encrypt data";
79 return std::string();
82 std::string base64_encoded_ciphertext;
83 base::Base64Encode(std::string(ciphertext.begin(), ciphertext.end()),
84 &base64_encoded_ciphertext);
85 return base64_encoded_ciphertext;
88 void VerifyAndEncryptDataCompleted(
89 const CryptoVerifyImpl::StringCallback& success_callback,
90 const CryptoVerifyImpl::FailureCallback& failure_callback,
91 const std::string& encrypted_data) {
92 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
93 if (encrypted_data.empty())
94 failure_callback.Run(networking_private::kErrorEncryptionError);
95 else
96 success_callback.Run(encrypted_data);
99 // Called when NetworkingPrivateCredentialsGetter completes (from an arbitrary
100 // thread). Posts the result to the UI thread.
101 void CredentialsGetterCompleted(
102 const CryptoVerifyImpl::StringCallback& success_callback,
103 const CryptoVerifyImpl::FailureCallback& failure_callback,
104 const std::string& key_data,
105 const std::string& error) {
106 if (!error.empty()) {
107 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
108 base::Bind(failure_callback, error));
109 } else {
110 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
111 base::Bind(success_callback, key_data));
115 // Called from a blocking pool task runner. Returns true if
116 // NetworkingPrivateCredentialsGetter is successfully started (which will
117 // invoke the appropriate callback when completed), or false if unable
118 // to start the getter (credentials or public key decode failed).
119 bool DoVerifyAndEncryptCredentials(
120 const std::string& guid,
121 const CryptoVerifyImpl::Credentials& credentials,
122 const CryptoVerifyImpl::StringCallback& success_callback,
123 const CryptoVerifyImpl::FailureCallback& failure_callback) {
124 bool verified;
125 if (!DecodeAndVerifyCredentials(credentials, &verified) || !verified)
126 return false;
128 std::string decoded_public_key;
129 if (!base::Base64Decode(credentials.public_key, &decoded_public_key)) {
130 LOG(ERROR) << "Failed to decode public key";
131 return false;
134 // Start getting credentials. CredentialsGetterCompleted will be called on
135 // completion. On Windows it will be called from a different thread after
136 // |credentials_getter| is deleted.
137 scoped_ptr<NetworkingPrivateCredentialsGetter> credentials_getter(
138 NetworkingPrivateCredentialsGetter::Create());
139 credentials_getter->Start(guid, decoded_public_key,
140 base::Bind(&CredentialsGetterCompleted,
141 success_callback, failure_callback));
142 return true;
145 void VerifyAndEncryptCredentialsCompleted(
146 const CryptoVerifyImpl::FailureCallback& failure_callback,
147 bool succeeded) {
148 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
149 // If VerifyAndEncryptCredentials succeeded, then the appropriate callback
150 // will be triggered from CredentialsGetterCompleted.
151 if (succeeded)
152 return;
153 failure_callback.Run(networking_private::kErrorEncryptionError);
156 } // namespace
158 CryptoVerifyImpl::Credentials::Credentials(
159 const VerificationProperties& properties) {
160 certificate = properties.certificate;
161 signed_data = properties.signed_data;
163 std::vector<std::string> data_parts;
164 data_parts.push_back(properties.device_ssid);
165 data_parts.push_back(properties.device_serial);
166 data_parts.push_back(properties.device_bssid);
167 data_parts.push_back(properties.public_key);
168 data_parts.push_back(properties.nonce);
169 unsigned_data = JoinString(data_parts, ",");
171 device_bssid = properties.device_bssid;
172 public_key = properties.public_key;
175 CryptoVerifyImpl::Credentials::~Credentials() {
178 CryptoVerifyImpl::CryptoVerifyImpl() {
179 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
180 base::SequencedWorkerPool::SequenceToken sequence_token =
181 content::BrowserThread::GetBlockingPool()->GetNamedSequenceToken(
182 kCryptoVerifySequenceTokenName);
183 blocking_pool_task_runner_ =
184 content::BrowserThread::GetBlockingPool()
185 ->GetSequencedTaskRunnerWithShutdownBehavior(
186 sequence_token, base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
189 CryptoVerifyImpl::~CryptoVerifyImpl() {
190 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
193 void CryptoVerifyImpl::VerifyDestination(
194 const VerificationProperties& verification_properties,
195 const BoolCallback& success_callback,
196 const FailureCallback& failure_callback) {
197 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
198 Credentials credentials(verification_properties);
199 bool* verified = new bool;
200 base::PostTaskAndReplyWithResult(
201 blocking_pool_task_runner_.get(), FROM_HERE,
202 base::Bind(&DecodeAndVerifyCredentials, credentials, verified),
203 base::Bind(&VerifyDestinationCompleted, success_callback,
204 failure_callback, base::Owned(verified)));
207 void CryptoVerifyImpl::VerifyAndEncryptCredentials(
208 const std::string& guid,
209 const VerificationProperties& verification_properties,
210 const StringCallback& success_callback,
211 const FailureCallback& failure_callback) {
212 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
213 Credentials credentials(verification_properties);
214 base::PostTaskAndReplyWithResult(
215 blocking_pool_task_runner_.get(), FROM_HERE,
216 base::Bind(&DoVerifyAndEncryptCredentials, guid, credentials,
217 success_callback, failure_callback),
218 base::Bind(&VerifyAndEncryptCredentialsCompleted, failure_callback));
221 void CryptoVerifyImpl::VerifyAndEncryptData(
222 const VerificationProperties& verification_properties,
223 const std::string& data,
224 const StringCallback& success_callback,
225 const FailureCallback& failure_callback) {
226 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
227 Credentials credentials(verification_properties);
228 base::PostTaskAndReplyWithResult(
229 blocking_pool_task_runner_.get(), FROM_HERE,
230 base::Bind(&DoVerifyAndEncryptData, credentials, data),
231 base::Bind(&VerifyAndEncryptDataCompleted, success_callback,
232 failure_callback));
235 } // namespace extensions