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

Unified Diff: chrome/browser/local_discovery/privetv3_session_unittest.cc

Issue 877613002: Added pairing with Spake SHA224 key exchange. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@brillo1
Patch Set: Thu Jan 29 23:44:10 PST 2015 Created 5 years, 11 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/local_discovery/privetv3_session_unittest.cc
diff --git a/chrome/browser/local_discovery/privetv3_session_unittest.cc b/chrome/browser/local_discovery/privetv3_session_unittest.cc
index c7e794394ee0a82c9b0dd334c29a50e1a5eaa8be..7b6f195dc5345328f1dca5f6eb03ff119bf55944 100644
--- a/chrome/browser/local_discovery/privetv3_session_unittest.cc
+++ b/chrome/browser/local_discovery/privetv3_session_unittest.cc
@@ -4,9 +4,14 @@
#include "chrome/browser/local_discovery/privetv3_session.h"
+#include "base/base64.h"
+#include "base/strings/stringprintf.h"
#include "chrome/browser/local_discovery/privet_http.h"
#include "content/public/test/test_utils.h"
+#include "crypto/hmac.h"
+#include "crypto/p224_spake.h"
#include "net/url_request/test_url_fetcher_factory.h"
+#include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -15,76 +20,213 @@ namespace local_discovery {
namespace {
using testing::Invoke;
-using testing::InvokeWithoutArgs;
+using testing::SaveArg;
using testing::StrictMock;
using testing::_;
+using PairingType = PrivetV3Session::PairingType;
+using Result = PrivetV3Session::Result;
+
+const char kInfoResponse[] =
+ "{\"version\":\"3.0\","
+ "\"endpoints\":{\"httpsPort\": 443},"
+ "\"authentication\":{"
+ " \"mode\":[\"anonymous\",\"pairing\",\"cloud\"],"
+ " \"pairing\":[\"pinCode\",\"embeddedCode\"],"
+ " \"crypto\":[\"p224_spake2\"]"
+ "}}";
+
+class MockPrivetHTTPClient : public PrivetHTTPClient {
+ public:
+ MockPrivetHTTPClient() {
+ request_context_ =
+ new net::TestURLRequestContextGetter(base::MessageLoopProxy::current());
+ }
+
+ MOCK_METHOD0(GetName, const std::string&());
+ MOCK_METHOD1(
+ CreateInfoOperationPtr,
+ PrivetJSONOperation*(const PrivetJSONOperation::ResultCallback&));
+
+ virtual void RefreshPrivetToken(
+ const PrivetURLFetcher::TokenCallback& callback) override {
+ FAIL();
+ }
+
+ virtual scoped_ptr<PrivetJSONOperation> CreateInfoOperation(
+ const PrivetJSONOperation::ResultCallback& callback) override {
+ return make_scoped_ptr(CreateInfoOperationPtr(callback));
+ }
+
+ virtual scoped_ptr<PrivetURLFetcher> CreateURLFetcher(
+ const GURL& url,
+ net::URLFetcher::RequestType request_type,
+ PrivetURLFetcher::Delegate* delegate) override {
+ return make_scoped_ptr(new PrivetURLFetcher(
+ url, request_type, request_context_.get(), delegate));
+ }
+
+ scoped_refptr<net::TestURLRequestContextGetter> request_context_;
+};
+
+} // namespace
+
class PrivetV3SessionTest : public testing::Test {
public:
- PrivetV3SessionTest() : session_(scoped_ptr<PrivetHTTPClient>()) {}
+ PrivetV3SessionTest()
+ : fetcher_factory_(nullptr),
+ session_(make_scoped_ptr(new MockPrivetHTTPClient())) {}
virtual ~PrivetV3SessionTest() {}
- MOCK_METHOD2(OnInitialized,
- void(PrivetV3Session::Result,
- const std::vector<PrivetV3Session::PairingType>&));
- MOCK_METHOD1(OnPairingStarted, void(PrivetV3Session::Result));
- MOCK_METHOD1(OnCodeConfirmed, void(PrivetV3Session::Result));
- MOCK_METHOD2(OnMessageSend,
- void(PrivetV3Session::Result,
- const base::DictionaryValue& value));
+ MOCK_METHOD2(OnInitialized, void(Result, const std::vector<PairingType>&));
+ MOCK_METHOD1(OnPairingStarted, void(Result));
+ MOCK_METHOD1(OnCodeConfirmed, void(Result));
+ MOCK_METHOD2(OnMessageSend, void(Result, const base::DictionaryValue& value));
+ MOCK_METHOD1(OnPostData, void(const base::DictionaryValue& data));
protected:
virtual void SetUp() override {
EXPECT_CALL(*this, OnInitialized(_, _)).Times(0);
EXPECT_CALL(*this, OnPairingStarted(_)).Times(0);
EXPECT_CALL(*this, OnCodeConfirmed(_)).Times(0);
+ EXPECT_CALL(*this, OnMessageSend(_, _)).Times(0);
+ EXPECT_CALL(*this, OnPostData(_)).Times(0);
+ session_.on_post_data_ =
+ base::Bind(&PrivetV3SessionTest::OnPostData, base::Unretained(this));
}
- PrivetV3Session session_;
base::MessageLoop loop_;
base::Closure quit_closure_;
+ net::FakeURLFetcherFactory fetcher_factory_;
+ PrivetV3Session session_;
};
-TEST_F(PrivetV3SessionTest, Pairing) {
- {
- base::RunLoop run_loop;
- EXPECT_CALL(*this,
- OnInitialized(PrivetV3Session::Result::STATUS_SUCCESS, _))
- .Times(1)
- .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
- session_.Init(base::Bind(&PrivetV3SessionTest::OnInitialized,
- base::Unretained(this)));
- run_loop.Run();
- }
+TEST_F(PrivetV3SessionTest, InitError) {
+ EXPECT_CALL(*this, OnInitialized(Result::STATUS_CONNECTIONERROR, _)).Times(1);
+ fetcher_factory_.SetFakeResponse(GURL("http://host/privet/info"), "",
+ net::HTTP_OK, net::URLRequestStatus::FAILED);
+ session_.Init(
+ base::Bind(&PrivetV3SessionTest::OnInitialized, base::Unretained(this)));
+ base::RunLoop().RunUntilIdle();
+}
- {
- base::RunLoop run_loop;
- EXPECT_CALL(*this,
- OnPairingStarted(PrivetV3Session::Result::STATUS_SUCCESS))
- .Times(1)
- .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
- session_.StartPairing(PrivetV3Session::PairingType::PAIRING_TYPE_PINCODE,
- base::Bind(&PrivetV3SessionTest::OnPairingStarted,
- base::Unretained(this)));
- run_loop.Run();
- }
+TEST_F(PrivetV3SessionTest, VersionError) {
+ std::string response(kInfoResponse);
+ ReplaceFirstSubstringAfterOffset(&response, 0, "3.0", "4.1");
+
+ EXPECT_CALL(*this, OnInitialized(Result::STATUS_SESSIONERROR, _)).Times(1);
+ fetcher_factory_.SetFakeResponse(GURL("http://host/privet/info"), response,
+ net::HTTP_OK,
+ net::URLRequestStatus::SUCCESS);
+ session_.Init(
+ base::Bind(&PrivetV3SessionTest::OnInitialized, base::Unretained(this)));
+ base::RunLoop().RunUntilIdle();
+}
- {
- base::RunLoop run_loop;
- EXPECT_CALL(*this, OnCodeConfirmed(PrivetV3Session::Result::STATUS_SUCCESS))
- .Times(1)
- .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
- session_.ConfirmCode("1234",
- base::Bind(&PrivetV3SessionTest::OnCodeConfirmed,
- base::Unretained(this)));
- run_loop.Run();
- }
+TEST_F(PrivetV3SessionTest, ModeError) {
+ std::string response(kInfoResponse);
+ ReplaceFirstSubstringAfterOffset(&response, 0, "mode", "mode_");
+
+ EXPECT_CALL(*this, OnInitialized(Result::STATUS_SESSIONERROR, _)).Times(1);
+ fetcher_factory_.SetFakeResponse(GURL("http://host/privet/info"), response,
+ net::HTTP_OK,
+ net::URLRequestStatus::SUCCESS);
+ session_.Init(
+ base::Bind(&PrivetV3SessionTest::OnInitialized, base::Unretained(this)));
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(PrivetV3SessionTest, Pairing) {
+ std::vector<PairingType> pairings;
+ EXPECT_CALL(*this, OnInitialized(Result::STATUS_SUCCESS, _))
+ .WillOnce(SaveArg<1>(&pairings));
+ fetcher_factory_.SetFakeResponse(GURL("http://host/privet/info"),
+ kInfoResponse, net::HTTP_OK,
+ net::URLRequestStatus::SUCCESS);
+
+ session_.Init(
+ base::Bind(&PrivetV3SessionTest::OnInitialized, base::Unretained(this)));
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(2u, pairings.size());
+ EXPECT_EQ(PairingType::PAIRING_TYPE_PINCODE, pairings[0]);
+ EXPECT_EQ(PairingType::PAIRING_TYPE_EMBEDDEDCODE, pairings[1]);
+
+ crypto::P224EncryptedKeyExchange spake(
+ crypto::P224EncryptedKeyExchange::kPeerTypeServer, "testPin");
+
+ EXPECT_CALL(*this, OnPairingStarted(Result::STATUS_SUCCESS)).Times(1);
+ EXPECT_CALL(*this, OnPostData(_))
+ .WillOnce(
+ testing::Invoke([this, &spake](const base::DictionaryValue& data) {
+ std::string pairing_type;
+ EXPECT_TRUE(data.GetString("pairing", &pairing_type));
+ EXPECT_EQ("embeddedCode", pairing_type);
+
+ std::string crypto_type;
+ EXPECT_TRUE(data.GetString("crypto", &crypto_type));
+ EXPECT_EQ("p224_spake2", crypto_type);
+
+ std::string device_commitment;
+ base::Base64Encode(spake.GetNextMessage(), &device_commitment);
+ fetcher_factory_.SetFakeResponse(
+ GURL("http://host/privet/v3/pairing/start"),
+ base::StringPrintf(
+ "{\"deviceCommitment\":\"%s\",\"sessionId\":\"testId\"}",
+ device_commitment.c_str()),
+ net::HTTP_OK, net::URLRequestStatus::SUCCESS);
+ }));
+ session_.StartPairing(PairingType::PAIRING_TYPE_EMBEDDEDCODE,
+ base::Bind(&PrivetV3SessionTest::OnPairingStarted,
+ base::Unretained(this)));
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_CALL(*this, OnCodeConfirmed(Result::STATUS_SUCCESS)).Times(1);
+ EXPECT_CALL(*this, OnPostData(_))
+ .WillOnce(
+ testing::Invoke([this, &spake](const base::DictionaryValue& data) {
+ std::string commitment_base64;
+ EXPECT_TRUE(data.GetString("clientCommitment", &commitment_base64));
+ std::string commitment;
+ EXPECT_TRUE(base::Base64Decode(commitment_base64, &commitment));
+
+ std::string session_id;
+ EXPECT_TRUE(data.GetString("sessionId", &session_id));
+ EXPECT_EQ("testId", session_id);
+
+ EXPECT_EQ(spake.ProcessMessage(commitment),
+ crypto::P224EncryptedKeyExchange::kResultPending);
+
+ std::string fingerprint("testFinterprint");
+ std::string fingerprint_base64;
+ base::Base64Encode(fingerprint, &fingerprint_base64);
+
+ crypto::HMAC hmac(crypto::HMAC::SHA256);
+ const std::string& key = spake.GetUnverifiedKey();
+ EXPECT_TRUE(hmac.Init(key));
+ std::string signature(hmac.DigestLength(), ' ');
+ EXPECT_TRUE(hmac.Sign(fingerprint, reinterpret_cast<unsigned char*>(
+ string_as_array(&signature)),
+ signature.size()));
+
+ std::string signature_base64;
+ base::Base64Encode(signature, &signature_base64);
+
+ fetcher_factory_.SetFakeResponse(
+ GURL("http://host/privet/v3/pairing/confirm"),
+ base::StringPrintf(
+ "{\"certFingerprint\":\"%s\",\"certSignature\":\"%s\"}",
+ fingerprint_base64.c_str(), signature_base64.c_str()),
+ net::HTTP_OK, net::URLRequestStatus::SUCCESS);
+ }));
+ session_.ConfirmCode("testPin",
+ base::Bind(&PrivetV3SessionTest::OnCodeConfirmed,
+ base::Unretained(this)));
+ base::RunLoop().RunUntilIdle();
}
// TODO(vitalybuka): replace PrivetHTTPClient with regular URL fetcher and
// implement SendMessage test.
-} // namespace
-
} // namespace local_discovery
« no previous file with comments | « chrome/browser/local_discovery/privetv3_session.cc ('k') | chrome/test/data/extensions/api_test/gcd_private/api/session.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698