@@ -1611,6 +1611,66 @@ TEST(SSLTest, test_SSL_set_ocsp_response_inside_select_certificate_cb) {
16111611}
16121612
16131613
1614+ /* *
1615+ * @brief This test exercises a leak in SSL_set_ocsp_response()
1616+ *
1617+ * This test exercises a leak in SSL_set_ocsp_response() that occurs when it is
1618+ * invoked multiple times from within the same certificate selection callback
1619+ * i.e. without the fix, running this test under valgrind or similar memory
1620+ * checker tool will report the memory leak.
1621+ *
1622+ * Note that the leak does _not_ occur if SSL_set_ocsp_response() is only called
1623+ * _once_ from within the same certificate selection callback. It is only the
1624+ * additional calls that leak.
1625+ */
1626+ TEST (SSLTest, test_SSL_set_ocsp_response_leak_inside_select_certificate_cb) {
1627+ TempFile server_2_key_pem { server_2_key_pem_str };
1628+ TempFile server_2_cert_chain_pem { server_2_cert_chain_pem_str };
1629+
1630+ static const uint8_t OCSP_RESPONSE[] { 1 , 2 , 3 , 4 , 5 };
1631+
1632+ int sockets[2 ];
1633+ ASSERT_EQ (0 , socketpair (AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0 , sockets));
1634+ SocketCloser close[] { sockets[0 ], sockets[1 ] };
1635+
1636+ bssl::UniquePtr<SSL_CTX> server_ctx (SSL_CTX_new (TLS_server_method ()));
1637+ bssl::UniquePtr<SSL_CTX> client_ctx (SSL_CTX_new (TLS_client_method ()));
1638+
1639+ // Set up server with a select certificate callback that calls
1640+ // SSL_set_ocsp_response() 5 times. This will result in 4 leaks if the
1641+ // SSL_set_ocsp_response() fix is not in place.
1642+ SSL_CTX_set_select_certificate_cb (server_ctx.get (), [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
1643+ SSL_set_ocsp_response (client_hello->ssl , OCSP_RESPONSE, sizeof (OCSP_RESPONSE));
1644+ SSL_set_ocsp_response (client_hello->ssl , OCSP_RESPONSE, sizeof (OCSP_RESPONSE));
1645+ SSL_set_ocsp_response (client_hello->ssl , OCSP_RESPONSE, sizeof (OCSP_RESPONSE));
1646+ SSL_set_ocsp_response (client_hello->ssl , OCSP_RESPONSE, sizeof (OCSP_RESPONSE));
1647+ SSL_set_ocsp_response (client_hello->ssl , OCSP_RESPONSE, sizeof (OCSP_RESPONSE));
1648+ return ssl_select_cert_success;
1649+ });
1650+ ASSERT_TRUE (SSL_CTX_use_certificate_chain_file (server_ctx.get (), server_2_cert_chain_pem.path ()));
1651+ ASSERT_TRUE (SSL_CTX_use_PrivateKey_file (server_ctx.get (), server_2_key_pem.path (), SSL_FILETYPE_PEM));
1652+ bssl::UniquePtr<SSL> server_ssl (SSL_new (server_ctx.get ()));
1653+ ASSERT_TRUE (SSL_set_fd (server_ssl.get (), sockets[0 ]));
1654+ SSL_set_accept_state (server_ssl.get ());
1655+
1656+ // Set up client with ocsp stapling enabled
1657+ SSL_CTX_set_verify (client_ctx.get (), SSL_VERIFY_NONE, nullptr );
1658+ bssl::UniquePtr<SSL> client_ssl (SSL_new (client_ctx.get ()));
1659+ ASSERT_TRUE (SSL_set_fd (client_ssl.get (), sockets[1 ]));
1660+ SSL_set_connect_state (client_ssl.get ());
1661+ SSL_enable_ocsp_stapling (client_ssl.get ());
1662+
1663+ ASSERT_TRUE (CompleteHandshakes (client_ssl.get (), server_ssl.get ()));
1664+
1665+ // Check that the client received the OCSP response ok
1666+ const uint8_t *ocsp_resp_data{};
1667+ size_t ocsp_resp_len{};
1668+ SSL_get0_ocsp_response (client_ssl.get (), &ocsp_resp_data, &ocsp_resp_len);
1669+ ASSERT_EQ (sizeof (OCSP_RESPONSE), ocsp_resp_len);
1670+ ASSERT_EQ (0 , memcmp (OCSP_RESPONSE, ocsp_resp_data, ocsp_resp_len));
1671+ }
1672+
1673+
16141674/* *
16151675 * Test that setting a TLS alert and returning ssl_verify_invalid, from a
16161676 * callback installed via SSL_CTX_set_custom_verify(), results in a handshake
0 commit comments