Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / remoting / protocol / negotiating_authenticator_unittest.cc
1 // Copyright (c) 2012 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.
4
5 #include "base/bind.h"
6 #include "net/base/net_errors.h"
7 #include "remoting/base/rsa_key_pair.h"
8 #include "remoting/protocol/authenticator_test_base.h"
9 #include "remoting/protocol/channel_authenticator.h"
10 #include "remoting/protocol/connection_tester.h"
11 #include "remoting/protocol/negotiating_authenticator_base.h"
12 #include "remoting/protocol/negotiating_client_authenticator.h"
13 #include "remoting/protocol/negotiating_host_authenticator.h"
14 #include "remoting/protocol/pairing_registry.h"
15 #include "remoting/protocol/protocol_mock_objects.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h"
19
20 using testing::_;
21 using testing::DeleteArg;
22 using testing::SaveArg;
23
24 namespace remoting {
25 namespace protocol {
26
27 namespace {
28
29 const int kMessageSize = 100;
30 const int kMessages = 1;
31
32 const char kNoClientId[] = "";
33 const char kNoPairedSecret[] = "";
34 const char kTestClientName[] = "client-name";
35 const char kTestClientId[] = "client-id";
36 const char kTestHostId[] = "12345678910123456";
37
38 const char kTestPairedSecret[] = "1111-2222-3333";
39 const char kTestPairedSecretBad[] = "4444-5555-6666";
40 const char kTestPin[] = "123456";
41 const char kTestPinBad[] = "654321";
42
43 }  // namespace
44
45 class NegotiatingAuthenticatorTest : public AuthenticatorTestBase {
46  public:
47   NegotiatingAuthenticatorTest() {
48   }
49   ~NegotiatingAuthenticatorTest() override {}
50
51  protected:
52   void InitAuthenticators(
53       const std::string& client_id,
54       const std::string& client_paired_secret,
55       const std::string& client_interactive_pin,
56       const std::string& host_secret,
57       AuthenticationMethod::HashFunction hash_function,
58       bool client_hmac_only) {
59     std::string host_secret_hash = AuthenticationMethod::ApplyHashFunction(
60         hash_function, kTestHostId, host_secret);
61     host_ = NegotiatingHostAuthenticator::CreateWithSharedSecret(
62         host_cert_, key_pair_, host_secret_hash, hash_function,
63         pairing_registry_);
64
65     std::vector<AuthenticationMethod> methods;
66     methods.push_back(AuthenticationMethod::Spake2Pair());
67     methods.push_back(AuthenticationMethod::Spake2(
68         AuthenticationMethod::HMAC_SHA256));
69     if (!client_hmac_only) {
70       methods.push_back(AuthenticationMethod::Spake2(
71           AuthenticationMethod::NONE));
72     }
73     bool pairing_expected = pairing_registry_.get() != NULL;
74     FetchSecretCallback fetch_secret_callback =
75         base::Bind(&NegotiatingAuthenticatorTest::FetchSecret,
76                    client_interactive_pin,
77                    pairing_expected);
78     client_as_negotiating_authenticator_ = new NegotiatingClientAuthenticator(
79         client_id, client_paired_secret,
80         kTestHostId, fetch_secret_callback,
81         nullptr, methods);
82     client_.reset(client_as_negotiating_authenticator_);
83   }
84
85   void CreatePairingRegistry(bool with_paired_client) {
86     pairing_registry_ = new SynchronousPairingRegistry(
87         make_scoped_ptr(new MockPairingRegistryDelegate()));
88     if (with_paired_client) {
89       PairingRegistry::Pairing pairing(
90           base::Time(), kTestClientName, kTestClientId, kTestPairedSecret);
91       pairing_registry_->AddPairing(pairing);
92     }
93   }
94
95   static void FetchSecret(
96       const std::string& client_secret,
97       bool pairing_supported,
98       bool pairing_expected,
99       const protocol::SecretFetchedCallback& secret_fetched_callback) {
100     secret_fetched_callback.Run(client_secret);
101     ASSERT_EQ(pairing_supported, pairing_expected);
102   }
103
104   void VerifyRejected(Authenticator::RejectionReason reason) {
105     ASSERT_TRUE(client_->state() == Authenticator::REJECTED ||
106                 host_->state() == Authenticator::REJECTED);
107     if (client_->state() == Authenticator::REJECTED) {
108       ASSERT_EQ(client_->rejection_reason(), reason);
109     }
110     if (host_->state() == Authenticator::REJECTED) {
111       ASSERT_EQ(host_->rejection_reason(), reason);
112     }
113   }
114
115   void VerifyAccepted(const AuthenticationMethod& expected_method) {
116     ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
117
118     ASSERT_EQ(Authenticator::ACCEPTED, host_->state());
119     ASSERT_EQ(Authenticator::ACCEPTED, client_->state());
120
121     client_auth_ = client_->CreateChannelAuthenticator();
122     host_auth_ = host_->CreateChannelAuthenticator();
123     RunChannelAuth(false);
124
125     EXPECT_TRUE(client_socket_.get() != NULL);
126     EXPECT_TRUE(host_socket_.get() != NULL);
127
128     StreamConnectionTester tester(host_socket_.get(), client_socket_.get(),
129                                   kMessageSize, kMessages);
130
131     tester.Start();
132     message_loop_.Run();
133     tester.CheckResults();
134     EXPECT_EQ(
135         expected_method,
136         client_as_negotiating_authenticator_->current_method_for_testing());
137   }
138
139   // Use a bare pointer because the storage is managed by the base class.
140   NegotiatingClientAuthenticator* client_as_negotiating_authenticator_;
141
142  private:
143   scoped_refptr<PairingRegistry> pairing_registry_;
144
145   DISALLOW_COPY_AND_ASSIGN(NegotiatingAuthenticatorTest);
146 };
147
148 TEST_F(NegotiatingAuthenticatorTest, SuccessfulAuthHmac) {
149   ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
150       kNoClientId, kNoPairedSecret, kTestPin, kTestPin,
151       AuthenticationMethod::HMAC_SHA256, false));
152   VerifyAccepted(
153       AuthenticationMethod::Spake2(AuthenticationMethod::HMAC_SHA256));
154 }
155
156 TEST_F(NegotiatingAuthenticatorTest, SuccessfulAuthPlain) {
157   ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
158       kNoClientId, kNoPairedSecret, kTestPin, kTestPin,
159       AuthenticationMethod::NONE, false));
160   VerifyAccepted(AuthenticationMethod::Spake2(AuthenticationMethod::NONE));
161 }
162
163 TEST_F(NegotiatingAuthenticatorTest, InvalidSecretHmac) {
164   ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
165       kNoClientId, kNoPairedSecret, kTestPinBad, kTestPin,
166       AuthenticationMethod::HMAC_SHA256, false));
167   ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
168
169   VerifyRejected(Authenticator::INVALID_CREDENTIALS);
170 }
171
172 TEST_F(NegotiatingAuthenticatorTest, InvalidSecretPlain) {
173   ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
174       kNoClientId, kNoPairedSecret, kTestPin, kTestPinBad,
175       AuthenticationMethod::NONE, false));
176   ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
177
178   VerifyRejected(Authenticator::INVALID_CREDENTIALS);
179 }
180
181 TEST_F(NegotiatingAuthenticatorTest, IncompatibleMethods) {
182   ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
183       kNoClientId, kNoPairedSecret, kTestPin, kTestPinBad,
184       AuthenticationMethod::NONE, true));
185   ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
186
187   VerifyRejected(Authenticator::PROTOCOL_ERROR);
188 }
189
190 TEST_F(NegotiatingAuthenticatorTest, PairingNotSupported) {
191   ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
192       kTestClientId, kTestPairedSecret, kTestPin, kTestPin,
193       AuthenticationMethod::HMAC_SHA256, false));
194   ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
195   VerifyAccepted(
196       AuthenticationMethod::Spake2(AuthenticationMethod::HMAC_SHA256));
197 }
198
199 TEST_F(NegotiatingAuthenticatorTest, PairingSupportedButNotPaired) {
200   CreatePairingRegistry(false);
201   ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
202       kNoClientId, kNoPairedSecret, kTestPin, kTestPin,
203       AuthenticationMethod::HMAC_SHA256, false));
204   ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
205   VerifyAccepted(AuthenticationMethod::Spake2Pair());
206 }
207
208 TEST_F(NegotiatingAuthenticatorTest, PairingRevokedPinOkay) {
209   CreatePairingRegistry(false);
210   ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
211       kTestClientId, kTestPairedSecret, kTestPin, kTestPin,
212       AuthenticationMethod::HMAC_SHA256, false));
213   ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
214   VerifyAccepted(AuthenticationMethod::Spake2Pair());
215 }
216
217 TEST_F(NegotiatingAuthenticatorTest, PairingRevokedPinBad) {
218   CreatePairingRegistry(false);
219   ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
220       kTestClientId, kTestPairedSecret, kTestPinBad, kTestPin,
221       AuthenticationMethod::HMAC_SHA256, false));
222   ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
223   VerifyRejected(Authenticator::INVALID_CREDENTIALS);
224 }
225
226 TEST_F(NegotiatingAuthenticatorTest, PairingSucceeded) {
227   CreatePairingRegistry(true);
228   ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
229       kTestClientId, kTestPairedSecret, kTestPinBad, kTestPin,
230       AuthenticationMethod::HMAC_SHA256, false));
231   ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
232   VerifyAccepted(AuthenticationMethod::Spake2Pair());
233 }
234
235 TEST_F(NegotiatingAuthenticatorTest,
236        PairingSucceededInvalidSecretButPinOkay) {
237   CreatePairingRegistry(true);
238   ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
239       kTestClientId, kTestPairedSecretBad, kTestPin, kTestPin,
240       AuthenticationMethod::HMAC_SHA256, false));
241   ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
242   VerifyAccepted(AuthenticationMethod::Spake2Pair());
243 }
244
245 TEST_F(NegotiatingAuthenticatorTest, PairingFailedInvalidSecretAndPin) {
246   CreatePairingRegistry(true);
247   ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
248       kTestClientId, kTestPairedSecretBad, kTestPinBad, kTestPin,
249       AuthenticationMethod::HMAC_SHA256, false));
250   ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
251   VerifyRejected(Authenticator::INVALID_CREDENTIALS);
252 }
253
254 }  // namespace protocol
255 }  // namespace remoting