Example #1
0
bool
ssl_connect_wget (int fd)
{
  static const int cert_type_priority[] = {
    GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0
  };
  struct wgnutls_transport_context *ctx;
  gnutls_session session;
  int err;
  int allowed_protocols[4] = {0, 0, 0, 0};
  gnutls_init (&session, GNUTLS_CLIENT);
  gnutls_set_default_priority (session);
  gnutls_certificate_type_set_priority (session, cert_type_priority);
  gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, credentials);
#ifndef FD_TO_SOCKET
# define FD_TO_SOCKET(X) (X)
#endif
  gnutls_transport_set_ptr (session, (gnutls_transport_ptr) FD_TO_SOCKET (fd));

  err = 0;
  switch (opt.secure_protocol)
    {
    case secure_protocol_auto:
      break;
    case secure_protocol_sslv2:
    case secure_protocol_sslv3:
      allowed_protocols[0] = GNUTLS_SSL3;
      err = gnutls_protocol_set_priority (session, allowed_protocols);
      break;
    case secure_protocol_tlsv1:
      allowed_protocols[0] = GNUTLS_TLS1_0;
      allowed_protocols[1] = GNUTLS_TLS1_1;
      allowed_protocols[2] = GNUTLS_TLS1_2;
      err = gnutls_protocol_set_priority (session, allowed_protocols);
      break;
    default:
      abort ();
    }
  if (err < 0)
    {
      logprintf (LOG_NOTQUIET, "GnuTLS: %s\n", gnutls_strerror (err));
      gnutls_deinit (session);
      return false;
    }

  err = gnutls_handshake (session);
  if (err < 0)
    {
      logprintf (LOG_NOTQUIET, "GnuTLS: %s\n", gnutls_strerror (err));
      gnutls_deinit (session);
      return false;
    }

  ctx = xnew0 (struct wgnutls_transport_context);
  ctx->session = session;
  fd_register_transport (fd, &wgnutls_transport, ctx);
  return true;
}
Example #2
0
static void
server (int fd, const char* prio)
{
int ret;
char buffer[MAX_BUF + 1];
gnutls_session_t session;

  /* this must be called once in the program
   */
  gnutls_global_init ();
  memset(buffer, 0, sizeof(buffer));

  if (debug)
    {
      gnutls_global_set_log_function (server_log_func);
      gnutls_global_set_log_level (4711);
    }

  gnutls_certificate_allocate_credentials (&x509_cred);
  gnutls_certificate_set_x509_key_mem (x509_cred, &server_cert, &server_key,
                                       GNUTLS_X509_FMT_PEM);

  gnutls_anon_allocate_server_credentials (&anoncred);

  session = initialize_tls_session (prio);

  gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) fd);

  do 
    {
      ret = gnutls_handshake (session);
    }
  while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
  if (ret < 0)
    {
      close (fd);
      gnutls_deinit (session);
      fail ("server: Handshake has failed (%s)\n\n", gnutls_strerror (ret));
      terminate();
    }
  if (debug)
    success ("server: Handshake was completed\n");

  if (debug)
    success ("server: TLS version is: %s\n",
             gnutls_protocol_get_name (gnutls_protocol_get_version
                                       (session)));
  close(fd);
  gnutls_deinit (session);

  gnutls_anon_free_server_credentials (anoncred);
  gnutls_certificate_free_credentials (x509_cred);

  gnutls_global_deinit ();

  if (debug)
    success ("server: finished\n");
}
Example #3
0
static void server(int sd)
{
	gnutls_certificate_credentials_t x509_cred;
	gnutls_session_t session;
	int ret;
	unsigned loops;

	/* this must be called once in the program
	 */
	global_init();

	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(6);

	gnutls_certificate_allocate_credentials(&x509_cred);
	gnutls_certificate_set_x509_trust_mem(x509_cred, &ca3_cert,
					      GNUTLS_X509_FMT_PEM);

	gnutls_certificate_set_x509_key_mem(x509_cred, &server_ca3_localhost_cert,
					    &server_ca3_key,
					    GNUTLS_X509_FMT_PEM);

	if (debug)
		success("Launched, generating DH parameters...\n");

	gnutls_init(&session, GNUTLS_SERVER);

	/* avoid calling all the priority functions, since the defaults
	 * are adequate.
	 */
	gnutls_priority_set_direct(session, "NORMAL", NULL);

	gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);

	gnutls_transport_set_int(session, sd);
	loops = 0;
	do {
		ret = gnutls_handshake(session);
		loops++;
		if (loops > 64)
			fail("Too many loops in the handshake!\n");
	} while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_WARNING_ALERT_RECEIVED);

	if (ret >= 0) {
		fail("server: Handshake succeeded unexpectedly\n");
	}

	close(sd);
	gnutls_deinit(session);

	gnutls_certificate_free_credentials(x509_cred);

	gnutls_global_deinit();

	if (debug)
		success("server: finished\n");
}
Example #4
0
u8 * tls_connection_handshake(void *ssl_ctx, struct tls_connection *conn,
			      const u8 *in_data, size_t in_len,
			      size_t *out_len)
{
	u8 *out_data;
	int ret;

	if (in_data && in_len) {
		if (conn->pull_buf) {
			wpa_printf(MSG_DEBUG, "%s - %d bytes remaining in "
				   "pull_buf", __func__, conn->pull_buf_len);
			free(conn->pull_buf);
		}
		conn->pull_buf = malloc(in_len);
		if (conn->pull_buf == NULL)
			return NULL;
		memcpy(conn->pull_buf, in_data, in_len);
		conn->pull_buf_offset = conn->pull_buf;
		conn->pull_buf_len = in_len;
	}

	ret = gnutls_handshake(conn->session);
	if (ret < 0) {
		switch (ret) {
		case GNUTLS_E_AGAIN:
			break;
		case GNUTLS_E_FATAL_ALERT_RECEIVED:
			wpa_printf(MSG_DEBUG, "%s - received fatal '%s' alert",
				   __func__, gnutls_alert_get_name(
					   gnutls_alert_get(conn->session)));
			conn->read_alerts++;
			/* continue */
		default:
			wpa_printf(MSG_DEBUG, "%s - gnutls_handshake failed "
				   "-> %s", __func__, gnutls_strerror(ret));
			conn->failed++;
		}
	} else {
		wpa_printf(MSG_DEBUG, "TLS: Handshake completed successfully");
		if (conn->verify_peer && tls_connection_verify_peer(conn)) {
			wpa_printf(MSG_INFO, "TLS: Peer certificate chain "
				   "failed validation");
			conn->failed++;
			return NULL;
		}
		conn->established = 1;
		if (conn->push_buf == NULL) {
			/* Need to return something to get final TLS ACK. */
			conn->push_buf = malloc(1);
		}
	}

	out_data = conn->push_buf;
	*out_len = conn->push_buf_len;
	conn->push_buf = NULL;
	conn->push_buf_len = 0;
	return out_data;
}
Example #5
0
void TLSTransaction::init (TLSServer& server)
{
  gnutls_init (&_session, GNUTLS_SERVER);
  gnutls_priority_set (_session, server._priorities);
  gnutls_credentials_set (_session, GNUTLS_CRD_CERTIFICATE, server._credentials);

  // Require client certificate.
  gnutls_certificate_server_set_request (_session, GNUTLS_CERT_REQUIRE);

/*
  // Set maximum compatibility mode. This is only suggested on public
  // webservers that need to trade security for compatibility
  gnutls_session_enable_compatibility_mode (_session);
*/

  struct sockaddr_in sa_cli = {0};
  socklen_t client_len = sizeof sa_cli;
  do
  {
    _socket = accept (server._socket, (struct sockaddr *) &sa_cli, &client_len);
  }
  while (errno == EINTR);

  if (_socket < 0)
    throw std::string (::strerror (errno));

  // Obtain client info.
  char topbuf[512];
  _address = inet_ntop (AF_INET, &sa_cli.sin_addr, topbuf, sizeof (topbuf));
  _port    = ntohs (sa_cli.sin_port);
  if (_debug)
    std::cout << "s: INFO connection from "
              << _address
              << " port "
              << _port
              << "\n";

#if GNUTLS_VERSION_NUMBER >= 0x030109
  gnutls_transport_set_int (_session, _socket);
#else
  gnutls_transport_set_ptr (_session, (gnutls_transport_ptr_t) (long) _socket);
#endif

  // Key exchange.
  int ret;
  do
  {
    ret = gnutls_handshake (_session);
  }
  while (ret < 0 && gnutls_error_is_fatal (ret) == 0);

  if (ret < 0)
    throw std::string ("Handshake has failed (") + gnutls_strerror (ret) + ")";

  if (_debug)
    std::cout << "s: INFO Handshake was completed\n";
}
static void client(int fd)
{
	int ret;
	gnutls_anon_client_credentials_t anoncred;
	gnutls_session_t session;
	/* Need to enable anonymous KX specifically. */

	global_init();

	if (debug) {
		gnutls_global_set_log_function(client_log_func);
		gnutls_global_set_log_level(4711);
	}

	gnutls_anon_allocate_client_credentials(&anoncred);

	/* Initialize TLS session
	 */
	gnutls_init(&session, GNUTLS_CLIENT | GNUTLS_DATAGRAM);
	gnutls_dtls_set_mtu(session, 1500);
	gnutls_handshake_set_timeout(session, 20 * 1000);

	/* Use default priorities */
	gnutls_priority_set_direct(session,
				   "NONE:+VERS-DTLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-ECDH:+CURVE-ALL",
				   NULL);

	/* put the anonymous credentials to the current session
	 */
	gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred);

	gnutls_transport_set_int(session, fd);
	gnutls_transport_set_push_function(session, push);

	/* Perform the TLS handshake
	 */
	do {
		ret = gnutls_handshake(session);
	}
	while (ret < 0 && gnutls_error_is_fatal(ret) == 0);

	if (ret < 0) {
		success("client: Handshake failed as expected\n");
		gnutls_perror(ret);
		goto exit;
	} else {
		fail("client: Handshake completed unexpectedly\n");
		goto exit;
	}

 exit:
	gnutls_deinit(session);

	gnutls_anon_free_client_credentials(anoncred);

	gnutls_global_deinit();
}
bool DTLS_Encrypt(NetworkAddress * destAddress, uint8_t * plainText, int plainTextLength, uint8_t * encryptedBuffer, int encryptedBufferLength, int * encryptedLength, void *context)
{
    bool result = false;
    DTLS_Session * session = GetSession(destAddress);
    if (session)
    {
        if (session->SessionEstablished)
        {
            gnutls_transport_set_push_function(session->Session, EncryptCallBack);
            session->Buffer = encryptedBuffer;
            session->BufferLength = encryptedBufferLength;
            int written = gnutls_write(session->Session, plainText, plainTextLength);
            if (written >= 0)
            {
                *encryptedLength = encryptedBufferLength - session->BufferLength;
                result = (*encryptedLength > 0);
            }
        }
        else
        {
            session->UserContext = context;
            gnutls_transport_set_push_function(session->Session, SSLSendCallBack);
            session->SessionEstablished = (gnutls_handshake(session->Session) == GNUTLS_E_SUCCESS);
            if (session->SessionEstablished)
                Lwm2m_Info("DTLS Session established\n");
        }
    }
    else
    {
        int index;
        for (index = 0;index < MAX_DTLS_SESSIONS; index++)
        {
            if (!sessions[index].Session)
            {
                SetupNewSession(index, destAddress, true);
                sessions[index].UserContext = context;
                gnutls_transport_set_push_function(sessions[index].Session, SSLSendCallBack);
                sessions[index].SessionEstablished = (gnutls_handshake(sessions[index].Session) == GNUTLS_E_SUCCESS);
                break;
            }
        }
    }
    return result;
}
Example #8
0
int dtls_try_handshake(struct openconnect_info *vpninfo)
{
	int err = gnutls_handshake(vpninfo->dtls_ssl);

	if (!err) {
#ifdef HAVE_GNUTLS_DTLS_SET_DATA_MTU
		/* Make sure GnuTLS's idea of the MTU is sufficient to take
		   a full VPN MTU (with 1-byte header) in a data record. */
		err = gnutls_dtls_set_data_mtu(vpninfo->dtls_ssl, vpninfo->ip_info.mtu + 1);
		if (err) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Failed to set DTLS MTU: %s\n"),
				     gnutls_strerror(err));
			goto error;
		}
