示例#1
0
void openssl_bioBS_io()
{
	BIO *b;
	char *outs;
	int len1 = 0, len2 = 0;

	b = BIO_new(BIO_s_mem());
	BIO_write(b, "openssl ", 8);
	BIO_printf(b, "%s", "zcp");
	len1 = BIO_ctrl_pending(b);
	outs = (char *)OPENSSL_malloc(len1 + 1);
	BIO_read(b, outs, len1);
	printf("\nBIO term output: %s\n", outs);
	OPENSSL_free(outs);
	BIO_free(b);

	b = BIO_new_file("/tmp/test.txt", "w");
	BIO_write(b, "openssl ", 8);
	BIO_printf(b, "%s", "zcp");
	BIO_free(b);
	b = BIO_new_file("/tmp/test.txt", "r");
	len1 = BIO_ctrl_pending(b);
	outs = (char *)OPENSSL_malloc(len1 + 1);
	while ((len1 = BIO_read(b, outs + len2, 1)) > 0)
		len2 += len1;
	printf("\nBIO file output: %s\n", outs);
	free(outs);
	BIO_free(b);
}
示例#2
0
文件: sctp.c 项目: homelee/librtcdc
gpointer
sctp_thread(gpointer user_data)
{
  struct rtcdc_peer_connection *peer = (struct rtcdc_peer_connection *)user_data;
  struct rtcdc_transport *transport = peer->transport;
  struct ice_transport *ice = transport->ice;
  struct dtls_transport *dtls = transport->dtls;
  struct sctp_transport *sctp = transport->sctp;

  while (!peer->exit_thread && !ice->negotiation_done)
    g_usleep(2500);
  if (peer->exit_thread)
    return NULL;

  while (!peer->exit_thread && !dtls->handshake_done)
    g_usleep(2500);
  if (peer->exit_thread)
    return NULL;

  char buf[BUFFER_SIZE];
  while (!peer->exit_thread) {
    if (BIO_ctrl_pending(sctp->incoming_bio) <= 0 && BIO_ctrl_pending(sctp->outgoing_bio) <= 0)
      g_usleep(2500);

    if (BIO_ctrl_pending(sctp->incoming_bio) > 0) {
      g_mutex_lock(&sctp->sctp_mutex);
      int nbytes = BIO_read(sctp->incoming_bio, buf, sizeof buf);
      g_mutex_unlock(&sctp->sctp_mutex);
#ifdef DEBUG_SCTP
      send(sctp->incoming_stub, buf, nbytes, 0);
#endif
      if (nbytes > 0) {
        usrsctp_conninput(sctp, buf, nbytes, 0);
      }
    }

    if (BIO_ctrl_pending(sctp->outgoing_bio) > 0) {
      g_mutex_lock(&sctp->sctp_mutex);
      int nbytes = BIO_read(sctp->outgoing_bio, buf, sizeof buf);
      g_mutex_unlock(&sctp->sctp_mutex);
#ifdef DEBUG_SCTP
      send(sctp->outgoing_stub, buf, nbytes, 0);
#endif
      if (nbytes > 0) {
        g_mutex_lock(&dtls->dtls_mutex);
        SSL_write(dtls->ssl, buf, nbytes);
        g_mutex_unlock(&dtls->dtls_mutex);
      }
    }
  }

  return NULL;
}
示例#3
0
文件: sslcompat.c 项目: geertj/gruvi
static PyObject *
memory_bio_read(PySSLMemoryBIO *self, PyObject *args)
{
    int len = -1, avail, nbytes;
    PyObject *Pret = NULL;

    if (!PyArg_ParseTuple(args, "|i:read", &len))
        RETURN_ERROR(NULL);

    avail = BIO_ctrl_pending(self->bio);
    if ((len < 0) || (len > avail))
        len = avail;

    Pret = PyBytes_FromStringAndSize(NULL, len);
    if (Pret == NULL)
        RETURN_ERROR(NULL);

    if (len > 0) {
        nbytes = BIO_read(self->bio, PyBytes_AS_STRING(Pret), len);
        /* There should never be any short reads but check anyway. */
        if ((nbytes < len) && (_PyBytes_Resize(&Pret, len) < 0)) {
            Py_DECREF(Pret); Pret = NULL;
            RETURN_ERROR(NULL);
        }
    }

error:
    return Pret;
}
示例#4
0
  void OpenSSL::pushFunc()
  {
    int wantwrite;
    size_t wantread;
    int frombio;
    int tobio;

    while( ( wantwrite = BIO_ctrl_pending( m_nbio ) ) > 0 )
    {
      if( wantwrite > m_bufsize )
        wantwrite = m_bufsize;

      if( !wantwrite )
        break;

      frombio = BIO_read( m_nbio, m_buf, wantwrite );

      if( m_handler )
        m_handler->handleEncryptedData( this, std::string( m_buf, frombio ) );
    }

    while( ( wantread = BIO_ctrl_get_read_request( m_nbio ) ) > 0 )
    {
      if( wantread > m_recvBuffer.length() )
        wantread = m_recvBuffer.length();

      if( !wantread )
        break;

      tobio = BIO_write( m_nbio, m_recvBuffer.c_str(), wantread );
      m_recvBuffer.erase( 0, tobio );
    }
  }
