| 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 "remoting/protocol/pairing_registry.h" | 14 #include "remoting/protocol/pairing_registry.h" |
| 15 #include "remoting/protocol/protocol_mock_objects.h" |
| 15 #include "testing/gmock/include/gmock/gmock.h" | 16 #include "testing/gmock/include/gmock/gmock.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 17 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" | 18 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" |
| 18 | 19 |
| 19 using testing::_; | 20 using testing::_; |
| 20 using testing::DeleteArg; | 21 using testing::DeleteArg; |
| 21 using testing::SaveArg; | 22 using testing::SaveArg; |
| 22 | 23 |
| 23 namespace remoting { | 24 namespace remoting { |
| 24 namespace protocol { | 25 namespace protocol { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 47 virtual ~NegotiatingAuthenticatorTest() { | 48 virtual ~NegotiatingAuthenticatorTest() { |
| 48 } | 49 } |
| 49 | 50 |
| 50 protected: | 51 protected: |
| 51 void InitAuthenticators( | 52 void InitAuthenticators( |
| 52 const std::string& client_id, | 53 const std::string& client_id, |
| 53 const std::string& client_paired_secret, | 54 const std::string& client_paired_secret, |
| 54 const std::string& client_interactive_pin, | 55 const std::string& client_interactive_pin, |
| 55 const std::string& host_secret, | 56 const std::string& host_secret, |
| 56 AuthenticationMethod::HashFunction hash_function, | 57 AuthenticationMethod::HashFunction hash_function, |
| 57 bool client_hmac_only, | 58 bool client_hmac_only) { |
| 58 scoped_refptr<PairingRegistry> pairing_registry) { | |
| 59 std::string host_secret_hash = AuthenticationMethod::ApplyHashFunction( | 59 std::string host_secret_hash = AuthenticationMethod::ApplyHashFunction( |
| 60 hash_function, kTestHostId, host_secret); | 60 hash_function, kTestHostId, host_secret); |
| 61 host_ = NegotiatingHostAuthenticator::CreateWithSharedSecret( | 61 host_ = NegotiatingHostAuthenticator::CreateWithSharedSecret( |
| 62 host_cert_, key_pair_, host_secret_hash, hash_function, | 62 host_cert_, key_pair_, host_secret_hash, hash_function, |
| 63 pairing_registry); | 63 pairing_registry_); |
| 64 | 64 |
| 65 std::vector<AuthenticationMethod> methods; | 65 std::vector<AuthenticationMethod> methods; |
| 66 methods.push_back(AuthenticationMethod::Spake2Pair()); | 66 methods.push_back(AuthenticationMethod::Spake2Pair()); |
| 67 methods.push_back(AuthenticationMethod::Spake2( | 67 methods.push_back(AuthenticationMethod::Spake2( |
| 68 AuthenticationMethod::HMAC_SHA256)); | 68 AuthenticationMethod::HMAC_SHA256)); |
| 69 if (!client_hmac_only) { | 69 if (!client_hmac_only) { |
| 70 methods.push_back(AuthenticationMethod::Spake2( | 70 methods.push_back(AuthenticationMethod::Spake2( |
| 71 AuthenticationMethod::NONE)); | 71 AuthenticationMethod::NONE)); |
| 72 } | 72 } |
| 73 bool pairing_expected = pairing_registry.get() != NULL; | 73 bool pairing_expected = pairing_registry_.get() != NULL; |
| 74 FetchSecretCallback fetch_secret_callback = | 74 FetchSecretCallback fetch_secret_callback = |
| 75 base::Bind(&NegotiatingAuthenticatorTest::FetchSecret, | 75 base::Bind(&NegotiatingAuthenticatorTest::FetchSecret, |
| 76 client_interactive_pin, | 76 client_interactive_pin, |
| 77 pairing_expected); | 77 pairing_expected); |
| 78 client_as_negotiating_authenticator_ = new NegotiatingClientAuthenticator( | 78 client_as_negotiating_authenticator_ = new NegotiatingClientAuthenticator( |
| 79 client_id, client_paired_secret, | 79 client_id, client_paired_secret, |
| 80 kTestHostId, fetch_secret_callback, | 80 kTestHostId, fetch_secret_callback, |
| 81 scoped_ptr<ThirdPartyClientAuthenticator::TokenFetcher>(), methods); | 81 scoped_ptr<ThirdPartyClientAuthenticator::TokenFetcher>(), methods); |
| 82 client_.reset(client_as_negotiating_authenticator_); | 82 client_.reset(client_as_negotiating_authenticator_); |
| 83 } | 83 } |
| 84 | 84 |
| 85 scoped_refptr<PairingRegistry> CreatePairingRegistry( | 85 void CreatePairingRegistry(bool with_paired_client) { |
| 86 PairingRegistry::Pairing* pairings, size_t num_pairings) { | 86 mock_delegate_ = new MockPairingRegistryDelegate; |
| 87 PairingRegistry::PairedClients clients; | 87 if (with_paired_client) { |
| 88 for (size_t i = 0; i < num_pairings; ++i) { | 88 PairingRegistry::Pairing pairing; |
| 89 clients[pairings[i].client_id] = pairings[i]; | 89 pairing.client_id = kTestClientId; |
| 90 pairing.shared_secret = kTestPairedSecret; |
| 91 mock_delegate_->AddPairing(pairing); |
| 90 } | 92 } |
| 91 scoped_refptr<PairingRegistry> result( | 93 pairing_registry_ = new PairingRegistry( |
| 92 new PairingRegistry( | 94 scoped_ptr<PairingRegistry::Delegate>(mock_delegate_)); |
| 93 scoped_ptr<PairingRegistry::Delegate>( | |
| 94 new NotImplementedPairingRegistryDelegate), | |
| 95 clients)); | |
| 96 return result; | |
| 97 } | 95 } |
| 98 | 96 |
| 99 static void FetchSecret( | 97 static void FetchSecret( |
| 100 const std::string& client_secret, | 98 const std::string& client_secret, |
| 101 bool pairing_supported, | 99 bool pairing_supported, |
| 102 bool pairing_expected, | 100 bool pairing_expected, |
| 103 const protocol::SecretFetchedCallback& secret_fetched_callback) { | 101 const protocol::SecretFetchedCallback& secret_fetched_callback) { |
| 104 secret_fetched_callback.Run(client_secret); | 102 secret_fetched_callback.Run(client_secret); |
| 105 ASSERT_EQ(pairing_supported, pairing_expected); | 103 ASSERT_EQ(pairing_supported, pairing_expected); |
| 106 } | 104 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 136 message_loop_.Run(); | 134 message_loop_.Run(); |
| 137 tester.CheckResults(); | 135 tester.CheckResults(); |
| 138 EXPECT_EQ( | 136 EXPECT_EQ( |
| 139 expected_method, | 137 expected_method, |
| 140 client_as_negotiating_authenticator_->current_method_for_testing()); | 138 client_as_negotiating_authenticator_->current_method_for_testing()); |
| 141 } | 139 } |
| 142 | 140 |
| 143 // Use a bare pointer because the storage is managed by the base class. | 141 // Use a bare pointer because the storage is managed by the base class. |
| 144 NegotiatingClientAuthenticator* client_as_negotiating_authenticator_; | 142 NegotiatingClientAuthenticator* client_as_negotiating_authenticator_; |
| 145 | 143 |
| 144 protected: |
| 145 MockPairingRegistryDelegate* mock_delegate_; |
| 146 |
| 146 private: | 147 private: |
| 148 scoped_refptr<PairingRegistry> pairing_registry_; |
| 149 |
| 147 DISALLOW_COPY_AND_ASSIGN(NegotiatingAuthenticatorTest); | 150 DISALLOW_COPY_AND_ASSIGN(NegotiatingAuthenticatorTest); |
| 148 }; | 151 }; |
| 149 | 152 |
| 150 TEST_F(NegotiatingAuthenticatorTest, SuccessfulAuthHmac) { | 153 TEST_F(NegotiatingAuthenticatorTest, SuccessfulAuthHmac) { |
| 151 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 154 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( |
| 152 kNoClientId, kNoPairedSecret, kTestPin, kTestPin, | 155 kNoClientId, kNoPairedSecret, kTestPin, kTestPin, |
| 153 AuthenticationMethod::HMAC_SHA256, false, NULL)); | 156 AuthenticationMethod::HMAC_SHA256, false)); |
| 154 VerifyAccepted( | 157 VerifyAccepted( |
| 155 AuthenticationMethod::Spake2(AuthenticationMethod::HMAC_SHA256)); | 158 AuthenticationMethod::Spake2(AuthenticationMethod::HMAC_SHA256)); |
| 156 } | 159 } |
| 157 | 160 |
| 158 TEST_F(NegotiatingAuthenticatorTest, SuccessfulAuthPlain) { | 161 TEST_F(NegotiatingAuthenticatorTest, SuccessfulAuthPlain) { |
| 159 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 162 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( |
| 160 kNoClientId, kNoPairedSecret, kTestPin, kTestPin, | 163 kNoClientId, kNoPairedSecret, kTestPin, kTestPin, |
| 161 AuthenticationMethod::NONE, false, NULL)); | 164 AuthenticationMethod::NONE, false)); |
| 162 VerifyAccepted(AuthenticationMethod::Spake2(AuthenticationMethod::NONE)); | 165 VerifyAccepted(AuthenticationMethod::Spake2(AuthenticationMethod::NONE)); |
| 163 } | 166 } |
| 164 | 167 |
| 165 TEST_F(NegotiatingAuthenticatorTest, InvalidSecretHmac) { | 168 TEST_F(NegotiatingAuthenticatorTest, InvalidSecretHmac) { |
| 166 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 169 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( |
| 167 kNoClientId, kNoPairedSecret, kTestPinBad, kTestPin, | 170 kNoClientId, kNoPairedSecret, kTestPinBad, kTestPin, |
| 168 AuthenticationMethod::HMAC_SHA256, false, NULL)); | 171 AuthenticationMethod::HMAC_SHA256, false)); |
| 169 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 172 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
| 170 | 173 |
| 171 VerifyRejected(Authenticator::INVALID_CREDENTIALS); | 174 VerifyRejected(Authenticator::INVALID_CREDENTIALS); |
| 172 } | 175 } |
| 173 | 176 |
| 174 TEST_F(NegotiatingAuthenticatorTest, InvalidSecretPlain) { | 177 TEST_F(NegotiatingAuthenticatorTest, InvalidSecretPlain) { |
| 175 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 178 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( |
| 176 kNoClientId, kNoPairedSecret, kTestPin, kTestPinBad, | 179 kNoClientId, kNoPairedSecret, kTestPin, kTestPinBad, |
| 177 AuthenticationMethod::NONE, false, NULL)); | 180 AuthenticationMethod::NONE, false)); |
| 178 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 181 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
| 179 | 182 |
| 180 VerifyRejected(Authenticator::INVALID_CREDENTIALS); | 183 VerifyRejected(Authenticator::INVALID_CREDENTIALS); |
| 181 } | 184 } |
| 182 | 185 |
| 183 TEST_F(NegotiatingAuthenticatorTest, IncompatibleMethods) { | 186 TEST_F(NegotiatingAuthenticatorTest, IncompatibleMethods) { |
| 184 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 187 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( |
| 185 kNoClientId, kNoPairedSecret, kTestPin, kTestPinBad, | 188 kNoClientId, kNoPairedSecret, kTestPin, kTestPinBad, |
| 186 AuthenticationMethod::NONE, true, NULL)); | 189 AuthenticationMethod::NONE, true)); |
| 187 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 190 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
| 188 | 191 |
| 189 VerifyRejected(Authenticator::PROTOCOL_ERROR); | 192 VerifyRejected(Authenticator::PROTOCOL_ERROR); |
| 190 } | 193 } |
| 191 | 194 |
| 192 TEST_F(NegotiatingAuthenticatorTest, PairingNotSupported) { | 195 TEST_F(NegotiatingAuthenticatorTest, PairingNotSupported) { |
| 193 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 196 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( |
| 194 kTestClientId, kTestPairedSecret, kTestPin, kTestPin, | 197 kTestClientId, kTestPairedSecret, kTestPin, kTestPin, |
| 195 AuthenticationMethod::HMAC_SHA256, false, NULL)); | 198 AuthenticationMethod::HMAC_SHA256, false)); |
| 196 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 199 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
| 197 VerifyAccepted( | 200 VerifyAccepted( |
| 198 AuthenticationMethod::Spake2(AuthenticationMethod::HMAC_SHA256)); | 201 AuthenticationMethod::Spake2(AuthenticationMethod::HMAC_SHA256)); |
| 199 } | 202 } |
| 200 | 203 |
| 201 TEST_F(NegotiatingAuthenticatorTest, PairingSupportedButNotPaired) { | 204 TEST_F(NegotiatingAuthenticatorTest, PairingSupportedButNotPaired) { |
| 205 CreatePairingRegistry(false); |
| 202 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 206 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( |
| 203 kNoClientId, kNoPairedSecret, kTestPin, kTestPin, | 207 kNoClientId, kNoPairedSecret, kTestPin, kTestPin, |
| 204 AuthenticationMethod::HMAC_SHA256, false, | 208 AuthenticationMethod::HMAC_SHA256, false)); |
| 205 CreatePairingRegistry(NULL, 0))); | |
| 206 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 209 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
| 207 VerifyAccepted(AuthenticationMethod::Spake2Pair()); | 210 VerifyAccepted(AuthenticationMethod::Spake2Pair()); |
| 208 } | 211 } |
| 209 | 212 |
| 210 TEST_F(NegotiatingAuthenticatorTest, PairingRevokedPinOkay) { | 213 TEST_F(NegotiatingAuthenticatorTest, PairingRevokedPinOkay) { |
| 214 CreatePairingRegistry(false); |
| 211 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 215 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( |
| 212 kTestClientId, kTestPairedSecret, kTestPin, kTestPin, | 216 kTestClientId, kTestPairedSecret, kTestPin, kTestPin, |
| 213 AuthenticationMethod::HMAC_SHA256, false, | 217 AuthenticationMethod::HMAC_SHA256, false)); |
| 214 CreatePairingRegistry(NULL, 0))); | |
| 215 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 218 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
| 219 mock_delegate_->RunCallback(); |
| 216 VerifyAccepted(AuthenticationMethod::Spake2Pair()); | 220 VerifyAccepted(AuthenticationMethod::Spake2Pair()); |
| 217 } | 221 } |
| 218 | 222 |
| 219 TEST_F(NegotiatingAuthenticatorTest, PairingRevokedPinBad) { | 223 TEST_F(NegotiatingAuthenticatorTest, PairingRevokedPinBad) { |
| 224 CreatePairingRegistry(false); |
| 220 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 225 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( |
| 221 kTestClientId, kTestPairedSecret, kTestPinBad, kTestPin, | 226 kTestClientId, kTestPairedSecret, kTestPinBad, kTestPin, |
| 222 AuthenticationMethod::HMAC_SHA256, false, | 227 AuthenticationMethod::HMAC_SHA256, false)); |
| 223 CreatePairingRegistry(NULL, 0))); | |
| 224 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 228 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
| 229 mock_delegate_->RunCallback(); |
| 225 VerifyRejected(Authenticator::INVALID_CREDENTIALS); | 230 VerifyRejected(Authenticator::INVALID_CREDENTIALS); |
| 226 } | 231 } |
| 227 | 232 |
| 228 TEST_F(NegotiatingAuthenticatorTest, PairingSucceeded) { | 233 TEST_F(NegotiatingAuthenticatorTest, PairingSucceeded) { |
| 229 PairingRegistry::Pairing pairing; | 234 CreatePairingRegistry(true); |
| 230 pairing.client_id = kTestClientId; | |
| 231 pairing.shared_secret = kTestPairedSecret; | |
| 232 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 235 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( |
| 233 kTestClientId, kTestPairedSecret, kTestPinBad, kTestPin, | 236 kTestClientId, kTestPairedSecret, kTestPinBad, kTestPin, |
| 234 AuthenticationMethod::HMAC_SHA256, false, | 237 AuthenticationMethod::HMAC_SHA256, false)); |
| 235 CreatePairingRegistry(&pairing, 1))); | |
| 236 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 238 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
| 239 mock_delegate_->RunCallback(); |
| 237 VerifyAccepted(AuthenticationMethod::Spake2Pair()); | 240 VerifyAccepted(AuthenticationMethod::Spake2Pair()); |
| 238 } | 241 } |
| 239 | 242 |
| 240 TEST_F(NegotiatingAuthenticatorTest, PairingSucceededInvalidSecretButPinOkay) { | 243 TEST_F(NegotiatingAuthenticatorTest, PairingSucceededInvalidSecretButPinOkay) { |
| 241 PairingRegistry::Pairing pairing; | 244 CreatePairingRegistry(true); |
| 242 pairing.client_id = kTestClientId; | |
| 243 pairing.shared_secret = kTestPairedSecret; | |
| 244 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 245 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( |
| 245 kTestClientId, kTestPairedSecretBad, kTestPin, kTestPin, | 246 kTestClientId, kTestPairedSecretBad, kTestPin, kTestPin, |
| 246 AuthenticationMethod::HMAC_SHA256, false, | 247 AuthenticationMethod::HMAC_SHA256, false)); |
| 247 CreatePairingRegistry(&pairing, 1))); | |
| 248 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 248 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
| 249 mock_delegate_->RunCallback(); |
| 249 VerifyAccepted(AuthenticationMethod::Spake2Pair()); | 250 VerifyAccepted(AuthenticationMethod::Spake2Pair()); |
| 250 } | 251 } |
| 251 | 252 |
| 252 TEST_F(NegotiatingAuthenticatorTest, PairingFailedInvalidSecretAndPin) { | 253 TEST_F(NegotiatingAuthenticatorTest, PairingFailedInvalidSecretAndPin) { |
| 253 PairingRegistry::Pairing pairing; | 254 CreatePairingRegistry(true); |
| 254 pairing.client_id = kTestClientId; | |
| 255 pairing.shared_secret = kTestPairedSecret; | |
| 256 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 255 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( |
| 257 kTestClientId, kTestPairedSecretBad, kTestPinBad, kTestPin, | 256 kTestClientId, kTestPairedSecretBad, kTestPinBad, kTestPin, |
| 258 AuthenticationMethod::HMAC_SHA256, false, | 257 AuthenticationMethod::HMAC_SHA256, false)); |
| 259 CreatePairingRegistry(&pairing, 1))); | |
| 260 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 258 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
| 259 mock_delegate_->RunCallback(); |
| 261 VerifyRejected(Authenticator::INVALID_CREDENTIALS); | 260 VerifyRejected(Authenticator::INVALID_CREDENTIALS); |
| 262 } | 261 } |
| 263 | 262 |
| 264 } // namespace protocol | 263 } // namespace protocol |
| 265 } // namespace remoting | 264 } // namespace remoting |
| OLD | NEW |