Upstream version 10.39.225.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   virtual ~NegotiatingAuthenticatorTest() {
50   }
51
52  protected:
53   void InitAuthenticators(
54       const std::string& client_id,
55       const std::string& client_paired_secret,
56       const std::string& client_interactive_pin,
57       const std::string& host_secret,
58       AuthenticationMethod::HashFunction hash_function,
59       bool client_hmac_only) {
60     std::string host_secret_hash = AuthenticationMethod::ApplyHashFunction(
61         hash_function, kTestHostId, host_secret);
62     host_ = NegotiatingHostAuthenticator::CreateWithSharedSecret(
63         host_cert_, key_pair_, host_secret_hash, hash_function,
64         pairing_registry_);
65
66     std::vector<AuthenticationMethod> methods;
67     methods.push_back(AuthenticationMethod::Spake2Pair());
68     methods.push_back(AuthenticationMethod::Spake2(
69         AuthenticationMethod::HMAC_SHA256));
70     if (!client_hmac_only) {
71       methods.push_back(AuthenticationMethod::Spake2(
72           AuthenticationMethod::NONE));
73     }
74     bool pairing_expected = pairing_registry_.get() != NULL;
75     FetchSecretCallback fetch_secret_callback =
76         base::Bind(&NegotiatingAuthenticatorTest::FetchSecret,
77                    client_interactive_pin,
78                    pairing_expected);
79     client_as_negotiating_authenticator_ = new NegotiatingClientAuthenticator(
80         client_id, client_paired_secret,
81         kTestHostId, fetch_secret_callback,
82         scoped_ptr<ThirdPartyClientAuthenticator::TokenFetcher>(), methods);
83     client_.reset(client_as_negotiating_authenticator_);
84   }
85
86   void CreatePairingRegistry(bool with_paired_client) {
87     pairing_registry_ = new SynchronousPairingRegistry(
88         scoped_ptr<PairingRegistry::Delegate>(
89             new MockPairingRegistryDelegate()));
90     if (with_paired_client) {
91       PairingRegistry::Pairing pairing(
92           base::Time(), kTestClientName, kTestClientId, kTestPairedSecret);
93       pairing_registry_->AddPairing(pairing);
94     }
95   }
96
97   static void FetchSecret(
98       const std::string& client_secret,
99       bool pairing_supported,
100       bool pairing_expected,
101       const protocol::SecretFetchedCallback& secret_fetched_callback) {
102     secret_fetched_callback.Run(client_secret);
103     ASSERT_EQ(pairing_supported, pairing_expected);
104   }
105
106   void VerifyRejected(Authenticator::RejectionReason reason) {
107     ASSERT_TRUE(client_->state() == Authenticator::REJECTED ||
108                 host_->state() == Authenticator::REJECTED);
109     if (client_->state() == Authenticator::REJECTED) {
110       ASSERT_EQ(client_->rejection_reason(), reason);
111     }
112     if (host_->state() == Authenticator::REJECTED) {
113       ASSERT_EQ(host_->rejection_reason(), reason);
114     }
115   }
116
117   void VerifyAccepted(const AuthenticationMethod& expected_method) {
118     ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
119
120     ASSERT_EQ(Authenticator::ACCEPTED, host_->state());
121     ASSERT_EQ(Authenticator::ACCEPTED, client_->state());
122
123     client_auth_ = client_->CreateChannelAuthenticator();
124     host_auth_ = host_->CreateChannelAuthenticator();
125     RunChannelAuth(false);
126
127     EXPECT_TRUE(client_socket_.get() != NULL);
128     EXPECT_TRUE(host_socket_.get() != NULL);
129
130     StreamConnectionTester tester(host_socket_.get(), client_socket_.get(),
131                                   kMessageSize, kMessages);
132
133     tester.Start();
134     message_loop_.Run();
135     tester.CheckResults();
136     EXPECT_EQ(
137         expected_method,
138         client_as_negotiating_authenticator_->current_method_for_testing());
139   }
140
141   // Use a bare pointer because the storage is managed by the base class.
142   NegotiatingClientAuthenticator* client_as_negotiating_authenticator_;
143
144  private:
145   scoped_refptr<PairingRegistry> pairing_registry_;
146
147   DISALLOW_COPY_AND_ASSIGN(NegotiatingAuthenticatorTest);
148 };
149
150 TEST_F(NegotiatingAuthenticatorTest, SuccessfulAuthHmac) {
151   ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
152       kNoClientId, kNoPairedSecret, kTestPin, kTestPin,
153       AuthenticationMethod::HMAC_SHA256, false));
154   VerifyAccepted(
155       AuthenticationMethod::Spake2(AuthenticationMethod::HMAC_SHA256));
156 }
157
158 TEST_F(NegotiatingAuthenticatorTest, SuccessfulAuthPlain) {
159   ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
160       kNoClientId, kNoPairedSecret, kTestPin, kTestPin,
161       AuthenticationMethod::NONE, false));
162   VerifyAccepted(AuthenticationMethod::Spake2(AuthenticationMethod::NONE));
163 }
164
165 TEST_F(NegotiatingAuthenticatorTest, InvalidSecretHmac) {
166   ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
167       kNoClientId, kNoPairedSecret, kTestPinBad, kTestPin,
168       AuthenticationMethod::HMAC_SHA256, false));
169   ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
170
171   VerifyRejected(Authenticator::INVALID_CREDENTIALS);
172 }
173
174 TEST_F(NegotiatingAuthenticatorTest, InvalidSecretPlain) {
175   ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
176       kNoClientId, kNoPairedSecret, kTestPin, kTestPinBad,
177       AuthenticationMethod::NONE, false));
178   ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
179
180   VerifyRejected(Authenticator::INVALID_CREDENTIALS);
181 }
182
183 TEST_F(NegotiatingAuthenticatorTest, IncompatibleMethods) {
184   ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
185       kNoClientId, kNoPairedSecret, kTestPin, kTestPinBad,
186       AuthenticationMethod::NONE, true));
187   ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
188
189   VerifyRejected(Authenticator::PROTOCOL_ERROR);
190 }
191
192 TEST_F(NegotiatingAuthenticatorTest, PairingNotSupported) {
193   ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
194       kTestClientId, kTestPairedSecret, kTestPin, kTestPin,
195       AuthenticationMethod::HMAC_SHA256, false));
196   ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
197   VerifyAccepted(
198       AuthenticationMethod::Spake2(AuthenticationMethod::HMAC_SHA256));
199 }
200
201 TEST_F(NegotiatingAuthenticatorTest, PairingSupportedButNotPaired) {
202   CreatePairingRegistry(false);
203   ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
204       kNoClientId, kNoPairedSecret, kTestPin, kTestPin,
205       AuthenticationMethod::HMAC_SHA256, false));
206   ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
207   VerifyAccepted(AuthenticationMethod::Spake2Pair());
208 }
209
210 TEST_F(NegotiatingAuthenticatorTest, PairingRevokedPinOkay) {
211   CreatePairingRegistry(false);
212   ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
213       kTestClientId, kTestPairedSecret, kTestPin, kTestPin,
214       AuthenticationMethod::HMAC_SHA256, false));
215   ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
216   VerifyAccepted(AuthenticationMethod::Spake2Pair());
217 }
218
219 TEST_F(NegotiatingAuthenticatorTest, PairingRevokedPinBad) {
220   CreatePairingRegistry(false);
221   ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
222       kTestClientId, kTestPairedSecret, kTestPinBad, kTestPin,
223       AuthenticationMethod::HMAC_SHA256, false));
224   ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
225   VerifyRejected(Authenticator::INVALID_CREDENTIALS);
226 }
227
228 TEST_F(NegotiatingAuthenticatorTest, PairingSucceeded) {
229   CreatePairingRegistry(true);
230   ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
231       kTestClientId, kTestPairedSecret, kTestPinBad, kTestPin,
232       AuthenticationMethod::HMAC_SHA256, false));
233   ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
234   VerifyAccepted(AuthenticationMethod::Spake2Pair());
235 }
236
237 TEST_F(NegotiatingAuthenticatorTest,
238        PairingSucceededInvalidSecretButPinOkay) {
239   CreatePairingRegistry(true);
240   ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
241       kTestClientId, kTestPairedSecretBad, kTestPin, kTestPin,
242       AuthenticationMethod::HMAC_SHA256, false));
243   ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
244   VerifyAccepted(AuthenticationMethod::Spake2Pair());
245 }
246
247 TEST_F(NegotiatingAuthenticatorTest, PairingFailedInvalidSecretAndPin) {
248   CreatePairingRegistry(true);
249   ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
250       kTestClientId, kTestPairedSecretBad, kTestPinBad, kTestPin,
251       AuthenticationMethod::HMAC_SHA256, false));
252   ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
253   VerifyRejected(Authenticator::INVALID_CREDENTIALS);
254 }
255
256 }  // namespace protocol
257 }  // namespace remoting