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