Exemple #1
0
static inline int tls_setup_process(shout_tls_t *tls)
{
	if (SSL_is_init_finished(tls->ssl))
		return tls_check_cert(tls);
	tls->ssl_ret = SSL_connect(tls->ssl);
	if (SSL_is_init_finished(tls->ssl))
		return tls_check_cert(tls);
	return SHOUTERR_BUSY;
}
bool SSLSocket::waitAccepted(uint32_t millis) {
    if(!ssl) {
        if(!Socket::waitAccepted(millis)) {
            return false;
        }
        ssl.reset(SSL_new(ctx));
        if(!ssl)
            checkSSL(-1);

        checkSSL(SSL_set_fd(ssl, getSock()));
    }

    if(SSL_is_init_finished(ssl)) {
        return true;
    }

    while(true) {
        int ret = SSL_accept(ssl);
        if(ret == 1) {
            dcdebug("Connected to SSL client using %s\n", SSL_get_cipher(ssl));
            return true;
        }
        if(!waitWant(ret, millis)) {
            return false;
        }
    }
}
Exemple #3
0
// HANDLE BUFFERS HERE!
// --------------------
void on_event(Client* c) { // is called after each socket event
  char buf[1024 * 10];
  int bytes_read = 0;

  if(!SSL_is_init_finished(c->ssl)) {
    int r = SSL_connect(c->ssl);
    if(r < 0) {
      handle_error(c, r);
    }
    check_outgoing_application_data(c);
  }
  else {
    // connect, check if there is encrypted data, or we need to send app data
    int r = SSL_read(c->ssl, buf, sizeof(buf));
    if(r < 0) {
      handle_error(c, r);
    }
    else if(r > 0) {
      std::copy(buf, buf+r, std::back_inserter(c->buffer_in));
      std::copy(c->buffer_in.begin(), c->buffer_in.end(), std::ostream_iterator<char>(std::cout));
      c->buffer_in.clear();
    }
    check_outgoing_application_data(c);
  }
}
Exemple #4
0
int krx_ssl_handle_traffic(krx* from, krx* to) {

  // Did SSL write something into the out buffer
  char outbuf[4096]; 
  int written = 0;
  int read = 0;
  int pending = BIO_ctrl_pending(from->out_bio);

  if(pending > 0) {
    read = BIO_read(from->out_bio, outbuf, sizeof(outbuf));
  }
  printf("%s Pending %d, and read: %d\n", from->name, pending, read);
  
  if(read > 0) {
    written = BIO_write(to->in_bio, outbuf, read);
  }
  
  if(written > 0) {
    if(!SSL_is_init_finished(to->ssl)) {
      SSL_do_handshake(to->ssl);
    }
    else {
      read = SSL_read(to->ssl, outbuf, sizeof(outbuf));
      printf("%s read: %s\n", to->name, outbuf);
    }
  }

  return 0;
}
gint er_dtls_connection_send(ErDtlsConnection *self, gpointer data, gint len)
{
    g_return_val_if_fail(ER_IS_DTLS_CONNECTION(self), 0);
    int ret = 0;

    g_return_val_if_fail(self->priv->ssl, 0);
    g_return_val_if_fail(self->priv->bio, 0);

    LOG_TRACE(self, "locking @ send");
    g_mutex_lock(&self->priv->mutex);
    LOG_TRACE(self, "locked @ send");

    if (SSL_is_init_finished(self->priv->ssl)) {
        ret = SSL_write(self->priv->ssl, data, len);
        LOG_DEBUG(self, "data sent: input was %d B, output is %d B", len, ret);
    } else {
        LOG_WARNING(self, "tried to send data before handshake was complete");
        ret = 0;
    }

    LOG_TRACE(self, "unlocking @ send");
    g_mutex_unlock(&self->priv->mutex);

    return ret;
}
bool SSLSocket::waitAccepted(uint64_t millis) {
	if(!ssl) {
		if(!Socket::waitAccepted(millis)) {
			return false;
		}
		ssl.reset(SSL_new(ctx));
		if(!ssl)
			checkSSL(-1);

		if(!verifyData) {
			SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
		} else SSL_set_ex_data(ssl, CryptoManager::idxVerifyData, verifyData.get());

		checkSSL(SSL_set_fd(ssl, static_cast<int>(getSock())));
	}

	if(SSL_is_init_finished(ssl)) {
		return true;
	}

	while(true) {
		int ret = SSL_accept(ssl);
		if(ret == 1) {
			dcdebug("Connected to SSL client using %s\n", SSL_get_cipher(ssl));
			return true;
		}
		if(!waitWant(ret, millis)) {
			return false;
		}
	}
}
Exemple #7
0
void SSLAdapter::flush() 
{
    //TraceL << "Flushing" << endl;

    if (!initialized()) {
        int r = SSL_connect(_ssl);
        if (r < 0) {
            TraceL << "Flush: Handle error" << endl;
            handleError(r);
        }
        return;
    }
    
    // Read any decrypted SSL data from the read BIO
    // NOTE: Overwriting the socket's raw SSL recv buffer
    int nread = 0;
    while ((nread = SSL_read(_ssl, _socket->_buffer.data(), _socket->_buffer.capacity())) > 0) {
        //_socket->_buffer.limit(nread);
        _socket->onRecv(mutableBuffer(_socket->_buffer.data(), nread));
    }
    
    // Flush any pending outgoing data
    if (SSL_is_init_finished(_ssl)) { 
        if (_bufferOut.size() > 0) {
            int r = SSL_write(_ssl, &_bufferOut[0], _bufferOut.size()); // causes the write_bio to fill up (which we need to flush)
            if (r < 0) {
                handleError(r);
            }
            _bufferOut.clear();
            flushWriteBIO();
        }
    }
}
bool OutboundSSLProtocol::DoHandshake() {
    if (_sslHandshakeCompleted)
        return true;
    int32_t errorCode = SSL_ERROR_NONE;
    errorCode = SSL_connect(_pSSL);
    if (errorCode < 0) {
        int32_t error = SSL_get_error(_pSSL, errorCode);
        if (error != SSL_ERROR_WANT_READ &&
                error != SSL_ERROR_WANT_WRITE) {
            FATAL("Unable to connect SSL: %d; %s", error, STR(GetSSLErrors()));
            return false;
        }
    }

    _sslHandshakeCompleted = SSL_is_init_finished(_pSSL);

    if (!PerformIO()) {
        FATAL("Unable to perform I/O");
        return false;
    }

    if (_sslHandshakeCompleted)
        return EnqueueForOutbound();

    return true;
}
bool SSLSocket::waitConnected(uint64_t millis) {
	if(!ssl) {
		if(!Socket::waitConnected(millis)) {
			return false;
		}
		ssl.reset(SSL_new(ctx));
		if(!ssl)
			checkSSL(-1);

		checkSSL(SSL_set_fd(ssl, sock));
	}

	if(SSL_is_init_finished(ssl)) {
		return true;
	}

	while(true) {
		// OpenSSL needs server handshake for NAT traversal
		int ret = ssl->server ? SSL_accept(ssl) : SSL_connect(ssl);
		if(ret == 1) {
			dcdebug("Connected to SSL server using %s as %s\n", SSL_get_cipher(ssl), ssl->server?"server":"client");
#ifndef HEADER_OPENSSLV_H			
			finished = true;
#endif
			return true;
		}
		if(!waitWant(ret, millis)) {
			return false;
		}
	}
}
bool SSLSocket::waitAccepted(uint64_t millis) {
	if(!ssl) {
		if(!Socket::waitAccepted(millis)) {
			return false;
		}
		ssl.reset(SSL_new(ctx));
		if(!ssl)
			checkSSL(-1);

		checkSSL(SSL_set_fd(ssl, sock));
	}

	if(SSL_is_init_finished(ssl)) {
		return true;
	}

	while(true) {
		int ret = SSL_accept(ssl);
		if(ret == 1) {
			dcdebug("Connected to SSL client using %s\n", SSL_get_cipher(ssl));
#ifndef HEADER_OPENSSLV_H
			finished = true;
#endif
			return true;
		}
		if(!waitWant(ret, millis)) {
			return false;
		}
	}
}
static void
log_state (GstDtlsConnection * self, const gchar * str)
{
  GstDtlsConnectionPrivate *priv = self->priv;
  guint states = 0;

  states |= (! !SSL_is_init_finished (priv->ssl) << 0);
  states |= (! !SSL_in_init (priv->ssl) << 4);
  states |= (! !SSL_in_before (priv->ssl) << 8);
  states |= (! !SSL_in_connect_init (priv->ssl) << 12);
  states |= (! !SSL_in_accept_init (priv->ssl) << 16);
  states |= (! !SSL_want_write (priv->ssl) << 20);
  states |= (! !SSL_want_read (priv->ssl) << 24);

#if OPENSSL_VERSION_NUMBER < 0x10100001L
  GST_LOG_OBJECT (self, "%s: role=%s buf=(%d,%p:%d/%d) %x|%x %s",
      str,
      priv->is_client ? "client" : "server",
      pqueue_size (priv->ssl->d1->sent_messages),
      priv->bio_buffer,
      priv->bio_buffer_offset,
      priv->bio_buffer_len,
      states, SSL_get_state (priv->ssl), SSL_state_string_long (priv->ssl));
#else
  GST_LOG_OBJECT (self, "%s: role=%s buf=(%p:%d/%d) %x|%x %s",
      str,
      priv->is_client ? "client" : "server",
      priv->bio_buffer,
      priv->bio_buffer_offset,
      priv->bio_buffer_len,
      states, SSL_get_state (priv->ssl), SSL_state_string_long (priv->ssl));
#endif
}
Exemple #12
0
static void
rb_ssl_tryconn_cb(rb_fde_t *F, void *data)
{
	struct ssl_connect *sconn = data;
	int ssl_err;
	if(!SSL_is_init_finished((SSL *) F->ssl))
	{
		if((ssl_err = SSL_connect((SSL *) F->ssl)) <= 0)
		{
			switch (ssl_err = SSL_get_error((SSL *) F->ssl, ssl_err))
			{
			case SSL_ERROR_SYSCALL:
				if(rb_ignore_errno(errno))
			case SSL_ERROR_WANT_READ:
			case SSL_ERROR_WANT_WRITE:
					{
						F->ssl_errno = get_last_err();
						rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE,
							     rb_ssl_tryconn_cb, sconn);
						return;
					}
			default:
				F->ssl_errno = get_last_err();
				rb_ssl_connect_realcb(F, RB_ERROR_SSL, sconn);
				return;
			}
		}
		else
		{
			rb_ssl_connect_realcb(F, RB_OK, sconn);
		}
	}
}
int
ACE_SSL_SOCK_Acceptor::ssl_accept (ACE_SSL_SOCK_Stream &new_stream) const
{
  if (SSL_is_init_finished (new_stream.ssl ()))
    return 0;

  if (!SSL_in_accept_init (new_stream.ssl ()))
    ::SSL_set_accept_state (new_stream.ssl ());

  int status = ::SSL_accept (new_stream.ssl ());

  switch (::SSL_get_error (new_stream.ssl (), status))
    {
    case SSL_ERROR_NONE:
      break;
    case SSL_ERROR_ZERO_RETURN:
      // The peer has notified us that it is shutting down via
      // the SSL "close_notify" message so we need to
      // shutdown, too.
      (void) new_stream.close ();
      return -1;
    default:
      ACE_SSL_Context::report_error ();

      return -1;
    }

  return 0;
}
Exemple #14
0
  void Parser::process(uint8_t* data, uint32_t nbytes) {

    if (!in_bio) {
      printf("dtls::Parser - error: in_bio is invalid, not initialized?\n");
      return;
    }

    if (!data) {
      printf("dtls::Parser - warning: calling Parser::process w/o valid data.\n");
      return;
    }

    if (!nbytes) {
      printf("dtls::Parser - warning: calling Parser::process with invalid nbytes.\n");
      return;
    }

    int written = BIO_write(in_bio, data, nbytes);
    if (written > 0) {
      printf("dtls::Parser - verbose: written: %d\n", written);
      if (!SSL_is_init_finished(ssl)) {
        SSL_do_handshake(ssl);
        checkOutputBuffer();
      }
    }
    else {
      printf("dtls::Parser - error: %d\n", written);
    }
  }