示例#5
0
int krypt_encrypt_buf(krypt_t *kconn, uint8_t *buf, size_t buf_data_size)
{
	int nbyte = 0;
	int pbyte = 0;
	int error = 0;
	int status = 0;
	nbyte = SSL_write(kconn->ssl, buf, buf_data_size);

	if (nbyte <= 0) {
		error = SSL_get_error(kconn->ssl, nbyte);
		switch (error) {

		case SSL_ERROR_WANT_READ:
			break;
		case SSL_ERROR_WANT_WRITE:
			status = -1;
			break;
		default:
			ssl_error_stack();
			return -1;
		}
	}

	pbyte = BIO_ctrl_pending(kconn->network_bio);

	kconn->buf_encrypt_data_size = 0;
	nbyte = BIO_read(kconn->network_bio, kconn->buf_encrypt, pbyte);

	if (nbyte > 0) {
		kconn->buf_encrypt_data_size = nbyte;
	}

	return status;
}
示例#6
0
void sslRead(SSLSocket *socket,
             void *buffer,
             size_t size,
             AsyncFlags flags,
             uint64_t usTimeout,
             sslCb callback,
             void *arg)
{
  size_t readSize = BIO_ctrl_pending(socket->bioIn);

  SSLOp *newOp = allocSSLOp(socket, callback, arg, buffer, size, afNone);  
  newOp->type = sslOpRead;
  newOp->state = sslStReadNewFrame;

  if (readSize >= size) {
    BIO_read(socket->bioOut, buffer, size);
    finishSSLOp(newOp, aosSuccess);
  } else if (!socket->current) {
    socket->current = newOp;
    asyncRead(socket->object, socket->sslReadBuffer, socket->sslReadBufferSize, afNone, usTimeout, readProc, newOp);
  } else {
    newOp->usTimeout = usTimeout;
    socket->current->next = newOp;
  }
}
示例#7
0
文件: text_ssl2.c 项目: roxlu/krx_rtc
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;
}
示例#8
0
文件: sctp.c 项目: TopPano/librtcdc
void sctp_to_dtls(struct rtcdc_peer_connection* peer)
{
    //struct rtcdc_peer_connection *peer = (struct rtcdc_peer_connection *)req->data;
    struct rtcdc_transport *transport = peer->transport; 
    struct ice_transport *ice = transport->ice;
    struct dtls_transport *dtls = transport->dtls;
    struct sctp_transport *sctp = transport->sctp;
    
    while (!peer->exit_thread && !ice->negotiation_done)
        g_usleep(500);
    if (peer->exit_thread)
        exit(1);

    while (!peer->exit_thread && !dtls->handshake_done)
        g_usleep(500);
    if (peer->exit_thread)
        exit(1);

    char buf[BUFFER_SIZE]; 
    if(BIO_ctrl_pending(sctp->outgoing_bio) > 0)
    {
        g_mutex_lock(&sctp->sctp_mutex);
        int nbytes = BIO_read(sctp->outgoing_bio, buf, sizeof buf);
        g_mutex_unlock(&sctp->sctp_mutex);
#ifdef DEBUG_SCTP
        send(sctp->outgoing_stub, buf, nbytes, 0);
#endif
        if (nbytes > 0) {
            g_mutex_lock(&dtls->dtls_mutex);
            SSL_write(dtls->ssl, buf, nbytes);
            g_mutex_unlock(&dtls->dtls_mutex);
        }
    }
}
示例#9
0
/* DTLS BIOs to/from socket bridge */
void janus_dtls_fd_bridge(janus_dtls_srtp *dtls) {
	if(dtls == NULL) {
		JANUS_LOG(LOG_ERR, "No DTLS-SRTP stack, no DTLS bridge...\n");
		return;
	}
	janus_ice_component *component = (janus_ice_component *)dtls->component;
	if(component == NULL) {
		JANUS_LOG(LOG_ERR, "No component, no DTLS bridge...\n");
		return;
	}
	janus_ice_stream *stream = component->stream;
	if(!stream) {
		JANUS_LOG(LOG_ERR, "No stream, no DTLS bridge...\n");
		return;
	}
	janus_ice_handle *handle = stream->handle;
	if(!handle || !handle->agent || !dtls->write_bio) {
		JANUS_LOG(LOG_ERR, "No handle/agent/bio, no DTLS bridge...\n");
		return;
	}
	int pending = BIO_ctrl_pending(dtls->filter_bio);
	while(pending > 0) {
		JANUS_LOG(LOG_HUGE, "[%"SCNu64"] >> Going to send DTLS data: %d bytes\n", handle->handle_id, pending);
		char outgoing[pending];
		int out = BIO_read(dtls->write_bio, outgoing, sizeof(outgoing));
		JANUS_LOG(LOG_HUGE, "[%"SCNu64"] >> >> Read %d bytes from the write_BIO...\n", handle->handle_id, out);
		if(out > 1500) {
			/* FIXME Just a warning for now, this will need to be solved with proper fragmentation */
			JANUS_LOG(LOG_WARN, "[%"SCNu64"] The DTLS stack is trying to send a packet of %d bytes, this may be larger than the MTU and get dropped!\n", handle->handle_id, out);
		}
		int bytes = nice_agent_send(handle->agent, component->stream_id, component->component_id, out, outgoing);
		if(bytes < out) {
			JANUS_LOG(LOG_ERR, "[%"SCNu64"] Error sending DTLS message on component %d of stream %d (%d)\n", handle->handle_id, component->component_id, stream->stream_id, bytes);
		} else {
			JANUS_LOG(LOG_HUGE, "[%"SCNu64"] >> >> ... and sent %d of those bytes on the socket\n", handle->handle_id, bytes);
		}
		/* Update stats (TODO Do the same for the last second window as well)
		 * FIXME: the Data stats includes the bytes used for the handshake */
		if(bytes > 0) {
			component->out_stats.data_packets++;
			component->out_stats.data_bytes += bytes;
		}
		/* Check if there's anything left to send (e.g., fragmented packets) */
		pending = BIO_ctrl_pending(dtls->filter_bio);
	}
}
示例#10
0
/* sqCopyBioSSL: Copies data from a BIO into an out buffer */
sqInt sqCopyBioSSL(sqSSL *ssl, BIO *bio, char *dstBuf, sqInt dstLen) {
  int nbytes = BIO_ctrl_pending(bio);

  if(ssl->loglevel) printf("sqCopyBioSSL: %d bytes pending; buffer size %d\n", 
	 nbytes, dstLen);
  if(nbytes > dstLen) return -1;
  return BIO_read(bio, dstBuf, dstLen);
}
示例#11
0
static size_t
get_extension_by_object (X509 *x509, ASN1_OBJECT *obj, char **output)
{
	int pos = X509_get_ext_by_OBJ (x509, obj, -1);
	if (pos < 0) {
		return 0;
	}
	X509_EXTENSION *ext = X509_get_ext (x509, pos);

	int tag;
	long len;
	int tc;
	const unsigned char *p = ext->value->data;

	ASN1_get_object (&p, &len, &tag, &tc, ext->value->length);

	size_t size;
	switch (tag) {
		case V_ASN1_UTF8STRING:
			{
				ASN1_UTF8STRING *str =
					ASN1_item_unpack (ext->value,
							  ASN1_ITEM_rptr
							  (ASN1_UTF8STRING));
				*output = strndup ((const char *)
						   ASN1_STRING_data (str),
						   str->length);
				size = str->length;
				ASN1_UTF8STRING_free (str);
				return size;
			}
		case V_ASN1_OCTET_STRING:
			{
				ASN1_OCTET_STRING *octstr =
					ASN1_item_unpack (ext->value,
							  ASN1_ITEM_rptr
							  (ASN1_OCTET_STRING));
				*output = malloc (octstr->length);
				memcpy (*output, octstr->data, octstr->length);
				size = octstr->length;
				ASN1_OCTET_STRING_free (octstr);
				return size;
			}
		default:
			{
				BIO *bio = BIO_new (BIO_s_mem ());
				X509V3_EXT_print (bio, ext, 0, 0);

				size_t size = BIO_ctrl_pending (bio);
				char *buf = malloc (sizeof (char) * size);
				BIO_read (bio, buf, size);
				*output = buf;
				BIO_free (bio);
				return size;
			}
	}
}
/**
  Build the CloseNotify packet.

  @param[in]       Tls            Pointer to the TLS object for state checking.
  @param[in, out]  Buffer         Pointer to the buffer to hold the built packet.
  @param[in, out]  BufferSize     Pointer to the buffer size in bytes. On input, it is
                                  the buffer size provided by the caller. On output, it
                                  is the buffer size in fact needed to contain the
                                  packet.

  @retval EFI_SUCCESS             The required TLS packet is built successfully.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  Tls is NULL.
                                  BufferSize is NULL.
                                  Buffer is NULL if *BufferSize is not zero.
  @retval EFI_BUFFER_TOO_SMALL    BufferSize is too small to hold the response packet.

**/
EFI_STATUS
EFIAPI
TlsCloseNotify (
  IN     VOID                     *Tls,
  IN OUT UINT8                    *Buffer,
  IN OUT UINTN                    *BufferSize
  )
{
  TLS_CONNECTION  *TlsConn;
  UINTN           PendingBufferSize;

  TlsConn           = (TLS_CONNECTION *) Tls;
  PendingBufferSize = 0;

  if (TlsConn == NULL || \
    TlsConn->Ssl == NULL || TlsConn->InBio == NULL || TlsConn->OutBio == NULL || \
    BufferSize == NULL || \
    (Buffer == NULL && *BufferSize != 0)) {
    return EFI_INVALID_PARAMETER;
  }

  PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
  if (PendingBufferSize == 0) {
    //
    // ssl3_send_alert() and ssl3_dispatch_alert() function will be called.
    //
    SSL_shutdown (TlsConn->Ssl);
    PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
  }

  if (PendingBufferSize > *BufferSize) {
    *BufferSize = PendingBufferSize;
    return EFI_BUFFER_TOO_SMALL;
  }

  if (PendingBufferSize > 0) {
    *BufferSize = BIO_read (TlsConn->OutBio, Buffer, (UINT32) PendingBufferSize);
  } else {
    *BufferSize = 0;
  }

  return EFI_SUCCESS;
}
示例#13
0
size_t copyFromOut(SSLSocket *S, SSLOp *Op)
{
  size_t nBytes = BIO_ctrl_pending(S->bioOut);
  if (nBytes > Op->sslBufferSize) {
    Op->sslBuffer = realloc(Op->sslBuffer, nBytes);
    Op->sslBufferSize = nBytes;
  }
  
  BIO_read(S->bioOut, Op->sslBuffer, nBytes);  
  return nBytes;
}
示例#14
0
void SSLAdapter::flushReadBIO()
{
    int npending = BIO_ctrl_pending(_readBIO);
    if (npending > 0) {
        int nread;
        char buffer[MAX_TCP_PACKET_SIZE]; // TODO: allocate npending bytes
        while ((nread = SSL_read(_ssl, buffer, MAX_TCP_PACKET_SIZE)) > 0) {
            _socket->onRecv(mutableBuffer(buffer, nread));
        }
    }
}
示例#15
0
void SSLAdapter::flushWriteBIO()
{
    int npending = BIO_ctrl_pending(_writeBIO);
    if (npending > 0) {
        char buffer[MAX_TCP_PACKET_SIZE]; // TODO: allocate npending bytes
        int nread = BIO_read(_writeBIO, buffer, MAX_TCP_PACKET_SIZE);
        if (nread > 0) {
            _socket->write(buffer, nread);
        }
    }
}
示例#16
0
// return # output bytes sitting in this layer
static size_t buffered_output(pn_transport_t *transport)
{
  size_t count = 0;
  pni_ssl_t *ssl = transport->ssl;
  if (ssl) {
    count += ssl->out_count;
    if (ssl->bio_net_io) { // pick up any bytes waiting for network io
      count += BIO_ctrl_pending(ssl->bio_net_io);
    }
  }
  return count;
}
示例#17
0
// return # input bytes sitting in this layer
static size_t buffered_input( pn_io_layer_t *io_layer )
{
  size_t count = 0;
  pn_ssl_t *ssl = (pn_ssl_t *)io_layer->context;
  if (ssl) {
    count += ssl->in_count;
    if (ssl->bio_ssl) { // pick up any bytes waiting to be read
      count += BIO_ctrl_pending(ssl->bio_ssl);
    }
  }
  return count;
}
示例#18
0
// return # output bytes sitting in this layer
static size_t buffered_output(pn_io_layer_t *io_layer)
{
  size_t count = 0;
  pn_ssl_t *ssl = (pn_ssl_t *)io_layer->context;
  if (ssl) {
    count += ssl->out_count;
    if (ssl->bio_net_io) { // pick up any bytes waiting for network io
      count += BIO_ctrl_pending(ssl->bio_net_io);
    }
  }
  return count;
}
示例#19
0
	bool SecureSocket::SendFromBio(int flags)
	{
		uint8_t buf[4096];
		size_t pending = BIO_ctrl_pending(m_out);
		if (!pending) 
			return true;
		size_t bytes = BIO_read(m_out, buf, sizeof(buf));
		if (bytes > 0) 
			return SendRaw(buf, bytes, flags);
		else if (bytes == -1 || bytes == 0)
			return true;
		return false;
	}
