| 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 "base/macros.h" | 6 #include "base/macros.h" |
| 7 #include "net/base/net_errors.h" | 7 #include "net/base/net_errors.h" |
| 8 #include "remoting/base/rsa_key_pair.h" | 8 #include "remoting/base/rsa_key_pair.h" |
| 9 #include "remoting/protocol/auth_util.h" |
| 9 #include "remoting/protocol/authenticator_test_base.h" | 10 #include "remoting/protocol/authenticator_test_base.h" |
| 10 #include "remoting/protocol/channel_authenticator.h" | 11 #include "remoting/protocol/channel_authenticator.h" |
| 11 #include "remoting/protocol/connection_tester.h" | 12 #include "remoting/protocol/connection_tester.h" |
| 12 #include "remoting/protocol/negotiating_authenticator_base.h" | 13 #include "remoting/protocol/negotiating_authenticator_base.h" |
| 13 #include "remoting/protocol/negotiating_client_authenticator.h" | 14 #include "remoting/protocol/negotiating_client_authenticator.h" |
| 14 #include "remoting/protocol/negotiating_host_authenticator.h" | 15 #include "remoting/protocol/negotiating_host_authenticator.h" |
| 15 #include "remoting/protocol/pairing_registry.h" | 16 #include "remoting/protocol/pairing_registry.h" |
| 16 #include "remoting/protocol/protocol_mock_objects.h" | 17 #include "remoting/protocol/protocol_mock_objects.h" |
| 17 #include "testing/gmock/include/gmock/gmock.h" | 18 #include "testing/gmock/include/gmock/gmock.h" |
| 18 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 46 class NegotiatingAuthenticatorTest : public AuthenticatorTestBase { | 47 class NegotiatingAuthenticatorTest : public AuthenticatorTestBase { |
| 47 public: | 48 public: |
| 48 NegotiatingAuthenticatorTest() {} | 49 NegotiatingAuthenticatorTest() {} |
| 49 ~NegotiatingAuthenticatorTest() override {} | 50 ~NegotiatingAuthenticatorTest() override {} |
| 50 | 51 |
| 51 protected: | 52 protected: |
| 52 void InitAuthenticators(const std::string& client_id, | 53 void InitAuthenticators(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 bool it2me, | 57 bool it2me) { |
| 57 bool client_hmac_only) { | |
| 58 if (it2me) { | 58 if (it2me) { |
| 59 host_ = NegotiatingHostAuthenticator::CreateForIt2Me( | 59 host_ = NegotiatingHostAuthenticator::CreateForIt2Me( |
| 60 host_cert_, key_pair_, host_secret); | 60 host_cert_, key_pair_, host_secret); |
| 61 } else { | 61 } else { |
| 62 std::string host_secret_hash = ApplySharedSecretHashFunction( | 62 std::string host_secret_hash = |
| 63 HashFunction::HMAC_SHA256, kTestHostId, host_secret); | 63 GetSharedSecretHash(kTestHostId, host_secret); |
| 64 host_ = NegotiatingHostAuthenticator::CreateWithPin( | 64 host_ = NegotiatingHostAuthenticator::CreateWithPin( |
| 65 host_cert_, key_pair_, host_secret_hash, pairing_registry_); | 65 host_cert_, key_pair_, host_secret_hash, pairing_registry_); |
| 66 } | 66 } |
| 67 | 67 |
| 68 std::vector<AuthenticationMethod> methods; | |
| 69 methods.push_back(AuthenticationMethod::SPAKE2_PAIR); | |
| 70 methods.push_back(AuthenticationMethod::SPAKE2_SHARED_SECRET_HMAC); | |
| 71 if (!client_hmac_only) { | |
| 72 methods.push_back(AuthenticationMethod::SPAKE2_SHARED_SECRET_PLAIN); | |
| 73 } | |
| 74 bool pairing_expected = pairing_registry_.get() != nullptr; | 68 bool pairing_expected = pairing_registry_.get() != nullptr; |
| 75 FetchSecretCallback fetch_secret_callback = | 69 FetchSecretCallback fetch_secret_callback = |
| 76 base::Bind(&NegotiatingAuthenticatorTest::FetchSecret, | 70 base::Bind(&NegotiatingAuthenticatorTest::FetchSecret, |
| 77 client_interactive_pin, | 71 client_interactive_pin, |
| 78 pairing_expected); | 72 pairing_expected); |
| 79 client_as_negotiating_authenticator_ = new NegotiatingClientAuthenticator( | 73 client_as_negotiating_authenticator_ = new NegotiatingClientAuthenticator( |
| 80 client_id, client_paired_secret, | 74 client_id, client_paired_secret, kTestHostId, fetch_secret_callback, |
| 81 kTestHostId, fetch_secret_callback, | 75 nullptr); |
| 82 nullptr, methods); | |
| 83 client_.reset(client_as_negotiating_authenticator_); | 76 client_.reset(client_as_negotiating_authenticator_); |
| 84 } | 77 } |
| 85 | 78 |
| 86 void CreatePairingRegistry(bool with_paired_client) { | 79 void CreatePairingRegistry(bool with_paired_client) { |
| 87 pairing_registry_ = new SynchronousPairingRegistry( | 80 pairing_registry_ = new SynchronousPairingRegistry( |
| 88 make_scoped_ptr(new MockPairingRegistryDelegate())); | 81 make_scoped_ptr(new MockPairingRegistryDelegate())); |
| 89 if (with_paired_client) { | 82 if (with_paired_client) { |
| 90 PairingRegistry::Pairing pairing( | 83 PairingRegistry::Pairing pairing( |
| 91 base::Time(), kTestClientName, kTestClientId, kTestPairedSecret); | 84 base::Time(), kTestClientName, kTestClientId, kTestPairedSecret); |
| 92 pairing_registry_->AddPairing(pairing); | 85 pairing_registry_->AddPairing(pairing); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 106 ASSERT_TRUE(client_->state() == Authenticator::REJECTED || | 99 ASSERT_TRUE(client_->state() == Authenticator::REJECTED || |
| 107 host_->state() == Authenticator::REJECTED); | 100 host_->state() == Authenticator::REJECTED); |
| 108 if (client_->state() == Authenticator::REJECTED) { | 101 if (client_->state() == Authenticator::REJECTED) { |
| 109 ASSERT_EQ(client_->rejection_reason(), reason); | 102 ASSERT_EQ(client_->rejection_reason(), reason); |
| 110 } | 103 } |
| 111 if (host_->state() == Authenticator::REJECTED) { | 104 if (host_->state() == Authenticator::REJECTED) { |
| 112 ASSERT_EQ(host_->rejection_reason(), reason); | 105 ASSERT_EQ(host_->rejection_reason(), reason); |
| 113 } | 106 } |
| 114 } | 107 } |
| 115 | 108 |
| 116 void VerifyAccepted(const AuthenticationMethod& expected_method) { | 109 void VerifyAccepted(NegotiatingAuthenticatorBase::Method expected_method) { |
| 117 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 110 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
| 118 | 111 |
| 119 ASSERT_EQ(Authenticator::ACCEPTED, host_->state()); | 112 ASSERT_EQ(Authenticator::ACCEPTED, host_->state()); |
| 120 ASSERT_EQ(Authenticator::ACCEPTED, client_->state()); | 113 ASSERT_EQ(Authenticator::ACCEPTED, client_->state()); |
| 121 | 114 |
| 122 client_auth_ = client_->CreateChannelAuthenticator(); | 115 client_auth_ = client_->CreateChannelAuthenticator(); |
| 123 host_auth_ = host_->CreateChannelAuthenticator(); | 116 host_auth_ = host_->CreateChannelAuthenticator(); |
| 124 RunChannelAuth(false); | 117 RunChannelAuth(false); |
| 125 | 118 |
| 126 EXPECT_TRUE(client_socket_.get() != nullptr); | 119 EXPECT_TRUE(client_socket_.get() != nullptr); |
| 127 EXPECT_TRUE(host_socket_.get() != nullptr); | 120 EXPECT_TRUE(host_socket_.get() != nullptr); |
| 128 | 121 |
| 129 StreamConnectionTester tester(host_socket_.get(), client_socket_.get(), | 122 StreamConnectionTester tester(host_socket_.get(), client_socket_.get(), |
| 130 kMessageSize, kMessages); | 123 kMessageSize, kMessages); |
| 131 | 124 |
| 132 tester.Start(); | 125 tester.Start(); |
| 133 message_loop_.Run(); | 126 message_loop_.Run(); |
| 134 tester.CheckResults(); | 127 tester.CheckResults(); |
| 135 EXPECT_EQ( | 128 EXPECT_EQ(expected_method, |
| 136 expected_method, | 129 client_as_negotiating_authenticator_->current_method_); |
| 137 client_as_negotiating_authenticator_->current_method_for_testing()); | |
| 138 } | 130 } |
| 139 | 131 |
| 140 // Use a bare pointer because the storage is managed by the base class. | 132 // Use a bare pointer because the storage is managed by the base class. |
| 141 NegotiatingClientAuthenticator* client_as_negotiating_authenticator_; | 133 NegotiatingClientAuthenticator* client_as_negotiating_authenticator_; |
| 142 | 134 |
| 143 private: | 135 private: |
| 144 scoped_refptr<PairingRegistry> pairing_registry_; | 136 scoped_refptr<PairingRegistry> pairing_registry_; |
| 145 | 137 |
| 146 DISALLOW_COPY_AND_ASSIGN(NegotiatingAuthenticatorTest); | 138 DISALLOW_COPY_AND_ASSIGN(NegotiatingAuthenticatorTest); |
| 147 }; | 139 }; |
| 148 | 140 |
| 149 TEST_F(NegotiatingAuthenticatorTest, SuccessfulAuthMe2MePin) { | 141 TEST_F(NegotiatingAuthenticatorTest, SuccessfulAuthMe2MePin) { |
| 150 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kNoClientId, kNoPairedSecret, | 142 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kNoClientId, kNoPairedSecret, |
| 151 kTestPin, kTestPin, false, false)); | 143 kTestPin, kTestPin, false)); |
| 152 VerifyAccepted(AuthenticationMethod::SPAKE2_SHARED_SECRET_HMAC); | 144 VerifyAccepted( |
| 145 NegotiatingAuthenticatorBase::Method::SPAKE2_SHARED_SECRET_HMAC); |
| 153 } | 146 } |
| 154 | 147 |
| 155 TEST_F(NegotiatingAuthenticatorTest, SuccessfulAuthIt2me) { | 148 TEST_F(NegotiatingAuthenticatorTest, SuccessfulAuthIt2me) { |
| 156 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kNoClientId, kNoPairedSecret, | 149 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kNoClientId, kNoPairedSecret, |
| 157 kTestPin, kTestPin, true, false)); | 150 kTestPin, kTestPin, true)); |
| 158 VerifyAccepted(AuthenticationMethod::SPAKE2_SHARED_SECRET_PLAIN); | 151 VerifyAccepted( |
| 152 NegotiatingAuthenticatorBase::Method::SPAKE2_SHARED_SECRET_PLAIN); |
| 159 } | 153 } |
| 160 | 154 |
| 161 TEST_F(NegotiatingAuthenticatorTest, InvalidMe2MePin) { | 155 TEST_F(NegotiatingAuthenticatorTest, InvalidMe2MePin) { |
| 162 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 156 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kNoClientId, kNoPairedSecret, |
| 163 kNoClientId, kNoPairedSecret, kTestPinBad, kTestPin, false, false)); | 157 kTestPinBad, kTestPin, false)); |
| 164 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 158 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
| 165 | 159 |
| 166 VerifyRejected(Authenticator::INVALID_CREDENTIALS); | 160 VerifyRejected(Authenticator::INVALID_CREDENTIALS); |
| 167 } | 161 } |
| 168 | 162 |
| 169 TEST_F(NegotiatingAuthenticatorTest, InvalidIt2MeAccessCode) { | 163 TEST_F(NegotiatingAuthenticatorTest, InvalidIt2MeAccessCode) { |
| 170 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 164 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kNoClientId, kNoPairedSecret, |
| 171 kNoClientId, kNoPairedSecret, kTestPin, kTestPinBad, true, false)); | 165 kTestPin, kTestPinBad, true)); |
| 172 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 166 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
| 173 | 167 |
| 174 VerifyRejected(Authenticator::INVALID_CREDENTIALS); | 168 VerifyRejected(Authenticator::INVALID_CREDENTIALS); |
| 175 } | 169 } |
| 176 | 170 |
| 177 TEST_F(NegotiatingAuthenticatorTest, IncompatibleMethods) { | 171 TEST_F(NegotiatingAuthenticatorTest, IncompatibleMethods) { |
| 178 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 172 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kNoClientId, kNoPairedSecret, |
| 179 kNoClientId, kNoPairedSecret, kTestPin, kTestPinBad, true, true)); | 173 kTestPin, kTestPinBad, true)); |
| 174 std::vector<NegotiatingAuthenticatorBase::Method>* methods = |
| 175 &(client_as_negotiating_authenticator_->methods_); |
| 176 methods->erase(std::find( |
| 177 methods->begin(), methods->end(), |
| 178 NegotiatingAuthenticatorBase::Method::SPAKE2_SHARED_SECRET_PLAIN)); |
| 179 |
| 180 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 180 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
| 181 | 181 |
| 182 VerifyRejected(Authenticator::PROTOCOL_ERROR); | 182 VerifyRejected(Authenticator::PROTOCOL_ERROR); |
| 183 } | 183 } |
| 184 | 184 |
| 185 TEST_F(NegotiatingAuthenticatorTest, PairingNotSupported) { | 185 TEST_F(NegotiatingAuthenticatorTest, PairingNotSupported) { |
| 186 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kTestClientId, kTestPairedSecret, | 186 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kTestClientId, kTestPairedSecret, |
| 187 kTestPin, kTestPin, false, false)); | 187 kTestPin, kTestPin, false)); |
| 188 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 188 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
| 189 VerifyAccepted(AuthenticationMethod::SPAKE2_SHARED_SECRET_HMAC); | 189 VerifyAccepted( |
| 190 NegotiatingAuthenticatorBase::Method::SPAKE2_SHARED_SECRET_HMAC); |
| 190 } | 191 } |
| 191 | 192 |
| 192 TEST_F(NegotiatingAuthenticatorTest, PairingSupportedButNotPaired) { | 193 TEST_F(NegotiatingAuthenticatorTest, PairingSupportedButNotPaired) { |
| 193 CreatePairingRegistry(false); | 194 CreatePairingRegistry(false); |
| 194 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kNoClientId, kNoPairedSecret, | 195 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kNoClientId, kNoPairedSecret, |
| 195 kTestPin, kTestPin, false, false)); | 196 kTestPin, kTestPin, false)); |
| 196 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 197 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
| 197 VerifyAccepted(AuthenticationMethod::SPAKE2_PAIR); | 198 VerifyAccepted(NegotiatingAuthenticatorBase::Method::SPAKE2_PAIR); |
| 198 } | 199 } |
| 199 | 200 |
| 200 TEST_F(NegotiatingAuthenticatorTest, PairingRevokedPinOkay) { | 201 TEST_F(NegotiatingAuthenticatorTest, PairingRevokedPinOkay) { |
| 201 CreatePairingRegistry(false); | 202 CreatePairingRegistry(false); |
| 202 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kTestClientId, kTestPairedSecret, | 203 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kTestClientId, kTestPairedSecret, |
| 203 kTestPin, kTestPin, false, false)); | 204 kTestPin, kTestPin, false)); |
| 204 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 205 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
| 205 VerifyAccepted(AuthenticationMethod::SPAKE2_PAIR); | 206 VerifyAccepted(NegotiatingAuthenticatorBase::Method::SPAKE2_PAIR); |
| 206 } | 207 } |
| 207 | 208 |
| 208 TEST_F(NegotiatingAuthenticatorTest, PairingRevokedPinBad) { | 209 TEST_F(NegotiatingAuthenticatorTest, PairingRevokedPinBad) { |
| 209 CreatePairingRegistry(false); | 210 CreatePairingRegistry(false); |
| 210 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 211 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kTestClientId, kTestPairedSecret, |
| 211 kTestClientId, kTestPairedSecret, kTestPinBad, kTestPin, false, false)); | 212 kTestPinBad, kTestPin, false)); |
| 212 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 213 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
| 213 VerifyRejected(Authenticator::INVALID_CREDENTIALS); | 214 VerifyRejected(Authenticator::INVALID_CREDENTIALS); |
| 214 } | 215 } |
| 215 | 216 |
| 216 TEST_F(NegotiatingAuthenticatorTest, PairingSucceeded) { | 217 TEST_F(NegotiatingAuthenticatorTest, PairingSucceeded) { |
| 217 CreatePairingRegistry(true); | 218 CreatePairingRegistry(true); |
| 218 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 219 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kTestClientId, kTestPairedSecret, |
| 219 kTestClientId, kTestPairedSecret, kTestPinBad, kTestPin, false, false)); | 220 kTestPinBad, kTestPin, false)); |
| 220 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 221 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
| 221 VerifyAccepted(AuthenticationMethod::SPAKE2_PAIR); | 222 VerifyAccepted(NegotiatingAuthenticatorBase::Method::SPAKE2_PAIR); |
| 222 } | 223 } |
| 223 | 224 |
| 224 TEST_F(NegotiatingAuthenticatorTest, | 225 TEST_F(NegotiatingAuthenticatorTest, |
| 225 PairingSucceededInvalidSecretButPinOkay) { | 226 PairingSucceededInvalidSecretButPinOkay) { |
| 226 CreatePairingRegistry(true); | 227 CreatePairingRegistry(true); |
| 227 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( | 228 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( |
| 228 kTestClientId, kTestPairedSecretBad, kTestPin, kTestPin, false, false)); | 229 kTestClientId, kTestPairedSecretBad, kTestPin, kTestPin, false)); |
| 229 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 230 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
| 230 VerifyAccepted(AuthenticationMethod::SPAKE2_PAIR); | 231 VerifyAccepted(NegotiatingAuthenticatorBase::Method::SPAKE2_PAIR); |
| 231 } | 232 } |
| 232 | 233 |
| 233 TEST_F(NegotiatingAuthenticatorTest, PairingFailedInvalidSecretAndPin) { | 234 TEST_F(NegotiatingAuthenticatorTest, PairingFailedInvalidSecretAndPin) { |
| 234 CreatePairingRegistry(true); | 235 CreatePairingRegistry(true); |
| 235 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kTestClientId, | 236 ASSERT_NO_FATAL_FAILURE(InitAuthenticators( |
| 236 kTestPairedSecretBad, kTestPinBad, | 237 kTestClientId, kTestPairedSecretBad, kTestPinBad, kTestPin, false)); |
| 237 kTestPin, false, false)); | |
| 238 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); | 238 ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
| 239 VerifyRejected(Authenticator::INVALID_CREDENTIALS); | 239 VerifyRejected(Authenticator::INVALID_CREDENTIALS); |
| 240 } | 240 } |
| 241 | 241 |
| 242 } // namespace protocol | 242 } // namespace protocol |
| 243 } // namespace remoting | 243 } // namespace remoting |
| OLD | NEW |