#else
		/* If we don't have gnutls_dtls_set_data_mtu() then make sure
		   we leave enough headroom by adding the worst-case overhead.
		   We only support AES128-CBC and DES-CBC3-SHA anyway, so
		   working out the worst case isn't hard. */
		gnutls_dtls_set_mtu(vpninfo->dtls_ssl,
				    vpninfo->ip_info.mtu + 1 /* packet + header */
				    + 13 /* DTLS header */
				    + 20 /* biggest supported MAC (SHA1) */
				    + 16 /* biggest supported IV (AES-128) */
				    + 16 /* max padding */);
#endif

		vpninfo->dtls_state = DTLS_CONNECTED;
		vpn_progress(vpninfo, PRG_INFO,
			     _("Established DTLS connection (using GnuTLS). Ciphersuite %s.\n"),
			     vpninfo->dtls_cipher);

		vpninfo->dtls_times.last_rekey = vpninfo->dtls_times.last_rx = 
			vpninfo->dtls_times.last_tx = time(NULL);

		/* XXX: For OpenSSL we explicitly prevent retransmits here. */
		return 0;
	}

	if (err == GNUTLS_E_AGAIN) {
		if (time(NULL) < vpninfo->new_dtls_started + 12)
			return 0;
		vpn_progress(vpninfo, PRG_DEBUG, _("DTLS handshake timed out\n"));
	}

	vpn_progress(vpninfo, PRG_ERR, _("DTLS handshake failed: %s\n"),
		     gnutls_strerror(err));

 error:
	dtls_close(vpninfo);

	vpninfo->dtls_state = DTLS_SLEEPING;
	time(&vpninfo->new_dtls_started);
	return -EINVAL;
}
Example #9
0
int
SSL_accept (SSL * ssl)
{
  X509_STORE_CTX *store;
  int cert_list_size = 0;
  int err;
  int i, j;
  int x_priority[GNUTLS_MAX_ALGORITHM_NUM];
  /* take options into account before accepting */

  memset (x_priority, 0, sizeof (x_priority));
  if (ssl->options & SSL_OP_NO_TLSv1)
    {
      for (i = 0, j = 0;
	   i < GNUTLS_MAX_ALGORITHM_NUM && x_priority[i] != 0; i++, j++)
	{
	  if (ssl->ctx->method->protocol_priority[j] == GNUTLS_TLS1)
	    j++;
	  else
	    x_priority[i] = ssl->ctx->method->protocol_priority[j];
	}
      if (i < GNUTLS_MAX_ALGORITHM_NUM)
	x_priority[i] = 0;
      gnutls_protocol_set_priority (ssl->gnutls_state,
				    ssl->ctx->method->protocol_priority);
    }

  /* FIXME: dh params, do we want client cert? */

  err = gnutls_handshake (ssl->gnutls_state);
  ssl->last_error = err;

  if (err < 0)
    {
      last_error = err;
      return 0;
    }

  store = (X509_STORE_CTX *) calloc (1, sizeof (X509_STORE_CTX));
  store->ssl = ssl;
  store->cert_list = gnutls_certificate_get_peers (ssl->gnutls_state,
						   &cert_list_size);

  if (ssl->verify_callback)
    {
      ssl->verify_callback (1 /*FIXME*/, store);
    }
  ssl->state = SSL_ST_OK;

  err = store->error;
  free (store);

  /* FIXME: deal with error from callback */

  return 1;
}
Example #10
0
/* retry an interrupted GTLS operation
 * rgerhards, 2008-04-30
 */
