Merge branch 'sslwarn'

pull/324/head
Tatsuhiro Tsujikawa 2015-01-05 18:57:24 +09:00
commit cc36df2625
1 changed files with 74 additions and 42 deletions

View File

@ -831,16 +831,19 @@ bool SocketCore::tlsConnect(const std::string& hostname)
bool SocketCore::tlsHandshake(TLSContext* tlsctx, const std::string& hostname) bool SocketCore::tlsHandshake(TLSContext* tlsctx, const std::string& hostname)
{ {
TLSVersion ver = TLS_PROTO_NONE;
int rv = 0;
std::string handshakeError;
wantRead_ = false; wantRead_ = false;
wantWrite_ = false; wantWrite_ = false;
switch(secure_) {
case A2_TLS_NONE: if(secure_ == A2_TLS_CONNECTED) {
// Already connected!
return true;
}
if(secure_ == A2_TLS_NONE) {
// Do some initial setup
A2_LOG_DEBUG("Creating TLS session"); A2_LOG_DEBUG("Creating TLS session");
tlsSession_.reset(TLSSession::make(tlsctx)); tlsSession_.reset(TLSSession::make(tlsctx));
rv = tlsSession_->init(sockfd_); auto rv = tlsSession_->init(sockfd_);
if(rv != TLS_ERR_OK) { if(rv != TLS_ERR_OK) {
std::string error = tlsSession_->getLastErrorString(); std::string error = tlsSession_->getLastErrorString();
tlsSession_.reset(); tlsSession_.reset();
@ -857,35 +860,26 @@ bool SocketCore::tlsHandshake(TLSContext* tlsctx, const std::string& hostname)
tlsSession_->getLastErrorString().c_str())); tlsSession_->getLastErrorString().c_str()));
} }
} }
// Done with the setup, now let handshaking begin immediately.
secure_ = A2_TLS_HANDSHAKING; secure_ = A2_TLS_HANDSHAKING;
A2_LOG_DEBUG("TLS Handshaking"); A2_LOG_DEBUG("TLS Handshaking");
// Fall through }
case A2_TLS_HANDSHAKING:
if(secure_ == A2_TLS_HANDSHAKING) {
// Starting handshake after intial setup or still handshaking.
TLSVersion ver = TLS_PROTO_NONE;
int rv = 0;
std::string handshakeError;
if(tlsctx->getSide() == TLS_CLIENT) { if(tlsctx->getSide() == TLS_CLIENT) {
rv = tlsSession_->tlsConnect(hostname, ver, handshakeError); rv = tlsSession_->tlsConnect(hostname, ver, handshakeError);
} else { } else {
rv = tlsSession_->tlsAccept(ver); rv = tlsSession_->tlsAccept(ver);
} }
if(rv == TLS_ERR_OK) {
secure_ = A2_TLS_CONNECTED;
break;
}
if(rv != TLS_ERR_WOULDBLOCK) {
throw DL_ABORT_EX(fmt("SSL/TLS handshake failure: %s",
handshakeError.empty() ?
tlsSession_->getLastErrorString().c_str() :
handshakeError.c_str()));
}
if(tlsSession_->checkDirection() == TLS_WANT_READ) {
wantRead_ = true;
} else {
wantWrite_ = true;
}
return false;
default:
break;
}
if(rv == TLS_ERR_OK) {
// We're good, more or less.
// 1. Construct peerinfo
std::stringstream ss; std::stringstream ss;
if (!hostname.empty()) { if (!hostname.empty()) {
ss << hostname << " ("; ss << hostname << " (";
@ -898,18 +892,56 @@ bool SocketCore::tlsHandshake(TLSContext* tlsctx, const std::string& hostname)
} }
auto peerInfo = ss.str(); auto peerInfo = ss.str();
// 2. Issue any warnings
switch(ver) { switch(ver) {
case TLS_PROTO_NONE: case TLS_PROTO_NONE:
A2_LOG_WARN(fmt(MSG_WARN_UNKNOWN_TLS_CONNECTION, peerInfo.c_str())); A2_LOG_WARN(fmt(MSG_WARN_UNKNOWN_TLS_CONNECTION, peerInfo.c_str()));
break; break;
case TLS_PROTO_SSL3: case TLS_PROTO_SSL3:
A2_LOG_WARN(fmt(MSG_WARN_OLD_TLS_CONNECTION, "SSLv3", peerInfo.c_str())); A2_LOG_WARN(fmt(MSG_WARN_OLD_TLS_CONNECTION,
"SSLv3", peerInfo.c_str()));
break; break;
default: default:
A2_LOG_DEBUG(fmt("Securely connected to %s", peerInfo.c_str()));
break; break;
} }
// 3. We're connected now!
secure_ = A2_TLS_CONNECTED;
return true; return true;
}
if(rv == TLS_ERR_WOULDBLOCK) {
// We're not done yet...
if(tlsSession_->checkDirection() == TLS_WANT_READ) {
// ... but read buffers are empty.
wantRead_ = true;
} else {
// ... but write buffers are full.
wantWrite_ = true;
}
// Returning false (instead of true==success or throwing) will cause this
// function to be called again once buffering is dealt with
return false;
}
if (rv == TLS_ERR_ERROR) {
// Damn those error.
throw DL_ABORT_EX(fmt("SSL/TLS handshake failure: %s",
handshakeError.empty() ?
tlsSession_->getLastErrorString().c_str() :
handshakeError.c_str()));
}
// Some implementation passed back an invalid result.
throw DL_ABORT_EX(fmt(EX_SSL_INIT_FAILURE,
"Invalid connect state (this is a bug in the TLS "
"backend!)"));
}
// We should never get here, i.e. all possible states should have been handled
// and returned from a branch before! Getting here is a bug, of course!
throw DL_ABORT_EX(fmt(EX_SSL_INIT_FAILURE, "Invalid state (this is a bug!)"));
} }
#endif // ENABLE_SSL #endif // ENABLE_SSL