示例#20
0
static bool openssl_iostream_bio_output(struct ssl_iostream *ssl_io)
{
	size_t bytes, max_bytes;
	ssize_t sent;
	unsigned char buffer[IO_BLOCK_SIZE];
	bool bytes_sent = FALSE;
	int ret;

	o_stream_cork(ssl_io->plain_output);
	while ((bytes = BIO_ctrl_pending(ssl_io->bio_ext)) > 0) {
		/* bytes contains how many SSL encrypted bytes we should be
		   sending out */
		max_bytes = o_stream_get_buffer_avail_size(ssl_io->plain_output);
		if (bytes > max_bytes) {
			if (max_bytes == 0) {
				/* wait until output buffer clears */
				o_stream_set_flush_pending(ssl_io->plain_output,
							   TRUE);
				break;
			}
			bytes = max_bytes;
		}
		if (bytes > sizeof(buffer))
			bytes = sizeof(buffer);

		/* BIO_read() is guaranteed to return all the bytes that
		   BIO_ctrl_pending() returned */
		ret = BIO_read(ssl_io->bio_ext, buffer, bytes);
		i_assert(ret == (int)bytes);

		/* we limited number of read bytes to plain_output's
		   available size. this send() is guaranteed to either
		   fully succeed or completely fail due to some error. */
		sent = o_stream_send(ssl_io->plain_output, buffer, bytes);
		if (sent < 0) {
			i_assert(ssl_io->plain_output->closed ||
				 ssl_io->plain_output->stream_errno != 0);
			i_free(ssl_io->plain_stream_errstr);
			ssl_io->plain_stream_errstr =
				i_strdup(o_stream_get_error(ssl_io->plain_output));
			ssl_io->plain_stream_errno =
				ssl_io->plain_output->stream_errno;
			ssl_io->closed = TRUE;
			break;
		}
		i_assert(sent == (ssize_t)bytes);
		bytes_sent = TRUE;
	}
	o_stream_uncork(ssl_io->plain_output);
	return bytes_sent;
}
示例#21
0
u8 * tls_connection_handshake(void *ssl_ctx, struct tls_connection *conn,
			      const u8 *in_data, size_t in_len,
			      size_t *out_len)
{
	int res;
	u8 *out_data;

	if (in_data &&
	    BIO_write(conn->ssl_in, in_data, in_len) < 0) {
		wpa_printf(MSG_INFO, "TLS: Handshake failed - BIO_write: %s",
			   ERR_error_string(ERR_get_error(), NULL));
		return NULL;
	}

	res = SSL_connect(conn->ssl);
	if (res != 1) {
		int err = SSL_get_error(conn->ssl, res);
		if (err == SSL_ERROR_WANT_READ)
			wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want "
				   "more data");
		else if (err == SSL_ERROR_WANT_WRITE)
			wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want to "
				   "write");
		else {
			wpa_printf(MSG_INFO, "SSL: SSL_connect: %s",
				   ERR_error_string(ERR_get_error(), NULL));
			return NULL;
		}
	}

	res = BIO_ctrl_pending(conn->ssl_out);
	wpa_printf(MSG_DEBUG, "SSL: %d bytes pending from ssl_out", res);
	out_data = malloc(res == 0 ? 1 : res);
	if (out_data == NULL) {
		wpa_printf(MSG_DEBUG, "SSL: Failed to allocate memory for "
			   "handshake output (%d bytes)", res);
		BIO_reset(conn->ssl_out);
		*out_len = 0;
		return NULL;
	}
	res = res == 0 ? 0 : BIO_read(conn->ssl_out, out_data, res);
	if (res < 0) {
		wpa_printf(MSG_INFO, "TLS: Handshake failed - BIO_read: %s",
			   ERR_error_string(ERR_get_error(), NULL));
		BIO_reset(conn->ssl_out);
		*out_len = 0;
		return NULL;
	}
	*out_len = res;
	return out_data;
}
示例#22
0
std::string BigNum::toString() const
{
    ScopedOpenSSL<BIO, BIO_vfree> bio(BIO_new(BIO_s_mem()));
    if(! BN_print(bio.get(), val_.get())) {
        OPENSSLEXCEPTION_MSG("BN_print() in BigNum::toString()");
    }
    // get number of bytes in bio
    size_t len = BIO_ctrl_pending(bio.get());
    std::vector<unsigned char> out(len);
    if(! BIO_read(bio.get(), &out[0], len)) {
        OPENSSLEXCEPTION_MSG("BIO_read() in BigNum::toString()");
    }
    return std::string(reinterpret_cast<const char*>(&out[0]), out.size());
}
示例#23
0
static PyObject *
time_to_string (ASN1_UTCTIME *time)
{
	BIO *bio = BIO_new (BIO_s_mem ());
	ASN1_UTCTIME_print (bio, time);

	size_t size = BIO_ctrl_pending (bio);
	char *buf = malloc (sizeof (char) * size);
	BIO_read (bio, buf, size);
	BIO_free (bio);

	PyObject *time_str = PyString_FromStringAndSize (buf, size);
	free (buf);
	return time_str;
}
示例#24
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;
}
示例#25
0
    /* 
    * The interface layer between network and BIO-pair. The BIO-pair buffers
    * the data to/from the TLS layer.
    */
    void SSLManager::_flushNetworkBIO(SSLConnection* conn){
        char buffer[BUFFER_SIZE];
        int wantWrite;

        /* 
        * Write the complete contents of the buffer. Leaving the buffer
        * unflushed could cause a deadlock. 
        */
        while ((wantWrite = BIO_ctrl_pending(conn->networkBIO)) > 0) {
            if (wantWrite > BUFFER_SIZE) {
                wantWrite = BUFFER_SIZE;
            }
            int fromBIO = BIO_read(conn->networkBIO, buffer, wantWrite);

            int writePos = 0;
            do {
                int numWrite = fromBIO - writePos;
                numWrite = send(conn->socket->rawFD(), buffer + writePos, numWrite, portSendFlags); 
                if (numWrite < 0) {
                    conn->socket->handleSendError(numWrite, "");
                }
                writePos += numWrite;
            } while (writePos < fromBIO);
        }

        int wantRead;
        while ((wantRead = BIO_ctrl_get_read_request(conn->networkBIO)) > 0)
        {
            if (wantRead > BUFFER_SIZE) {
                wantRead = BUFFER_SIZE;
            }

            int numRead = recv(conn->socket->rawFD(), buffer, wantRead, portRecvFlags);
            if (numRead <= 0) {
                conn->socket->handleRecvError(numRead, wantRead);
                continue;
            }

            int toBIO = BIO_write(conn->networkBIO, buffer, numRead);
            if (toBIO != numRead) {
                LOG(3) << "Failed to write network data to the SSL BIO layer";
                throw SocketException(SocketException::RECV_ERROR , conn->socket->remoteString());
            }
        } 
    }
