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