static rsRetVal
doRetry(nsd_gtls_t *pNsd)
{
	DEFiRet;
	int gnuRet;

	dbgprintf("GnuTLS requested retry of %d operation - executing\n", pNsd->rtryCall);

	/* We follow a common scheme here: first, we do the systen call and
	 * then we check the result. So far, the result is checked after the
	 * switch, because the result check is the same for all calls. Note that
	 * this may change once we deal with the read and write calls (but
	 * probably this becomes an issue only when we begin to work on TLS
	 * for relp). -- rgerhards, 2008-04-30
	 */
	switch(pNsd->rtryCall) {
		case gtlsRtry_handshake:
			gnuRet = gnutls_handshake(pNsd->sess);
			if(gnuRet == 0) {
				pNsd->rtryCall = gtlsRtry_None; /* we are done */
				/* we got a handshake, now check authorization */
				CHKiRet(gtlsChkPeerAuth(pNsd));
			}
			break;
		case gtlsRtry_recv:
			dbgprintf("retrying gtls recv, nsd: %p\n", pNsd);
			CHKiRet(gtlsRecordRecv(pNsd));
			pNsd->rtryCall = gtlsRtry_None; /* we are done */
			gnuRet = 0;
			break;
		case gtlsRtry_None:
		default:
			assert(0); /* this shall not happen! */
			dbgprintf("ERROR: pNsd->rtryCall invalid in nsdsel_gtls.c:%d\n", __LINE__);
			gnuRet = 0; /* if it happens, we have at least a defined behaviour... ;) */
			break;
	}

	if(gnuRet == 0) {
		pNsd->rtryCall = gtlsRtry_None; /* we are done */
	} else if(gnuRet != GNUTLS_E_AGAIN && gnuRet != GNUTLS_E_INTERRUPTED) {
		uchar *pErr = gtlsStrerror(gnuRet);
		errmsg.LogError(0, RS_RET_GNUTLS_ERR, "unexpected GnuTLS error %d in %s:%d: %s\n", gnuRet, __FILE__, __LINE__, pErr); \
		free(pErr);
		pNsd->rtryCall = gtlsRtry_None; /* we are also done... ;) */
		ABORT_FINALIZE(RS_RET_GNUTLS_ERR);
	}
	/* if we are interrupted once again (else case), we do not need to
	 * change our status because we are already setup for retries.
	 */
		
finalize_it:
	if(iRet != RS_RET_OK && iRet != RS_RET_CLOSED && iRet != RS_RET_RETRY)
		pNsd->bAbortConn = 1; /* request abort */
	RETiRet;
}
Example #11
0
/**
 * Enables SSL for the given connection.
 *
 * @param connection The connection to enable SSL for.
 *
 * @return IDEVICE_E_SUCCESS on success, IDEVICE_E_INVALID_ARG when connection
 *     is NULL or connection->ssl_data is non-NULL, or IDEVICE_E_SSL_ERROR when
 *     SSL initialization, setup, or handshake fails.
 */