示例#26
0
/* DTLS BIOs to/from socket bridge */
void janus_dtls_fd_bridge(janus_dtls_srtp *dtls) {
	if(dtls == NULL) {
		JANUS_LOG(LOG_ERR, "No DTLS-SRTP stack, no DTLS bridge...\n");
		return;
	}
	janus_ice_component *component = (janus_ice_component *)dtls->component;
	if(component == NULL) {
		JANUS_LOG(LOG_ERR, "No component, no DTLS bridge...\n");
		return;
	}
	janus_ice_stream *stream = component->stream;
	if(!stream) {
		JANUS_LOG(LOG_ERR, "No stream, no DTLS bridge...\n");
		return;
	}
	janus_ice_handle *handle = stream->handle;
	if(!handle || !handle->agent || !dtls->write_bio) {
		JANUS_LOG(LOG_ERR, "No handle/agent/bio, no DTLS bridge...\n");
		return;
	}
	int pending = BIO_ctrl_pending(dtls->write_bio);
	JANUS_LOG(LOG_HUGE, "[%"SCNu64"] DTLS check pending: %d\n", handle->handle_id, pending);
	if (pending > 0) {
		JANUS_LOG(LOG_HUGE, "[%"SCNu64"] >> Going to send DTLS data: %d bytes\n", handle->handle_id, pending);
		char outgoing[pending];
		size_t out = BIO_read(dtls->write_bio, outgoing, sizeof(outgoing));
		JANUS_LOG(LOG_HUGE, "[%"SCNu64"] >> >> Read %d bytes from the write_BIO...\n", handle->handle_id, pending);
		int bytes = nice_agent_send(handle->agent, component->stream_id, component->component_id, out, outgoing);
		JANUS_LOG(LOG_HUGE, "[%"SCNu64"] >> >> ... and sent %d of those bytes on the socket\n", handle->handle_id, bytes);

		/* Take note of the last sent message */
		if(dtls->dtls_last_msg != NULL) {
			g_free(dtls->dtls_last_msg);
			dtls->dtls_last_msg = NULL;
			dtls->dtls_last_len = 0;
		}
		dtls->dtls_last_msg = calloc(pending, sizeof(char));
		if(dtls->dtls_last_msg == NULL) {
			JANUS_LOG(LOG_FATAL, "Memory error!\n");
			return;
		}
		memcpy(dtls->dtls_last_msg, &outgoing, out);
		dtls->dtls_last_len = out;
	}
}
示例#27
0
static PyObject *
as_pem (certificate_x509 *self, PyObject *args)
{
	if (!PyArg_ParseTuple (args, "")) {
		return NULL;
	}

	BIO *bio = BIO_new (BIO_s_mem ());
	PEM_write_bio_X509 (bio, self->x509);

	size_t size = BIO_ctrl_pending (bio);
	char *buf = malloc (sizeof (char) * size);
	BIO_read (bio, buf, size);
	BIO_free (bio);

	PyObject *pem = PyString_FromStringAndSize (buf, size);
	free (buf);
	return pem;
}
示例#28
0
long CSSLApplication::TranSSLforWrite(CContextItem* mContext, CListItem* &mBuffer, long size, long op, long opSide)
{
	CSSLContext* sslContext = (CSSLContext*)mContext;
	long ret_err = 0x01;
	int byteTotal;																							//

	__TRY

	ret_err = 0x10;
	size_t pending = BIO_ctrl_pending(sslContext->bioOut);
	if (pending > 0)
	{
		ret_err = 0x20;
		byteTotal = ReadEncode(mContext, mBuffer, pending);

		if (byteTotal > 0)
		{
			ret_err = 0x30;
			if (mContext->PPeer)
			{
				if ( NoneProFunc(mContext->PProtocol, fPostSend)(mContext, mBuffer, byteTotal, op, opSide) ) break;			
			}
			else
			{
				mContext->PPeer = mContext;
				if ( NoneProFunc(mContext->PProtocol, fPostConnect)(mContext, mBuffer, byteTotal, OP_CONNECT) ) break;			
			}

		}
		else if (BIO_should_retry(sslContext->bioOut)) ret_err = 0xff;
	}
	else
	{
//	In handshake
		ret_err = 0x40;
// 			if (SSLMode == MODE_SSL_SERVER) needdataop = OP_CLIENT_READ;
// 			if (SSLMode == MODE_SSL_CLIENT) needdataop = OP_SERVER_READ;
		if ( NeedDataOp && NoneProFunc(mContext->PProtocol, fPostReceive)														//
			(mContext, mBuffer, mBuffer->BufferType->BufferSize, NeedDataOp, 0) ) break;
	}

	__CATCH_LOOP(MODULE_APPLICATION, "SSLApplicaton - TranSSLforWrite", 0xff)
}
示例#29
0
u8 * tls_connection_server_handshake(void *ssl_ctx,
				     struct tls_connection *conn,
				     const u8 *in_data, size_t in_len,
				     size_t *out_len)
{
	int res;
	u8 *out_data;
	char buf[10];

	if (in_data &&
	    BIO_write(conn->ssl_in, in_data, in_len) < 0) {
		wpa_printf(MSG_INFO, "TLS: Handshake failed - BIO_write: %s",
			   ERR_error_string(ERR_get_error(), NULL));
		return NULL;
	}

	res = SSL_read(conn->ssl, buf, sizeof(buf));
	if (res >= 0) {
		wpa_printf(MSG_DEBUG, "SSL: Unexpected data from SSL_read "
			   "(res=%d)", res);
	}

	res = BIO_ctrl_pending(conn->ssl_out);
	wpa_printf(MSG_DEBUG, "SSL: %d bytes pending from ssl_out", res);
	out_data = malloc(res == 0 ? 1 : res);
	if (out_data == NULL) {
		wpa_printf(MSG_DEBUG, "SSL: Failed to allocate memory for "
			   "handshake output (%d bytes)", res);
		BIO_reset(conn->ssl_out);
		*out_len = 0;
		return NULL;
	}
	res = res == 0 ? 0 : BIO_read(conn->ssl_out, out_data, res);
	if (res < 0) {
		wpa_printf(MSG_INFO, "TLS: Handshake failed - BIO_read: %s",
			   ERR_error_string(ERR_get_error(), NULL));
		BIO_reset(conn->ssl_out);
		*out_len = 0;
		return NULL;
	}
	*out_len = res;
	return out_data;
}
示例#30
0
static char *X509ToPEMAlloc(X509 *x)
{
	char *x509_str = NULL;
	size_t plen  = 0;
        int len = 0;

	if (!x)
		return NULL;
	
	BIO *bp = BIO_new(BIO_s_mem());
	
	if (!bp)
		return NULL;
	
	if (!PEM_write_bio_X509_AUX(bp, x))
		goto done;
	
	/* Get the length of the data written */	
	plen = BIO_ctrl_pending(bp);	
	
	if (plen == 0)
		goto done;
	
	/* Allocate enough memory to hold the PEM string */
	x509_str = (char *)malloc(plen + 1);
	
	if (!x509_str)
		goto done;
	
	len = BIO_read(bp, x509_str, plen);
	
	if (len <= 0) {
		free(x509_str);
		x509_str = NULL;
	} else {
                x509_str[len] = '\0';
        }	
done:
	BIO_free(bp);
	
	return x509_str;
}