Chromium Code Reviews| 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[] = "1234-1234-5678"; | |
|
rmsousa
2013/05/21 23:17:07
Nit: Since we're fixing this file, might as well u
Jamie
2013/05/22 00:19:14
Done.
| |
| 38 const char kTestPinBad[] = "0000-0000-0001"; | |
| 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(expected_method, | |
| 131 client_as_negotiating_authenticator_->current_method()); | |
| 99 } | 132 } |
| 100 | 133 |
| 134 // Use a bare pointer because the storage is managed by the base class. | |
| 135 NegotiatingClientAuthenticator* client_as_negotiating_authenticator_; | |
| 136 | |
| 101 private: | 137 private: |
| 102 DISALLOW_COPY_AND_ASSIGN(NegotiatingAuthenticatorTest); | 138 DISALLOW_COPY_AND_ASSIGN(NegotiatingAuthenticatorTest); |
| 103 }; | 139 }; |
| 104 | 140 |
| 105 TEST_F(NegotiatingAuthenticatorTest, SuccessfulAuthHmac) { | 141 TEST_F(NegotiatingAuthenticatorTest, SuccessfulAuthHmac) { |
| 106 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 142 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( |
| 107 kTestSharedSecret, kTestSharedSecret, | 143 kNoClientId, kNoPairedSecret, kTestPin, kTestPin, |
| 108 AuthenticationMethod::HMAC_SHA256, false)); | 144 AuthenticationMethod::HMAC_SHA256, false, NULL)); |
| 109 VerifyAccepted(); | 145 VerifyAccepted( |
| 146 AuthenticationMethod::Spake2(AuthenticationMethod::HMAC_SHA256)); | |
| 110 } | 147 } |
| 111 | 148 |
| 112 TEST_F(NegotiatingAuthenticatorTest, SuccessfulAuthPlain) { | 149 TEST_F(NegotiatingAuthenticatorTest, SuccessfulAuthPlain) { |
| 113 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 150 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( |
| 114 kTestSharedSecret, kTestSharedSecret, | 151 kNoClientId, kNoPairedSecret, kTestPin, kTestPin, |
| 115 AuthenticationMethod::NONE, false)); | 152 AuthenticationMethod::NONE, false, NULL)); |
| 116 VerifyAccepted(); | 153 VerifyAccepted(AuthenticationMethod::Spake2(AuthenticationMethod::NONE)); |
| 117 } | 154 } |
| 118 | 155 |
| 119 TEST_F(NegotiatingAuthenticatorTest, InvalidSecretHmac) { | 156 TEST_F(NegotiatingAuthenticatorTest, InvalidSecretHmac) { |
| 120 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 157 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( |
| 121 kTestSharedSecret, kTestSharedSecretBad, | 158 kNoClientId, kNoPairedSecret, kTestPinBad, kTestPin, |
| 122 AuthenticationMethod::HMAC_SHA256, false)); | 159 AuthenticationMethod::HMAC_SHA256, false, NULL)); |
| 123 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 160 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
| 124 | 161 |
| 125 VerifyRejected(Authenticator::INVALID_CREDENTIALS); | 162 VerifyRejected(Authenticator::INVALID_CREDENTIALS); |
| 126 } | 163 } |
| 127 | 164 |
| 128 TEST_F(NegotiatingAuthenticatorTest, InvalidSecretPlain) { | 165 TEST_F(NegotiatingAuthenticatorTest, InvalidSecretPlain) { |
| 129 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 166 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( |
| 130 kTestSharedSecret, kTestSharedSecretBad, | 167 kNoClientId, kNoPairedSecret, kTestPin, kTestPinBad, |
| 131 AuthenticationMethod::NONE, false)); | 168 AuthenticationMethod::NONE, false, NULL)); |
| 132 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 169 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
| 133 | 170 |
| 134 VerifyRejected(Authenticator::INVALID_CREDENTIALS); | 171 VerifyRejected(Authenticator::INVALID_CREDENTIALS); |
| 135 } | 172 } |
| 136 | 173 |
| 137 TEST_F(NegotiatingAuthenticatorTest, IncompatibleMethods) { | 174 TEST_F(NegotiatingAuthenticatorTest, IncompatibleMethods) { |
| 138 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 175 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( |
| 139 kTestSharedSecret, kTestSharedSecretBad, | 176 kNoClientId, kNoPairedSecret, kTestPin, kTestPinBad, |
| 140 AuthenticationMethod::NONE, true)); | 177 AuthenticationMethod::NONE, true, NULL)); |
| 141 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 178 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
| 142 | 179 |
| 143 VerifyRejected(Authenticator::PROTOCOL_ERROR); | 180 VerifyRejected(Authenticator::PROTOCOL_ERROR); |
| 144 } | 181 } |
| 145 | 182 |
| 183 TEST_F(NegotiatingAuthenticatorTest, PairingNotSupported) { | |
| 184 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | |
| 185 kTestClientId, kTestPairedSecret, kTestPin, kTestPin, | |
| 186 AuthenticationMethod::HMAC_SHA256, false, NULL)); | |
| 187 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | |
| 188 VerifyAccepted( | |
| 189 AuthenticationMethod::Spake2(AuthenticationMethod::HMAC_SHA256)); | |
| 190 } | |
| 191 | |
| 192 TEST_F(NegotiatingAuthenticatorTest, PairingSupportedButNotPaired) { | |
| 193 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | |
| 194 kNoClientId, kNoPairedSecret, kTestPin, kTestPin, | |
| 195 AuthenticationMethod::HMAC_SHA256, false, | |
| 196 CreatePairingRegistry(NULL, 0))); | |
| 197 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | |
| 198 VerifyAccepted(AuthenticationMethod::Spake2Pair()); | |
| 199 } | |
| 200 | |
| 201 TEST_F(NegotiatingAuthenticatorTest, PairingRevokedPinOkay) { | |
| 202 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | |
| 203 kTestClientId, kTestPairedSecret, kTestPin, kTestPin, | |
| 204 AuthenticationMethod::HMAC_SHA256, false, | |
| 205 CreatePairingRegistry(NULL, 0))); | |
| 206 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | |
| 207 VerifyAccepted(AuthenticationMethod::Spake2Pair()); | |
| 208 } | |
| 209 | |
| 210 TEST_F(NegotiatingAuthenticatorTest, PairingRevokedPinBad) { | |
| 211 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | |
| 212 kTestClientId, kTestPairedSecret, kTestPinBad, kTestPin, | |
| 213 AuthenticationMethod::HMAC_SHA256, false, | |
| 214 CreatePairingRegistry(NULL, 0))); | |
| 215 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | |
| 216 VerifyRejected(Authenticator::INVALID_CREDENTIALS); | |
| 217 } | |
| 218 | |
| 219 TEST_F(NegotiatingAuthenticatorTest, PairingSucceeded) { | |
| 220 PairingRegistry::Pairing pairing; | |
| 221 pairing.client_id = kTestClientId; | |
| 222 pairing.shared_secret = kTestPairedSecret; | |
| 223 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | |
| 224 kTestClientId, kTestPairedSecret, kTestPinBad, kTestPin, | |
| 225 AuthenticationMethod::HMAC_SHA256, false, | |
| 226 CreatePairingRegistry(&pairing, 1))); | |
| 227 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | |
| 228 VerifyAccepted(AuthenticationMethod::Spake2Pair()); | |
| 229 } | |
| 230 | |
| 231 TEST_F(NegotiatingAuthenticatorTest, PairingSucceededInvalidSecretButPinOkay) { | |
| 232 PairingRegistry::Pairing pairing; | |
| 233 pairing.client_id = kTestClientId; | |
| 234 pairing.shared_secret = kTestPairedSecret; | |
| 235 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | |
| 236 kTestClientId, kTestPairedSecretBad, kTestPin, kTestPin, | |
| 237 AuthenticationMethod::HMAC_SHA256, false, | |
| 238 CreatePairingRegistry(&pairing, 1))); | |
| 239 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | |
| 240 VerifyAccepted(AuthenticationMethod::Spake2Pair()); | |
| 241 } | |
| 242 | |
| 243 TEST_F(NegotiatingAuthenticatorTest, PairingFailedInvalidSecretAndPin) { | |
| 244 PairingRegistry::Pairing pairing; | |
| 245 pairing.client_id = kTestClientId; | |
| 246 pairing.shared_secret = kTestPairedSecret; | |
| 247 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | |
| 248 kTestClientId, kTestPairedSecretBad, kTestPinBad, kTestPin, | |
| 249 AuthenticationMethod::HMAC_SHA256, false, | |
| 250 CreatePairingRegistry(&pairing, 1))); | |
| 251 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | |
| 252 VerifyRejected(Authenticator::INVALID_CREDENTIALS); | |
| 253 } | |
| 254 | |
| 146 } // namespace protocol | 255 } // namespace protocol |
| 147 } // namespace remoting | 256 } // namespace remoting |
| OLD | NEW |