Exemple #15
0
int krypt_do_handshake(krypt_t *kconn, uint8_t *buf, size_t buf_data_size)
{
	int ret = 0;
	int nbyte = 0;
	int status = -1;

	if (buf != NULL && buf_data_size > 0) {
		nbyte = BIO_write(kconn->network_bio, buf, buf_data_size);
	}

	ret = SSL_do_handshake(kconn->ssl);

	jlog(L_NOTICE, "SSL state: %s", SSL_state_string_long(kconn->ssl));

	if (ret > 0 && !SSL_is_init_finished(kconn->ssl)) {
		// Need more data to continue ?
		jlog(L_ERROR, "handshake need more data to continue ??");
		status = 1;
	}
	else if (ret > 0 && SSL_is_init_finished(kconn->ssl)) {
		// Handshake successfully completed
		post_handshake_check(kconn);
		kconn->status = KRYPT_SECURE;
		status = 0;
	}
	else if (ret == 0) {
		// Error
		kconn->status = KRYPT_FAIL;
		jlog(L_ERROR, "ssl_get_error: %d\n", SSL_get_error(kconn->ssl, ret));
		ssl_error_stack();
		jlog(L_ERROR, "handshake error");
		status = -1;
	}
	else if (ret < 0) {
		// Need more data to continue
		status = 1;
	}

	nbyte = BIO_ctrl_pending(kconn->network_bio);

	if (nbyte > 0) { // Read pending data into the BIO
		nbyte = BIO_read(kconn->network_bio, kconn->buf_encrypt, kconn->buf_encrypt_size);
		kconn->buf_encrypt_data_size = nbyte; // FIXME dynamic buffer
	}

	return status;
}
Exemple #16
0
int DTLSBio::sslRead(char* buf, int bufLen)
{
  /// 1. Read available data from the external input (probably libnice)
  /// If packet is not a DTLS packet, return the read value, else goto 2
  /// 2. Store (encrypted) read data into the input BIO using BIO_write
  /// 3. Call SSL_read to decrypt the data
  /// Returns return value of SSL_read
  ///
  if (!_pSSL)
  {
    OSS_LOG_ERROR("DTLSBio::sslRead - _pSSL is not set.");
    return 0;
  }
  
  if (!SSL_is_init_finished(_pSSL))
  {
    OSS_LOG_ERROR("DTLSBio::sslRead - SSL Handshake is not yet completed.");
    return 0;
  }
  
  int ret = 0;
  char readBuf[DTLS_BIO_BUFFER_LEN];
  
  ret = readDirect(readBuf, DTLS_BIO_BUFFER_LEN);
  
  if (ret > 0)
  {
    //
    // We have read some packets
    //
    if (DTLSSession::peek(readBuf) != DTLSSession::DTLS)
    {
      //
      // Not a DTLS packet.  return the raw packet
      //
      if (ret > bufLen)
      {
        //
        // We have read a packet that is bigger than the buffer provided
        // we do not have any better option but to truncate
        //
        OSS_LOG_WARNING("DTLSBio::sslRead - buffer size is smaller than the packet in the buffer.  Packet will be truncated!");
        ret = bufLen;
      }
      memcpy(buf, readBuf, ret);
      return ret;
    }
    
    ret = BIO_write(_pInBIO, readBuf, ret);
    if (ret > 0)
    {
      //
      // Packets are written to the IN BIO.  Read it back unencrypted.
      //
      ret = SSL_read(_pSSL, buf, bufLen); 
    }
  }
  return ret;
}
Exemple #17
0
  bool Parser::isHandshakeFinished() {

    if (!ssl) { 
      return false;
    }

    return SSL_is_init_finished(ssl);
  }
