|
6 | 6 | #include "../crypto/test/file_util.h" |
7 | 7 | #include "../crypto/test/test_util.h" |
8 | 8 | #include "internal.h" |
| 9 | +#include "openssl/ssl.h" |
9 | 10 | #include "ssl_common_test.h" |
10 | 11 |
|
11 | 12 | BSSL_NAMESPACE_BEGIN |
@@ -336,53 +337,54 @@ TEST(SSLTest, QuietShutdown) { |
336 | 337 | } |
337 | 338 |
|
338 | 339 | // Test that |SSL_OP_IGNORE_UNEXPECTED_EOF| causes an unexpected transport EOF |
339 | | -// when the server closes without a close_notify to be reported as a clean shutdown, |
340 | | -// |SSL_ERROR_ZERO_RETURN|, instead of |SSL_ERROR_SYSCALL|. |
341 | | -TEST(SSLTest, IgnoreUnexpectedEOFClient) { |
| 340 | +// (the peer closing without a close_notify) to be reported as a clean shutdown, |
| 341 | +// |SSL_ERROR_ZERO_RETURN|, instead of |SSL_ERROR_SYSCALL|, for both the client |
| 342 | +// and the server. |
| 343 | +TEST(SSLTest, IgnoreUnexpectedEOF) { |
342 | 344 | bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())); |
343 | 345 | bssl::UniquePtr<SSL_CTX> server_ctx = |
344 | 346 | CreateContextWithTestCertificate(TLS_method()); |
345 | 347 | ASSERT_TRUE(client_ctx); |
346 | 348 | ASSERT_TRUE(server_ctx); |
347 | 349 | SSL_CTX_set_options(client_ctx.get(), SSL_OP_IGNORE_UNEXPECTED_EOF); |
| 350 | + SSL_CTX_set_options(server_ctx.get(), SSL_OP_IGNORE_UNEXPECTED_EOF); |
348 | 351 | bssl::UniquePtr<SSL> client, server; |
349 | 352 | ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(), |
350 | 353 | server_ctx.get())); |
351 | 354 |
|
352 | | - // Close the server's write side without sending a close_notify, so the client |
353 | | - // sees an unexpected transport EOF. |
354 | | - EXPECT_TRUE(BIO_shutdown_wr(SSL_get_wbio(server.get()))); |
| 355 | + // Create a fake read BIO that mimics a socket: it returns 0 on read to |
| 356 | + // signal a transport EOF. |
| 357 | + bssl::UniquePtr<BIO_METHOD> method(BIO_meth_new(0, nullptr)); |
| 358 | + ASSERT_TRUE(method); |
| 359 | + ASSERT_TRUE(BIO_meth_set_create(method.get(), [](BIO *b) -> int { |
| 360 | + BIO_set_init(b, 1); |
| 361 | + return 1; |
| 362 | + })); |
| 363 | + ASSERT_TRUE(BIO_meth_set_read(method.get(), |
| 364 | + [](BIO *, char *, int) -> int { return 0; })); |
| 365 | + ASSERT_TRUE(BIO_meth_set_ctrl( |
| 366 | + method.get(), [](BIO *, int, long, void *) -> long { return 0; })); |
| 367 | + |
| 368 | + BIO *eof_bio_client = BIO_new(method.get()); |
| 369 | + BIO *eof_bio_server = BIO_new(method.get()); |
| 370 | + ASSERT_TRUE(eof_bio_client); |
| 371 | + ASSERT_TRUE(eof_bio_server); |
355 | 372 |
|
356 | | - // With the option set, the client reports the EOF as a clean shutdown rather |
357 | | - // than |SSL_ERROR_SYSCALL|. |
| 373 | + // Dummy BIOs must mimic a socket BIO (BIO_eof == 0) |
| 374 | + EXPECT_EQ(BIO_eof(eof_bio_client), 0); |
| 375 | + EXPECT_EQ(BIO_eof(eof_bio_server), 0); |
| 376 | + |
| 377 | + SSL_set0_rbio(client.get(), eof_bio_client); |
| 378 | + SSL_set0_rbio(server.get(), eof_bio_server); |
| 379 | + |
| 380 | + // With the option set, an unexpected transport EOF is reported as a clean |
| 381 | + // shutdown, |SSL_ERROR_ZERO_RETURN|, rather than |SSL_ERROR_SYSCALL|. |
358 | 382 | char buf[1]; |
359 | 383 | int ret = SSL_read(client.get(), buf, sizeof(buf)); |
360 | 384 | EXPECT_EQ(ret, 0); |
361 | 385 | EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_ZERO_RETURN); |
362 | | -} |
363 | 386 |
|
364 | | -// Test that |SSL_OP_IGNORE_UNEXPECTED_EOF| behaves symmetrically on the server: |
365 | | -// when the client closes without a close_notify, the server's |SSL_read| reports |
366 | | -// the unexpected transport EOF as a clean shutdown with |SSL_ERROR_ZERO_RETURN|. |
367 | | -TEST(SSLTest, IgnoreUnexpectedEOFServer) { |
368 | | - bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())); |
369 | | - bssl::UniquePtr<SSL_CTX> server_ctx = |
370 | | - CreateContextWithTestCertificate(TLS_method()); |
371 | | - ASSERT_TRUE(client_ctx); |
372 | | - ASSERT_TRUE(server_ctx); |
373 | | - SSL_CTX_set_options(server_ctx.get(), SSL_OP_IGNORE_UNEXPECTED_EOF); |
374 | | - bssl::UniquePtr<SSL> client, server; |
375 | | - ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(), |
376 | | - server_ctx.get())); |
377 | | - |
378 | | - // Close the client's write side without sending a close_notify, so the server |
379 | | - // sees an unexpected transport EOF. |
380 | | - EXPECT_TRUE(BIO_shutdown_wr(SSL_get_wbio(client.get()))); |
381 | | - |
382 | | - // With the option set, the server reports the EOF as a clean shutdown rather |
383 | | - // than |SSL_ERROR_SYSCALL|. |
384 | | - char buf[1]; |
385 | | - int ret = SSL_read(server.get(), buf, sizeof(buf)); |
| 387 | + ret = SSL_read(server.get(), buf, sizeof(buf)); |
386 | 388 | EXPECT_EQ(ret, 0); |
387 | 389 | EXPECT_EQ(SSL_get_error(server.get(), ret), SSL_ERROR_ZERO_RETURN); |
388 | 390 | } |
|
0 commit comments