idevice_error_t idevice_connection_enable_ssl(idevice_connection_t connection)
{
	if (!connection || connection->ssl_data)
		return IDEVICE_E_INVALID_ARG;

	idevice_error_t ret = IDEVICE_E_SSL_ERROR;
	uint32_t return_me = 0;

	ssl_data_t ssl_data_loc = (ssl_data_t)malloc(sizeof(struct ssl_data_private));

	/* Set up GnuTLS... */
	debug_info("enabling SSL mode");
	errno = 0;
	gnutls_global_init();
	gnutls_certificate_allocate_credentials(&ssl_data_loc->certificate);
	gnutls_certificate_client_set_retrieve_function (ssl_data_loc->certificate, internal_cert_callback);
	gnutls_init(&ssl_data_loc->session, GNUTLS_CLIENT);
	gnutls_priority_set_direct(ssl_data_loc->session, "NONE:+VERS-SSL3.0:+ANON-DH:+RSA:+AES-128-CBC:+AES-256-CBC:+SHA1:+MD5:+COMP-NULL", NULL);
	gnutls_credentials_set(ssl_data_loc->session, GNUTLS_CRD_CERTIFICATE, ssl_data_loc->certificate);
	gnutls_session_set_ptr(ssl_data_loc->session, ssl_data_loc);

	gnutls_x509_crt_init(&ssl_data_loc->root_cert);
	gnutls_x509_crt_init(&ssl_data_loc->host_cert);
	gnutls_x509_privkey_init(&ssl_data_loc->root_privkey);
	gnutls_x509_privkey_init(&ssl_data_loc->host_privkey);

	userpref_error_t uerr = userpref_get_keys_and_certs(ssl_data_loc->root_privkey, ssl_data_loc->root_cert, ssl_data_loc->host_privkey, ssl_data_loc->host_cert);
	if (uerr != USERPREF_E_SUCCESS) {
		debug_info("Error %d when loading keys and certificates! %d", uerr);
	}

	debug_info("GnuTLS step 1...");
	gnutls_transport_set_ptr(ssl_data_loc->session, (gnutls_transport_ptr_t)connection);
	debug_info("GnuTLS step 2...");
	gnutls_transport_set_push_function(ssl_data_loc->session, (gnutls_push_func) & internal_ssl_write);
	debug_info("GnuTLS step 3...");
	gnutls_transport_set_pull_function(ssl_data_loc->session, (gnutls_pull_func) & internal_ssl_read);
	debug_info("GnuTLS step 4 -- now handshaking...");
	if (errno)
		debug_info("WARN: errno says %s before handshake!", strerror(errno));
	return_me = gnutls_handshake(ssl_data_loc->session);
	debug_info("GnuTLS handshake done...");

	if (return_me != GNUTLS_E_SUCCESS) {
		internal_ssl_cleanup(ssl_data_loc);
		free(ssl_data_loc);
		debug_info("GnuTLS reported something wrong.");
		gnutls_perror(return_me);
		debug_info("oh.. errno says %s", strerror(errno));
	} else {
		connection->ssl_data = ssl_data_loc;
		ret = IDEVICE_E_SUCCESS;
		debug_info("SSL mode enabled");
	}
	return ret;
}
Example #12
0
/* Only to be called from wr_send() and wr_recv() ! */
static bool wr_handshake(wr_socket s)
{
  int res = gnutls_handshake (s->tls_s);
  if (GNUTLS_E_SUCCESS == res)
    s->tls_connected = !0;
  else if (GNUTLS_E_AGAIN == res)
    MHD_socket_set_error_ (MHD_SCKT_EAGAIN_);
  else
    MHD_socket_set_error_ (MHD_SCKT_ECONNABORTED_); /* hard error */
  return s->tls_connected;
}
Example #13
0
static gpointer
server_thread (gpointer user_data)
{
	int listener = GPOINTER_TO_INT (user_data), client;
	gnutls_certificate_credentials creds;
	gnutls_session_t session;
	struct sockaddr_in sin;
	int len;
	char buf[BUFSIZE];
	int status;

	gnutls_certificate_allocate_credentials (&creds);
	if (gnutls_certificate_set_x509_key_file (creds,
						  ssl_cert_file, ssl_key_file,
						  GNUTLS_X509_FMT_PEM) != 0) {
		g_error ("Failed to set SSL certificate and key files "
			 "(%s, %s).", ssl_cert_file, ssl_key_file);
	}
	gnutls_certificate_set_dh_params (creds, dh_params);

	/* Create a new session */
	gnutls_init (&session, GNUTLS_SERVER);
	gnutls_set_default_priority (session);
	gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, creds);
	gnutls_dh_set_prime_bits (session, DH_BITS);

	/* Wait for client thread to connect */
	len = sizeof (sin);
	client = accept (listener, (struct sockaddr *) &sin, (void *)&len);
	gnutls_transport_set_ptr (session, GINT_TO_POINTER (client));

	/* Initial handshake */
	status = gnutls_handshake (session);
	if (status < 0)
		g_error ("initial handshake failed: %d", status);

	/* Synchronous client test. */
	server_read (session, buf, BUFSIZE);
	server_write (session, buf, BUFSIZE);

	/* Async client test. */
	server_read (session, buf, BUFSIZE);
	server_write (session, buf, BUFSIZE);

	/* That's all, folks. */
	gnutls_bye (session, GNUTLS_SHUT_WR);
	gnutls_deinit (session);
	close (client);
	gnutls_certificate_free_credentials (creds);

	return NULL;
}
static int
test_tls_session_time_out (gnutls_session_t session)
{
  int ret;
  MHD_socket sd;
  struct sockaddr_in sa;

  sd = socket (AF_INET, SOCK_STREAM, 0);
  if (sd == -1)
    {
      fprintf (stderr, "Failed to create socket: %s\n", strerror (errno));
      return -1;
    }

  memset (&sa, '\0', sizeof (struct sockaddr_in));
  sa.sin_family = AF_INET;
  sa.sin_port = htons (DEAMON_TEST_PORT);
  sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);

  gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) (intptr_t) sd);

  ret = connect (sd, (struct sockaddr *) &sa, sizeof (struct sockaddr_in));

  if (ret < 0)
    {
      fprintf (stderr, "Error: %s\n", MHD_E_FAILED_TO_CONNECT);
      close (sd);
      return -1;
    }

  ret = gnutls_handshake (session);
  if (ret < 0)
    {
      fprintf (stderr, "Handshake failed\n");
      close (sd);
      return -1;
    }

  sleep (TIME_OUT + 1);

  /* check that server has closed the connection */
  /* TODO better RST trigger */
  if (send (sd, "", 1, 0) == 0)
    {
      fprintf (stderr, "Connection failed to time-out\n");
      close (sd);
      return -1;
    }

  close (sd);
  return 0;
}
void socket_thread_main(apr_thread_t *self, void *data)
{
	int ret = 0;
	socket_thread_data_t *thread_data = (socket_thread_data_t*)data;
	gnutls_session_t session;
	apr_os_sock_t sock;

	if(tls_cert != NULL)
	{
		if(apr_os_sock_get(&sock, thread_data->socket) != APR_SUCCESS)
		{
			syslog(LOG_ERR, "Can't get raw socket for TLS use");
			ret = -1;
		}
		else if((thread_data->tls_session=apr_pcalloc(
				thread_data->pool, sizeof(gnutls_session_t)))!=NULL)
		{
			session = initialize_tls_session ();
			gnutls_transport_set_ptr (session,
					(gnutls_transport_ptr_t) (sock));
			do
			{
				ret = gnutls_handshake (session);
			}
			while (ret < 0 && gnutls_error_is_fatal (ret) == 0);

			if (ret < 0)
			{
				syslog(LOG_ERR, "handshake has failed (%s)\n\n", gnutls_strerror (ret));
			}
			*(thread_data->tls_session) = session;
		}
		else
		{
			syslog(LOG_ERR, "memory allocation failure");
			ret = -1;
		}
	}

	if(ret >= 0)
	{
		socket_thread_handle(thread_data);
		if(thread_data->tls_session != NULL)
			gnutls_bye(session, GNUTLS_SHUT_WR);
	}

	apr_socket_close(thread_data->socket);
	if(thread_data->tls_session != NULL)
		gnutls_deinit (session);
	apr_pool_destroy(thread_data->pool);
	syslog(LOG_INFO, "client connection closed");
}
Example #16
0
    int TLSSocket::handshake() {
        int ret ;
        do {

            ret = gnutls_handshake (session);
        } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED );

        if (ret < 0) {
            gnutls_perror(ret);
            Socket::close();
        }
        return ret;
    }
