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
3 // found in the LICENSE file.
6 #include "net/base/net_errors.h"
7 #include "remoting/base/rsa_key_pair.h"
8 #include "remoting/protocol/authenticator_test_base.h"
9 #include "remoting/protocol/channel_authenticator.h"
10 #include "remoting/protocol/connection_tester.h"
11 #include "remoting/protocol/negotiating_authenticator_base.h"
12 #include "remoting/protocol/negotiating_client_authenticator.h"
13 #include "remoting/protocol/negotiating_host_authenticator.h"
14 #include "remoting/protocol/pairing_registry.h"
15 #include "remoting/protocol/protocol_mock_objects.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h"
21 using testing::DeleteArg
;
22 using testing::SaveArg
;
29 const int kMessageSize
= 100;
30 const int kMessages
= 1;
32 const char kNoClientId
[] = "";
33 const char kNoPairedSecret
[] = "";
34 const char kTestClientName
[] = "client-name";
35 const char kTestClientId
[] = "client-id";
36 const char kTestHostId
[] = "12345678910123456";
38 const char kTestPairedSecret
[] = "1111-2222-3333";
39 const char kTestPairedSecretBad
[] = "4444-5555-6666";
40 const char kTestPin
[] = "123456";
41 const char kTestPinBad
[] = "654321";
45 class NegotiatingAuthenticatorTest
: public AuthenticatorTestBase
{
47 NegotiatingAuthenticatorTest() {
49 ~NegotiatingAuthenticatorTest() override
{}
52 void InitAuthenticators(
53 const std::string
& client_id
,
54 const std::string
& client_paired_secret
,
55 const std::string
& client_interactive_pin
,
56 const std::string
& host_secret
,
57 AuthenticationMethod::HashFunction hash_function
,
58 bool client_hmac_only
) {
59 std::string host_secret_hash
= AuthenticationMethod::ApplyHashFunction(
60 hash_function
, kTestHostId
, host_secret
);
61 host_
= NegotiatingHostAuthenticator::CreateWithSharedSecret(
62 host_cert_
, key_pair_
, host_secret_hash
, hash_function
,
65 std::vector
<AuthenticationMethod
> methods
;
66 methods
.push_back(AuthenticationMethod::Spake2Pair());
67 methods
.push_back(AuthenticationMethod::Spake2(
68 AuthenticationMethod::HMAC_SHA256
));
69 if (!client_hmac_only
) {
70 methods
.push_back(AuthenticationMethod::Spake2(
71 AuthenticationMethod::NONE
));
73 bool pairing_expected
= pairing_registry_
.get() != nullptr;
74 FetchSecretCallback fetch_secret_callback
=
75 base::Bind(&NegotiatingAuthenticatorTest::FetchSecret
,
76 client_interactive_pin
,
78 client_as_negotiating_authenticator_
= new NegotiatingClientAuthenticator(
79 client_id
, client_paired_secret
,
80 kTestHostId
, fetch_secret_callback
,
82 client_
.reset(client_as_negotiating_authenticator_
);
85 void CreatePairingRegistry(bool with_paired_client
) {
86 pairing_registry_
= new SynchronousPairingRegistry(
87 make_scoped_ptr(new MockPairingRegistryDelegate()));
88 if (with_paired_client
) {
89 PairingRegistry::Pairing
pairing(
90 base::Time(), kTestClientName
, kTestClientId
, kTestPairedSecret
);
91 pairing_registry_
->AddPairing(pairing
);
95 static void FetchSecret(
96 const std::string
& client_secret
,
97 bool pairing_supported
,
98 bool pairing_expected
,
99 const protocol::SecretFetchedCallback
& secret_fetched_callback
) {
100 secret_fetched_callback
.Run(client_secret
);
101 ASSERT_EQ(pairing_supported
, pairing_expected
);
104 void VerifyRejected(Authenticator::RejectionReason reason
) {
105 ASSERT_TRUE(client_
->state() == Authenticator::REJECTED
||
106 host_
->state() == Authenticator::REJECTED
);
107 if (client_
->state() == Authenticator::REJECTED
) {
108 ASSERT_EQ(client_
->rejection_reason(), reason
);
110 if (host_
->state() == Authenticator::REJECTED
) {
111 ASSERT_EQ(host_
->rejection_reason(), reason
);
115 void VerifyAccepted(const AuthenticationMethod
& expected_method
) {
116 ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
118 ASSERT_EQ(Authenticator::ACCEPTED
, host_
->state());
119 ASSERT_EQ(Authenticator::ACCEPTED
, client_
->state());
121 client_auth_
= client_
->CreateChannelAuthenticator();
122 host_auth_
= host_
->CreateChannelAuthenticator();
123 RunChannelAuth(false);
125 EXPECT_TRUE(client_socket_
.get() != nullptr);
126 EXPECT_TRUE(host_socket_
.get() != nullptr);
128 StreamConnectionTester
tester(host_socket_
.get(), client_socket_
.get(),
129 kMessageSize
, kMessages
);
133 tester
.CheckResults();
136 client_as_negotiating_authenticator_
->current_method_for_testing());
139 // Use a bare pointer because the storage is managed by the base class.
140 NegotiatingClientAuthenticator
* client_as_negotiating_authenticator_
;
143 scoped_refptr
<PairingRegistry
> pairing_registry_
;
145 DISALLOW_COPY_AND_ASSIGN(NegotiatingAuthenticatorTest
);
148 TEST_F(NegotiatingAuthenticatorTest
, SuccessfulAuthHmac
) {
149 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
150 kNoClientId
, kNoPairedSecret
, kTestPin
, kTestPin
,
151 AuthenticationMethod::HMAC_SHA256
, false));
153 AuthenticationMethod::Spake2(AuthenticationMethod::HMAC_SHA256
));
156 TEST_F(NegotiatingAuthenticatorTest
, SuccessfulAuthPlain
) {
157 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
158 kNoClientId
, kNoPairedSecret
, kTestPin
, kTestPin
,
159 AuthenticationMethod::NONE
, false));
160 VerifyAccepted(AuthenticationMethod::Spake2(AuthenticationMethod::NONE
));
163 TEST_F(NegotiatingAuthenticatorTest
, InvalidSecretHmac
) {
164 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
165 kNoClientId
, kNoPairedSecret
, kTestPinBad
, kTestPin
,
166 AuthenticationMethod::HMAC_SHA256
, false));
167 ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
169 VerifyRejected(Authenticator::INVALID_CREDENTIALS
);
172 TEST_F(NegotiatingAuthenticatorTest
, InvalidSecretPlain
) {
173 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
174 kNoClientId
, kNoPairedSecret
, kTestPin
, kTestPinBad
,
175 AuthenticationMethod::NONE
, false));
176 ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
178 VerifyRejected(Authenticator::INVALID_CREDENTIALS
);
181 TEST_F(NegotiatingAuthenticatorTest
, IncompatibleMethods
) {
182 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
183 kNoClientId
, kNoPairedSecret
, kTestPin
, kTestPinBad
,
184 AuthenticationMethod::NONE
, true));
185 ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
187 VerifyRejected(Authenticator::PROTOCOL_ERROR
);
190 TEST_F(NegotiatingAuthenticatorTest
, PairingNotSupported
) {
191 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
192 kTestClientId
, kTestPairedSecret
, kTestPin
, kTestPin
,
193 AuthenticationMethod::HMAC_SHA256
, false));
194 ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
196 AuthenticationMethod::Spake2(AuthenticationMethod::HMAC_SHA256
));
199 TEST_F(NegotiatingAuthenticatorTest
, PairingSupportedButNotPaired
) {
200 CreatePairingRegistry(false);
201 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
202 kNoClientId
, kNoPairedSecret
, kTestPin
, kTestPin
,
203 AuthenticationMethod::HMAC_SHA256
, false));
204 ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
205 VerifyAccepted(AuthenticationMethod::Spake2Pair());
208 TEST_F(NegotiatingAuthenticatorTest
, PairingRevokedPinOkay
) {
209 CreatePairingRegistry(false);
210 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
211 kTestClientId
, kTestPairedSecret
, kTestPin
, kTestPin
,
212 AuthenticationMethod::HMAC_SHA256
, false));
213 ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
214 VerifyAccepted(AuthenticationMethod::Spake2Pair());
217 TEST_F(NegotiatingAuthenticatorTest
, PairingRevokedPinBad
) {
218 CreatePairingRegistry(false);
219 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
220 kTestClientId
, kTestPairedSecret
, kTestPinBad
, kTestPin
,
221 AuthenticationMethod::HMAC_SHA256
, false));
222 ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
223 VerifyRejected(Authenticator::INVALID_CREDENTIALS
);
226 TEST_F(NegotiatingAuthenticatorTest
, PairingSucceeded
) {
227 CreatePairingRegistry(true);
228 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
229 kTestClientId
, kTestPairedSecret
, kTestPinBad
, kTestPin
,
230 AuthenticationMethod::HMAC_SHA256
, false));
231 ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
232 VerifyAccepted(AuthenticationMethod::Spake2Pair());
235 TEST_F(NegotiatingAuthenticatorTest
,
236 PairingSucceededInvalidSecretButPinOkay
) {
237 CreatePairingRegistry(true);
238 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
239 kTestClientId
, kTestPairedSecretBad
, kTestPin
, kTestPin
,
240 AuthenticationMethod::HMAC_SHA256
, false));
241 ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
242 VerifyAccepted(AuthenticationMethod::Spake2Pair());
245 TEST_F(NegotiatingAuthenticatorTest
, PairingFailedInvalidSecretAndPin
) {
246 CreatePairingRegistry(true);
247 ASSERT_NO_FATAL_FAILURE(InitAuthenticators(
248 kTestClientId
, kTestPairedSecretBad
, kTestPinBad
, kTestPin
,
249 AuthenticationMethod::HMAC_SHA256
, false));
250 ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
251 VerifyRejected(Authenticator::INVALID_CREDENTIALS
);
254 } // namespace protocol
255 } // namespace remoting