Upstreaming browser/ui/uikit_ui_util from iOS.
[chromium-blink-merge.git] / remoting / protocol / ssl_hmac_channel_authenticator_unittest.cc
blobdf0b45995fd8413788852c502e3340b3fa412802
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.
5 #include "remoting/protocol/ssl_hmac_channel_authenticator.h"
7 #include "base/base64.h"
8 #include "base/bind.h"
9 #include "base/files/file_path.h"
10 #include "base/files/file_util.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/test/test_timeouts.h"
13 #include "base/timer/timer.h"
14 #include "crypto/rsa_private_key.h"
15 #include "net/base/net_errors.h"
16 #include "net/base/test_data_directory.h"
17 #include "net/test/cert_test_util.h"
18 #include "remoting/base/rsa_key_pair.h"
19 #include "remoting/protocol/connection_tester.h"
20 #include "remoting/protocol/fake_session.h"
21 #include "remoting/protocol/p2p_stream_socket.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h"
26 using testing::_;
27 using testing::NotNull;
28 using testing::SaveArg;
30 namespace remoting {
31 namespace protocol {
33 namespace {
35 const char kTestSharedSecret[] = "1234-1234-5678";
36 const char kTestSharedSecretBad[] = "0000-0000-0001";
38 class MockChannelDoneCallback {
39 public:
40 MOCK_METHOD2(OnDone, void(int error, P2PStreamSocket* socket));
43 ACTION_P(QuitThreadOnCounter, counter) {
44 --(*counter);
45 EXPECT_GE(*counter, 0);
46 if (*counter == 0)
47 base::MessageLoop::current()->Quit();
50 } // namespace
52 class SslHmacChannelAuthenticatorTest : public testing::Test {
53 public:
54 SslHmacChannelAuthenticatorTest() {}
55 ~SslHmacChannelAuthenticatorTest() override {}
57 protected:
58 void SetUp() override {
59 base::FilePath certs_dir(net::GetTestCertsDirectory());
61 base::FilePath cert_path = certs_dir.AppendASCII("unittest.selfsigned.der");
62 ASSERT_TRUE(base::ReadFileToString(cert_path, &host_cert_));
64 base::FilePath key_path = certs_dir.AppendASCII("unittest.key.bin");
65 std::string key_string;
66 ASSERT_TRUE(base::ReadFileToString(key_path, &key_string));
67 std::string key_base64;
68 base::Base64Encode(key_string, &key_base64);
69 key_pair_ = RsaKeyPair::FromString(key_base64);
70 ASSERT_TRUE(key_pair_.get());
73 void RunChannelAuth(int expected_client_error, int expected_host_error) {
74 client_fake_socket_.reset(new FakeStreamSocket());
75 host_fake_socket_.reset(new FakeStreamSocket());
76 client_fake_socket_->PairWith(host_fake_socket_.get());
78 client_auth_->SecureAndAuthenticate(
79 client_fake_socket_.Pass(),
80 base::Bind(&SslHmacChannelAuthenticatorTest::OnClientConnected,
81 base::Unretained(this)));
83 host_auth_->SecureAndAuthenticate(
84 host_fake_socket_.Pass(),
85 base::Bind(&SslHmacChannelAuthenticatorTest::OnHostConnected,
86 base::Unretained(this), std::string("ref argument value")));
88 // Expect two callbacks to be called - the client callback and the host
89 // callback.
90 int callback_counter = 2;
92 if (expected_client_error != net::OK) {
93 EXPECT_CALL(client_callback_, OnDone(expected_client_error, nullptr))
94 .WillOnce(QuitThreadOnCounter(&callback_counter));
95 } else {
96 EXPECT_CALL(client_callback_, OnDone(net::OK, NotNull()))
97 .WillOnce(QuitThreadOnCounter(&callback_counter));
100 if (expected_host_error != net::OK) {
101 EXPECT_CALL(host_callback_, OnDone(expected_host_error, nullptr))
102 .WillOnce(QuitThreadOnCounter(&callback_counter));
103 } else {
104 EXPECT_CALL(host_callback_, OnDone(net::OK, NotNull()))
105 .WillOnce(QuitThreadOnCounter(&callback_counter));
108 // Ensure that .Run() does not run unbounded if the callbacks are never
109 // called.
110 base::Timer shutdown_timer(false, false);
111 shutdown_timer.Start(FROM_HERE,
112 TestTimeouts::action_timeout(),
113 base::MessageLoop::QuitClosure());
114 message_loop_.Run();
117 void OnHostConnected(const std::string& ref_argument,
118 int error,
119 scoped_ptr<P2PStreamSocket> socket) {
120 // Try deleting the authenticator and verify that this doesn't destroy
121 // reference parameters.
122 host_auth_.reset();
123 DCHECK_EQ(ref_argument, "ref argument value");
125 host_callback_.OnDone(error, socket.get());
126 host_socket_ = socket.Pass();
129 void OnClientConnected(int error, scoped_ptr<P2PStreamSocket> socket) {
130 client_auth_.reset();
131 client_callback_.OnDone(error, socket.get());
132 client_socket_ = socket.Pass();
135 base::MessageLoop message_loop_;
137 scoped_refptr<RsaKeyPair> key_pair_;
138 std::string host_cert_;
139 scoped_ptr<FakeStreamSocket> client_fake_socket_;
140 scoped_ptr<FakeStreamSocket> host_fake_socket_;
141 scoped_ptr<ChannelAuthenticator> client_auth_;
142 scoped_ptr<ChannelAuthenticator> host_auth_;
143 MockChannelDoneCallback client_callback_;
144 MockChannelDoneCallback host_callback_;
145 scoped_ptr<P2PStreamSocket> client_socket_;
146 scoped_ptr<P2PStreamSocket> host_socket_;
148 DISALLOW_COPY_AND_ASSIGN(SslHmacChannelAuthenticatorTest);
151 // Verify that a channel can be connected using a valid shared secret.
152 TEST_F(SslHmacChannelAuthenticatorTest, SuccessfulAuth) {
153 client_auth_ = SslHmacChannelAuthenticator::CreateForClient(
154 host_cert_, kTestSharedSecret);
155 host_auth_ = SslHmacChannelAuthenticator::CreateForHost(
156 host_cert_, key_pair_, kTestSharedSecret);
158 RunChannelAuth(net::OK, net::OK);
160 ASSERT_TRUE(client_socket_.get() != nullptr);
161 ASSERT_TRUE(host_socket_.get() != nullptr);
163 StreamConnectionTester tester(host_socket_.get(), client_socket_.get(),
164 100, 2);
166 tester.Start();
167 message_loop_.Run();
168 tester.CheckResults();
171 // Verify that channels cannot be using invalid shared secret.
172 TEST_F(SslHmacChannelAuthenticatorTest, InvalidChannelSecret) {
173 client_auth_ = SslHmacChannelAuthenticator::CreateForClient(
174 host_cert_, kTestSharedSecretBad);
175 host_auth_ = SslHmacChannelAuthenticator::CreateForHost(
176 host_cert_, key_pair_, kTestSharedSecret);
178 RunChannelAuth(net::ERR_FAILED, net::ERR_FAILED);
180 ASSERT_TRUE(host_socket_.get() == nullptr);
183 // Verify that channels cannot be using invalid certificate.
184 TEST_F(SslHmacChannelAuthenticatorTest, InvalidCertificate) {
185 // Import a second certificate for the client to expect.
186 scoped_refptr<net::X509Certificate> host_cert2(
187 net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem"));
188 std::string host_cert2_der;
189 ASSERT_TRUE(net::X509Certificate::GetDEREncoded(host_cert2->os_cert_handle(),
190 &host_cert2_der));
192 client_auth_ = SslHmacChannelAuthenticator::CreateForClient(
193 host_cert2_der, kTestSharedSecret);
194 host_auth_ = SslHmacChannelAuthenticator::CreateForHost(
195 host_cert_, key_pair_, kTestSharedSecret);
197 RunChannelAuth(net::ERR_CERT_INVALID, net::ERR_CONNECTION_CLOSED);
199 ASSERT_TRUE(host_socket_.get() == nullptr);
202 } // namespace protocol
203 } // namespace remoting