void TLSSocket::Handshake(TCPSocket& socket, HandshakeRole role, TLSSocket* reuse) { SSL_CTX* ctx = role == Client ? TLSClientContext::Get() : TLSServerContext::Get(); if (!ctx) throw TLSError("TLS context not initialised."); session = SSL_new(ctx); if (!session) throw TLSProtocolError(); if (SSL_set_fd(session, socket.Socket()) != 1) throw TLSProtocolError(); if (reuse) { assert(reuse->session); SSL_copy_session_id(session, reuse->session); } if (role == Client) SSL_set_connect_state(session); else SSL_set_accept_state(session); int result; while (true) { if (role == Client) result = SSL_connect(session); else result = SSL_accept(session); boost::this_thread::interruption_point(); if (result == 1) break; else EvaluateResult(result); } }
bool SSLSocket::setupCrypto(SSLSocket *session /* = NULL */) { if (m_handle) { raise_warning("SSL/TLS already set-up for this stream"); return false; } /* need to do slightly different things, based on client/server method, * so lets remember which method was selected */ #if OPENSSL_VERSION_NUMBER < 0x00909000L SSL_METHOD *smethod; #else const SSL_METHOD *smethod; #endif switch (m_method) { case ClientSSLv23: m_client = true; smethod = SSLv23_client_method(); break; case ClientSSLv3: m_client = true; smethod = SSLv3_client_method(); break; case ClientTLS: m_client = true; smethod = TLSv1_client_method(); break; case ServerSSLv23: m_client = false; smethod = SSLv23_server_method(); break; case ServerSSLv3: m_client = false; smethod = SSLv3_server_method(); break; /* SSLv2 protocol might be disabled in the OpenSSL library */ #ifndef OPENSSL_NO_SSL2 case ClientSSLv2: m_client = true; smethod = SSLv2_client_method(); break; case ServerSSLv2: m_client = false; smethod = SSLv2_server_method(); break; #else case ClientSSLv2: case ServerSSLv2: raise_warning("OpenSSL library does not support SSL2 protocol"); return false; break; #endif case ServerTLS: m_client = false; smethod = TLSv1_server_method(); break; default: return false; } SSL_CTX *ctx = SSL_CTX_new(smethod); if (ctx == nullptr) { raise_warning("failed to create an SSL context"); return false; } SSL_CTX_set_options(ctx, SSL_OP_ALL); m_handle = createSSL(ctx); if (m_handle == nullptr) { raise_warning("failed to create an SSL handle"); SSL_CTX_free(ctx); return false; } if (!SSL_set_fd(m_handle, m_fd)) { handleError(0, true); } if (session) { SSL_copy_session_id(m_handle, session->m_handle); } return true; }
int BIO_ssl_copy_session_id(BIO *t, BIO *f) { t=BIO_find_type(t,BIO_TYPE_SSL); f=BIO_find_type(f,BIO_TYPE_SSL); if ((t == NULL) || (f == NULL)) return(0); if ( (((BIO_SSL *)t->ptr)->ssl == NULL) || (((BIO_SSL *)f->ptr)->ssl == NULL)) return(0); SSL_copy_session_id(((BIO_SSL *)t->ptr)->ssl,((BIO_SSL *)f->ptr)->ssl); return(1); }
int BIO_ssl_copy_session_id(BIO *t, BIO *f) { BIO_SSL *tdata, *fdata; t = BIO_find_type(t, BIO_TYPE_SSL); f = BIO_find_type(f, BIO_TYPE_SSL); if ((t == NULL) || (f == NULL)) return 0; tdata = BIO_get_data(t); fdata = BIO_get_data(f); if ((tdata->ssl == NULL) || (fdata->ssl == NULL)) return 0; if (!SSL_copy_session_id(tdata->ssl, (fdata->ssl))) return 0; return 1; }
static void create_conn (Sess *sess, struct Conn_Info *ci) { Conn_Private_Data *cpriv; /* No connection yet (or anymore). Create a new connection. Note that CI->CONN is NOT reference-counted. This is again to avoid introducing recursive dependencies (see also comment regarding member CONN in call.h). */ ci->conn = conn_new (); if (!ci->conn) { sess_failure (sess); return; } cpriv = CONN_PRIVATE_DATA (ci->conn); cpriv->sess = sess; cpriv->ci = ci; ci->is_connected = 0; ci->is_successful = 0; ci->num_sent = 0; /* (re-)send all pending calls */ #ifdef HAVE_SSL if (param.ssl_reuse && ci->conn->ssl && sess->ssl) { if (DBG > 0) fprintf (stderr, "create_conn: reusing SSL session %p\n", (void *) sess->ssl); SSL_copy_session_id (ci->conn->ssl, sess->ssl); } #endif if (core_connect (ci->conn) < 0) sess_failure (sess); }
/* {{{ data_accept */ databuf_t* data_accept(databuf_t *data, ftpbuf_t *ftp) { php_sockaddr_storage addr; socklen_t size; #if HAVE_OPENSSL_EXT SSL_CTX *ctx; zend_long ssl_ctx_options = SSL_OP_ALL; #endif if (data->fd != -1) { goto data_accepted; } size = sizeof(addr); data->fd = my_accept(ftp, data->listener, (struct sockaddr*) &addr, &size); closesocket(data->listener); data->listener = -1; if (data->fd == -1) { efree(data); return NULL; } data_accepted: #if HAVE_OPENSSL_EXT /* now enable ssl if we need to */ if (ftp->use_ssl && ftp->use_ssl_for_data) { ctx = SSL_CTX_new(SSLv23_client_method()); if (ctx == NULL) { php_error_docref(NULL, E_WARNING, "data_accept: failed to create the SSL context"); return 0; } #if OPENSSL_VERSION_NUMBER >= 0x0090605fL ssl_ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; #endif SSL_CTX_set_options(ctx, ssl_ctx_options); data->ssl_handle = SSL_new(ctx); if (data->ssl_handle == NULL) { php_error_docref(NULL, E_WARNING, "data_accept: failed to create the SSL handle"); SSL_CTX_free(ctx); return 0; } SSL_set_fd(data->ssl_handle, data->fd); if (ftp->old_ssl) { SSL_copy_session_id(data->ssl_handle, ftp->ssl_handle); } if (SSL_connect(data->ssl_handle) <= 0) { php_error_docref(NULL, E_WARNING, "data_accept: SSL/TLS handshake failed"); SSL_shutdown(data->ssl_handle); SSL_free(data->ssl_handle); return 0; } data->ssl_active = 1; } #endif return data; }
/* {{{ data_accept */ databuf_t* data_accept(databuf_t *data, ftpbuf_t *ftp) { php_sockaddr_storage addr; socklen_t size; #ifdef HAVE_FTP_SSL SSL_CTX *ctx; SSL_SESSION *session; int err, res; zend_bool retry; #endif if (data->fd != -1) { goto data_accepted; } size = sizeof(addr); data->fd = my_accept(ftp, data->listener, (struct sockaddr*) &addr, &size); closesocket(data->listener); data->listener = -1; if (data->fd == -1) { efree(data); return NULL; } data_accepted: #ifdef HAVE_FTP_SSL /* now enable ssl if we need to */ if (ftp->use_ssl && ftp->use_ssl_for_data) { ctx = SSL_get_SSL_CTX(ftp->ssl_handle); if (ctx == NULL) { php_error_docref(NULL, E_WARNING, "data_accept: failed to retreive the existing SSL context"); return 0; } data->ssl_handle = SSL_new(ctx); if (data->ssl_handle == NULL) { php_error_docref(NULL, E_WARNING, "data_accept: failed to create the SSL handle"); return 0; } SSL_set_fd(data->ssl_handle, data->fd); if (ftp->old_ssl) { SSL_copy_session_id(data->ssl_handle, ftp->ssl_handle); } /* get the session from the control connection so we can re-use it */ session = SSL_get_session(ftp->ssl_handle); if (session == NULL) { php_error_docref(NULL, E_WARNING, "data_accept: failed to retreive the existing SSL session"); SSL_free(data->ssl_handle); return 0; } /* and set it on the data connection */ res = SSL_set_session(data->ssl_handle, session); if (res == 0) { php_error_docref(NULL, E_WARNING, "data_accept: failed to set the existing SSL session"); SSL_free(data->ssl_handle); return 0; } do { res = SSL_connect(data->ssl_handle); err = SSL_get_error(data->ssl_handle, res); switch (err) { case SSL_ERROR_NONE: retry = 0; break; case SSL_ERROR_ZERO_RETURN: retry = 0; SSL_shutdown(data->ssl_handle); break; case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: { php_pollfd p; int i; p.fd = ftp->fd; p.events = (err == SSL_ERROR_WANT_READ) ? (POLLIN|POLLPRI) : POLLOUT; p.revents = 0; i = php_poll2(&p, 1, 300); retry = i > 0; } break; default: php_error_docref(NULL, E_WARNING, "data_accept: SSL/TLS handshake failed"); SSL_shutdown(data->ssl_handle); SSL_free(data->ssl_handle); return 0; } } while (retry); data->ssl_active = 1; } #endif return data; }
/* {{{ data_accept */ databuf_t* data_accept(databuf_t *data, ftpbuf_t *ftp) { php_sockaddr_storage addr; socklen_t size; #ifdef HAVE_FTP_SSL SSL_CTX *ctx; zend_long ssl_ctx_options = SSL_OP_ALL; int err, res; zend_bool retry; #endif if (data->fd != -1) { goto data_accepted; } size = sizeof(addr); data->fd = my_accept(ftp, data->listener, (struct sockaddr*) &addr, &size); closesocket(data->listener); data->listener = -1; if (data->fd == -1) { efree(data); return NULL; } data_accepted: #ifdef HAVE_FTP_SSL /* now enable ssl if we need to */ if (ftp->use_ssl && ftp->use_ssl_for_data) { ctx = SSL_CTX_new(SSLv23_client_method()); if (ctx == NULL) { php_error_docref(NULL, E_WARNING, "data_accept: failed to create the SSL context"); return 0; } #if OPENSSL_VERSION_NUMBER >= 0x0090605fL ssl_ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; #endif SSL_CTX_set_options(ctx, ssl_ctx_options); data->ssl_handle = SSL_new(ctx); if (data->ssl_handle == NULL) { php_error_docref(NULL, E_WARNING, "data_accept: failed to create the SSL handle"); SSL_CTX_free(ctx); return 0; } SSL_set_fd(data->ssl_handle, data->fd); if (ftp->old_ssl) { SSL_copy_session_id(data->ssl_handle, ftp->ssl_handle); } do { res = SSL_connect(data->ssl_handle); err = SSL_get_error(data->ssl_handle, res); switch (err) { case SSL_ERROR_NONE: retry = 0; break; case SSL_ERROR_ZERO_RETURN: retry = 0; SSL_shutdown(data->ssl_handle); break; case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: { php_pollfd p; int i; p.fd = ftp->fd; p.events = (err == SSL_ERROR_WANT_READ) ? (POLLIN|POLLPRI) : POLLOUT; p.revents = 0; i = php_poll2(&p, 1, 300); retry = i > 0; } break; default: php_error_docref(NULL, E_WARNING, "data_accept: SSL/TLS handshake failed"); SSL_shutdown(data->ssl_handle); SSL_free(data->ssl_handle); return 0; } } while (retry); data->ssl_active = 1; } #endif return data; }