Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(975)

Unified Diff: chrome/browser/extensions/api/gcd_private/privet_v3_session.cc

Issue 2704313002: Remove gcdPrivate API code. (Closed)
Patch Set: Remove gcdPrivate API code. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/api/gcd_private/privet_v3_session.cc
diff --git a/chrome/browser/extensions/api/gcd_private/privet_v3_session.cc b/chrome/browser/extensions/api/gcd_private/privet_v3_session.cc
deleted file mode 100644
index 389d2cf7ad8e62990a52d1267b98d2806e49e4c5..0000000000000000000000000000000000000000
--- a/chrome/browser/extensions/api/gcd_private/privet_v3_session.cc
+++ /dev/null
@@ -1,526 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/extensions/api/gcd_private/privet_v3_session.h"
-
-#include "base/base64.h"
-#include "base/json/json_reader.h"
-#include "base/json/json_writer.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/single_thread_task_runner.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "chrome/browser/extensions/api/gcd_private/privet_v3_context_getter.h"
-#include "crypto/hmac.h"
-#include "crypto/p224_spake.h"
-#include "net/base/load_flags.h"
-#include "net/http/http_response_headers.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
-#include "net/url_request/url_fetcher_delegate.h"
-#include "url/gurl.h"
-
-namespace extensions {
-
-namespace {
-
-const char kPrivetV3AuthTokenHeaderPrefix[] = "Authorization: ";
-
-const char kPrivetV3AuthAnonymous[] = "Privet anonymous";
-const char kPrivetV3CryptoP224Spake2[] = "p224_spake2";
-const char kPrivetV3Auto[] = "auto";
-
-const char kPrivetV3InfoKeyAuth[] = "authentication";
-const char kPrivetV3InfoKeyVersion[] = "version";
-const char kPrivetV3InfoVersion[] = "3.0";
-
-const char kPrivetV3KeyAccessToken[] = "accessToken";
-const char kPrivetV3KeyAuthCode[] = "authCode";
-const char kPrivetV3KeyCertFingerprint[] = "certFingerprint";
-const char kPrivetV3KeyCertSignature[] = "certSignature";
-const char kPrivetV3KeyClientCommitment[] = "clientCommitment";
-const char kPrivetV3KeyCrypto[] = "crypto";
-const char kPrivetV3KeyDeviceCommitment[] = "deviceCommitment";
-const char kPrivetV3KeyMode[] = "mode";
-const char kPrivetV3KeyPairing[] = "pairing";
-const char kPrivetV3KeyRequestedScope[] = "requestedScope";
-const char kPrivetV3KeyScope[] = "scope";
-const char kPrivetV3KeySessionId[] = "sessionId";
-const char kPrivetV3KeyTokenType[] = "tokenType";
-const char kPrivetV3KeyError[] = "error";
-
-const char kPrivetV3InfoHttpsPort[] = "endpoints.httpsPort";
-
-const char kPrivetInfoPath[] = "/privet/info";
-const char kPrivetV3PairingStartPath[] = "/privet/v3/pairing/start";
-const char kPrivetV3PairingConfirmPath[] = "/privet/v3/pairing/confirm";
-const char kPrivetV3PairingCancelPath[] = "/privet/v3/pairing/cancel";
-const char kPrivetV3AuthPath[] = "/privet/v3/auth";
-
-const char kContentTypeJSON[] = "application/json";
-
-const int kUrlFetcherTimeoutSec = 60;
-
-using PairingType = PrivetV3Session::PairingType;
-
-bool GetDecodedString(const base::DictionaryValue& response,
- const std::string& key,
- std::string* value) {
- std::string base64;
- return response.GetString(key, &base64) && base::Base64Decode(base64, value);
-}
-
-bool ContainsString(const base::DictionaryValue& dictionary,
- const std::string& key,
- const std::string& expected_value) {
- const base::ListValue* list_of_string = nullptr;
- if (!dictionary.GetList(key, &list_of_string))
- return false;
-
- for (const auto& value : *list_of_string) {
- std::string string_value;
- if (value->GetAsString(&string_value) && string_value == expected_value)
- return true;
- }
- return false;
-}
-
-std::unique_ptr<base::DictionaryValue> GetJson(const net::URLFetcher* source) {
- if (!source->GetStatus().is_success())
- return nullptr;
-
- const net::HttpResponseHeaders* headers = source->GetResponseHeaders();
- if (!headers)
- return nullptr;
-
- std::string content_type;
- if (!headers->GetMimeType(&content_type))
- return nullptr;
-
- if (content_type != kContentTypeJSON)
- return nullptr;
-
- std::string json;
- if (!source->GetResponseAsString(&json))
- return nullptr;
-
- base::JSONReader json_reader(base::JSON_ALLOW_TRAILING_COMMAS);
- return base::DictionaryValue::From(json_reader.ReadToValue(json));
-}
-
-} // namespace
-
-class PrivetV3Session::FetcherDelegate : public net::URLFetcherDelegate {
- public:
- FetcherDelegate(const base::WeakPtr<PrivetV3Session>& session,
- const PrivetV3Session::MessageCallback& callback);
- ~FetcherDelegate() override;
-
- // URLFetcherDelegate methods.
- void OnURLFetchComplete(const net::URLFetcher* source) override;
-
- net::URLFetcher* CreateURLFetcher(const GURL& url,
- net::URLFetcher::RequestType request_type,
- bool orphaned);
-
- private:
- void ReplyAndDestroyItself(Result result, const base::DictionaryValue& value);
- void OnTimeout();
-
- std::unique_ptr<net::URLFetcher> url_fetcher_;
- base::WeakPtr<PrivetV3Session> session_;
- MessageCallback callback_;
-
- base::WeakPtrFactory<FetcherDelegate> weak_ptr_factory_;
- DISALLOW_COPY_AND_ASSIGN(FetcherDelegate);
-};
-
-PrivetV3Session::FetcherDelegate::FetcherDelegate(
- const base::WeakPtr<PrivetV3Session>& session,
- const PrivetV3Session::MessageCallback& callback)
- : session_(session),
- callback_(callback),
- weak_ptr_factory_(this) {}
-
-PrivetV3Session::FetcherDelegate::~FetcherDelegate() {}
-
-void PrivetV3Session::FetcherDelegate::OnURLFetchComplete(
- const net::URLFetcher* source) {
- VLOG(1) << "PrivetURLFetcher url: " << source->GetURL()
- << ", status: " << source->GetStatus().status()
- << ", error: " << source->GetStatus().error()
- << ", response code: " << source->GetResponseCode();
-
- std::unique_ptr<base::DictionaryValue> value = GetJson(source);
- if (!value) {
- return ReplyAndDestroyItself(Result::STATUS_CONNECTIONERROR,
- base::DictionaryValue());
- }
-
- bool has_error = value->HasKey(kPrivetV3KeyError);
- LOG_IF(ERROR, has_error) << "Response: " << value.get();
- ReplyAndDestroyItself(
- has_error ? Result::STATUS_DEVICEERROR : Result::STATUS_SUCCESS, *value);
-}
-
-net::URLFetcher* PrivetV3Session::FetcherDelegate::CreateURLFetcher(
- const GURL& url,
- net::URLFetcher::RequestType request_type,
- bool orphaned) {
- DCHECK(!url_fetcher_);
- DCHECK(session_);
- url_fetcher_ = net::URLFetcher::Create(url, request_type, this,
- NO_TRAFFIC_ANNOTATION_YET);
- auto timeout_task =
- orphaned ? base::Bind(&FetcherDelegate::OnTimeout, base::Owned(this))
- : base::Bind(&FetcherDelegate::OnTimeout,
- weak_ptr_factory_.GetWeakPtr());
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, timeout_task,
- base::TimeDelta::FromSeconds(kUrlFetcherTimeoutSec));
- return url_fetcher_.get();
-}
-
-void PrivetV3Session::FetcherDelegate::ReplyAndDestroyItself(
- Result result,
- const base::DictionaryValue& value) {
- if (session_) {
- if (!callback_.is_null()) {
- callback_.Run(result, value);
- callback_.Reset();
- }
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(&PrivetV3Session::DeleteFetcher, session_,
- base::Unretained(this)));
- session_.reset();
- }
- url_fetcher_.reset();
-}
-
-void PrivetV3Session::FetcherDelegate::OnTimeout() {
- LOG(ERROR) << "PrivetURLFetcher timeout, url: " << url_fetcher_->GetURL();
- ReplyAndDestroyItself(Result::STATUS_CONNECTIONERROR,
- base::DictionaryValue());
-}
-
-PrivetV3Session::PrivetV3Session(
- const scoped_refptr<PrivetV3ContextGetter>& context_getter,
- const net::HostPortPair& host_port)
- : host_port_(host_port),
- context_getter_(context_getter),
- weak_ptr_factory_(this) {
- CHECK(context_getter_);
-}
-
-PrivetV3Session::~PrivetV3Session() {
- Cancel();
-}
-
-void PrivetV3Session::Init(const InitCallback& callback) {
- DCHECK(fetchers_.empty());
- DCHECK(!use_https_);
- DCHECK(session_id_.empty());
- DCHECK(privet_auth_token_.empty());
-
- privet_auth_token_ = kPrivetV3AuthAnonymous;
- StartGetRequest(kPrivetInfoPath,
- base::Bind(&PrivetV3Session::OnInfoDone,
- weak_ptr_factory_.GetWeakPtr(), callback));
-}
-
-void PrivetV3Session::OnInfoDone(const InitCallback& callback,
- Result result,
- const base::DictionaryValue& response) {
- if (result != Result::STATUS_SUCCESS)
- return callback.Run(result, response);
-
- std::string version;
- if (!response.GetString(kPrivetV3InfoKeyVersion, &version) ||
- version != kPrivetV3InfoVersion) {
- LOG(ERROR) << "Response: " << response;
- return callback.Run(Result::STATUS_SESSIONERROR, response);
- }
-
- const base::DictionaryValue* authentication = nullptr;
- const base::ListValue* pairing = nullptr;
- if (!response.GetDictionary(kPrivetV3InfoKeyAuth, &authentication) ||
- !authentication->GetList(kPrivetV3KeyPairing, &pairing)) {
- LOG(ERROR) << "Response: " << response;
- return callback.Run(Result::STATUS_SESSIONERROR, response);
- }
-
- // The only supported crypto.
- if (!ContainsString(*authentication, kPrivetV3KeyCrypto,
- kPrivetV3CryptoP224Spake2) ||
- !ContainsString(*authentication, kPrivetV3KeyMode, kPrivetV3KeyPairing)) {
- LOG(ERROR) << "Response: " << response;
- return callback.Run(Result::STATUS_SESSIONERROR, response);
- }
-
- int port = 0;
- if (!response.GetInteger(kPrivetV3InfoHttpsPort, &port) || port <= 0 ||
- port > std::numeric_limits<uint16_t>::max()) {
- LOG(ERROR) << "Response: " << response;
- return callback.Run(Result::STATUS_SESSIONERROR, response);
- }
- https_port_ = port;
-
- callback.Run(Result::STATUS_SUCCESS, response);
-}
-
-void PrivetV3Session::StartPairing(PairingType pairing_type,
- const ResultCallback& callback) {
- base::DictionaryValue input;
- input.SetString(kPrivetV3KeyPairing,
- extensions::api::gcd_private::ToString(pairing_type));
- input.SetString(kPrivetV3KeyCrypto, kPrivetV3CryptoP224Spake2);
-
- StartPostRequest(kPrivetV3PairingStartPath, input,
- base::Bind(&PrivetV3Session::OnPairingStartDone,
- weak_ptr_factory_.GetWeakPtr(), callback));
-}
-
-void PrivetV3Session::OnPairingStartDone(
- const ResultCallback& callback,
- Result result,
- const base::DictionaryValue& response) {
- if (result != Result::STATUS_SUCCESS)
- return callback.Run(result);
-
- if (!response.GetString(kPrivetV3KeySessionId, &session_id_) ||
- !GetDecodedString(response, kPrivetV3KeyDeviceCommitment, &commitment_)) {
- LOG(ERROR) << "Response: " << response;
- return callback.Run(Result::STATUS_SESSIONERROR);
- }
-
- return callback.Run(Result::STATUS_SUCCESS);
-}
-
-void PrivetV3Session::ConfirmCode(const std::string& code,
- const ResultCallback& callback) {
- if (session_id_.empty()) {
- LOG(ERROR) << "Pairing is not started";
- return callback.Run(Result::STATUS_SESSIONERROR);
- }
-
- spake_.reset(new crypto::P224EncryptedKeyExchange(
- crypto::P224EncryptedKeyExchange::kPeerTypeClient, code));
-
- base::DictionaryValue input;
- input.SetString(kPrivetV3KeySessionId, session_id_);
-
- std::string client_commitment;
- base::Base64Encode(spake_->GetNextMessage(), &client_commitment);
- input.SetString(kPrivetV3KeyClientCommitment, client_commitment);
-
- // Call ProcessMessage after GetNextMessage().
- crypto::P224EncryptedKeyExchange::Result result =
- spake_->ProcessMessage(commitment_);
- DCHECK_EQ(result, crypto::P224EncryptedKeyExchange::kResultPending);
-
- StartPostRequest(kPrivetV3PairingConfirmPath, input,
- base::Bind(&PrivetV3Session::OnPairingConfirmDone,
- weak_ptr_factory_.GetWeakPtr(), callback));
-}
-
-void PrivetV3Session::OnPairingConfirmDone(
- const ResultCallback& callback,
- Result result,
- const base::DictionaryValue& response) {
- if (result != Result::STATUS_SUCCESS)
- return callback.Run(result);
-
- std::string fingerprint;
- std::string signature;
- if (!GetDecodedString(response, kPrivetV3KeyCertFingerprint, &fingerprint) ||
- !GetDecodedString(response, kPrivetV3KeyCertSignature, &signature)) {
- LOG(ERROR) << "Invalid response: " << response;
- return callback.Run(Result::STATUS_SESSIONERROR);
- }
-
- net::SHA256HashValue hash;
- if (fingerprint.size() != sizeof(hash.data)) {
- LOG(ERROR) << "Invalid fingerprint size: " << response;
- return callback.Run(Result::STATUS_SESSIONERROR);
- }
- memcpy(hash.data, fingerprint.data(), sizeof(hash.data));
-
- crypto::HMAC hmac(crypto::HMAC::SHA256);
- // Key will be verified below, using HMAC.
- const std::string& key = spake_->GetUnverifiedKey();
- if (!hmac.Init(reinterpret_cast<const unsigned char*>(key.c_str()),
- key.size()) ||
- !hmac.Verify(fingerprint, signature)) {
- LOG(ERROR) << "Verification failed: " << response;
- return callback.Run(Result::STATUS_BADPAIRINGCODEERROR);
- }
-
- std::string auth_code(hmac.DigestLength(), ' ');
- if (!hmac.Sign(session_id_, reinterpret_cast<unsigned char*>(
- base::string_as_array(&auth_code)),
- auth_code.size())) {
- LOG(FATAL) << "Signing failed";
- return callback.Run(Result::STATUS_SESSIONERROR);
- }
-
- VLOG(1) << "Expected certificate: " << fingerprint;
- context_getter_->AddPairedHost(
- host_port_.host(), hash,
- base::Bind(&PrivetV3Session::OnPairedHostAddedToContext,
- weak_ptr_factory_.GetWeakPtr(), auth_code, callback));
-}
-
-void PrivetV3Session::OnPairedHostAddedToContext(
- const std::string& auth_code,
- const ResultCallback& callback) {
- SwitchToHttps();
-
- std::string auth_code_base64;
- base::Base64Encode(auth_code, &auth_code_base64);
-
- base::DictionaryValue input;
- input.SetString(kPrivetV3KeyAuthCode, auth_code_base64);
- input.SetString(kPrivetV3KeyMode, kPrivetV3KeyPairing);
- input.SetString(kPrivetV3KeyRequestedScope, kPrivetV3Auto);
-
- // Now we can use SendMessage with certificate validation.
- SendMessage(kPrivetV3AuthPath, input,
- base::Bind(&PrivetV3Session::OnAuthenticateDone,
- weak_ptr_factory_.GetWeakPtr(), callback));
-}
-
-void PrivetV3Session::OnAuthenticateDone(
- const ResultCallback& callback,
- Result result,
- const base::DictionaryValue& response) {
- if (result != Result::STATUS_SUCCESS)
- return callback.Run(result);
-
- std::string access_token;
- std::string token_type;
- std::string scope;
- if (!response.GetString(kPrivetV3KeyAccessToken, &access_token) ||
- !response.GetString(kPrivetV3KeyTokenType, &token_type) ||
- !response.GetString(kPrivetV3KeyScope, &scope)) {
- LOG(ERROR) << "Response: " << response;
- return callback.Run(Result::STATUS_SESSIONERROR);
- }
-
- privet_auth_token_ = token_type + " " + access_token;
-
- return callback.Run(Result::STATUS_SUCCESS);
-}
-
-void PrivetV3Session::SendMessage(const std::string& api,
- const base::DictionaryValue& input,
- const MessageCallback& callback) {
- if (!use_https_) {
- LOG(ERROR) << "Session is not paired";
- return callback.Run(Result::STATUS_SESSIONERROR, base::DictionaryValue());
- }
-
- StartPostRequest(api, input, callback);
-}
-
-void PrivetV3Session::RunCallback(const base::Closure& callback) {
- callback.Run();
-}
-
-void PrivetV3Session::StartGetRequest(const std::string& api,
- const MessageCallback& callback) {
- net::URLFetcher* fetcher =
- CreateFetcher(api, net::URLFetcher::RequestType::GET, callback);
- if (!fetcher)
- return;
- fetcher->Start();
-}
-
-void PrivetV3Session::StartPostRequest(const std::string& api,
- const base::DictionaryValue& input,
- const MessageCallback& callback) {
- if (!on_post_data_.is_null())
- on_post_data_.Run(input);
- std::string json;
- base::JSONWriter::WriteWithOptions(
- input, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json);
- net::URLFetcher* fetcher =
- CreateFetcher(api, net::URLFetcher::RequestType::POST, callback);
- if (!fetcher)
- return;
- fetcher->SetUploadData(kContentTypeJSON, json);
- fetcher->Start();
-}
-
-void PrivetV3Session::SwitchToHttps() {
- host_port_.set_port(https_port_);
- use_https_ = true;
-}
-
-GURL PrivetV3Session::CreatePrivetURL(const std::string& path) const {
- GURL url("http://host/");
- GURL::Replacements replacements;
- std::string schema = use_https_ ? "https" : "http";
- replacements.SetSchemeStr(schema);
- std::string host = host_port_.HostForURL();
- replacements.SetHostStr(host);
- std::string port = base::UintToString(host_port_.port());
- replacements.SetPortStr(port);
- replacements.SetPathStr(path);
- url = url.ReplaceComponents(replacements);
- DCHECK(url.is_valid()) << url;
- return url;
-}
-
-net::URLFetcher* PrivetV3Session::CreateFetcher(
- const std::string& api,
- net::URLFetcher::RequestType request_type,
- const MessageCallback& callback) {
- GURL url = CreatePrivetURL(api);
- if (!url.is_valid()) {
- callback.Run(Result::STATUS_SESSIONERROR, base::DictionaryValue());
- return nullptr;
- }
-
- // Don't abort cancel requests after session object is destroyed.
- const bool orphaned = (api == kPrivetV3PairingCancelPath);
- FetcherDelegate* fetcher =
- new FetcherDelegate(weak_ptr_factory_.GetWeakPtr(), callback);
- if (!orphaned)
- fetchers_.push_back(base::WrapUnique(fetcher));
- net::URLFetcher* url_fetcher =
- fetcher->CreateURLFetcher(url, request_type, orphaned);
- url_fetcher->SetLoadFlags(url_fetcher->GetLoadFlags() |
- net::LOAD_BYPASS_PROXY | net::LOAD_DISABLE_CACHE |
- net::LOAD_DO_NOT_SEND_COOKIES);
- url_fetcher->SetRequestContext(context_getter_.get());
- url_fetcher->AddExtraRequestHeader(
- std::string(kPrivetV3AuthTokenHeaderPrefix) + privet_auth_token_);
-
- return url_fetcher;
-}
-
-void PrivetV3Session::DeleteFetcher(const FetcherDelegate* fetcher) {
- for (std::vector<std::unique_ptr<FetcherDelegate>>::iterator iter =
- fetchers_.begin();
- iter != fetchers_.end(); ++iter) {
- if (iter->get() == fetcher) {
- fetchers_.erase(iter);
- break;
- }
- }
-}
-
-void PrivetV3Session::Cancel() {
- // Only session with pairing in process needs to be canceled. Paired sessions
- // (in https mode) does not need to be canceled.
- if (session_id_.empty() || use_https_)
- return;
- base::DictionaryValue input;
- input.SetString(kPrivetV3KeySessionId, session_id_);
- StartPostRequest(kPrivetV3PairingCancelPath, input, MessageCallback());
-}
-
-} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698