Exemple #18
0
static void im_ssl_write(nx_module_t *module, nx_event_t *event)
{
    int rv;
    SSL *ssl;
    apr_socket_t *sock;
    nx_module_input_t *input = NULL;
    int errcode;
    nx_exception_t e;

    sock = (apr_socket_t *) event->data;

    ASSERT(module != NULL);
    
    CHECKERR_MSG(apr_socket_data_get((void **) &input, "input", sock),
		 "couldn't get input data from socket");
    ASSERT(input != NULL);
    ssl = (SSL *) nx_module_input_data_get(input, "ssl");
    ASSERT(ssl != NULL);

    if ( !SSL_is_init_finished(ssl) )
    {
	log_debug("doing handshake");
	try
	{
	    if ( (rv = SSL_do_handshake(ssl)) <= 0 )
	    {
		switch ( (errcode = nx_ssl_check_io_error(ssl, rv)) )
		{
		    case SSL_ERROR_ZERO_RETURN: // disconnected
			throw_msg("im_ssl got disconnected during handshake");
			break;
		    case SSL_ERROR_WANT_WRITE:
			log_debug("im_ssl WANT_WRITE");
			nx_module_pollset_add_socket(module, input->desc.s, APR_POLLOUT | APR_POLLHUP);
			break;
		    case SSL_ERROR_WANT_READ:
			log_debug("im_ssl WANT_READ");
			nx_module_pollset_add_socket(module, input->desc.s, APR_POLLIN | APR_POLLHUP);
			break;
		    default:
			throw_msg("im_ssl couldn't write handshake data (error code: %d)", errcode);
		}
	    }
	}
	catch(e)
	{
	    log_exception(e);
	    im_ssl_disconnect(input);
	    return;
	}
    }
    else
    {
	log_warn("SSL socket should not be sending anything after the handshake");
	nx_module_pollset_add_socket(module, input->desc.s, APR_POLLIN | APR_POLLHUP);
    }
}
Exemple #19
0
int SslBox_t::PutPlaintext (const char *buf, int bufsize)
{
	// The caller will interpret the return value as the number of bytes written.
	// WARNING WARNING WARNING, are there any situations in which a 0 or -1 return
	// from SSL_write means we should immediately retry? The socket-machine loop
	// will probably wait for a time-out cycle (perhaps a second) before re-trying.
	// THIS WOULD CAUSE A PERCEPTIBLE DELAY!

	/* We internally queue any outbound plaintext that can't be dispatched
	 * because we're in the middle of a handshake or something.
	 * When we get called, try to send any queued data first, and then
	 * send the caller's data (or queue it). We may get called with no outbound
	 * data, which means we try to send the outbound queue and that's all.
	 *
	 * Return >0 if we wrote any data, 0 if we didn't, and <0 for a fatal error.
	 * Note that if we return 0, the connection is still considered live
	 * and we are signalling that we have accepted the outbound data (if any).
	 */

	OutboundQ.Push (buf, bufsize);

	if (!SSL_is_init_finished (pSSL))
		return 0;

	bool fatal = false;
	bool did_work = false;
	int pending =  BIO_pending(pbioWrite);

	while (OutboundQ.HasPages() && pending < SSLBOX_WRITE_BUFFER_SIZE) {
		const char *page;
		int length;
		OutboundQ.Front (&page, &length);
		assert (page && (length > 0));
		int n = SSL_write (pSSL, page, length);
		pending =  BIO_pending(pbioWrite);

		if (n > 0) {
			did_work = true;
			OutboundQ.PopFront();
		}
		else {
			int er = SSL_get_error (pSSL, n);
			if ((er != SSL_ERROR_WANT_READ) && (er != SSL_ERROR_WANT_WRITE))
				fatal = true;
			break;
		}
	}


	if (did_work)
		return 1;
	else if (fatal)
		return -1;
	else
		return 0;
}
Exemple #20
0
void check_outgoing_application_data(Client* c) {    
  if(SSL_is_init_finished(c->ssl)) {
    if(c->buffer_out.size() > 0) {
      std::copy(c->buffer_out.begin(), c->buffer_out.end(), std::ostream_iterator<char>(std::cout,""));
      int r = SSL_write(c->ssl, &c->buffer_out[0], c->buffer_out.size());
      c->buffer_out.clear();
      handle_error(c, r);
      flush_read_bio(c);
    }
  }
}
ngx_int_t ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size)
{
    int         n, sslerr;
    ngx_err_t   err;
    char       *handshake;

    n = SSL_read(c->ssl->ssl, buf, size);

    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_read: %d", n); 

    if (n > 0) {
        return n;
    }

    sslerr = SSL_get_error(c->ssl->ssl, n);

    err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;

    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);

    if (sslerr == SSL_ERROR_WANT_READ) {
        return NGX_AGAIN;
    }

    if (sslerr == SSL_ERROR_WANT_WRITE) {
        ngx_log_error(NGX_LOG_ALERT, c->log, err,
                      "SSL wants to write%s", handshake);
        return NGX_ERROR;
#if 0
        return NGX_AGAIN;
#endif
    }

    if (!SSL_is_init_finished(c->ssl->ssl)) {
        handshake = "in SSL handshake";

    } else {
        handshake = "";
    }

    c->ssl->no_rcv_shut = 1;

    if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
        ngx_log_error(NGX_LOG_INFO, c->log, err,
                      "client closed connection%s", handshake);

        return NGX_ERROR;
    }

    ngx_ssl_error(NGX_LOG_ALERT, c->log, err,
                  "SSL_read() failed%s", handshake);

    return NGX_ERROR;
}
Exemple #22
0
int SslBox_t::GetPlaintext (char *buf, int bufsize)
{
	if (!SSL_is_init_finished (pSSL)) {
		int e = bIsServer ? SSL_accept (pSSL) : SSL_connect (pSSL);
		if (e < 0) {
			int er = SSL_get_error (pSSL, e);
			if (er != SSL_ERROR_WANT_READ) {
				// Return -1 for a nonfatal error, -2 for an error that should force the connection down.
				return (er == SSL_ERROR_SSL) ? (-2) : (-1);
			}
			else
				return 0;
		}
		bHandshakeCompleted = true;
		// If handshake finished, FALL THROUGH and return the available plaintext.
	}

	if (!SSL_is_init_finished (pSSL)) {
		// We can get here if a browser abandons a handshake.
		// The user can see a warning dialog and abort the connection.
		cerr << "<SSL_incomp>";
		return 0;
	}

	//cerr << "CIPH: " << SSL_get_cipher (pSSL) << endl;

	int n = SSL_read (pSSL, buf, bufsize);
	if (n >= 0) {
		return n;
	}
	else {
		if (SSL_get_error (pSSL, n) == SSL_ERROR_WANT_READ) {
			return 0;
		}
		else {
			return -1;
		}
	}

	return 0;
}
Exemple #23
0
void  * tcp_forwardlistenthread(void * pParam)
{
	SSL_CTX *ctx = (SSL_CTX *)pParam;
	SSL *ssl = NULL;
	ssl = SSL_new(ctx);
	if (ssl == NULL) exit(-1);
	SOCKET socket1 = socket(AF_INET, SOCK_STREAM, 0);
	if (socket1 < 0) exit(-1);
	struct sockaddr_in service;
	service.sin_family = AF_INET;
	service.sin_addr.S_un.S_addr = inet_addr(MYIP);
	service.sin_port = htons(MYPORT);
	if (connect (socket1, (struct sockaddr*)&service, sizeof(service)) == -1) exit(-1);
	SSL_set_fd(ssl, socket1);
	int sslResult = SSL_connect(ssl);
	if (!SSL_is_init_finished(ssl)) exit(-1);

	char buff[1024] = {0};
	scanf("%s", buff);
	SSL_write(ssl, buff, 1024);

	fd_set fds_bak,fds;
	FD_ZERO(&fds_bak);
	int m = 0;
	MFDSET(m, socket1, &fds_bak);
	while(true)
	{
		fds = fds_bak;
		int ret = select(m+1, &fds, NULL, NULL, NULL);
		if (ret == 0) 
		{
			puts("time out");
			goto _exit;
		}
		if (ret < 0)
		{
			puts("getlasterr");
			goto _exit;
		}
		if (socket1 >0 && FD_ISSET(socket1, &fds))
		{
			SSL_read(ssl, buff, 1024);
			puts(buff);
			scanf("%s", buff);
			SSL_write(ssl, buff, strlen(buff)+1);
		}
	}
	getchar();
_exit:
	closesocket(socket1);
	SSL_shutdown(ssl);
	SSL_free(ssl);
}
// ************************************************************
// Do SSL handshake if necessary
// return code:
// 1   SSL handshake is finished already, success
// 0   SSL handshake in progress
// -1  failure
// ************************************************************
int
ACE_SSL_Asynch_Stream::do_SSL_handshake (void)
{
  if (SSL_is_init_finished (this->ssl_))
    return 1;

  if (this->flags_ & SF_REQ_SHUTDOWN)
    return -1;

  int retval = -1;

  switch (this->type_)
    {
    case ST_CLIENT:
      retval = ::SSL_connect (this->ssl_);
      break;

    case ST_SERVER:
      retval = ::SSL_accept (this->ssl_);
      break;

    default:
      ACE_ERROR_RETURN
        ((LM_ERROR,
          ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream %p\n"),
          ACE_TEXT ("- invalid stream type")),
         -1);
    }

  int status = ::SSL_get_error (this->ssl_, retval);

  switch (status)
    {
    case SSL_ERROR_NONE:
      break;

    case SSL_ERROR_WANT_READ:
    case SSL_ERROR_WANT_WRITE:
    case SSL_ERROR_WANT_CONNECT:
    //case SSL_ERROR_WANT_ACCEPT:
    case SSL_ERROR_WANT_X509_LOOKUP:
      return 0;

    case SSL_ERROR_ZERO_RETURN:
    case SSL_ERROR_SYSCALL:
    default:
      this->print_error (status,
                         ACE_TEXT ("Handshake error"));
      return -1;
    }

  return 1;
}
Exemple #25
0
/* patched SSL_write call */
int __cdecl my_SSL_write(void *ssl, const void *buf, int num)
{
	if(!ssl || num < 1 || !buf)
		return s_lpfn_SSL_write(ssl, buf, num);

	SOCKET s = (SOCKET)_SSL_get_fd(ssl);

	if(!s)
		return s_lpfn_SSL_write(ssl, buf, num);

	::EnterCriticalSection(&s_socketsLock);
	auto it = s_sockets.find(s);

	if(it != s_sockets.end()
		&& it->second->IsSSL()
		&& it->second->GetState() != MSCK_NOT_IRC)
	{
		auto l_sock = it->second;

		::LeaveCriticalSection(&s_socketsLock);

		l_sock->Lock();

		if(l_sock->GetState() == MSCK_TLS_HANDSHAKE && SSL_is_init_finished(ssl))
		{
			l_sock->OnSSLHandshakeComplete();
		}

		bool l_modified = l_sock->OnSending(true, (const char*)buf, num);

		if(l_modified)
		{
			const std::string l_buf = l_sock->GetSendBuffer();

			l_sock->Unlock();

			int l_ret = s_lpfn_SSL_write(ssl, l_buf.c_str(), l_buf.size());

			return (l_ret > 0 ? num : l_ret);
		}
		else
		{
			l_sock->Unlock();
			// fall through to normal SSL_write call
		}
	}
	else
	{
		::LeaveCriticalSection(&s_socketsLock);
	}

	return s_lpfn_SSL_write(ssl, buf, num);
}
Exemple #26
0
BOOL CSSLSession::ReadRecvChannel()
{
	BOOL isOK = TRUE;
	int bytes = SSL_read(m_ssl, m_bufRecv.buf, m_pitRecv->Capacity());

	if(bytes > 0)
		m_bufRecv.len = bytes;
	else if(!IsFatalError(bytes))
		m_bufRecv.len = 0;
	else
		isOK = FALSE;

	if(isOK && m_enStatus == SSL_HSS_PROC && SSL_is_init_finished(m_ssl))
		m_enStatus = SSL_HSS_SUCC;

	return isOK;
}
sdmmd_return_t SDMMD_ServiceSend(SocketConnection handle, CFDataRef data)
{
	CFIndex msgLen = (data ? CFDataGetLength(data) : 0);
	if (msgLen) {
		msgLen = htonl((uint32_t)msgLen);
		uint64_t result;
		// Send 32-bit data length header
		if (handle.isSSL) {
			if (handle.socket.ssl != NULL && SSL_is_init_finished(handle.socket.ssl)) {
				result = SSL_write(handle.socket.ssl, &msgLen, sizeof(uint32_t));
			}
			else {
				printf("%s: Invalid SSL Socket!\n", __PRETTY_FUNCTION__);
				return kAMDNotConnectedError;
			}
		}
		else {
			if (handle.socket.conn != -1) {
				result = send(handle.socket.conn, &msgLen, sizeof(uint32_t), 0);
			}
			else {
				printf("%s: Invalid Socket!\n", __PRETTY_FUNCTION__);
				return kAMDNotConnectedError;
			}
		}
		// Send data body
		if (result == sizeof(uint32_t)) {
			msgLen = ntohl(msgLen);
			if (handle.isSSL) {
				result = SSL_write(handle.socket.ssl, CFDataGetBytePtr(data), (uint32_t)msgLen);
			}
			else {
				result = send(handle.socket.conn, CFDataGetBytePtr(data), msgLen, 0);
			}
			return (result == msgLen ? kAMDSuccess : kAMDInvalidResponseError);
		}
		else {
			printf("%s: Incomplete length.\n", __PRETTY_FUNCTION__);
			return kAMDNotConnectedError;
		}
	}
	else {
		return kAMDInvalidArgumentError;
	}
}
Exemple #28
0
int SSLStateMachine_read_extract(SSLStateMachine *pMachine,
				 unsigned char *aucBuf,int nBuf)
    {
    int n;

    if(!SSL_is_init_finished(pMachine->pSSL))
	{
	fprintf(stderr,"Doing SSL_accept\n");
	n=SSL_accept(pMachine->pSSL);
	if(n == 0)
	    fprintf(stderr,"SSL_accept returned zero\n");
	if(n < 0)
	    {
	    int err;

	    if((err=SSL_get_error(pMachine->pSSL,n)) == SSL_ERROR_WANT_READ)
		{
		fprintf(stderr,"SSL_accept wants more data\n");
		return 0;
		}

	    SSLStateMachine_print_error(pMachine,"SSL_accept error");
	    exit(7);
	    }
	return 0;
	}

    n=SSL_read(pMachine->pSSL,aucBuf,nBuf);
    if(n < 0)
	{
	int err=SSL_get_error(pMachine->pSSL,n);

	if(err == SSL_ERROR_WANT_READ)
	    {
	    fprintf(stderr,"SSL_read wants more data\n");
	    return 0;
	    }

	SSLStateMachine_print_error(pMachine,"SSL_read error");
	exit(8);
	}

    fprintf(stderr,"%d bytes of decrypted data read from state machine\n",n);
    return n;
    }