Example #17
0
static int
handshake (struct stream_data *data)
{
	const int protocol_priority[] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 };
	const int kx_priority[] = { GNUTLS_KX_RSA, 0 };
	const int cipher_priority[] = { GNUTLS_CIPHER_3DES_CBC, GNUTLS_CIPHER_ARCFOUR, 0};
	const int comp_priority[] = { GNUTLS_COMP_ZLIB, GNUTLS_COMP_NULL, 0 };
	const int mac_priority[] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 };
	int ret;

#ifndef WIN32
	gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
#endif

	if (gnutls_global_init () != 0)
		return IKS_NOMEM;

	if (gnutls_certificate_allocate_credentials (&data->cred) < 0)
		return IKS_NOMEM;

	if (gnutls_init (&data->sess, GNUTLS_CLIENT) != 0) {
		gnutls_certificate_free_credentials (data->cred);
		return IKS_NOMEM;
	}
	gnutls_protocol_set_priority (data->sess, protocol_priority);
	gnutls_cipher_set_priority(data->sess, cipher_priority);
	gnutls_compression_set_priority(data->sess, comp_priority);
	gnutls_kx_set_priority(data->sess, kx_priority);
	gnutls_mac_set_priority(data->sess, mac_priority);
	gnutls_credentials_set (data->sess, GNUTLS_CRD_CERTIFICATE, data->cred);


	gnutls_transport_set_push_function (data->sess, (gnutls_push_func) tls_push);
	gnutls_transport_set_pull_function (data->sess, (gnutls_pull_func) tls_pull);
	
	gnutls_transport_set_ptr (data->sess, data->prs);

	ret = gnutls_handshake (data->sess);
	if (ret != 0) {
		gnutls_deinit (data->sess);
		gnutls_certificate_free_credentials (data->cred);
		return IKS_NET_TLSFAIL;
	}

	data->flags &= (~SF_TRY_SECURE);
	data->flags |= SF_SECURE;

	iks_send_header (data->prs, data->server);

	return IKS_OK;
} // HAVE_GNUTLS
Example #18
0
static void client(int fd, const char *prio)
{
	int ret;
	gnutls_certificate_credentials_t x509_cred;
	gnutls_session_t session;

	global_init();

	if (debug) {
		gnutls_global_set_log_function(client_log_func);
		gnutls_global_set_log_level(7);
	}

	gnutls_certificate_allocate_credentials(&x509_cred);

	assert(gnutls_init(&session, GNUTLS_CLIENT)>=0);

	assert(gnutls_priority_set_direct(session, prio, NULL)>=0);

	gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);

	gnutls_transport_set_int(session, fd);

	do {
		ret = gnutls_handshake(session);
	}
	while (ret < 0 && gnutls_error_is_fatal(ret) == 0);

	if (ret < 0) {
		fail("client: Handshake failed: %s\n", gnutls_strerror(ret));
		terminate();
	} else {
		if (debug)
			success("client: Handshake was completed\n");
	}

	if (debug)
		success("client: TLS version is: %s\n",
			gnutls_protocol_get_name
			(gnutls_protocol_get_version(session)));

	gnutls_bye(session, GNUTLS_SHUT_WR);

	close(fd);

	gnutls_deinit(session);

	gnutls_certificate_free_credentials(x509_cred);

	gnutls_global_deinit();
}
int
SSL_accept (SSL * ssl)
{
  X509_STORE_CTX *store;
  int cert_list_size = 0;
  int err;
  char x_priority[256];
  /* take options into account before connecting */

  memset (x_priority, 0, sizeof (x_priority));
  if (ssl->options & SSL_OP_NO_TLSv1)
    {
      snprintf(x_priority, sizeof(x_priority), "%s:-VERS-TLS1.0", ssl->ctx->method->priority_string);
      err = gnutls_priority_set_direct(ssl->gnutls_state, x_priority, NULL);
      if (err < 0)
        {
          last_error = err;
          return 0;
        }
    }

  /* FIXME: dh params, do we want client cert? */

  err = gnutls_handshake (ssl->gnutls_state);
  ssl->last_error = err;

  if (err < 0)
    {
      last_error = err;
      return 0;
    }

  store = (X509_STORE_CTX *) calloc (1, sizeof (X509_STORE_CTX));
  store->ssl = ssl;
  store->cert_list = gnutls_certificate_get_peers (ssl->gnutls_state,
                                                   &cert_list_size);

  if (ssl->verify_callback)
    {
      ssl->verify_callback (1 /*FIXME*/, store);
    }
  ssl->state = SSL_ST_OK;

  err = store->error;
  free (store);

  /* FIXME: deal with error from callback */

  return 1;
}
Example #20
0
static void client(int fd)
{
	int ret;
	gnutls_certificate_credentials_t x509_cred;
	gnutls_session_t session;

	gnutls_certificate_allocate_credentials(&x509_cred);

	/* Initialize TLS session
	 */
	gnutls_init(&session, GNUTLS_CLIENT);

	/* Use default priorities */
	assert(gnutls_priority_set_direct(session, "NORMAL:-VERS-ALL:+VERS-TLS1.2", NULL)>=0);

	gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);

	gnutls_transport_set_int(session, fd);

	/* Perform the TLS handshake
	 */
	do {
		ret = gnutls_handshake(session);
	}
	while (ret < 0 && gnutls_error_is_fatal(ret) == 0);

	if (ret < 0) {
		fail("client: Handshake failed\n");
		gnutls_perror(ret);
		exit(1);
	} else {
		if (debug)
			success("client: Handshake was completed\n");
	}

	if (debug)
		success("client: TLS version is: %s\n",
			gnutls_protocol_get_name
			(gnutls_protocol_get_version(session)));

	gnutls_bye(session, GNUTLS_SHUT_WR);

	close(fd);

	gnutls_deinit(session);

	gnutls_certificate_free_credentials(x509_cred);

	gnutls_global_deinit();
}
static void client(int fd)
{
	int ret;
	gnutls_certificate_credentials_t xcred;
	gnutls_session_t session;

	global_init();

	if (debug) {
		gnutls_global_set_log_function(client_log_func);
		gnutls_global_set_log_level(4711);
	}

	gnutls_certificate_allocate_credentials(&xcred);

	/* Initialize TLS session
	 */
	gnutls_init(&session, GNUTLS_CLIENT);
	gnutls_handshake_set_timeout(session, 20 * 1000);

	/* Use default priorities */
	gnutls_priority_set_direct(session,
				   "NORMAL:-KX-ALL:+ECDHE-RSA:%COMPAT",
				   NULL);

	gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);

	gnutls_transport_set_int(session, fd);
	gnutls_transport_set_push_function(session, odd_push);

	/* Perform the TLS handshake
	 */
	do {
		ret = gnutls_handshake(session);
	}
	while (ret < 0 && gnutls_error_is_fatal(ret) == 0);

	if (ret >= 0) {
		fail("client: Handshake succeeded!\n");
		exit(1);
	}

	close(fd);

	gnutls_deinit(session);

	gnutls_certificate_free_credentials(xcred);

	gnutls_global_deinit();
}
Example #22
0
  void GnuTlsStream::handshake(const GnuTlsServer& server)
  {
    log_debug("gnutls_init(session, GNUTLS_SERVER)");
    int ret = gnutls_init(&_session, GNUTLS_SERVER);
    if (ret != 0)
      throw GnuTlsException("gnutls_init", ret);

    log_debug("gnutls_set_default_priority");
    ret = gnutls_set_default_priority(_session);
    if (ret != 0)
      throw GnuTlsException("gnutls_set_default_priority", ret);

    log_debug("gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, "
      << server.getCred() << ')');
    ret = gnutls_credentials_set(_session, GNUTLS_CRD_CERTIFICATE, server.getCred());
    if (ret != 0)
      throw GnuTlsException("gnutls_credentials_set", ret);

    log_debug("gnutls_dh_set_prime_bits(session, 1024)");
    gnutls_dh_set_prime_bits(_session, 1024);

    _fdInfo.fd = getFd();
    _fdInfo.timeout = getTimeout();

    log_debug("gnutls_transport_set_ptr(ptr)");
    gnutls_transport_set_ptr(_session, static_cast<gnutls_transport_ptr_t>(&_fdInfo));

    log_debug("gnutls_transport_set_pull_function()");
    gnutls_transport_set_pull_function(_session, pull_func);

    log_debug("gnutls_transport_set_push_function()");
    gnutls_transport_set_push_function(_session, push_func);

    // non-blocking/with timeout

    _fdInfo.timeout = 10000;

    log_debug("gnutls_handshake");
    ret = gnutls_handshake(_session);
    log_debug("gnutls_handshake => " << ret);

    if (ret != 0)
      throw GnuTlsException("gnutls_handshake", ret);

    _connected = true;
    _fdInfo.timeout = getTimeout();

    log_debug("ssl-handshake was completed");
  }
