| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/local_discovery/privetv3_session.h" | 5 #include "chrome/browser/local_discovery/privetv3_session.h" |
| 6 | 6 |
| 7 #include "base/base64.h" | 7 #include "base/base64.h" |
| 8 #include "base/json/json_writer.h" | 8 #include "base/json/json_writer.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 11 #include "chrome/browser/local_discovery/privet_constants.h" | 11 #include "chrome/browser/local_discovery/privet_constants.h" |
| 12 #include "chrome/browser/local_discovery/privet_http.h" | 12 #include "chrome/browser/local_discovery/privet_http.h" |
| 13 #include "chrome/browser/local_discovery/privet_url_fetcher.h" | 13 #include "chrome/browser/local_discovery/privet_url_fetcher.h" |
| 14 #include "chrome/common/cloud_print/cloud_print_constants.h" | 14 #include "chrome/common/cloud_print/cloud_print_constants.h" |
| 15 #include "crypto/hmac.h" | 15 #include "crypto/hmac.h" |
| 16 #include "crypto/p224_spake.h" | 16 #include "crypto/p224_spake.h" |
| 17 #include "url/gurl.h" | 17 #include "url/gurl.h" |
| 18 | 18 |
| 19 namespace local_discovery { | 19 namespace local_discovery { |
| 20 | 20 |
| 21 namespace { | 21 namespace { |
| 22 | 22 |
| 23 const char kPrivetV3AuthAnonymous[] = "Privet anonymous"; | 23 const char kPrivetV3AuthAnonymous[] = "Privet anonymous"; |
| 24 const char kPrivetV3CryptoP224Spake2[] = "p224_spake2"; | 24 const char kPrivetV3CryptoP224Spake2[] = "p224_spake2"; |
| 25 const char kPrivetV3Auto[] = "auto"; |
| 25 | 26 |
| 26 const char kPrivetV3InfoKeyAuth[] = "authentication"; | 27 const char kPrivetV3InfoKeyAuth[] = "authentication"; |
| 27 const char kPrivetV3InfoKeyVersion[] = "version"; | 28 const char kPrivetV3InfoKeyVersion[] = "version"; |
| 28 const char kPrivetV3InfoVersion[] = "3.0"; | 29 const char kPrivetV3InfoVersion[] = "3.0"; |
| 29 | 30 |
| 31 const char kPrivetV3KeyAccessToken[] = "accessToken"; |
| 32 const char kPrivetV3KeyAuthCode[] = "authCode"; |
| 30 const char kPrivetV3KeyCertFingerprint[] = "certFingerprint"; | 33 const char kPrivetV3KeyCertFingerprint[] = "certFingerprint"; |
| 31 const char kPrivetV3KeyCertSignature[] = "certSignature"; | 34 const char kPrivetV3KeyCertSignature[] = "certSignature"; |
| 32 const char kPrivetV3KeyClientCommitment[] = "clientCommitment"; | 35 const char kPrivetV3KeyClientCommitment[] = "clientCommitment"; |
| 33 const char kPrivetV3KeyCrypto[] = "crypto"; | 36 const char kPrivetV3KeyCrypto[] = "crypto"; |
| 34 const char kPrivetV3KeyDeviceCommitment[] = "deviceCommitment"; | 37 const char kPrivetV3KeyDeviceCommitment[] = "deviceCommitment"; |
| 35 const char kPrivetV3KeyMode[] = "mode"; | 38 const char kPrivetV3KeyMode[] = "mode"; |
| 36 const char kPrivetV3KeyPairing[] = "pairing"; | 39 const char kPrivetV3KeyPairing[] = "pairing"; |
| 40 const char kPrivetV3KeyRequestedScope[] = "requestedScope"; |
| 41 const char kPrivetV3KeyScope[] = "scope"; |
| 37 const char kPrivetV3KeySessionId[] = "sessionId"; | 42 const char kPrivetV3KeySessionId[] = "sessionId"; |
| 43 const char kPrivetV3KeyTokenType[] = "tokenType"; |
| 38 | 44 |
| 45 const char kPrivetV3PairingStartPath[] = "/privet/v3/pairing/start"; |
| 39 const char kPrivetV3PairingConfirmPath[] = "/privet/v3/pairing/confirm"; | 46 const char kPrivetV3PairingConfirmPath[] = "/privet/v3/pairing/confirm"; |
| 40 const char kPrivetV3PairingStartPath[] = "/privet/v3/pairing/start"; | 47 const char kPrivetV3AuthPath[] = "/privet/v3/auth"; |
| 41 | 48 |
| 42 const char kUrlPlaceHolder[] = "http://host/"; | 49 const char kUrlPlaceHolder[] = "http://host/"; |
| 43 | 50 |
| 44 GURL CreatePrivetURL(const std::string& path) { | 51 GURL CreatePrivetURL(const std::string& path) { |
| 45 GURL url(kUrlPlaceHolder); | 52 GURL url(kUrlPlaceHolder); |
| 46 GURL::Replacements replacements; | 53 GURL::Replacements replacements; |
| 47 replacements.SetPathStr(path); | 54 replacements.SetPathStr(path); |
| 48 return url.ReplaceComponents(replacements); | 55 return url.ReplaceComponents(replacements); |
| 49 } | 56 } |
| 50 | 57 |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 | 345 |
| 339 crypto::HMAC hmac(crypto::HMAC::SHA256); | 346 crypto::HMAC hmac(crypto::HMAC::SHA256); |
| 340 // Key will be verified below, using HMAC. | 347 // Key will be verified below, using HMAC. |
| 341 const std::string& key = spake_->GetUnverifiedKey(); | 348 const std::string& key = spake_->GetUnverifiedKey(); |
| 342 if (!hmac.Init(reinterpret_cast<const unsigned char*>(key.c_str()), | 349 if (!hmac.Init(reinterpret_cast<const unsigned char*>(key.c_str()), |
| 343 key.size()) || | 350 key.size()) || |
| 344 !hmac.Verify(fingerprint, signature)) { | 351 !hmac.Verify(fingerprint, signature)) { |
| 345 return callback.Run(Result::STATUS_SESSIONERROR); | 352 return callback.Run(Result::STATUS_SESSIONERROR); |
| 346 } | 353 } |
| 347 | 354 |
| 355 std::string auth_code(hmac.DigestLength(), ' '); |
| 356 if (!hmac.Sign(session_id_, |
| 357 reinterpret_cast<unsigned char*>(string_as_array(&auth_code)), |
| 358 auth_code.size())) { |
| 359 NOTREACHED(); |
| 360 return callback.Run(Result::STATUS_SESSIONERROR); |
| 361 } |
| 362 // From now this is expected certificate. |
| 363 fingerprint_ = fingerprint; |
| 364 |
| 365 std::string auth_code_base64; |
| 366 base::Base64Encode(auth_code, &auth_code_base64); |
| 367 |
| 368 base::DictionaryValue input; |
| 369 input.SetString(kPrivetV3KeyAuthCode, auth_code_base64); |
| 370 input.SetString(kPrivetV3KeyMode, kPrivetV3KeyPairing); |
| 371 input.SetString(kPrivetV3KeyRequestedScope, kPrivetV3Auto); |
| 372 |
| 373 // Now we can use SendMessage with certificate validateion. |
| 374 SendMessage(kPrivetV3AuthPath, input, |
| 375 base::Bind(&PrivetV3Session::OnAuthenticateDone, |
| 376 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 377 } |
| 378 |
| 379 void PrivetV3Session::OnAuthenticateDone( |
| 380 const ResultCallback& callback, |
| 381 Result result, |
| 382 const base::DictionaryValue& response) { |
| 383 if (result != Result::STATUS_SUCCESS) |
| 384 return callback.Run(result); |
| 385 |
| 386 std::string access_token; |
| 387 std::string token_type; |
| 388 std::string scope; |
| 389 if (!response.GetString(kPrivetV3KeyAccessToken, &access_token) || |
| 390 !response.GetString(kPrivetV3KeyTokenType, &token_type) || |
| 391 !response.GetString(kPrivetV3KeyScope, &scope)) { |
| 392 return callback.Run(Result::STATUS_SESSIONERROR); |
| 393 } |
| 394 |
| 395 privet_auth_token_ = token_type + " " + access_token; |
| 396 |
| 348 return callback.Run(Result::STATUS_SUCCESS); | 397 return callback.Run(Result::STATUS_SUCCESS); |
| 349 } | 398 } |
| 350 | 399 |
| 351 void PrivetV3Session::SendMessage(const std::string& api, | 400 void PrivetV3Session::SendMessage(const std::string& api, |
| 352 const base::DictionaryValue& input, | 401 const base::DictionaryValue& input, |
| 353 const MessageCallback& callback) { | 402 const MessageCallback& callback) { |
| 354 // TODO(vitalybuka): Implement validating HTTPS certificate using | 403 // TODO(vitalybuka): Implement validating HTTPS certificate using |
| 355 // fingerprint_. | 404 // fingerprint_. |
| 356 if (fingerprint_.empty()) | 405 if (fingerprint_.empty()) |
| 357 return callback.Run(Result::STATUS_SESSIONERROR, base::DictionaryValue()); | 406 return callback.Run(Result::STATUS_SESSIONERROR, base::DictionaryValue()); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 fetchers_.push_back(new FetcherDelegate(weak_ptr_factory_.GetWeakPtr(), | 438 fetchers_.push_back(new FetcherDelegate(weak_ptr_factory_.GetWeakPtr(), |
| 390 privet_auth_token_, callback)); | 439 privet_auth_token_, callback)); |
| 391 return fetchers_.back()->CreateURLFetcher(CreatePrivetURL(api), request_type); | 440 return fetchers_.back()->CreateURLFetcher(CreatePrivetURL(api), request_type); |
| 392 } | 441 } |
| 393 | 442 |
| 394 void PrivetV3Session::DeleteFetcher(const FetcherDelegate* fetcher) { | 443 void PrivetV3Session::DeleteFetcher(const FetcherDelegate* fetcher) { |
| 395 fetchers_.erase(std::find(fetchers_.begin(), fetchers_.end(), fetcher)); | 444 fetchers_.erase(std::find(fetchers_.begin(), fetchers_.end(), fetcher)); |
| 396 } | 445 } |
| 397 | 446 |
| 398 } // namespace local_discovery | 447 } // namespace local_discovery |
| OLD | NEW |