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 // This test suite uses SSLClientSocket to test the implementation of | 5 // This test suite uses SSLClientSocket to test the implementation of |
| 6 // SSLServerSocket. In order to establish connections between the sockets | 6 // SSLServerSocket. In order to establish connections between the sockets |
| 7 // we need two additional classes: | 7 // we need two additional classes: |
| 8 // 1. FakeSocket | 8 // 1. FakeSocket |
| 9 // Connects SSL socket to FakeDataChannel. This class is just a stub. | 9 // Connects SSL socket to FakeDataChannel. This class is just a stub. |
| 10 // | 10 // |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 34 #include "net/base/net_log.h" | 34 #include "net/base/net_log.h" |
| 35 #include "net/base/test_data_directory.h" | 35 #include "net/base/test_data_directory.h" |
| 36 #include "net/cert/cert_status_flags.h" | 36 #include "net/cert/cert_status_flags.h" |
| 37 #include "net/cert/mock_cert_verifier.h" | 37 #include "net/cert/mock_cert_verifier.h" |
| 38 #include "net/cert/x509_certificate.h" | 38 #include "net/cert/x509_certificate.h" |
| 39 #include "net/http/transport_security_state.h" | 39 #include "net/http/transport_security_state.h" |
| 40 #include "net/socket/client_socket_factory.h" | 40 #include "net/socket/client_socket_factory.h" |
| 41 #include "net/socket/socket_test_util.h" | 41 #include "net/socket/socket_test_util.h" |
| 42 #include "net/socket/ssl_client_socket.h" | 42 #include "net/socket/ssl_client_socket.h" |
| 43 #include "net/socket/stream_socket.h" | 43 #include "net/socket/stream_socket.h" |
| 44 #include "net/ssl/ssl_cert_request_info.h" | |
| 44 #include "net/ssl/ssl_config_service.h" | 45 #include "net/ssl/ssl_config_service.h" |
| 45 #include "net/ssl/ssl_info.h" | 46 #include "net/ssl/ssl_info.h" |
| 46 #include "net/test/cert_test_util.h" | 47 #include "net/test/cert_test_util.h" |
| 47 #include "testing/gtest/include/gtest/gtest.h" | 48 #include "testing/gtest/include/gtest/gtest.h" |
| 48 #include "testing/platform_test.h" | 49 #include "testing/platform_test.h" |
| 49 | 50 |
| 50 namespace net { | 51 namespace net { |
| 51 | 52 |
| 52 namespace { | 53 namespace { |
| 53 | 54 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 64 DCHECK(read_callback_.is_null()); | 65 DCHECK(read_callback_.is_null()); |
| 65 DCHECK(!read_buf_.get()); | 66 DCHECK(!read_buf_.get()); |
| 66 if (closed_) | 67 if (closed_) |
| 67 return 0; | 68 return 0; |
| 68 if (data_.empty()) { | 69 if (data_.empty()) { |
| 69 read_callback_ = callback; | 70 read_callback_ = callback; |
| 70 read_buf_ = buf; | 71 read_buf_ = buf; |
| 71 read_buf_len_ = buf_len; | 72 read_buf_len_ = buf_len; |
| 72 return ERR_IO_PENDING; | 73 return ERR_IO_PENDING; |
| 73 } | 74 } |
| 74 return PropogateData(buf, buf_len); | 75 return PropagateData(buf, buf_len); |
| 75 } | 76 } |
| 76 | 77 |
| 77 int Write(IOBuffer* buf, int buf_len, const CompletionCallback& callback) { | 78 int Write(IOBuffer* buf, int buf_len, const CompletionCallback& callback) { |
| 78 DCHECK(write_callback_.is_null()); | 79 DCHECK(write_callback_.is_null()); |
| 79 if (closed_) { | 80 if (closed_) { |
| 80 if (write_called_after_close_) | 81 if (write_called_after_close_) |
| 81 return ERR_CONNECTION_RESET; | 82 return ERR_CONNECTION_RESET; |
| 82 write_called_after_close_ = true; | 83 write_called_after_close_ = true; |
| 83 write_callback_ = callback; | 84 write_callback_ = callback; |
| 84 base::MessageLoop::current()->PostTask( | 85 base::MessageLoop::current()->PostTask( |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 95 weak_factory_.GetWeakPtr())); | 96 weak_factory_.GetWeakPtr())); |
| 96 return buf_len; | 97 return buf_len; |
| 97 } | 98 } |
| 98 | 99 |
| 99 // Closes the FakeDataChannel. After Close() is called, Read() returns 0, | 100 // Closes the FakeDataChannel. After Close() is called, Read() returns 0, |
| 100 // indicating EOF, and Write() fails with ERR_CONNECTION_RESET. Note that | 101 // indicating EOF, and Write() fails with ERR_CONNECTION_RESET. Note that |
| 101 // after the FakeDataChannel is closed, the first Write() call completes | 102 // after the FakeDataChannel is closed, the first Write() call completes |
| 102 // asynchronously, which is necessary to reproduce bug 127822. | 103 // asynchronously, which is necessary to reproduce bug 127822. |
| 103 void Close() { | 104 void Close() { |
| 104 closed_ = true; | 105 closed_ = true; |
| 106 if (!read_callback_.is_null()) { | |
| 107 base::MessageLoop::current()->PostTask( | |
| 108 FROM_HERE, base::Bind(&FakeDataChannel::DoReadCallback, | |
| 109 weak_factory_.GetWeakPtr())); | |
| 110 } | |
| 105 } | 111 } |
| 106 | 112 |
| 107 private: | 113 private: |
| 108 void DoReadCallback() { | 114 void DoReadCallback() { |
| 109 if (read_callback_.is_null() || data_.empty()) | 115 if (read_callback_.is_null()) |
| 110 return; | 116 return; |
| 111 | 117 int copied = PropagateData(read_buf_, read_buf_len_); |
| 112 int copied = PropogateData(read_buf_, read_buf_len_); | 118 if (!copied && !closed_) |
| 119 return; | |
| 113 CompletionCallback callback = read_callback_; | 120 CompletionCallback callback = read_callback_; |
| 114 read_callback_.Reset(); | 121 read_callback_.Reset(); |
| 115 read_buf_ = NULL; | 122 read_buf_ = NULL; |
| 116 read_buf_len_ = 0; | 123 read_buf_len_ = 0; |
| 117 callback.Run(copied); | 124 callback.Run(copied); |
| 118 } | 125 } |
| 119 | 126 |
| 120 void DoWriteCallback() { | 127 void DoWriteCallback() { |
| 121 if (write_callback_.is_null()) | 128 if (write_callback_.is_null()) |
| 122 return; | 129 return; |
| 123 | 130 |
| 124 CompletionCallback callback = write_callback_; | 131 CompletionCallback callback = write_callback_; |
| 125 write_callback_.Reset(); | 132 write_callback_.Reset(); |
| 126 callback.Run(ERR_CONNECTION_RESET); | 133 callback.Run(ERR_CONNECTION_RESET); |
| 127 } | 134 } |
| 128 | 135 |
| 129 int PropogateData(scoped_refptr<IOBuffer> read_buf, int read_buf_len) { | 136 int PropagateData(scoped_refptr<IOBuffer> read_buf, int read_buf_len) { |
| 137 if (data_.empty()) | |
| 138 return 0; | |
| 130 scoped_refptr<DrainableIOBuffer> buf = data_.front(); | 139 scoped_refptr<DrainableIOBuffer> buf = data_.front(); |
| 131 int copied = std::min(buf->BytesRemaining(), read_buf_len); | 140 int copied = std::min(buf->BytesRemaining(), read_buf_len); |
| 132 memcpy(read_buf->data(), buf->data(), copied); | 141 memcpy(read_buf->data(), buf->data(), copied); |
| 133 buf->DidConsume(copied); | 142 buf->DidConsume(copied); |
| 134 | 143 |
| 135 if (!buf->BytesRemaining()) | 144 if (!buf->BytesRemaining()) |
| 136 data_.pop(); | 145 data_.pop(); |
| 137 return copied; | 146 return copied; |
| 138 } | 147 } |
| 139 | 148 |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 271 EXPECT_LE(written, kTestDataSize); | 280 EXPECT_LE(written, kTestDataSize); |
| 272 | 281 |
| 273 read = callback.WaitForResult(); | 282 read = callback.WaitForResult(); |
| 274 EXPECT_GT(read, 0); | 283 EXPECT_GT(read, 0); |
| 275 EXPECT_LE(read, written); | 284 EXPECT_LE(read, written); |
| 276 EXPECT_EQ(0, memcmp(kTestData, read_buf->data(), read)); | 285 EXPECT_EQ(0, memcmp(kTestData, read_buf->data(), read)); |
| 277 } | 286 } |
| 278 | 287 |
| 279 class SSLServerSocketTest : public PlatformTest { | 288 class SSLServerSocketTest : public PlatformTest { |
| 280 public: | 289 public: |
| 290 enum ClientCertSupply { | |
| 291 kNoneSupplied = 0, | |
| 292 kCorrectCertSupplied = 1, | |
| 293 kWrongCertSupplied = 2 | |
| 294 }; | |
| 295 | |
| 296 enum ClientCertExpect { | |
| 297 kNoneExpected = 0, | |
| 298 kCertAllowed = 1, | |
| 299 kCertRequired = 2 | |
| 300 }; | |
| 301 | |
| 281 SSLServerSocketTest() | 302 SSLServerSocketTest() |
| 282 : socket_factory_(ClientSocketFactory::GetDefaultFactory()), | 303 : socket_factory_(ClientSocketFactory::GetDefaultFactory()), |
| 283 cert_verifier_(new MockCertVerifier()), | 304 cert_verifier_(new MockCertVerifier()), |
| 305 client_cert_verifier_(new MockCertVerifier()), | |
| 284 transport_security_state_(new TransportSecurityState) { | 306 transport_security_state_(new TransportSecurityState) { |
| 285 cert_verifier_->set_default_result(CERT_STATUS_AUTHORITY_INVALID); | 307 cert_verifier_->set_default_result(CERT_STATUS_AUTHORITY_INVALID); |
| 308 client_cert_verifier_->set_default_result(CERT_STATUS_AUTHORITY_INVALID); | |
| 286 } | 309 } |
| 287 | 310 |
| 288 protected: | 311 protected: |
| 289 void Initialize() { | 312 void Initialize() { |
| 290 scoped_ptr<ClientSocketHandle> client_connection(new ClientSocketHandle); | 313 scoped_ptr<ClientSocketHandle> client_connection(new ClientSocketHandle); |
| 291 client_connection->SetSocket( | 314 client_connection->SetSocket( |
| 292 scoped_ptr<StreamSocket>(new FakeSocket(&channel_1_, &channel_2_))); | 315 scoped_ptr<StreamSocket>(new FakeSocket(&channel_1_, &channel_2_))); |
| 293 scoped_ptr<StreamSocket> server_socket( | 316 scoped_ptr<StreamSocket> server_socket( |
| 294 new FakeSocket(&channel_2_, &channel_1_)); | 317 new FakeSocket(&channel_2_, &channel_1_)); |
| 295 | 318 |
| 319 std::string server_cert_der; | |
| 320 scoped_refptr<X509Certificate> server_cert( | |
| 321 ReadTestCert("unittest.selfsigned.der", &server_cert_der)); | |
| 322 scoped_ptr<crypto::RSAPrivateKey> server_private_key( | |
| 323 ReadTestKey("unittest.key.bin")); | |
| 324 | |
| 325 SSLConfig ssl_client_config; | |
| 326 ssl_client_config.false_start_enabled = false; | |
| 327 ssl_client_config.channel_id_enabled = false; | |
| 328 | |
| 329 // Certificate provided by the host doesn't need authority. | |
| 330 SSLConfig::CertAndStatus cert_and_status; | |
| 331 cert_and_status.cert_status = CERT_STATUS_AUTHORITY_INVALID; | |
| 332 cert_and_status.der_cert = server_cert_der; | |
| 333 ssl_client_config.allowed_bad_certs.push_back(cert_and_status); | |
| 334 | |
| 335 SSLConfig ssl_server_config; | |
| 336 HostPortPair host_and_pair("unittest", 0); | |
| 337 SSLClientSocketContext context; | |
| 338 context.cert_verifier = cert_verifier_.get(); | |
| 339 context.transport_security_state = transport_security_state_.get(); | |
| 340 socket_factory_->ClearSSLSessionCache(); | |
| 341 client_socket_ = socket_factory_->CreateSSLClientSocket( | |
| 342 client_connection.Pass(), host_and_pair, ssl_client_config, context); | |
| 343 | |
| 344 server_socket_ = | |
| 345 CreateSSLServerSocket(server_socket.Pass(), server_cert.get(), | |
| 346 server_private_key.get(), ssl_server_config); | |
| 347 } | |
| 348 | |
| 349 void InitializeClientCertsForClient(ClientCertSupply supply) { | |
| 350 scoped_refptr<X509Certificate> cert; | |
| 351 scoped_ptr<crypto::RSAPrivateKey> key; | |
| 352 if (supply != kNoneSupplied) { | |
| 353 const char* cert_file_name = supply == kCorrectCertSupplied | |
| 354 ? kClientCertFileName | |
| 355 : kWrongClientCertFileName; | |
| 356 const char* private_key_file_name = supply == kCorrectCertSupplied | |
| 357 ? kClientPrivateKeyFileName | |
| 358 : kWrongClientPrivateKeyFileName; | |
| 359 cert = ImportCertFromFile(GetTestCertsDirectory(), cert_file_name); | |
| 360 key.reset(ReadTestKey(private_key_file_name)); | |
| 361 } | |
| 362 client_socket_->ForceClientCertificateAndKeyForTest(cert, key.Pass()); | |
| 363 } | |
| 364 | |
| 365 void InitializeClientCertsForServer(ClientCertExpect expect) { | |
| 366 if (expect == kNoneExpected) | |
| 367 return; | |
| 368 | |
| 369 server_socket_->SetAllowClientCert(true); | |
| 370 | |
| 371 if (expect == kCertRequired) { | |
| 372 scoped_refptr<X509Certificate> expected_client_ca_cert( | |
| 373 ImportCertFromFile(GetTestCertsDirectory(), kClientCertCAFileName)); | |
| 374 CertificateList ca_list; | |
| 375 ca_list.push_back(expected_client_ca_cert); | |
| 376 server_socket_->SetClientCertCAList(ca_list); | |
| 377 scoped_refptr<X509Certificate> expected_client_cert( | |
| 378 ImportCertFromFile(GetTestCertsDirectory(), kClientCertFileName)); | |
| 379 CertVerifyResult ignored; | |
| 380 ignored.verified_cert = expected_client_cert; | |
| 381 ignored.cert_status = 0; | |
| 382 client_cert_verifier_->AddResultForCert(expected_client_cert.get(), | |
| 383 ignored, OK); | |
| 384 server_socket_->SetClientCertVerifier(client_cert_verifier_.get()); | |
| 385 } | |
| 386 } | |
| 387 | |
| 388 X509Certificate* ReadTestCert(const base::StringPiece& name, | |
| 389 std::string* cert_der) { | |
| 296 base::FilePath certs_dir(GetTestCertsDirectory()); | 390 base::FilePath certs_dir(GetTestCertsDirectory()); |
| 391 base::FilePath cert_path = certs_dir.AppendASCII(name); | |
| 392 std::string unneeded; | |
| 393 if (!cert_der) { | |
| 394 cert_der = &unneeded; | |
| 395 } | |
|
Ryan Sleevi
2015/03/19 04:38:25
no braces
| |
| 396 if (!base::ReadFileToString(cert_path, cert_der)) | |
| 397 return NULL; | |
| 398 return X509Certificate::CreateFromBytes(cert_der->data(), cert_der->size()); | |
| 399 } | |
| 297 | 400 |
| 298 base::FilePath cert_path = certs_dir.AppendASCII("unittest.selfsigned.der"); | 401 crypto::RSAPrivateKey* ReadTestKey(const base::StringPiece& name) { |
| 299 std::string cert_der; | 402 base::FilePath certs_dir(GetTestCertsDirectory()); |
| 300 ASSERT_TRUE(base::ReadFileToString(cert_path, &cert_der)); | 403 base::FilePath key_path = certs_dir.AppendASCII(name); |
| 301 | |
| 302 scoped_refptr<X509Certificate> cert = | |
| 303 X509Certificate::CreateFromBytes(cert_der.data(), cert_der.size()); | |
| 304 | |
| 305 base::FilePath key_path = certs_dir.AppendASCII("unittest.key.bin"); | |
| 306 std::string key_string; | 404 std::string key_string; |
| 307 ASSERT_TRUE(base::ReadFileToString(key_path, &key_string)); | 405 if (!base::ReadFileToString(key_path, &key_string)) |
| 406 return NULL; | |
| 308 std::vector<uint8> key_vector( | 407 std::vector<uint8> key_vector( |
| 309 reinterpret_cast<const uint8*>(key_string.data()), | 408 reinterpret_cast<const uint8*>(key_string.data()), |
| 310 reinterpret_cast<const uint8*>(key_string.data() + | 409 reinterpret_cast<const uint8*>(key_string.data() + |
| 311 key_string.length())); | 410 key_string.length())); |
| 312 | 411 return crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_vector); |
| 313 scoped_ptr<crypto::RSAPrivateKey> private_key( | |
| 314 crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_vector)); | |
| 315 | |
| 316 SSLConfig ssl_config; | |
| 317 ssl_config.false_start_enabled = false; | |
| 318 ssl_config.channel_id_enabled = false; | |
| 319 | |
| 320 // Certificate provided by the host doesn't need authority. | |
| 321 SSLConfig::CertAndStatus cert_and_status; | |
| 322 cert_and_status.cert_status = CERT_STATUS_AUTHORITY_INVALID; | |
| 323 cert_and_status.der_cert = cert_der; | |
| 324 ssl_config.allowed_bad_certs.push_back(cert_and_status); | |
| 325 | |
| 326 HostPortPair host_and_pair("unittest", 0); | |
| 327 SSLClientSocketContext context; | |
| 328 context.cert_verifier = cert_verifier_.get(); | |
| 329 context.transport_security_state = transport_security_state_.get(); | |
| 330 client_socket_ = | |
| 331 socket_factory_->CreateSSLClientSocket( | |
| 332 client_connection.Pass(), host_and_pair, ssl_config, context); | |
| 333 server_socket_ = CreateSSLServerSocket( | |
| 334 server_socket.Pass(), | |
| 335 cert.get(), private_key.get(), SSLConfig()); | |
| 336 } | 412 } |
| 337 | 413 |
| 338 FakeDataChannel channel_1_; | 414 FakeDataChannel channel_1_; |
| 339 FakeDataChannel channel_2_; | 415 FakeDataChannel channel_2_; |
| 340 scoped_ptr<SSLClientSocket> client_socket_; | 416 scoped_ptr<SSLClientSocket> client_socket_; |
| 341 scoped_ptr<SSLServerSocket> server_socket_; | 417 scoped_ptr<SSLServerSocket> server_socket_; |
| 342 ClientSocketFactory* socket_factory_; | 418 ClientSocketFactory* socket_factory_; |
| 343 scoped_ptr<MockCertVerifier> cert_verifier_; | 419 scoped_ptr<MockCertVerifier> cert_verifier_; |
| 420 scoped_ptr<MockCertVerifier> client_cert_verifier_; | |
| 344 scoped_ptr<TransportSecurityState> transport_security_state_; | 421 scoped_ptr<TransportSecurityState> transport_security_state_; |
| 422 CertificateList trusted_certs_; | |
| 423 | |
| 424 const char* kClientCertFileName = "client_1.pem"; | |
|
Ryan Sleevi
2015/03/19 04:38:25
STYLE:
const char kClientCertFilename[] =
But r
| |
| 425 const char* kClientPrivateKeyFileName = "client_1.pk8"; | |
| 426 const char* kWrongClientCertFileName = "client_2.pem"; | |
| 427 const char* kWrongClientPrivateKeyFileName = "client_2.pk8"; | |
| 428 const char* kClientCertCAFileName = "client_1_ca.pem"; | |
| 345 }; | 429 }; |
| 346 | 430 |
| 347 // This test only executes creation of client and server sockets. This is to | 431 // This test only executes creation of client and server sockets. This is to |
| 348 // test that creation of sockets doesn't crash and have minimal code to run | 432 // test that creation of sockets doesn't crash and have minimal code to run |
| 349 // under valgrind in order to help debugging memory problems. | 433 // under valgrind in order to help debugging memory problems. |
| 350 TEST_F(SSLServerSocketTest, Initialize) { | 434 TEST_F(SSLServerSocketTest, Initialize) { |
| 351 Initialize(); | 435 Initialize(); |
| 352 } | 436 } |
| 353 | 437 |
| 354 // This test executes Connect() on SSLClientSocket and Handshake() on | 438 // This test executes Connect() on SSLClientSocket and Handshake() on |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 372 if (server_ret == ERR_IO_PENDING) { | 456 if (server_ret == ERR_IO_PENDING) { |
| 373 EXPECT_EQ(OK, handshake_callback.WaitForResult()); | 457 EXPECT_EQ(OK, handshake_callback.WaitForResult()); |
| 374 } | 458 } |
| 375 | 459 |
| 376 // Make sure the cert status is expected. | 460 // Make sure the cert status is expected. |
| 377 SSLInfo ssl_info; | 461 SSLInfo ssl_info; |
| 378 client_socket_->GetSSLInfo(&ssl_info); | 462 client_socket_->GetSSLInfo(&ssl_info); |
| 379 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, ssl_info.cert_status); | 463 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, ssl_info.cert_status); |
| 380 } | 464 } |
| 381 | 465 |
| 466 // TODO(dougsteed). The following tests using client certificates cannot | |
| 467 // be performed if NSS with platform-based client auth is in use. That's because | |
| 468 // the tests use SSLClientSocket to make requests against the server, and on | |
| 469 // those builds, that class does not support supplying of a test key and cert. | |
| 470 // An alternative approach that would broaden the applicability of these tests | |
| 471 // would be to build and use the openssl flavor of SSLClientSocket, even | |
| 472 // on NSS platforms. | |
| 473 #if !defined(USE_NSS) || !defined(NSS_PLATFORM_CLIENT_AUTH) | |
| 474 | |
| 475 // This test executes Connect() on SSLClientSocket and Handshake() on | |
| 476 // SSLServerSocket to make sure handshaking between the two sockets is | |
| 477 // completed successfully, using client certificate. | |
| 478 TEST_F(SSLServerSocketTest, HandshakeWithClientCert) { | |
| 479 scoped_refptr<X509Certificate> client_cert = | |
| 480 ImportCertFromFile(GetTestCertsDirectory(), kClientCertFileName); | |
| 481 Initialize(); | |
| 482 InitializeClientCertsForServer(kCertAllowed); | |
| 483 InitializeClientCertsForClient(kCorrectCertSupplied); | |
| 484 | |
| 485 TestCompletionCallback connect_callback; | |
| 486 TestCompletionCallback handshake_callback; | |
| 487 | |
| 488 int server_ret = server_socket_->Handshake(handshake_callback.callback()); | |
| 489 EXPECT_TRUE(server_ret == OK || server_ret == ERR_IO_PENDING); | |
| 490 | |
| 491 int client_ret = client_socket_->Connect(connect_callback.callback()); | |
| 492 EXPECT_TRUE(client_ret == OK || client_ret == ERR_IO_PENDING); | |
| 493 | |
| 494 if (client_ret == ERR_IO_PENDING) { | |
| 495 EXPECT_EQ(OK, connect_callback.WaitForResult()); | |
| 496 } | |
| 497 if (server_ret == ERR_IO_PENDING) { | |
| 498 EXPECT_EQ(OK, handshake_callback.WaitForResult()); | |
| 499 } | |
| 500 | |
| 501 // Make sure the cert status is expected. | |
| 502 SSLInfo ssl_info; | |
| 503 client_socket_->GetSSLInfo(&ssl_info); | |
| 504 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, ssl_info.cert_status); | |
| 505 server_socket_->GetSSLInfo(&ssl_info); | |
| 506 EXPECT_TRUE(ssl_info.client_cert_sent); | |
| 507 EXPECT_TRUE(ssl_info.client_cert_sent); | |
| 508 EXPECT_TRUE(ssl_info.cert.get()); | |
| 509 EXPECT_TRUE(client_cert->Equals(ssl_info.cert.get())); | |
| 510 } | |
| 511 | |
| 512 TEST_F(SSLServerSocketTest, HandshakeWithClientCertAllowedNotSupplied) { | |
| 513 scoped_refptr<X509Certificate> client_cert = | |
| 514 ImportCertFromFile(GetTestCertsDirectory(), kClientCertFileName); | |
| 515 Initialize(); | |
| 516 InitializeClientCertsForServer(kCertAllowed); | |
| 517 InitializeClientCertsForClient(kNoneSupplied); | |
| 518 | |
| 519 TestCompletionCallback connect_callback; | |
| 520 TestCompletionCallback handshake_callback; | |
| 521 | |
| 522 int server_ret = server_socket_->Handshake(handshake_callback.callback()); | |
| 523 EXPECT_TRUE(server_ret == OK || server_ret == ERR_IO_PENDING); | |
| 524 | |
| 525 int client_ret = client_socket_->Connect(connect_callback.callback()); | |
| 526 EXPECT_TRUE(client_ret == OK || client_ret == ERR_IO_PENDING); | |
| 527 | |
| 528 if (client_ret == ERR_IO_PENDING) { | |
| 529 EXPECT_EQ(OK, connect_callback.WaitForResult()); | |
| 530 } | |
| 531 if (server_ret == ERR_IO_PENDING) { | |
| 532 EXPECT_EQ(OK, handshake_callback.WaitForResult()); | |
| 533 } | |
| 534 } | |
| 535 | |
| 536 TEST_F(SSLServerSocketTest, HandshakeWithClientCertRequiredNotSupplied) { | |
| 537 Initialize(); | |
| 538 InitializeClientCertsForServer(kCertRequired); | |
| 539 // We use the default setting for the client socket. This causes the client to | |
| 540 // get SSL_CLIENT_AUTH_CERT_NEEDED. This code path allows us to access the | |
| 541 // cert_authorities from the CertificateRequest. | |
| 542 | |
| 543 TestCompletionCallback connect_callback; | |
| 544 TestCompletionCallback handshake_callback; | |
| 545 | |
| 546 int server_ret = server_socket_->Handshake(handshake_callback.callback()); | |
| 547 EXPECT_TRUE(server_ret == ERR_IO_PENDING); | |
| 548 | |
| 549 int client_ret = client_socket_->Connect(connect_callback.callback()); | |
| 550 EXPECT_TRUE(client_ret == ERR_SSL_CLIENT_AUTH_CERT_NEEDED || | |
| 551 client_ret == ERR_IO_PENDING); | |
| 552 | |
| 553 if (client_ret == ERR_IO_PENDING) { | |
| 554 EXPECT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, | |
| 555 connect_callback.WaitForResult()); | |
| 556 } | |
| 557 | |
| 558 scoped_refptr<SSLCertRequestInfo> request_info = new SSLCertRequestInfo(); | |
| 559 client_socket_->GetSSLCertRequestInfo(request_info.get()); | |
| 560 | |
| 561 // Check that the authority name that arrived in the CertificateRequest | |
| 562 // handshake message is as expected. | |
| 563 scoped_refptr<X509Certificate> client_cert = | |
| 564 ImportCertFromFile(GetTestCertsDirectory(), kClientCertFileName); | |
| 565 EXPECT_TRUE(client_cert->IsIssuedByEncoded(request_info->cert_authorities)); | |
| 566 | |
| 567 client_socket_->Disconnect(); | |
| 568 | |
| 569 if (server_ret == ERR_IO_PENDING) { | |
| 570 server_ret = handshake_callback.WaitForResult(); | |
| 571 EXPECT_TRUE(server_ret == ERR_CONNECTION_CLOSED || | |
| 572 server_ret == ERR_FAILED); | |
| 573 } | |
| 574 } | |
| 575 | |
| 576 TEST_F(SSLServerSocketTest, HandshakeWithWrongClientCertSupplied) { | |
| 577 scoped_refptr<X509Certificate> client_cert = | |
| 578 ImportCertFromFile(GetTestCertsDirectory(), kClientCertFileName); | |
| 579 Initialize(); | |
| 580 InitializeClientCertsForServer(kCertRequired); | |
| 581 InitializeClientCertsForClient(kWrongCertSupplied); | |
| 582 | |
| 583 TestCompletionCallback connect_callback; | |
| 584 TestCompletionCallback handshake_callback; | |
| 585 | |
| 586 int server_ret = server_socket_->Handshake(handshake_callback.callback()); | |
| 587 EXPECT_TRUE(server_ret == ERR_IO_PENDING); | |
| 588 | |
| 589 int client_ret = client_socket_->Connect(connect_callback.callback()); | |
| 590 EXPECT_TRUE(client_ret == ERR_BAD_SSL_CLIENT_AUTH_CERT || | |
| 591 client_ret == ERR_IO_PENDING); | |
| 592 | |
| 593 if (client_ret == ERR_IO_PENDING) { | |
| 594 EXPECT_EQ(ERR_BAD_SSL_CLIENT_AUTH_CERT, connect_callback.WaitForResult()); | |
| 595 } | |
| 596 | |
| 597 server_ret = handshake_callback.WaitForResult(); | |
| 598 // We get a different result on NSS and OpenSSL. That's because an error | |
| 599 // mapping with OpenSSL makes an assumption that is true for SSLClientSocket | |
| 600 // but not SSLServerSocket (namely that peer cert rejection only occurs due to | |
| 601 // a cert change during renego). | |
| 602 EXPECT_TRUE(server_ret == ERR_BAD_SSL_CLIENT_AUTH_CERT || | |
| 603 server_ret == ERR_SSL_SERVER_CERT_CHANGED); | |
| 604 } | |
| 605 #endif //!defined(USE_NSS) || !defined(NSS_PLATFORM_CLIENT_AUTH) | |
| 606 | |
| 382 TEST_F(SSLServerSocketTest, DataTransfer) { | 607 TEST_F(SSLServerSocketTest, DataTransfer) { |
| 383 Initialize(); | 608 Initialize(); |
| 384 | 609 |
| 385 TestCompletionCallback connect_callback; | 610 TestCompletionCallback connect_callback; |
| 386 TestCompletionCallback handshake_callback; | 611 TestCompletionCallback handshake_callback; |
| 387 | 612 |
| 388 // Establish connection. | 613 // Establish connection. |
| 389 int client_ret = client_socket_->Connect(connect_callback.callback()); | 614 int client_ret = client_socket_->Connect(connect_callback.callback()); |
| 390 ASSERT_TRUE(client_ret == OK || client_ret == ERR_IO_PENDING); | 615 ASSERT_TRUE(client_ret == OK || client_ret == ERR_IO_PENDING); |
| 391 | 616 |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 553 const char kKeyingLabelBad[] = "EXPERIMENTAL-server-socket-test-bad"; | 778 const char kKeyingLabelBad[] = "EXPERIMENTAL-server-socket-test-bad"; |
| 554 unsigned char client_bad[kKeyingMaterialSize]; | 779 unsigned char client_bad[kKeyingMaterialSize]; |
| 555 rv = client_socket_->ExportKeyingMaterial(kKeyingLabelBad, | 780 rv = client_socket_->ExportKeyingMaterial(kKeyingLabelBad, |
| 556 false, kKeyingContext, | 781 false, kKeyingContext, |
| 557 client_bad, sizeof(client_bad)); | 782 client_bad, sizeof(client_bad)); |
| 558 ASSERT_EQ(rv, OK); | 783 ASSERT_EQ(rv, OK); |
| 559 EXPECT_NE(0, memcmp(server_out, client_bad, sizeof(server_out))); | 784 EXPECT_NE(0, memcmp(server_out, client_bad, sizeof(server_out))); |
| 560 } | 785 } |
| 561 | 786 |
| 562 } // namespace net | 787 } // namespace net |
| OLD | NEW |