|
23 | 23 | #include "request_callback.hpp" |
24 | 24 | #include "ssl.hpp" |
25 | 25 |
|
| 26 | +#include <cstdio> |
| 27 | +#include <fstream> |
| 28 | + |
26 | 29 | #ifdef WIN32 |
27 | 30 | #undef STATUS_TIMEOUT |
28 | 31 | #endif |
@@ -190,6 +193,48 @@ TEST_F(ConnectionUnitTest, Ssl) { |
190 | 193 | EXPECT_EQ(state.status, STATUS_SUCCESS); |
191 | 194 | } |
192 | 195 |
|
| 196 | +TEST_F(ConnectionUnitTest, SslDefaultVerifyPaths) { |
| 197 | + const String host = "127.0.0.1"; |
| 198 | + const int verification_flags = CASS_SSL_VERIFY_PEER_CERT | CASS_SSL_VERIFY_PEER_IDENTITY; |
| 199 | + const char* cert_path = "cassandra-unit-test.cert"; |
| 200 | + |
| 201 | + mockssandra::SimpleCluster cluster(simple()); |
| 202 | + const String cert = cluster.use_ssl(host); |
| 203 | + EXPECT_FALSE(cert.empty()) << "Unable to enable SSL"; |
| 204 | + ConnectionSettings settings; |
| 205 | + settings.socket_settings.ssl_context = SslContextFactory::create(); |
| 206 | + settings.socket_settings.ssl_context->set_verify_flags(verification_flags); |
| 207 | + ASSERT_EQ(cluster.start_all(), 0); |
| 208 | + |
| 209 | + // Test that cert verification fails prior to calling set_default_verify_paths |
| 210 | + Connector::ConnectionError connect_rc = Connector::CONNECTION_OK; |
| 211 | + Connector::Ptr connector0(new Connector(Host::Ptr(new Host(Address(host, PORT))), |
| 212 | + PROTOCOL_VERSION, |
| 213 | + bind_callback(on_connection_error_code, &connect_rc))); |
| 214 | + connector0->with_settings(settings)->connect(loop()); |
| 215 | + uv_run(loop(), UV_RUN_DEFAULT); |
| 216 | + EXPECT_EQ(connect_rc, Connector::CONNECTION_ERROR_SSL_VERIFY) |
| 217 | + << "Verification succeeded without certificate."; |
| 218 | + |
| 219 | + // Generate certificate as file (which is used by our mock cluster) and import it |
| 220 | + std::ofstream cert_buffer(cert_path); |
| 221 | + cert_buffer << cert; |
| 222 | + cert_buffer.close(); |
| 223 | + ASSERT_EQ(uv_os_setenv("SSL_CERT_FILE", cert_path), 0) << "Failed to prepare openssl environment"; |
| 224 | + ASSERT_EQ(settings.socket_settings.ssl_context->set_default_verify_paths(), CASS_OK) |
| 225 | + << "Failed to import default / system SSL certificates."; |
| 226 | + ASSERT_EQ(std::remove(cert_path), 0) << "Failed to cleanup temporary certificate file."; |
| 227 | + |
| 228 | + // Ensure verification succeeds with this certificate. |
| 229 | + State state; |
| 230 | + Connector::Ptr connector1(new Connector(Host::Ptr(new Host(Address(host, PORT))), |
| 231 | + PROTOCOL_VERSION, |
| 232 | + bind_callback(on_connection_connected, &state))); |
| 233 | + connector1->with_settings(settings)->connect(loop()); |
| 234 | + uv_run(loop(), UV_RUN_DEFAULT); |
| 235 | + EXPECT_EQ(state.status, STATUS_SUCCESS); |
| 236 | +} |
| 237 | + |
193 | 238 | TEST_F(ConnectionUnitTest, Refused) { |
194 | 239 | // Don't start cluster |
195 | 240 |
|
|
0 commit comments