/**
  Checks if the TLS handshake was done.

  This function will check if the specified TLS handshake was done.

  @param[in]  Tls    Pointer to the TLS object for handshake state checking.

  @retval  TRUE     The TLS handshake was done.
  @retval  FALSE    The TLS handshake was not done.

**/
BOOLEAN
EFIAPI
TlsInHandshake (
  IN     VOID                     *Tls
  )
{
  TLS_CONNECTION  *TlsConn;

  TlsConn = (TLS_CONNECTION *) Tls;
  if (TlsConn == NULL || TlsConn->Ssl == NULL) {
    return FALSE;
  }

  //
  // Return the status which indicates if the TLS handshake was done.
  //
  return !SSL_is_init_finished (TlsConn->Ssl);
}
Exemple #30
0
static void
rb_ssl_tryaccept(rb_fde_t *F, void *data)
{
	int ssl_err;
	lrb_assert(F->accept != NULL);
	int flags;
	struct acceptdata *ad;

	if(!SSL_is_init_finished((SSL *) F->ssl))
	{
		if((ssl_err = SSL_accept((SSL *) F->ssl)) <= 0)
		{
			switch (ssl_err = SSL_get_error((SSL *) F->ssl, ssl_err))
			{
			case SSL_ERROR_WANT_READ:
			case SSL_ERROR_WANT_WRITE:
				if(ssl_err == SSL_ERROR_WANT_WRITE)
					flags = RB_SELECT_WRITE;
				else
					flags = RB_SELECT_READ;
				F->ssl_errno = get_last_err();
				rb_setselect(F, flags, rb_ssl_tryaccept, NULL);
				break;
			case SSL_ERROR_SYSCALL:
				F->accept->callback(F, RB_ERROR, NULL, 0, F->accept->data);
				break;
			default:
				F->ssl_errno = get_last_err();
				F->accept->callback(F, RB_ERROR_SSL, NULL, 0, F->accept->data);
				break;
			}
			return;
		}
	}
	rb_settimeout(F, 0, NULL, NULL);
	rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE, NULL, NULL);

	ad = F->accept;
	F->accept = NULL;
	ad->callback(F, RB_OK, (struct sockaddr *)&ad->S, ad->addrlen, ad->data);
	rb_free(ad);

}