OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "base/bind.h" | 5 #include "base/bind.h" |
6 #include "net/base/net_errors.h" | 6 #include "net/base/net_errors.h" |
7 #include "remoting/base/rsa_key_pair.h" | 7 #include "remoting/base/rsa_key_pair.h" |
8 #include "remoting/protocol/authenticator_test_base.h" | 8 #include "remoting/protocol/authenticator_test_base.h" |
9 #include "remoting/protocol/channel_authenticator.h" | 9 #include "remoting/protocol/channel_authenticator.h" |
10 #include "remoting/protocol/connection_tester.h" | 10 #include "remoting/protocol/connection_tester.h" |
11 #include "remoting/protocol/negotiating_authenticator_base.h" | 11 #include "remoting/protocol/negotiating_authenticator_base.h" |
12 #include "remoting/protocol/negotiating_client_authenticator.h" | 12 #include "remoting/protocol/negotiating_client_authenticator.h" |
13 #include "remoting/protocol/negotiating_host_authenticator.h" | 13 #include "remoting/protocol/negotiating_host_authenticator.h" |
14 #include "testing/gmock/include/gmock/gmock.h" | 14 #include "testing/gmock/include/gmock/gmock.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
16 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" | 16 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" |
17 | 17 |
18 using testing::_; | 18 using testing::_; |
19 using testing::DeleteArg; | 19 using testing::DeleteArg; |
20 using testing::SaveArg; | 20 using testing::SaveArg; |
21 | 21 |
22 namespace remoting { | 22 namespace remoting { |
23 namespace protocol { | 23 namespace protocol { |
24 | 24 |
25 namespace { | 25 namespace { |
26 | 26 |
27 const int kMessageSize = 100; | 27 const int kMessageSize = 100; |
28 const int kMessages = 1; | 28 const int kMessages = 1; |
29 | 29 |
30 const char kNoClientId[] = ""; | |
31 const char kTestClientId[] = "client-id"; | |
30 const char kTestHostId[] = "12345678910123456"; | 32 const char kTestHostId[] = "12345678910123456"; |
31 | 33 |
32 const char kTestSharedSecret[] = "1234-1234-5678"; | 34 const char kTestSharedSecret[] = "1234-1234-5678"; |
33 const char kTestSharedSecretBad[] = "0000-0000-0001"; | 35 const char kTestSharedSecretBad[] = "0000-0000-0001"; |
34 | 36 |
35 } // namespace | 37 } // namespace |
36 | 38 |
37 class NegotiatingAuthenticatorTest : public AuthenticatorTestBase { | 39 class NegotiatingAuthenticatorTest : public AuthenticatorTestBase { |
38 public: | 40 public: |
39 NegotiatingAuthenticatorTest() { | 41 NegotiatingAuthenticatorTest() { |
40 } | 42 } |
41 virtual ~NegotiatingAuthenticatorTest() { | 43 virtual ~NegotiatingAuthenticatorTest() { |
42 } | 44 } |
43 | 45 |
44 protected: | 46 protected: |
45 void InitAuthenticators( | 47 void InitAuthenticators( |
48 const std::string& client_id, | |
46 const std::string& client_secret, | 49 const std::string& client_secret, |
47 const std::string& host_secret, | 50 const std::string& host_secret, |
48 AuthenticationMethod::HashFunction hash_function, | 51 AuthenticationMethod::HashFunction hash_function, |
49 bool client_hmac_only) { | 52 bool client_hmac_only, |
53 scoped_refptr<PairingRegistry> pairing_registry) { | |
50 std::string host_secret_hash = AuthenticationMethod::ApplyHashFunction( | 54 std::string host_secret_hash = AuthenticationMethod::ApplyHashFunction( |
51 hash_function, kTestHostId, host_secret); | 55 hash_function, kTestHostId, host_secret); |
52 host_ = NegotiatingHostAuthenticator::CreateWithSharedSecret( | 56 host_ = NegotiatingHostAuthenticator::CreateWithSharedSecret( |
53 host_cert_, key_pair_, host_secret_hash, hash_function); | 57 host_cert_, key_pair_, host_secret_hash, hash_function, |
58 pairing_registry); | |
54 | 59 |
55 std::vector<AuthenticationMethod> methods; | 60 std::vector<AuthenticationMethod> methods; |
61 methods.push_back(AuthenticationMethod::Spake2Pair()); | |
56 methods.push_back(AuthenticationMethod::Spake2( | 62 methods.push_back(AuthenticationMethod::Spake2( |
57 AuthenticationMethod::HMAC_SHA256)); | 63 AuthenticationMethod::HMAC_SHA256)); |
58 if (!client_hmac_only) { | 64 if (!client_hmac_only) { |
59 methods.push_back(AuthenticationMethod::Spake2( | 65 methods.push_back(AuthenticationMethod::Spake2( |
60 AuthenticationMethod::NONE)); | 66 AuthenticationMethod::NONE)); |
61 } | 67 } |
62 client_.reset(new NegotiatingClientAuthenticator( | 68 client_as_negotiating_authenticator_ = new NegotiatingClientAuthenticator( |
69 client_id, client_secret, | |
63 kTestHostId, base::Bind(&NegotiatingAuthenticatorTest::FetchSecret, | 70 kTestHostId, base::Bind(&NegotiatingAuthenticatorTest::FetchSecret, |
64 client_secret), | 71 client_secret), |
65 scoped_ptr<ThirdPartyClientAuthenticator::TokenFetcher>(), methods)); | 72 scoped_ptr<ThirdPartyClientAuthenticator::TokenFetcher>(), methods); |
73 client_.reset(client_as_negotiating_authenticator_); | |
74 } | |
75 | |
76 scoped_refptr<PairingRegistry> CreatePairingRegistry( | |
77 PairingRegistry::Pairing* pairings, size_t num_pairings) { | |
78 PairingRegistry::PairedClients clients; | |
79 for (size_t i = 0; i < num_pairings; ++i) { | |
80 clients[pairings[i].client_id] = pairings[i]; | |
81 } | |
82 scoped_refptr<PairingRegistry> result( | |
83 new PairingRegistry( | |
84 scoped_ptr<PairingRegistry::Delegate>( | |
85 new NotImplementedPairingRegistryDelegate), | |
86 clients)); | |
87 return result; | |
66 } | 88 } |
67 | 89 |
68 static void FetchSecret( | 90 static void FetchSecret( |
69 const std::string& client_secret, | 91 const std::string& client_secret, |
70 const protocol::SecretFetchedCallback& secret_fetched_callback) { | 92 const protocol::SecretFetchedCallback& secret_fetched_callback) { |
71 secret_fetched_callback.Run(client_secret); | 93 secret_fetched_callback.Run(client_secret); |
72 } | 94 } |
95 | |
73 void VerifyRejected(Authenticator::RejectionReason reason) { | 96 void VerifyRejected(Authenticator::RejectionReason reason) { |
74 ASSERT_TRUE((client_->state() == Authenticator::REJECTED && | 97 ASSERT_TRUE(client_->state() == Authenticator::REJECTED || |
75 (client_->rejection_reason() == reason)) || | 98 host_->state() == Authenticator::REJECTED); |
76 (host_->state() == Authenticator::REJECTED && | 99 if (client_->state() == Authenticator::REJECTED) { |
77 (host_->rejection_reason() == reason))); | 100 ASSERT_EQ(client_->rejection_reason(), reason); |
101 } | |
102 if (host_->state() == Authenticator::REJECTED) { | |
103 ASSERT_EQ(host_->rejection_reason(), reason); | |
104 } | |
78 } | 105 } |
79 | 106 |
80 void VerifyAccepted() { | 107 void VerifyAccepted(const AuthenticationMethod& expected_method) { |
81 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 108 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
82 | 109 |
83 ASSERT_EQ(Authenticator::ACCEPTED, host_->state()); | 110 ASSERT_EQ(Authenticator::ACCEPTED, host_->state()); |
84 ASSERT_EQ(Authenticator::ACCEPTED, client_->state()); | 111 ASSERT_EQ(Authenticator::ACCEPTED, client_->state()); |
85 | 112 |
86 client_auth_ = client_->CreateChannelAuthenticator(); | 113 client_auth_ = client_->CreateChannelAuthenticator(); |
87 host_auth_ = host_->CreateChannelAuthenticator(); | 114 host_auth_ = host_->CreateChannelAuthenticator(); |
88 RunChannelAuth(false); | 115 RunChannelAuth(false); |
89 | 116 |
90 EXPECT_TRUE(client_socket_.get() != NULL); | 117 EXPECT_TRUE(client_socket_.get() != NULL); |
91 EXPECT_TRUE(host_socket_.get() != NULL); | 118 EXPECT_TRUE(host_socket_.get() != NULL); |
92 | 119 |
93 StreamConnectionTester tester(host_socket_.get(), client_socket_.get(), | 120 StreamConnectionTester tester(host_socket_.get(), client_socket_.get(), |
94 kMessageSize, kMessages); | 121 kMessageSize, kMessages); |
95 | 122 |
96 tester.Start(); | 123 tester.Start(); |
97 message_loop_.Run(); | 124 message_loop_.Run(); |
98 tester.CheckResults(); | 125 tester.CheckResults(); |
126 EXPECT_EQ(expected_method, | |
127 client_as_negotiating_authenticator_->current_method()); | |
99 } | 128 } |
100 | 129 |
130 // Use a bare pointer because the storage is managed by the base class. | |
131 NegotiatingClientAuthenticator* client_as_negotiating_authenticator_; | |
rmsousa
2013/05/16 00:46:25
Nit: why not just static_cast<NegotiatingAuthentic
Jamie
2013/05/16 19:30:16
It would introduce a hidden, type-unsafe, dependen
| |
132 | |
101 private: | 133 private: |
102 DISALLOW_COPY_AND_ASSIGN(NegotiatingAuthenticatorTest); | 134 DISALLOW_COPY_AND_ASSIGN(NegotiatingAuthenticatorTest); |
103 }; | 135 }; |
104 | 136 |
105 TEST_F(NegotiatingAuthenticatorTest, SuccessfulAuthHmac) { | 137 TEST_F(NegotiatingAuthenticatorTest, SuccessfulAuthHmac) { |
106 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 138 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( |
107 kTestSharedSecret, kTestSharedSecret, | 139 kNoClientId, kTestSharedSecret, kTestSharedSecret, |
108 AuthenticationMethod::HMAC_SHA256, false)); | 140 AuthenticationMethod::HMAC_SHA256, false, NULL)); |
109 VerifyAccepted(); | 141 VerifyAccepted( |
142 AuthenticationMethod::Spake2(AuthenticationMethod::HMAC_SHA256)); | |
110 } | 143 } |
111 | 144 |
112 TEST_F(NegotiatingAuthenticatorTest, SuccessfulAuthPlain) { | 145 TEST_F(NegotiatingAuthenticatorTest, SuccessfulAuthPlain) { |
113 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 146 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( |
114 kTestSharedSecret, kTestSharedSecret, | 147 kNoClientId, kTestSharedSecret, kTestSharedSecret, |
115 AuthenticationMethod::NONE, false)); | 148 AuthenticationMethod::NONE, false, NULL)); |
116 VerifyAccepted(); | 149 VerifyAccepted(AuthenticationMethod::Spake2(AuthenticationMethod::NONE)); |
117 } | 150 } |
118 | 151 |
119 TEST_F(NegotiatingAuthenticatorTest, InvalidSecretHmac) { | 152 TEST_F(NegotiatingAuthenticatorTest, InvalidSecretHmac) { |
120 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 153 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( |
121 kTestSharedSecret, kTestSharedSecretBad, | 154 kNoClientId, kTestSharedSecret, kTestSharedSecretBad, |
122 AuthenticationMethod::HMAC_SHA256, false)); | 155 AuthenticationMethod::HMAC_SHA256, false, NULL)); |
123 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 156 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
124 | 157 |
125 VerifyRejected(Authenticator::INVALID_CREDENTIALS); | 158 VerifyRejected(Authenticator::INVALID_CREDENTIALS); |
126 } | 159 } |
127 | 160 |
128 TEST_F(NegotiatingAuthenticatorTest, InvalidSecretPlain) { | 161 TEST_F(NegotiatingAuthenticatorTest, InvalidSecretPlain) { |
129 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 162 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( |
130 kTestSharedSecret, kTestSharedSecretBad, | 163 kNoClientId, kTestSharedSecret, kTestSharedSecretBad, |
131 AuthenticationMethod::NONE, false)); | 164 AuthenticationMethod::NONE, false, NULL)); |
132 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 165 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
133 | 166 |
134 VerifyRejected(Authenticator::INVALID_CREDENTIALS); | 167 VerifyRejected(Authenticator::INVALID_CREDENTIALS); |
135 } | 168 } |
136 | 169 |
137 TEST_F(NegotiatingAuthenticatorTest, IncompatibleMethods) { | 170 TEST_F(NegotiatingAuthenticatorTest, IncompatibleMethods) { |
138 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 171 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( |
139 kTestSharedSecret, kTestSharedSecretBad, | 172 kNoClientId, kTestSharedSecret, kTestSharedSecretBad, |
140 AuthenticationMethod::NONE, true)); | 173 AuthenticationMethod::NONE, true, NULL)); |
141 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 174 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
142 | 175 |
143 VerifyRejected(Authenticator::PROTOCOL_ERROR); | 176 VerifyRejected(Authenticator::PROTOCOL_ERROR); |
144 } | 177 } |
145 | 178 |
179 TEST_F(NegotiatingAuthenticatorTest, PairingRequestedButNotSupported) { | |
180 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | |
181 kTestClientId, kTestSharedSecret, kTestSharedSecret, | |
182 AuthenticationMethod::HMAC_SHA256, false, NULL)); | |
183 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | |
184 VerifyAccepted( | |
185 AuthenticationMethod::Spake2(AuthenticationMethod::HMAC_SHA256)); | |
186 } | |
187 | |
188 TEST_F(NegotiatingAuthenticatorTest, PairingSupportedButNotPaired) { | |
189 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | |
190 kNoClientId, kTestSharedSecret, kTestSharedSecret, | |
rmsousa
2013/05/16 00:52:39
This is only passing because the same string is be
Jamie
2013/05/16 19:30:16
Ah yes. I knew there was something I intended to f
| |
191 AuthenticationMethod::HMAC_SHA256, false, | |
192 CreatePairingRegistry(NULL, 0))); | |
193 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | |
194 VerifyAccepted(AuthenticationMethod::Spake2Pair()); | |
195 } | |
196 | |
197 TEST_F(NegotiatingAuthenticatorTest, RevokedPairing) { | |
198 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | |
199 kTestClientId, kTestSharedSecret, kTestSharedSecret, | |
200 AuthenticationMethod::HMAC_SHA256, false, | |
201 CreatePairingRegistry(NULL, 0))); | |
202 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | |
203 VerifyAccepted(AuthenticationMethod::Spake2Pair()); | |
204 } | |
205 | |
206 TEST_F(NegotiatingAuthenticatorTest, SuccessfulPairing) { | |
207 PairingRegistry::Pairing pairing; | |
208 pairing.client_id = kTestClientId; | |
209 pairing.shared_secret = kTestSharedSecret; | |
210 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | |
211 kTestClientId, kTestSharedSecret, kTestSharedSecret, | |
212 AuthenticationMethod::HMAC_SHA256, false, | |
213 CreatePairingRegistry(&pairing, 1))); | |
214 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | |
215 VerifyAccepted(AuthenticationMethod::Spake2Pair()); | |
216 } | |
217 | |
218 TEST_F(NegotiatingAuthenticatorTest, FailedPairingInvalidSecret) { | |
219 PairingRegistry::Pairing pairing; | |
220 pairing.client_id = kTestClientId; | |
221 pairing.shared_secret = kTestSharedSecret; | |
222 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | |
223 kTestClientId, kTestSharedSecretBad, kTestSharedSecret, | |
224 AuthenticationMethod::HMAC_SHA256, false, | |
225 CreatePairingRegistry(&pairing, 1))); | |
226 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | |
227 VerifyRejected(Authenticator::INVALID_CREDENTIALS); | |
228 } | |
229 | |
146 } // namespace protocol | 230 } // namespace protocol |
147 } // namespace remoting | 231 } // namespace remoting |
OLD | NEW |