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 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 |