Example #23
0
int
do_handshake (gnutls_session session)
{
  int ret, alert;

  do
    {
      ret = gnutls_handshake (session);
    }
  while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);

  handshake_output = ret;

  if (ret < 0 && verbose > 1)
    {
      if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED
	  || ret == GNUTLS_E_FATAL_ALERT_RECEIVED)
	{
	  alert = gnutls_alert_get (session);
	  printf ("\n");
	  printf ("*** Received alert [%d]: %s\n",
		  alert, gnutls_alert_get_name (alert));
	}
    }

  if (ret < 0)
    return TEST_FAILED;

  gnutls_session_get_data (session, NULL, &session_data_size);

  if (sfree != 0)
    {
      free (session_data);
      sfree = 0;
    }
  session_data = malloc (session_data_size);
  sfree = 1;
  if (session_data == NULL)
    {
      fprintf (stderr, "Memory error\n");
      exit (1);
    }
  gnutls_session_get_data (session, session_data, &session_data_size);

  session_id_size = sizeof (session_id);
  gnutls_session_get_id (session, session_id, &session_id_size);

  return TEST_SUCCEED;
}
Example #24
0
static Eina_Bool
_process_data(gnutls_session_t client, Ecore_Fd_Handler * fd_handler)
{
	static int ret, lastret;
	static unsigned int count = 0;

	if (!done) {
		lastret = ret;
		ret = gnutls_handshake(client);
		count++;
		if (gnutls_record_get_direction(client))
			ecore_main_fd_handler_active_set(fd_handler,
							 ECORE_FD_WRITE);
		else
			ecore_main_fd_handler_active_set(fd_handler,
							 ECORE_FD_READ);
		/* avoid printing messages infinity times */
		if (lastret != ret && ret != 0 && ret != GNUTLS_E_AGAIN) {
			print("gnutls returned with: %s - %s",
			      gnutls_strerror_name(ret),
			      gnutls_strerror(ret));
			if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED)
			    || (ret == GNUTLS_E_FATAL_ALERT_RECEIVED))
				print("Also received alert: %s",
				      gnutls_alert_get_name
				      (gnutls_alert_get(client)));
			print("last out: %s",
			      SSL_GNUTLS_PRINT_HANDSHAKE_STATUS
			      (gnutls_handshake_get_last_out(client)));
			print("last in: %s",
			      SSL_GNUTLS_PRINT_HANDSHAKE_STATUS
			      (gnutls_handshake_get_last_in(client)));
		}

		if (gnutls_error_is_fatal(ret)) {
			print("yarrr this be an error!");
			exit(1);
		}

	}
	if (ret == GNUTLS_E_SUCCESS) {
		done = 1;
		//print("Handshake successful in %u handshake calls!", count);
		ecore_main_loop_quit();
	}

	return ECORE_CALLBACK_RENEW;
}
Example #25
0
static void ssl_handshake(struct sockifo* ifo) {
	int rv = gnutls_handshake(ifo->ssl);
	if (rv == GNUTLS_E_SUCCESS) {
		ifo->state.poll = POLL_NORMAL;
		ifo->state.ssl = SSL_ACTIVE;
		if (ifo->state.ssl_verify_type == VERIFY_CA) {
			ssl_vfy_ca(ifo);
		} else if (ifo->state.ssl_verify_type == VERIFY_FP) {
			ssl_vfy_fp(ifo);
		}
	} else if (rv == GNUTLS_E_AGAIN || rv == GNUTLS_E_INTERRUPTED) {
		do_eagain(ifo, 1);
	} else {
		esock(ifo, gnutls_strerror(rv));
	}
}
Example #26
0
int SSLi_nonblockaccept( SSL_handle_t *session, bool_t * isSSLReady )
{
	int error;
	do {
		error = gnutls_handshake(*session);
	} while(error < GNUTLS_E_SUCCESS && !gnutls_error_is_fatal(error));

	if ( error < GNUTLS_E_SUCCESS ) {
		Log_warn("TLS handshake failed with error %i (%s).", error, gnutls_strerror(error));
	}

	if(isSSLReady)
		*isSSLReady = true;

	return error;
}
Example #27
0
static gnutls_session_t new_tls_session(int sock)
{
        int ret;
        gnutls_session_t session;
        const char *err;

#if defined LIBGNUTLS_VERSION_MAJOR && LIBGNUTLS_VERSION_MAJOR >= 3
# define TLS_DH_STR "+ANON-ECDH:+ANON-DH"
#else
# define TLS_DH_STR "+ANON-DH"
#endif

#ifdef GNUTLS_SRP_ENABLED
        const char *pstring = "NORMAL:+SRP:+SRP-DSS:+SRP-RSA:" TLS_DH_STR;
#else
        const char *pstring = "NORMAL:" TLS_DH_STR;
#endif

        gnutls_init(&session, GNUTLS_SERVER);
        gnutls_set_default_priority(session);

        ret = gnutls_priority_set_direct(session, pstring, &err);
        if (ret < 0) {
                fprintf(stderr, "TLS priority syntax error at: %s\n", err);
                return NULL;
        }

#ifdef GNUTLS_SRP_ENABLED
        gnutls_credentials_set(session, GNUTLS_CRD_SRP, srpcred);
        gnutls_certificate_server_set_request(session, GNUTLS_CERT_IGNORE);
#endif
        gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred);

        gnutls_transport_set_ptr(session, fd_to_ptr(sock));
        gnutls_transport_set_pull_function(session, tls_pull);
        gnutls_transport_set_push_function(session, tls_push);

        ret = gnutls_handshake(session);
        if ( ret < 0 ) {
                fprintf(stderr, "GnuTLS handshake failed: %s.\n", gnutls_strerror(ret));
                gnutls_alert_send_appropriate(session, ret);
                return NULL;
        }

        return session;
}
Example #28
0
sstream::sstream(const TCPServer *tcp, secure::server_t scontext, size_t size) :
tcpstream(tcp, size)
{

    ssl = __context::session((__context *)scontext);
    bio = NULL;
    server = true;

    if(!is_open() || !ssl)
        return;

    gnutls_transport_set_ptr((SSL)ssl, reinterpret_cast<gnutls_transport_ptr_t>( so));
    int result = gnutls_handshake((SSL)ssl);

    if(result >= 0)
        bio = ssl;
}
Example #29
0
static int get_cert(socket_st *hd, const char *hostname, unsigned udp, int fd)
{
	gnutls_certificate_credentials_t xcred;
	gnutls_session_t session;
	int ret;
	struct priv_st priv;

	priv.found = 0;
	priv.fd = fd;

	ret = gnutls_certificate_allocate_credentials(&xcred);
	if (ret < 0) {
		fprintf(stderr, "error[%d]: %s\n", __LINE__,
			gnutls_strerror(ret));
		exit(1);
	}
	gnutls_certificate_set_verify_function(xcred, cert_callback);

	ret = gnutls_init(&session, (udp?GNUTLS_DATAGRAM:0)|GNUTLS_CLIENT);
	if (ret < 0) {
		fprintf(stderr, "error[%d]: %s\n", __LINE__,
			gnutls_strerror(ret));
		exit(1);
	}
	gnutls_session_set_ptr(session, &priv);
	gnutls_transport_set_int(session, hd->fd);

	gnutls_set_default_priority(session);
	if (hostname && is_ip(hostname)==0) {
		gnutls_server_name_set(session, GNUTLS_NAME_DNS, hostname, strlen(hostname));
	}
	gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);

	do {
		ret = gnutls_handshake(session);
	} while(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_WARNING_ALERT_RECEIVED);
	/* we don't care on the result */

	gnutls_deinit(session);
	gnutls_certificate_free_credentials(xcred);

	if (priv.found == 0)
		return -1;

	return 0;
}
Example #30
0
void sstream::open(const char *host, const char *service, size_t bufsize)
{
    if(server)
        return;

    close();
    tcpstream::open(host, service, bufsize);

    if(!is_open() || !ssl)
        return;

    gnutls_transport_set_ptr((SSL)ssl, reinterpret_cast<gnutls_transport_ptr_t>(so));
    int result = gnutls_handshake((SSL)ssl);

    if(result >= 0)
        bio = ssl;
}