00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00040 #include "OW_config.h"
00041 #include "OW_SSLSocketImpl.hpp"
00042 #include "OW_Format.hpp"
00043 #include "OW_Assertion.hpp"
00044 #ifdef OW_HAVE_OPENSSL
00045 #include <openssl/err.h>
00046 #include <OW_Format.hpp>
00047 #include <OW_SocketUtils.hpp>
00048
00049
00050 namespace OW_NAMESPACE
00051 {
00053 SSLSocketImpl::SSLSocketImpl(SSLClientCtxRef sslCtx)
00054 : SocketBaseImpl()
00055 , m_ssl(0)
00056 , m_sslCtx(sslCtx)
00057 {
00058 }
00059
00060 namespace
00061 {
00062
00063 void sslWaitForIO(SocketBaseImpl& s, int type)
00064 {
00065 if(type == SSL_ERROR_WANT_READ)
00066 {
00067 s.waitForInput();
00068 }
00069 else
00070 {
00071 s.waitForOutput();
00072 }
00073 }
00074
00075 void shutdownSSL(SSL* ssl)
00076 {
00077 OW_ASSERT(ssl != 0);
00078 if (SSL_shutdown(ssl) == -1)
00079 {
00080
00081 }
00082
00083
00084 }
00085
00086 void connectWithSSL(SSL* ssl, SocketBaseImpl& s)
00087 {
00088 OW_ASSERT(ssl != 0);
00089 int retries = 0;
00090 ERR_clear_error();
00091 int cc = SSL_connect(ssl);
00092 cc = SSL_get_error(ssl, cc);
00093 while((cc == SSL_ERROR_WANT_READ
00094 || cc == SSL_ERROR_WANT_WRITE)
00095 && retries < OW_SSL_RETRY_LIMIT)
00096 {
00097 sslWaitForIO(s, cc);
00098 ERR_clear_error();
00099 cc = SSL_connect(ssl);
00100 cc = SSL_get_error(ssl, cc);
00101 retries++;
00102 }
00103
00104 if (cc != SSL_ERROR_NONE)
00105 {
00106 OW_THROW(SSLException, Format("SSL connect error: %1", SSLCtxMgr::getOpenSSLErrorDescription()).c_str());
00107 }
00108 }
00109
00110 int acceptSSL(SSL* ssl, SocketBaseImpl& s, String& errorDescription)
00111 {
00112 OW_ASSERT(ssl != 0);
00113 int retries = 0;
00114 int cc = SSL_ERROR_WANT_READ;
00115 while((cc == SSL_ERROR_WANT_READ || cc == SSL_ERROR_WANT_WRITE)
00116 && retries < OW_SSL_RETRY_LIMIT)
00117 {
00118 sslWaitForIO(s, cc);
00119 ERR_clear_error();
00120 cc = SSL_accept(ssl);
00121 cc = SSL_get_error(ssl, cc);
00122 retries++;
00123 }
00124 if (cc == SSL_ERROR_NONE)
00125 {
00126 return 0;
00127 }
00128 else
00129 {
00130 errorDescription = SSLCtxMgr::getOpenSSLErrorDescription();
00131 return -1;
00132 }
00133 }
00134
00135 }
00136
00138 SSLSocketImpl::SSLSocketImpl()
00139 : SocketBaseImpl()
00140 , m_ssl(0)
00141 , m_sbio(0)
00142 {
00143 }
00145 SSLSocketImpl::SSLSocketImpl(SocketHandle_t fd,
00146 SocketAddress::AddressType addrType, const SSLServerCtxRef& sslCtx)
00147 : SocketBaseImpl(fd, addrType)
00148 {
00149 OW_ASSERT(sslCtx);
00150 ERR_clear_error();
00151 m_ssl = SSL_new(sslCtx->getSSLCtx());
00152 if (!m_ssl)
00153 {
00154 OW_THROW(SSLException, Format("SSL_new failed: %1", SSLCtxMgr::getOpenSSLErrorDescription()).c_str());
00155 }
00156
00157 if (SSL_set_ex_data(m_ssl, SSLServerCtx::SSL_DATA_INDEX, &m_owctx) == 0)
00158 {
00159 OW_THROW(SSLException, Format("SSL_set_ex_data failed: %1", SSLCtxMgr::getOpenSSLErrorDescription()).c_str());
00160 }
00161
00162 BIO* bio = BIO_new_socket(fd, BIO_NOCLOSE);
00163 if (!bio)
00164 {
00165 SSL_free(m_ssl);
00166 OW_THROW(SSLException, Format("BIO_new_socket failed: %1", SSLCtxMgr::getOpenSSLErrorDescription()).c_str());
00167 }
00168
00169 SSL_set_bio(m_ssl, bio, bio);
00170 String errorDescription;
00171 if (acceptSSL(m_ssl, *this, errorDescription) != 0)
00172 {
00173 shutdownSSL(m_ssl);
00174 SSL_free(m_ssl);
00175 ERR_remove_state(0);
00176 OW_THROW(SSLException, Format("SSLSocketImpl ctor: SSL accept error while connecting to %1: %2", m_peerAddress.toString(), errorDescription).c_str());
00177 }
00178 if (!SSLCtxMgr::checkClientCert(m_ssl, m_peerAddress.getName()))
00179 {
00180 shutdownSSL(m_ssl);
00181 SSL_free(m_ssl);
00182 ERR_remove_state(0);
00183 OW_THROW(SSLException, "SSL failed to authenticate client");
00184 }
00185 }
00186
00187
00189 SSLSocketImpl::SSLSocketImpl(SocketHandle_t fd,
00190 SocketAddress::AddressType addrType)
00191 : SocketBaseImpl(fd, addrType)
00192 {
00193 ERR_clear_error();
00194 m_ssl = SSL_new(SSLCtxMgr::getSSLCtxServer());
00195 if (!m_ssl)
00196 {
00197 OW_THROW(SSLException, Format("SSL_new failed: %1", SSLCtxMgr::getOpenSSLErrorDescription()).c_str());
00198 }
00199
00200 m_sbio = BIO_new_socket(fd, BIO_NOCLOSE);
00201 if (!m_sbio)
00202 {
00203 SSL_free(m_ssl);
00204 OW_THROW(SSLException, Format("BIO_new_socket failed: %1", SSLCtxMgr::getOpenSSLErrorDescription()).c_str());
00205 }
00206
00207 SSL_set_bio(m_ssl, m_sbio, m_sbio);
00208 String errorDescription;
00209 if (acceptSSL(m_ssl, *this, errorDescription) != 0)
00210 {
00211 shutdownSSL(m_ssl);
00212 SSL_free(m_ssl);
00213 ERR_remove_state(0);
00214 OW_THROW(SSLException, Format("SSLSocketImpl ctor: SSL accept error while connecting to %1: %2", m_peerAddress.toString(), errorDescription).c_str());
00215 }
00216 if (!SSLCtxMgr::checkClientCert(m_ssl, m_peerAddress.getName()))
00217 {
00218 shutdownSSL(m_ssl);
00219 SSL_free(m_ssl);
00220 ERR_remove_state(0);
00221 OW_THROW(SSLException, "SSL failed to authenticate client");
00222 }
00223 }
00225 SSLSocketImpl::SSLSocketImpl(const SocketAddress& addr)
00226 : SocketBaseImpl(addr)
00227 {
00228 connectSSL();
00229 }
00231 SSLSocketImpl::~SSLSocketImpl()
00232 {
00233 try
00234 {
00235 disconnect();
00236 if (m_ssl)
00237 {
00238 SSL_free(m_ssl);
00239 m_ssl = 0;
00240 }
00241 ERR_remove_state(0);
00242 }
00243 catch (...)
00244 {
00245
00246 }
00247 }
00249 Select_t
00250 SSLSocketImpl::getSelectObj() const
00251 {
00252 #if defined(OW_WIN32)
00253 Select_t st;
00254 st.event = m_event;
00255 st.sockfd = m_sockfd;
00256 st.networkevents = FD_READ | FD_WRITE;
00257 st.doreset = true;
00258 return st;
00259 #else
00260 return m_sockfd;
00261 #endif
00262 }
00264 void
00265 SSLSocketImpl::connect(const SocketAddress& addr)
00266 {
00267 SocketBaseImpl::connect(addr);
00268 connectSSL();
00269 }
00271 void
00272 SSLSocketImpl::connectSSL()
00273 {
00274 m_isConnected = false;
00275 OW_ASSERT(m_sslCtx);
00276 if (m_ssl)
00277 {
00278 SSL_free(m_ssl);
00279 m_ssl = 0;
00280 }
00281 ERR_clear_error();
00282 m_ssl = SSL_new(m_sslCtx->getSSLCtx());
00283
00284 if (!m_ssl)
00285 {
00286 OW_THROW(SSLException, Format("SSL_new failed: %1", SSLCtxMgr::getOpenSSLErrorDescription()).c_str());
00287 }
00288 m_sbio = BIO_new_socket(m_sockfd, BIO_NOCLOSE);
00289 if (!m_sbio)
00290 {
00291 SSL_free(m_ssl);
00292 OW_THROW(SSLException, Format("BIO_new_socket failed: %1", SSLCtxMgr::getOpenSSLErrorDescription()).c_str());
00293 }
00294 SSL_set_bio(m_ssl, m_sbio, m_sbio);
00295
00296 connectWithSSL(m_ssl, *this);
00297
00298 if (!SSLCtxMgr::checkServerCert(m_ssl, m_peerAddress.getName()))
00299 {
00300 OW_THROW(SSLException, "Failed to validate peer certificate");
00301 }
00302 m_isConnected = true;
00303 }
00305 void
00306 SSLSocketImpl::disconnect()
00307 {
00308 #if defined(OW_WIN32)
00309 if (m_sockfd != INVALID_SOCKET && m_isConnected)
00310 #else
00311 if (m_sockfd != -1 && m_isConnected)
00312 #endif
00313 {
00314 if (m_ssl)
00315 {
00316 shutdownSSL(m_ssl);
00317 }
00318 }
00319 SocketBaseImpl::disconnect();
00320 }
00322 int
00323 SSLSocketImpl::writeAux(const void* dataOut, int dataOutLen)
00324 {
00325 return SSLCtxMgr::sslWrite(m_ssl, static_cast<const char*>(dataOut),
00326 dataOutLen);
00327 }
00329 int
00330 SSLSocketImpl::readAux(void* dataIn, int dataInLen)
00331 {
00332 return SSLCtxMgr::sslRead(m_ssl, static_cast<char*>(dataIn),
00333 dataInLen);
00334 }
00336 SSL*
00337 SSLSocketImpl::getSSL() const
00338 {
00339 return m_ssl;
00340 }
00341
00343 bool
00344 SSLSocketImpl::peerCertVerified() const
00345 {
00346 return (m_owctx.peerCertPassedVerify == OWSSLContext::VERIFY_PASS);
00347 }
00348
00350
00351
00352 bool
00353 SSLSocketImpl::waitForInput(int timeOutSecs)
00354 {
00355
00356 if (SSL_pending(m_ssl))
00357 {
00358 return false;
00359 }
00360 return SocketBaseImpl::waitForInput(timeOutSecs);
00361 }
00363
00364 }
00365
00367 #endif // #ifdef OW_HAVE_OPENSSL
00368