in activemq-cpp/src/main/decaf/internal/net/ssl/openssl/OpenSSLSocket.cpp [331:425]
void OpenSSLSocket::startHandshake() {
if (!this->isConnected()) {
throw IOException(__FILE__, __LINE__, "Socket is not connected.");
}
if (this->isClosed()) {
throw IOException(__FILE__, __LINE__, "Socket already closed.");
}
try {
#ifdef HAVE_OPENSSL
synchronized( &(this->data->handshakeLock ) ) {
if (this->data->handshakeStarted) {
return;
}
this->data->handshakeStarted = true;
bool peerVerifyDisabled = Boolean::parseBoolean(System::getProperty("decaf.net.ssl.disablePeerVerification", "false"));
if (this->parameters->getUseClientMode()) {
// Since we are a client we want to enforce peer verification, we set a
// callback so we can collect data on why a verify failed for debugging.
if (!peerVerifyDisabled) {
// Check host https://wiki.openssl.org/index.php/Hostname_validation
X509_VERIFY_PARAM *param = SSL_get0_param(this->parameters->getSSL());
X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
X509_VERIFY_PARAM_set1_host(param, this->data->commonName.c_str(), 0);
SSL_set_verify(this->parameters->getSSL(), SSL_VERIFY_PEER, SocketData::verifyCallback);
} else {
SSL_set_verify(this->parameters->getSSL(), SSL_VERIFY_NONE, NULL);
}
std::vector<std::string> serverNames = this->parameters->getServerNames();
if (!serverNames.empty()) {
std::string serverName = serverNames.at(0);
SSL_set_tlsext_host_name(this->parameters->getSSL(), serverName.c_str());
}
int result = SSL_connect(this->parameters->getSSL());
// Checks the error status
switch (SSL_get_error(this->parameters->getSSL(), result)) {
case SSL_ERROR_NONE:
break;
case SSL_ERROR_SSL:
case SSL_ERROR_ZERO_RETURN:
case SSL_ERROR_SYSCALL:
default:
SSLSocket::close();
throw OpenSSLSocketException(__FILE__, __LINE__);
}
} else { // We are in Server Mode.
int mode = SSL_VERIFY_NONE;
if (!peerVerifyDisabled) {
if (this->parameters->getWantClientAuth()) {
mode = SSL_VERIFY_PEER;
}
if (this->parameters->getNeedClientAuth()) {
mode = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
}
}
// Since we are a server we want to enforce peer verification, we set a
// callback so we can collect data on why a verify failed for debugging.
SSL_set_verify(this->parameters->getSSL(), mode, SocketData::verifyCallback);
int result = SSL_accept(this->parameters->getSSL());
if (result != SSL_ERROR_NONE) {
SSLSocket::close();
throw OpenSSLSocketException(__FILE__, __LINE__);
}
}
this->data->handshakeCompleted = true;
}
#else
throw IOException( __FILE__, __LINE__, "SSL Not Supported." );
#endif
}
DECAF_CATCH_RETHROW(IOException)
DECAF_CATCHALL_THROW(IOException)
}