示例#1
0
文件: gnutls.c 项目: Belxjander/Asuna
void *ma_ssl_init(MYSQL *mysql)
{
  gnutls_session_t ssl= NULL;
  int ssl_error= 0;
  const char *err;

  pthread_mutex_lock(&LOCK_gnutls_config);

  if ((ssl_error= ma_ssl_set_certs(mysql)) < 0)
    goto error;

  if ((ssl_error = gnutls_init(&ssl, GNUTLS_CLIENT & GNUTLS_NONBLOCK)) < 0)
    goto error;
  gnutls_session_set_ptr(ssl, (void *)mysql);

  ssl_error= gnutls_priority_set_direct(ssl, "NORMAL:-DHE-RSA", &err);
  if (ssl_error < 0)
    goto error;

  if ((ssl_error= gnutls_credentials_set(ssl, GNUTLS_CRD_CERTIFICATE, GNUTLS_xcred)) < 0)
    goto error;
  
  pthread_mutex_unlock(&LOCK_gnutls_config);
  return (void *)ssl;
error:
  ma_ssl_set_error(mysql, ssl_error);
  if (ssl)
    gnutls_deinit(ssl);
  pthread_mutex_unlock(&LOCK_gnutls_config);
  return NULL;
}
示例#2
0
static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond )
{
	struct scd *conn = data;
	
	if( source == -1 )
	{
		conn->func( conn->data, 0, NULL, cond );
		g_free( conn );
		return FALSE;
	}
	
	ssl_init();
	
	gnutls_init( &conn->session, GNUTLS_CLIENT );
	if( conn->verify )
		gnutls_session_set_ptr( conn->session, (void *) conn->hostname );
#if GNUTLS_VERSION_NUMBER < 0x020c00
	gnutls_transport_set_lowat( conn->session, 0 );
#endif
	gnutls_set_default_priority( conn->session );
	gnutls_credentials_set( conn->session, GNUTLS_CRD_CERTIFICATE, xcred );
	
	sock_make_nonblocking( conn->fd );
	gnutls_transport_set_ptr( conn->session, (gnutls_transport_ptr) GNUTLS_STUPID_CAST conn->fd );
	
	return ssl_handshake( data, source, cond );
}
示例#3
0
SslSocket::SslSocket(SslDriver *driver, struct ev_loop *loop, int fd, int af) :
	x0::Socket(loop, fd, af),
#ifndef XZERO_NDEBUG
	ctime_(ev_now(loop)),
#endif
	driver_(driver),
	context_(nullptr),
	session_()
{
	TRACE("SslSocket()");

	setSecure(true);
	setState(Handshake);

	GNUTLS_CHECK( gnutls_init(&session_, GNUTLS_SERVER) );

	gnutls_handshake_set_post_client_hello_function(session_, &SslSocket::onClientHello);

	gnutls_certificate_server_set_request(session_, GNUTLS_CERT_REQUEST);
	gnutls_dh_set_prime_bits(session_, 1024);

	gnutls_session_enable_compatibility_mode(session_);

	gnutls_session_set_ptr(session_, this);
	gnutls_transport_set_ptr(session_, reinterpret_cast<gnutls_transport_ptr_t>(handle()));

	driver_->initialize(this);
}
示例#4
0
文件: daemon.c 项目: sqs/pakeproxy
void* connection_thread(void* arg) {
  int sd;
  gnutls_session_t session;
  pp_session_t ppsession;
  int ret;

  sd = (int)(long)arg;

  ret = initialize_tls_session(&session);
  if (ret != GNUTLS_E_SUCCESS) {
    fprintf(stderr, "Error initializing TLS session\n");
    return (void *)(long)ret;
  }
  gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t)(long)sd);

  memset(&ppsession, '\0', sizeof(pp_session_t));
  ppsession.cfg = &cfg;
  gnutls_session_set_ptr(session, &ppsession);

  ret = do_proxy(session);
  if (ret != GNUTLS_E_SUCCESS)
    fprintf(stderr, "- Proxy exited with failure\n");

  close((int)(long)gnutls_transport_get_ptr(session));
  gnutls_deinit(session);

  return 0;
}
示例#5
0
liGnuTLSFilter* li_gnutls_filter_new(
	liServer *srv, liWorker *wrk,
	const liGnuTLSFilterCallbacks *callbacks, gpointer data,
	gnutls_session_t session, liStream *crypt_source, liStream *crypt_drain
) {
	liEventLoop *loop = crypt_source->loop;
	liGnuTLSFilter *f;
	liCQLimit *out_limit;

	f = g_slice_new0(liGnuTLSFilter);
	f->refcount = 5; /* 1 + 4 streams */
	f->callbacks = callbacks;
	f->callback_data = data;
	f->srv = srv;
	f->wrk = wrk;

	f->session = session;
	gnutls_transport_set_ptr(f->session, (gnutls_transport_ptr_t) f);
	gnutls_transport_set_push_function(f->session, stream_push);
#ifdef HAVE_GIOVEC
	gnutls_transport_set_vec_push_function(f->session, stream_pushv);
#endif
	gnutls_transport_set_pull_function(f->session, stream_pull);

	gnutls_session_set_ptr(f->session, f);
	gnutls_handshake_set_post_client_hello_function(f->session, post_client_hello_cb);

	f->initial_handshaked_finished = 0;
	f->closing = f->aborted = 0;
	f->write_wants_read = 0;

	li_stream_init(&f->crypt_source, loop, stream_crypt_source_cb);
	li_stream_init(&f->crypt_drain, loop, stream_crypt_drain_cb);
	li_stream_init(&f->plain_source, loop, stream_plain_source_cb);
	li_stream_init(&f->plain_drain, loop, stream_plain_drain_cb);

	/* "virtual" connections - the content goes through SSL */
	li_stream_connect(&f->plain_drain, &f->crypt_source);
	li_stream_connect(&f->crypt_drain, &f->plain_source);

	li_stream_connect(crypt_source, &f->crypt_drain);
	li_stream_connect(&f->crypt_source, crypt_drain);

	/* separate limit for buffer of encrypted data
	 *
	 * f->plain_drain is already connected to f->crypt_source,
	 *   so they won't share the same limit */
	out_limit = li_cqlimit_new();
	out_limit->notify = stream_crypt_source_limit_notify_cb;
	out_limit->context = f;
	li_cqlimit_set_limit(out_limit, 32*1024);
	li_chunkqueue_set_limit(crypt_drain->out, out_limit);
	li_chunkqueue_set_limit(f->crypt_source.out, out_limit);
	li_cqlimit_release(out_limit);

	return f;
}
示例#6
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;
}
示例#7
0
    void TLSSocket::connect(const std::string& addr, int port) {
        gnutls_init(&session, GNUTLS_CLIENT);

        gnutls_priority_set(session, priority_cache);
        gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);
        Socket::connect(addr, port);
        gnutls_session_set_ptr(session, (void*)getInfo().c_str());
        gnutls_transport_set_ptr (session, 
                (gnutls_transport_ptr_t) fd);
    }
示例#8
0
void DomainHandler::initializeDTLSSession() {
    if (!_dtlsSession) {
        _dtlsSession = new DTLSClientSession(NodeList::getInstance()->getDTLSSocket(), _sockAddr);
        
        gnutls_session_set_ptr(*_dtlsSession->getGnuTLSSession(), this);
        
        // start a timer to complete the handshake process
        _handshakeTimer = new QTimer(this);
        connect(_handshakeTimer, &QTimer::timeout, this, &DomainHandler::completeDTLSHandshake);
        
        // start the handshake right now
        completeDTLSHandshake();
        
        // start the timer to finish off the handshake
        _handshakeTimer->start(DTLS_HANDSHAKE_INTERVAL_MSECS);
    }
}
示例#9
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;
}
示例#10
0
bool CTlsSocket::InitSession()
{
	if (!m_certCredentials) {
		Uninit();
		return false;
	}

	int res = gnutls_init(&m_session, GNUTLS_CLIENT);
	if (res) {
		LogError(res, _T("gnutls_init"));
		Uninit();
		return false;
	}

	// For use in callbacks
	gnutls_session_set_ptr(m_session, this);

	// Even though the name gnutls_db_set_cache_expiration
	// implies expiration of some cache, it also governs
	// the actual session lifetime, independend whether the
	// session is cached or not.
	gnutls_db_set_cache_expiration(m_session, 100000000);

	res = gnutls_priority_set_direct(m_session, ciphers, 0);
	if (res) {
		LogError(res, _T("gnutls_priority_set_direct"));
		Uninit();
		return false;
	}

	gnutls_dh_set_prime_bits(m_session, 1024);

	gnutls_credentials_set(m_session, GNUTLS_CRD_CERTIFICATE, m_certCredentials);

	// Setup transport functions
	gnutls_transport_set_push_function(m_session, PushFunction);
	gnutls_transport_set_pull_function(m_session, PullFunction);
	gnutls_transport_set_ptr(m_session, (gnutls_transport_ptr_t)this);

	return true;
}
示例#11
0
static int tls_gnutls_init_session(struct tls_global *global,
				   struct tls_connection *conn)
{
	const char *err;
	int ret;

	ret = gnutls_init(&conn->session,
			  global->server ? GNUTLS_SERVER : GNUTLS_CLIENT);
	if (ret < 0) {
		wpa_printf(MSG_INFO, "TLS: Failed to initialize new TLS "
			   "connection: %s", gnutls_strerror(ret));
		return -1;
	}

	ret = gnutls_set_default_priority(conn->session);
	if (ret < 0)
		goto fail;

	ret = gnutls_priority_set_direct(conn->session, "NORMAL:-VERS-SSL3.0",
					 &err);
	if (ret < 0) {
		wpa_printf(MSG_ERROR, "GnuTLS: Priority string failure at "
			   "'%s'", err);
		goto fail;
	}

	gnutls_transport_set_pull_function(conn->session, tls_pull_func);
	gnutls_transport_set_push_function(conn->session, tls_push_func);
	gnutls_transport_set_ptr(conn->session, (gnutls_transport_ptr_t) conn);
	gnutls_session_set_ptr(conn->session, conn);

	return 0;

fail:
	wpa_printf(MSG_INFO, "TLS: Failed to setup new TLS connection: %s",
		   gnutls_strerror(ret));
	gnutls_deinit(conn->session);
	return -1;
}
static void client(int fd, unsigned tickets)
{
	int ret;
	gnutls_certificate_credentials_t x509_cred;
	gnutls_session_t session;
	char buf[64];
	unsigned try = 0;
	gnutls_datum_t session_data = {NULL, 0};

	global_init();
	tickets_seen = 0;

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

	assert(gnutls_certificate_allocate_credentials(&x509_cred)>=0);

 retry:
	/* Initialize TLS session
	 */
	assert(gnutls_init(&session, GNUTLS_CLIENT|GNUTLS_POST_HANDSHAKE_AUTH)>=0);

	gnutls_handshake_set_timeout(session, 20 * 1000);

	ret = gnutls_priority_set_direct(session, "NORMAL:-VERS-ALL:+VERS-TLS1.3:+VERS-TLS1.2:+VERS-TLS1.0", NULL);
	if (ret < 0)
		fail("cannot set TLS 1.3 priorities\n");


	if (try == 0) {
		gnutls_session_set_ptr(session, &session_data);
		gnutls_handshake_set_hook_function(session, GNUTLS_HANDSHAKE_NEW_SESSION_TICKET,
						   GNUTLS_HOOK_BOTH,
						   ticket_callback);
	} else {
示例#13
0
文件: connect.c 项目: baishakhir/ssl
int main (int argc, char **argv)
{
  int ret, sd, ii;
  gnutls_session_t session;
  char buffer[1024];
  const char *err;
  char *host = argv[1];
  int port = atoi(argv[2]);
  char *cafile = argv[3];

  gnutls_certificate_credentials_t xcred;

  gnutls_global_init ();

  /* X509 stuff */
  gnutls_certificate_allocate_credentials (&xcred);

  /* sets the trusted cas file
   */
  gnutls_certificate_set_x509_trust_file (xcred, cafile, GNUTLS_X509_FMT_PEM);
  gnutls_certificate_set_verify_function (xcred, _verify_certificate_callback);

  /* Initialize TLS session 
   */
  gnutls_init (&session, GNUTLS_CLIENT);
  gnutls_session_set_ptr (session, (void *) "my_host_name");

  gnutls_server_name_set (session, GNUTLS_NAME_DNS, "my_host_name", 
                          strlen("my_host_name"));

  /* Use default priorities */
  ret = gnutls_priority_set_direct (session, "NORMAL", &err);
  if (ret < 0)
    {
      if (ret == GNUTLS_E_INVALID_REQUEST)
        {
          fprintf (stderr, "Syntax error at: %s\n", err);
        }
      exit (1);
    }

  /* put the x509 credentials to the current session
   */
  gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);

  /* connect to the peer
   */
  sd = tcp_connect (host, port);

  gnutls_transport_set_int (session, sd);
  gnutls_handshake_set_timeout (session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);

  /* Perform the TLS handshake
   */

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

  if (ret < 0)
    {
      if (ret != GNUTLS_E_CERTIFICATE_ERROR)
	      exit(1);
    }
  gnutls_record_send (session, "", strlen (""));

  ret = gnutls_record_recv (session, buffer, sizeof(buffer));


  gnutls_bye (session, GNUTLS_SHUT_RDWR);
  printf("%d\n", verification_result);
end:

  close(sd);
  gnutls_deinit (session);

  gnutls_certificate_free_credentials (xcred);

  gnutls_global_deinit ();

  return 0;
}
PresentationServer::PresentationServer(const std::string & conferenceUrl,
		const std::string & managerHost, unsigned short managerPort,
		int screenWidth, int screenHeight,
		const std::string & caCertificate,
		const std::string & managerPath, const std::string & managerParam) :
_server(0), _fps(5) {

	if (caCertificate.empty()) {
		throw std::invalid_argument("no CA Certificate provided!");
	}
	//Erstmal d�rfte jetzt die Authorisierung und die Anfrage an den Manager geschehen
	//Dazu einfach �ber nen Socket ne primitive http anfrage senden und die Antwort auswerten
	//Achtung momentan ist BUF_SIZE auch die maximale Nachrichtengr��e die Empfangen werden kann!!
	//@TODO Dringend ne bessere HTTP Implementation verwenden oder selber bauen.
	const int BUF_SIZE = 2048;
	char tmpBuffer[BUF_SIZE];
	SOCKET httpSocket = rfbConnectToTcpAddr(const_cast<char*> (managerHost.c_str()), managerPort);
	std::string httpResponse;
	if (httpSocket == INVALID_SOCKET) {
		std::cerr << "Failed to connect to " << managerHost << ":" << managerPort << std::endl;
		throw std::runtime_error(STR_ERR_WEBHOST_UNREACHABLE);
		return;
	}

	//HTTPS Verbindung mit GnuTLS und handkodierter HTTP Nachricht :)
	gnutls_session_t session = 0;
	gnutls_certificate_credentials_t credentials = 0;
	gnutls_datum_t data;
	int gtlsRet = GNUTLS_E_SUCCESS;
	try {
		//Zertifikat
		if (GNUTLS_E_SUCCESS != (gtlsRet = gnutls_certificate_allocate_credentials(&credentials))) {
			std::cerr << "failed to allocate credentials." << std::endl;
			throw std::runtime_error("failed to allocate credentials.");
		}

		data.size = caCertificate.size();
		data.data = (unsigned char*) caCertificate.data();
		gnutls_certificate_set_x509_trust_mem(credentials, &data, GNUTLS_X509_FMT_PEM);
		
		// Verifizierung des Zertifikats in der übergebenen Callback Funktion, Ausführung erfolgt als Teil des Handshakes
		gnutls_certificate_set_verify_function(credentials, [] (gnutls_session_t session) throw () -> int {
			std::cout << "verifying certificate...";
			//Server Zertifikat prüfen:
			unsigned int verify = 0;
			if (GNUTLS_E_SUCCESS != gnutls_certificate_verify_peers3(session, (const char*) gnutls_session_get_ptr(session), &verify)) {
				std::cerr << "certficate verification failed." << std::endl;
				return -1;
			}
			if (verify != 0) {
				gnutls_datum_t pr;
				std::cout << "no" << std::endl;
				gnutls_certificate_verification_status_print(verify, GNUTLS_CRT_X509, &pr, 0);
				std::cerr << pr.data << std::endl;
				free(pr.data);
				return -2;
			}
			std::cout << "yes" << std::endl;
			return 0;
		});
		//Session
		if (GNUTLS_E_SUCCESS != (gtlsRet = gnutls_init(&session, GNUTLS_CLIENT))) {
			std::cerr << "failed to init session." << std::endl;
			throw std::runtime_error("failed to init session.");
		}

		gnutls_server_name_set(session, GNUTLS_NAME_DNS, managerHost.data(), managerHost.length());
		gnutls_session_set_ptr(session, (void*) managerHost.c_str());

		if (GNUTLS_E_SUCCESS != (gtlsRet = gnutls_priority_set_direct(session, CIPHERSUITE_PRIORITIES, 0))) {
			std::cerr << "failed to set priority." << std::endl;
			throw std::runtime_error("failed to set priority.");
		}

		gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, credentials);
		gnutls_transport_set_int(session, httpSocket);
		gnutls_handshake_set_timeout(session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
		if (GNUTLS_E_SUCCESS != ((gtlsRet = gnutls_handshake(session)))) {
			std::cerr << "handshake failed." << std::endl;
			throw std::runtime_error("handshake failed.");
		}

		//Ciphersuite 
		std::cout << "ciphersuite: " << gnutls_cipher_suite_get_name(gnutls_kx_get(session), gnutls_cipher_get(session), gnutls_mac_get(session)) << std::endl;
		//Prepare HTTP Request
		std::string httpRequest;
		std::string httpRequestBody = managerParam + "=" + urlencode(conferenceUrl) + "&version=" + std::to_string(TOOL_VERSION);
		httpRequest += "POST ";
		httpRequest += managerPath;
		httpRequest += " HTTP/1.1\r\n";
		httpRequest += "Host: ";
		httpRequest += managerHost + "\r\n";
		httpRequest += "Content-Type: application/x-www-form-urlencoded\r\n"; //< Beachte der Webserver kann auf der Zielroute momentan auch nichts anderes
		httpRequest += "Connection: close\r\n";
		sprintf(tmpBuffer, "%d", httpRequestBody.length());
		httpRequest += "Content-Length: " + std::string(tmpBuffer) + "\r\n";
		httpRequest += "\r\n";
		httpRequest += httpRequestBody;

		std::cout << "SEND >>" << std::endl << httpRequest << std::endl << "<<" << std::endl;

		gnutls_record_send(session, httpRequest.data(), httpRequest.length());

		std::cout << "WAITING TO RECEIVE.." << std::endl;
		//Alles lesen und hoffen dass sich der Webserver dran h�lt und die Verbindung schlie�t
		//wenn er fertig mit Senden ist
		int c = 0, r = 0;

		do {
			r = gnutls_record_recv(session, tmpBuffer + c, BUF_SIZE - c);
			if (r > 0) c += r;
		} while (r > 0 && c < BUF_SIZE);

		if (c > 1024 || c <= 0) {
			std::cout << "received " << c << " bytes" << std::endl;
			std::cout << std::string(tmpBuffer, c) << std::endl;
			std::cerr << "Couldn't receive answer." << std::endl;
			throw std::runtime_error(STR_ERR_WRONG_ANSWER);
		}

		httpResponse = std::string(tmpBuffer, c);

		//Und fertig Verbindung beenden
		gnutls_bye(session, GNUTLS_SHUT_RDWR);
		gnutls_deinit(session);
		gnutls_certificate_free_credentials(credentials);
		closesocket(httpSocket);
	} catch (...) {
		//Irgendein Fehler trat auf, dann schließen.
		std::cerr << gtlsRet << ' ' << gnutls_error_is_fatal(gtlsRet) << std::endl;
		std::cerr << gnutls_strerror(gtlsRet) << std::endl;
		std::cerr << gnutls_alert_get_name(gnutls_alert_get(session)) << std::endl;
		if (session) gnutls_deinit(session);
		if (credentials) gnutls_certificate_free_credentials(credentials);
		closesocket(httpSocket);
		throw std::runtime_error(STR_ERR_TLS_FAILED); //weiterschmeißen
	}
	std::cout << "RECV >>" << std::endl << httpResponse << std::endl << "<<" << std::endl;
	/**
		Antwort sollte jetzt der typische HTTP Antwortquark sein und als Inhalt
		sollte ein Text der folgenden Form sein:

		PresentationServerUseHost: <host>\n
		PresentationServerUsePort: <port>\n
	 */
	unsigned short port;
	std::string host;
	int lifetime;

	try {
		_messageBox = utf8_to_ucs2(getParameter(httpResponse, "MessageBox", ""));
		port = atoi(getParameter(httpResponse, "PresentationServerUsePort").c_str());
		host = getParameter(httpResponse, "PresentationServerUseHost");
		_demo = atoi(getParameter(httpResponse, "Demo", "0").c_str()) ? true : false;
		lifetime = atoi(getParameter(httpResponse, "RuntimeSec", "0").c_str());
		_serverPassword = getParameter(httpResponse, "PresentationServerPassword");
	} catch (std::runtime_error e) {
		if (!_messageBox.empty())
			throw runtime_error_with_extra_msg(_messageBox, getParameter(httpResponse, "Message"));
		throw std::runtime_error(getParameter(httpResponse, "Message"));
	}

	//Wenn die erfolgreich war dann den Server erstellen, Gr��e = Desktopgr��e
	_initRfbServer(screenWidth, screenHeight, _serverPassword, managerHost, caCertificate, host, port);

	if (lifetime > 0) {
		_timeOfDeath = std::chrono::system_clock::now() + std::chrono::seconds(lifetime);
		_useTimeOfDeath = true;
	} else {
		_useTimeOfDeath = false;
	}
}
rfbNewClientAction upgradeNewClientToTls (_rfbClientRec* cl) {
	//Eine SSL Session beginnen
	gnutls_session_t session = 0;
	gnutls_certificate_credentials_t credentials = 0;
	gnutls_datum_t data;
	int gtlsRet = GNUTLS_E_SUCCESS;
	std::cout<<"New Client Connection, upgrade protocol to Tls"<<std::endl;
	try {
		//Zertifikat
		if (GNUTLS_E_SUCCESS != (gtlsRet = gnutls_certificate_allocate_credentials(&credentials))) {
			std::cerr << "failed to allocate credentials." << std::endl;
			throw std::runtime_error("failed to allocate credentials.");
		}

		data.size = g_caCertificate.size();
		data.data = (unsigned char*) g_caCertificate.data();
		gnutls_certificate_set_x509_trust_mem(credentials, &data, GNUTLS_X509_FMT_PEM);

		// Verifizierung des Zertifikats in der übergebenen Callback Funktion, Ausführung erfolgt als Teil des Handshakes
		gnutls_certificate_set_verify_function(credentials, [] (gnutls_session_t session) throw () -> int {
			std::cout << "verifying certificate...";
			//Server Zertifikat prüfen:
			unsigned int verify = 0;
			if (GNUTLS_E_SUCCESS != gnutls_certificate_verify_peers3(session, (const char*) gnutls_session_get_ptr(session), &verify)) {
				std::cerr << "certficate verification failed." << std::endl;
				return -1;
			}
			if (verify != 0) {
				gnutls_datum_t pr;
				std::cout << "no" << std::endl;
				gnutls_certificate_verification_status_print(verify, GNUTLS_CRT_X509, &pr, 0);
				std::cerr << pr.data << std::endl;
				free(pr.data);
				return -2;
			}
			std::cout << "yes" << std::endl;
			return 0;
		});
		//Session
		if (GNUTLS_E_SUCCESS != (gtlsRet = gnutls_init(&session, GNUTLS_CLIENT))) {
			std::cerr << "failed to init session." << std::endl;
			throw std::runtime_error("failed to init session.");
		}

		gnutls_server_name_set(session, GNUTLS_NAME_DNS, g_peerHostName.data(), g_peerHostName.length());
		gnutls_session_set_ptr(session, (void*) g_peerHostName.c_str());

		if (GNUTLS_E_SUCCESS != (gtlsRet = gnutls_priority_set_direct(session, CIPHERSUITE_PRIORITIES, 0))) {
			std::cerr << "failed to set priority." << std::endl;
			throw std::runtime_error("failed to set priority.");
		}

		gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, credentials);
		gnutls_transport_set_int(session, cl->sock);
		gnutls_handshake_set_timeout(session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
		if (GNUTLS_E_SUCCESS != ((gtlsRet = gnutls_handshake(session)))) {
			std::cerr << "handshake failed." << std::endl;
			throw std::runtime_error("handshake failed.");
		}

		//Ciphersuite 
		std::cout << "ciphersuite: " << gnutls_cipher_suite_get_name(gnutls_kx_get(session), gnutls_cipher_get(session), gnutls_mac_get(session)) << std::endl;

		//Send password, which was received in answer of webserver
		if ((gtlsRet = gnutls_record_send(session, (void*)g_serverPassword.data(), g_serverPassword.size())) <= 0) {
			std::cerr << "Sending Password failed." << std::endl;
			throw std::runtime_error("Sending Password failed.");
		}

		rfbssl_ctx* ctx = (rfbssl_ctx*) malloc(sizeof(struct rfbssl_ctx));
		ctx->peeklen = 0;
		ctx->peekstart = 0;
		ctx->session = session;
		ctx->x509_cred = credentials;
		ctx->dh_params = 0;
		
		cl->sslctx = (rfbSslCtx*)ctx;
	} catch (...) {
		//Irgendein Fehler trat auf, dann schließen.
		std::cerr << gtlsRet << ' ' << gnutls_error_is_fatal(gtlsRet) << std::endl;
		std::cerr << gnutls_strerror(gtlsRet) << std::endl;
		std::cerr << gnutls_alert_get_name(gnutls_alert_get(session)) << std::endl;
		if (session) gnutls_deinit(session);
		if (credentials) gnutls_certificate_free_credentials(credentials);
		
		return RFB_CLIENT_REFUSE;
	}
	
	return RFB_CLIENT_ACCEPT;
}
示例#16
0
/* Returns true if resumed */
static unsigned handshake(const char *prio, unsigned t, const gnutls_datum_t *sdata,
			  gnutls_datum_t *ndata,
			  gnutls_datum_t *skey,
			  struct hsk_st *h)
{
	int ret;
	/* Server stuff. */
	gnutls_certificate_credentials_t serverx509cred;
	gnutls_session_t server;
	int sret = GNUTLS_E_AGAIN;
	/* Client stuff. */
	gnutls_certificate_credentials_t clientx509cred;
	gnutls_session_t client;
	int cret = GNUTLS_E_AGAIN;
	char buf[128];

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

	assert(gnutls_certificate_allocate_credentials(&serverx509cred)>=0);
	assert(gnutls_certificate_set_x509_key_mem(serverx509cred,
					    &server_cert, &server_key,
					    GNUTLS_X509_FMT_PEM)>=0);

	assert(gnutls_init(&server, GNUTLS_SERVER)>=0);
	gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE,
				serverx509cred);
	assert(gnutls_priority_set_direct(server, prio, NULL)>=0);
	gnutls_transport_set_push_function(server, server_push);
	gnutls_transport_set_pull_function(server, server_pull);
	gnutls_transport_set_ptr(server, server);
	gnutls_session_set_ptr(server, h);

	gnutls_db_set_cache_expiration(server, t);
	assert(gnutls_session_ticket_enable_server(server, skey) >= 0);

	gnutls_handshake_set_hook_function(server, -1,
					   GNUTLS_HOOK_POST,
					   handshake_callback);

	assert(gnutls_certificate_allocate_credentials(&clientx509cred)>=0);
	assert(gnutls_certificate_set_x509_trust_mem(clientx509cred, &ca_cert, GNUTLS_X509_FMT_PEM)>=0);
	assert(gnutls_init(&client, GNUTLS_CLIENT)>=0);

	assert(gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE,
				      clientx509cred)>=0);

	assert(gnutls_priority_set_direct(client, prio, NULL)>=0);
	gnutls_transport_set_push_function(client, client_push);
	gnutls_transport_set_pull_function(client, client_pull);
	gnutls_transport_set_ptr(client, client);

	if (sdata) {
		assert(gnutls_session_set_data(client, sdata->data, sdata->size)>=0);
	}

	memset(buf, 0, sizeof(buf));
	ret = gnutls_session_set_data(client, buf, sizeof(buf));
	if (ret != GNUTLS_E_DB_ERROR) {
		fail("unexpected error: %s\n", gnutls_strerror(ret));
	}

	HANDSHAKE(client, server);

	gnutls_record_recv(client, buf, sizeof(buf));

	if (ndata) {
		ret = gnutls_session_get_data2(client, ndata);
		if (ret < 0) {
			fail("unexpected error: %s\n", gnutls_strerror(ret));
		}
	}

	ret = gnutls_session_is_resumed(client);

	gnutls_deinit(server);
	gnutls_deinit(client);

	gnutls_certificate_free_credentials(serverx509cred);
	gnutls_certificate_free_credentials(clientx509cred);

	reset_buffers();
	return ret;
}
示例#17
0
void TLSClient::connect (const std::string& host, const std::string& port)
{
  // Store the host name, so the verification callback can access it during the
  // handshake below.
  gnutls_session_set_ptr (_session, (void*) host.c_str ());

  // use IPv4 or IPv6, does not matter.
  struct addrinfo hints = {0};
  hints.ai_family   = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_flags    = AI_PASSIVE; // use my IP

  struct addrinfo* res;
  if (::getaddrinfo (host.c_str (), port.c_str (), &hints, &res) != 0)
    throw std::string (::gai_strerror (errno));

  // Try them all, stop on success.
  struct addrinfo* p;
  for (p = res; p != NULL; p = p->ai_next)
  {
    if ((_socket = ::socket (p->ai_family, p->ai_socktype, p->ai_protocol)) == -1)
      continue;

    // When a socket is closed, it remains unavailable for a while (netstat -an).
    // Setting SO_REUSEADDR allows this program to assume control of a closed,
    // but unavailable socket.
    int on = 1;
    if (::setsockopt (_socket,
                      SOL_SOCKET,
                      SO_REUSEADDR,
                      (const void*) &on,
                      sizeof (on)) == -1)
      throw std::string (::strerror (errno));

    if (::connect (_socket, p->ai_addr, p->ai_addrlen) == -1)
      continue;

    break;
  }

  free (res);

  if (p == NULL)
    throw std::string ("Could not connect to ") + host + " " + port;

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

  // Perform the TLS handshake
  int ret;
  do
  {
    ret = gnutls_handshake (_session);
  }
  while (ret < 0 && gnutls_error_is_fatal (ret) == 0);
  if (ret < 0)
    throw std::string ("Handshake failed.  ") + gnutls_strerror (ret);

  if (_debug)
  {
#if GNUTLS_VERSION_NUMBER >= 0x03010a
    char* desc = gnutls_session_get_desc (_session);
    std::cout << "c: INFO Handshake was completed: " << desc << "\n";
    gnutls_free (desc);
#else
    std::cout << "c: INFO Handshake was completed.\n";
#endif
  }
}
void session::set_user_ptr (void *ptr)
{
    gnutls_session_set_ptr (s, ptr);
}
示例#19
0
static int setup_dtls_connection(struct worker_st *ws)
{
	int ret;
	gnutls_session_t session;
	gnutls_datum_t master =
	    { ws->master_secret, sizeof(ws->master_secret) };
	gnutls_datum_t sid = { ws->session_id, sizeof(ws->session_id) };

	if (ws->req.selected_ciphersuite == NULL) {
		oclog(ws, LOG_ERR, "no DTLS ciphersuite negotiated");
		return -1;
	}

	oclog(ws, LOG_DEBUG, "setting up DTLS connection");
	/* DTLS cookie verified.
	 * Initialize session.
	 */
	ret = gnutls_init(&session, GNUTLS_SERVER|GNUTLS_DATAGRAM|GNUTLS_NONBLOCK);
	if (ret < 0) {
		oclog(ws, LOG_ERR, "could not initialize TLS session: %s",
		      gnutls_strerror(ret));
		return -1;
	}

	ret =
	    gnutls_priority_set_direct(session,
				       ws->req.
				       selected_ciphersuite->gnutls_name, NULL);
	if (ret < 0) {
		oclog(ws, LOG_ERR, "could not set TLS priority: %s",
		      gnutls_strerror(ret));
		goto fail;
	}

	ret = gnutls_session_set_premaster(session, GNUTLS_SERVER,
					   ws->req.
					   selected_ciphersuite->gnutls_version,
					   GNUTLS_KX_RSA,
					   ws->req.
					   selected_ciphersuite->gnutls_cipher,
					   ws->req.
					   selected_ciphersuite->gnutls_mac,
					   GNUTLS_COMP_NULL, &master, &sid);
	if (ret < 0) {
		oclog(ws, LOG_ERR, "could not set TLS premaster: %s",
		      gnutls_strerror(ret));
		goto fail;
	}

	ret =
	    gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
				   ws->creds->xcred);
	if (ret < 0) {
		oclog(ws, LOG_ERR, "could not set TLS credentials: %s",
		      gnutls_strerror(ret));
		goto fail;
	}

	gnutls_transport_set_push_function(session, dtls_push);
	gnutls_transport_set_pull_function(session, dtls_pull);
	gnutls_transport_set_pull_timeout_function(session, dtls_pull_timeout);
	gnutls_transport_set_ptr(session, &ws->dtls_tptr);

	gnutls_session_set_ptr(session, ws);
	gnutls_certificate_server_set_request(session, GNUTLS_CERT_IGNORE);

	gnutls_handshake_set_timeout(session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);

	ws->udp_state = UP_HANDSHAKE;

	ws->dtls_session = session;

	return 0;
 fail:
	gnutls_deinit(session);
	return -1;
}
示例#20
0
mref_err_t mref_fetch_handle(struct mref *m, FILE *h, const char *me) {
    char *mhsh, *rhsh, *store;
    gnutls_session_t sess;
    gnutls_anon_client_credentials_t cred;
    int fd = fileno(h);
    int err, i, store_good;
    unsigned char h_mref[32], h_calc[32];
    gcry_md_hd_t ghd;
    size_t mhsh_len, ns_len, rhsh_len, store_len;

    if (!mref_split(m)) return MREF_ERR_NOT_FIELDS;

    store = mref_field_alloc(m, MREF_FLD_STORE);
    if (!store) return MREF_ERR_NOMEM;
    //printf("store is: %s\n", store);

    mhsh = mref_field_alloc(m, MREF_FLD_MESSAGE_HASH);
    if (!mhsh) return MREF_ERR_NOMEM;
    _mref_b64dec(h_mref, mhsh, mref_field_length(m, MREF_FLD_MESSAGE_HASH));
    //printf("mhsh is: %s\n", mhsh);

    rhsh = mref_field_alloc(m, MREF_FLD_MREF_HASH);
    rhsh_len = mref_field_length(m, MREF_FLD_MREF_HASH);
    if (!rhsh) return MREF_ERR_NOMEM;
    //printf("rhsh is: %s\n", rhsh);

    /*
       err = gnutls_global_init();
       if (err != GNUTLS_E_SUCCESS) return MREF_ERR_TLS(err);
       err = gnutls_init(&sess, GNUTLS_CLIENT);
       if (err != GNUTLS_E_SUCCESS) return MREF_ERR_TLS(err);
       err = gnutls_credentials_set(sess, GNUTLS_CRD_ANON, &cred);
       if (err != GNUTLS_E_SUCCESS) return MREF_ERR_TLS(err);
       */

    /*** from info gnutls ***/

    {
        int ret, sd;
        gnutls_session_t session;
        char buffer[MAX_BUF + 1];
        const char *err;

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

        gnutls_session_set_ptr (session, (void *) store);

        gnutls_server_name_set (session, GNUTLS_NAME_DNS, store, strlen(store));

        /* Use default priorities */
        ret = gnutls_priority_set_direct (session, "NORMAL", &err);
        if (ret < 0)
        {
            if (ret == GNUTLS_E_INVALID_REQUEST)
            {
                fprintf (stderr, "Syntax error at: %s\n", err);
            }
            exit (1);
        }

        /* put the x509 credentials to the current session
        */
        gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, mref_cred());

        /* connect to the peer
        */
        sd = tcp_connect(store);
        if (sd == -1) {
            gnutls_deinit (session);
            return MREF_ERR_CONNECT_FAIL;
        }

        gnutls_transport_set_int (session, sd);
        gnutls_handshake_set_timeout (session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);

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

        if (ret < 0) {
            tcp_close(sd);
            gnutls_deinit(session);
            return MREF_ERR_TLS(ret);
        }

        gnutls_record_send (session, rhsh, rhsh_len);
        //fprintf(stderr, "sent rhsh, %d bytes\n", rhsh_len);

        mref_trace_headers(m, h, sd, me);

        state = st_goodbad;
        ns_len = 0;
        gcry_md_open(&ghd, GCRY_MD_SHA256, 0);
        if (!ghd) return MREF_ERR_GCRYPT;

        while ((ret = gnutls_record_recv (session, buffer, MAX_BUF)) > 0) {
            int i;
            for (i = 0; i < ret; ++i) {

                switch (state) {
                    case st_goodbad:
                        store_good = buffer[i] == '+';
                        ++state;
                        break;
                    case st_count:
                        if (buffer[i] >= '0' && buffer[i] <= '9')
                            ns_len = ns_len * 10 + buffer[i] - '0';
                        else if (buffer[i] == ':') ++state;
                        else return MREF_ERR_STORE_PROTO;
                        break;
                    case st_data:
                        if (store_good) fputc(buffer[i], h);
                        else fputc(buffer[i], stderr);
                        gcry_md_write(ghd, buffer + i, 1);
                        if (--ns_len == 0) ++ state;
                        break;
                    case st_comma:
                        if (buffer[i] == ',') break;
                    case st_toomuch:
                        return MREF_ERR_STORE_PROTO;
                }
            }
        }
        if (ret < 0) {
           if (gnutls_error_is_fatal(ret)) {
               fprintf (stderr, "*** Error: %s\n", gnutls_strerror (ret));
           } else {
               fprintf (stderr, "*** Warning: %s\n", gnutls_strerror (ret));
               gnutls_bye (session, GNUTLS_SHUT_RDWR);
           }
           tcp_close(sd);
           gnutls_deinit (session);
           return MREF_ERR_TLS(ret);
        }

        tcp_close(sd);
        gnutls_deinit (session);

        memcpy(h_calc, gcry_md_read(ghd, 0), 32);
        gcry_md_close(ghd);

        if (memcmp(h_mref, h_calc, 32) != 0) return MREF_ERR_BAD_MSG_HASH;

        if (fflush(h) != 0) return MREF_ERR_SYS;
        if (fsync(fd) != 0) return MREF_ERR_SYS;
        fclose(h); /* cannot fail */

        return 0;
    }
}
示例#21
0
static struct mailstream_ssl_data * ssl_data_new(int fd, void (* callback)(struct mailstream_ssl_context * ssl_context, void * cb_data), void * cb_data)
{
  struct mailstream_ssl_data * ssl_data;
  gnutls_session session;
  struct mailstream_cancel * cancel;
  
  const int cipher_prio[] = { GNUTLS_CIPHER_AES_128_CBC,
		  		GNUTLS_CIPHER_3DES_CBC,
		  		GNUTLS_CIPHER_AES_256_CBC,
		  		GNUTLS_CIPHER_ARCFOUR_128, 0 };
  const int kx_prio[] = { GNUTLS_KX_DHE_RSA,
		  	   GNUTLS_KX_RSA, 
		  	   GNUTLS_KX_DHE_DSS, 0 };
  const int mac_prio[] = { GNUTLS_MAC_SHA1,
		  		GNUTLS_MAC_MD5, 0 };
  const int proto_prio[] = { GNUTLS_TLS1,
		  		  GNUTLS_SSL3, 0 };

  gnutls_certificate_credentials_t xcred;
  int r;
  struct mailstream_ssl_context * ssl_context = NULL;
  
  mailstream_ssl_init();
  
  if (gnutls_certificate_allocate_credentials (&xcred) != 0)
    return NULL;

  r = gnutls_init(&session, GNUTLS_CLIENT);
  if (session == NULL || r != 0)
    return NULL;
  
  if (callback != NULL) {
    ssl_context = mailstream_ssl_context_new(session, fd);
    callback(ssl_context, cb_data);
  }
  
  gnutls_session_set_ptr(session, ssl_context);
  gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);
  gnutls_certificate_client_set_retrieve_function(xcred, mailstream_gnutls_client_cert_cb);

  gnutls_set_default_priority(session);
  gnutls_protocol_set_priority (session, proto_prio);
  gnutls_cipher_set_priority (session, cipher_prio);
  gnutls_kx_set_priority (session, kx_prio);
  gnutls_mac_set_priority (session, mac_prio);
  gnutls_record_disable_padding(session);
  gnutls_dh_set_prime_bits(session, 512);

  gnutls_transport_set_ptr(session, (gnutls_transport_ptr) fd);

  /* lower limits on server key length restriction */
  gnutls_dh_set_prime_bits(session, 512);
  
  do {
    r = gnutls_handshake(session);
  } while (r == GNUTLS_E_AGAIN || r == GNUTLS_E_INTERRUPTED);

  if (r < 0) {
    gnutls_perror(r);
    goto free_ssl_conn;
  }
  
  cancel = mailstream_cancel_new();
  if (cancel == NULL)
    goto free_ssl_conn;
  
  r = mailstream_prepare_fd(fd);
  if (r < 0)
    goto free_cancel;
  
  ssl_data = malloc(sizeof(* ssl_data));
  if (ssl_data == NULL)
    goto err;
  
  ssl_data->fd = fd;
  ssl_data->session = session;
  ssl_data->xcred = xcred;
  ssl_data->cancel = cancel;
  
  mailstream_ssl_context_free(ssl_context);

  return ssl_data;
  
 free_cancel:
  mailstream_cancel_free(cancel);
 free_ssl_conn:
  gnutls_certificate_free_credentials(xcred);
  mailstream_ssl_context_free(ssl_context);
  gnutls_deinit(session);
 err:
  return NULL;
}
示例#22
0
int main (void)
{
  int ret, sd, ii;
  gnutls_session_t session;
  char buffer[MAX_BUF + 1];
  const char *err;
  gnutls_certificate_credentials_t xcred;

  gnutls_global_init ();

  /* X509 stuff */
  gnutls_certificate_allocate_credentials (&xcred);

  /* sets the trusted cas file
   */
  gnutls_certificate_set_x509_trust_file (xcred, CAFILE, GNUTLS_X509_FMT_PEM);
  gnutls_certificate_set_verify_function (xcred, _verify_certificate_callback);

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

  gnutls_session_set_ptr (session, (void *) "my_host_name");

  /* Use default priorities */
  ret = gnutls_priority_set_direct (session, "NORMAL", &err);
  if (ret < 0)
    {
      if (ret == GNUTLS_E_INVALID_REQUEST)
        {
          fprintf (stderr, "Syntax error at: %s\n", err);
        }
      exit (1);
    }

  /* put the x509 credentials to the current session
   */
  gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);

  /* connect to the peer
   */
  sd = tcp_connect ();

  gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd);

  /* Perform the TLS handshake
   */
  ret = gnutls_handshake (session);

  if (ret < 0)
    {
      fprintf (stderr, "*** Handshake failed\n");
      gnutls_perror (ret);
      goto end;
    }
  else
    {
      printf ("- Handshake was completed\n");
    }

  gnutls_record_send (session, MSG, strlen (MSG));

  ret = gnutls_record_recv (session, buffer, MAX_BUF);
  if (ret == 0)
    {
      printf ("- Peer has closed the TLS connection\n");
      goto end;
    }
  else if (ret < 0)
    {
      fprintf (stderr, "*** Error: %s\n", gnutls_strerror (ret));
      goto end;
    }

  printf ("- Received %d bytes: ", ret);
  for (ii = 0; ii < ret; ii++)
    {
      fputc (buffer[ii], stdout);
    }
  fputs ("\n", stdout);

  gnutls_bye (session, GNUTLS_SHUT_RDWR);

end:

  tcp_close (sd);

  gnutls_deinit (session);

  gnutls_certificate_free_credentials (xcred);

  gnutls_global_deinit ();

  return 0;
}
示例#23
0
void TLSClient::connect (const std::string& host, const std::string& port)
{
  _host = host;
  _port = port;

  // Store the TLSClient instance, so that the verification callback can access
  // it during the handshake below and call the verifcation method.
  gnutls_session_set_ptr (_session, (void*) this);

  // use IPv4 or IPv6, does not matter.
  struct addrinfo hints {};
  hints.ai_family   = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_flags    = AI_PASSIVE; // use my IP

  struct addrinfo* res;
  int ret = ::getaddrinfo (host.c_str (), port.c_str (), &hints, &res);
  if (ret != 0)
    throw std::string (::gai_strerror (ret));

  // Try them all, stop on success.
  struct addrinfo* p;
  for (p = res; p != NULL; p = p->ai_next)
  {
    if ((_socket = ::socket (p->ai_family, p->ai_socktype, p->ai_protocol)) == -1)
      continue;

    // When a socket is closed, it remains unavailable for a while (netstat -an).
    // Setting SO_REUSEADDR allows this program to assume control of a closed,
    // but unavailable socket.
    int on = 1;
    if (::setsockopt (_socket,
                      SOL_SOCKET,
                      SO_REUSEADDR,
                      (const void*) &on,
                      sizeof (on)) == -1)
      throw std::string (::strerror (errno));

    if (::connect (_socket, p->ai_addr, p->ai_addrlen) == -1)
      continue;

    break;
  }

  free (res);

  if (p == NULL)
    throw format (STRING_CMD_SYNC_CONNECT, host, port);

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

  // Perform the TLS handshake
  do
  {
    ret = gnutls_handshake (_session);
  }
  while (ret < 0 && gnutls_error_is_fatal (ret) == 0);
  if (ret < 0)
    throw format (STRING_CMD_SYNC_HANDSHAKE, gnutls_strerror (ret));

#if GNUTLS_VERSION_NUMBER < 0x02090a
  // The automatic verification for the server certificate with
  // gnutls_certificate_set_verify_function does only work with gnutls
  // >=2.9.10. So with older versions we should call the verify function
  // manually after the gnutls handshake.
  ret = verify_certificate ();
  if (ret < 0)
  {
    if (_debug)
      std::cout << "c: ERROR Certificate verification failed.\n";
    throw format (STRING_TLS_INIT_FAIL, gnutls_strerror (ret));
  }
#endif

  if (_debug)
  {
#if GNUTLS_VERSION_NUMBER >= 0x03010a
    char* desc = gnutls_session_get_desc (_session);
    std::cout << "c: INFO Handshake was completed: " << desc << "\n";
    gnutls_free (desc);
#else
    std::cout << "c: INFO Handshake was completed.\n";
#endif
  }
}
示例#24
0
int ne_sock_connect_ssl(ne_socket *sock, ne_ssl_context *ctx, void *userdata)
{
    int ret;

#if defined(HAVE_OPENSSL)
    SSL *ssl;

    if (seed_ssl_prng()) {
	set_error(sock, _("SSL disabled due to lack of entropy"));
	return NE_SOCK_ERROR;
    }

    /* If runtime library version differs from compile-time version
     * number in major/minor/fix level, abort soon. */
    if ((SSLeay() ^ OPENSSL_VERSION_NUMBER) & 0xFFFFF000) {
        set_error(sock, _("SSL disabled due to library version mismatch"));
        return NE_SOCK_ERROR;
    }

    sock->ssl = ssl = SSL_new(ctx->ctx);
    if (!ssl) {
	set_error(sock, _("Could not create SSL structure"));
	return NE_SOCK_ERROR;
    }
    
    SSL_set_app_data(ssl, userdata);
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
    SSL_set_fd(ssl, sock->fd);
    sock->ops = &iofns_ssl;
    
    if (ctx->sess)
	SSL_set_session(ssl, ctx->sess);

    ret = SSL_connect(ssl);
    if (ret != 1) {
	error_ossl(sock, ret);
	SSL_free(ssl);
	sock->ssl = NULL;
	return NE_SOCK_ERROR;
    }
#elif defined(HAVE_GNUTLS)
    /* DH and RSA params are set in ne_ssl_context_create */
    gnutls_init(&sock->ssl, GNUTLS_CLIENT);
    gnutls_set_default_priority(sock->ssl);
    gnutls_session_set_ptr(sock->ssl, userdata);
    gnutls_credentials_set(sock->ssl, GNUTLS_CRD_CERTIFICATE, ctx->cred);

    gnutls_transport_set_ptr(sock->ssl, (gnutls_transport_ptr) sock->fd);

    if (ctx->cache.client.data) {
#if defined(HAVE_GNUTLS_SESSION_GET_DATA2)
        gnutls_session_set_data(sock->ssl, 
                                ctx->cache.client.data, 
                                ctx->cache.client.size);
#else
        gnutls_session_set_data(sock->ssl, 
                                ctx->cache.client.data, 
                                ctx->cache.client.len);
#endif
    }
    sock->ops = &iofns_ssl;

    ret = gnutls_handshake(sock->ssl);
    if (ret < 0) {
	error_gnutls(sock, ret);
        return NE_SOCK_ERROR;
    }

    if (!gnutls_session_is_resumed(sock->ssl)) {
        /* New session.  The old method of using the _get_data
         * function seems to be broken with 1.3.0 and later*/
#if defined(HAVE_GNUTLS_SESSION_GET_DATA2)
        gnutls_session_get_data2(sock->ssl, &ctx->cache.client);
#else
        ctx->cache.client.len = 0;
        if (gnutls_session_get_data(sock->ssl, NULL, 
                                    &ctx->cache.client.len) == 0) {
            ctx->cache.client.data = ne_malloc(ctx->cache.client.len);
            gnutls_session_get_data(sock->ssl, ctx->cache.client.data, 
                                    &ctx->cache.client.len);
        }
#endif
    }
#endif
    return 0;
}
示例#25
0
文件: dtls_gnutls.c 项目: 7u83/actube
struct dtls_gnutls_data *dtls_gnutls_data_create(struct conn *conn,int config)
{
	const char *errpos;
	int rc;
	gnutls_datum_t key;
	int bits;
	struct dtls_gnutls_data *d = malloc(sizeof(struct dtls_gnutls_data));
	if (!d)
		return 0;

	gnutls_global_set_log_level(10);
	gnutls_global_set_log_function(dtls_log_cb);
	
	rc = gnutls_init(&d->session, config); 
	if (rc < 0) {
		cw_log(LOG_ERR, "DTLS - Can't init session: %s", gnutls_strerror(rc));
		dtls_gnutls_data_destroy(d);
		return 0;
	}


	gnutls_certificate_allocate_credentials(&d->x509_cred);




	/* Set credentials */

	if (conn->dtls_cert_file && conn->dtls_key_file){

		rc = gnutls_certificate_set_x509_key_file(d->x509_cred, conn->dtls_cert_file,
							  conn->dtls_key_file, GNUTLS_X509_FMT_PEM);

		if (rc < 0) {
			cw_log(LOG_ERR, "DTLS - Can't set cert/key: %s", gnutls_strerror(rc));
			dtls_gnutls_data_destroy(d);
			return 0;
		}
	}



/*
#if GNUTLS_VERSION_NUMBER >= 0x030100
	bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_INSECURE);
#else
*/	bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LEGACY);
/*#endif*/






	/* Set ciphers */
/*
	rc = gnutls_priority_init(&d->priority_cache, conn->dtls_cipher, &errpos);
	if (rc < 0) {
		cw_log(LOG_ERR, "DTLS - Can't init ciphers '%s' at '%s' : %s", conn->dtls_cipher,
		       errpos, gnutls_strerror(rc));
		dtls_gnutls_data_destroy(d);
		return 0;
	}


	rc = gnutls_priority_set(d->session, d->priority_cache);
	if (rc < 0) {
		cw_log(LOG_ERR, "DTLS - Can't set priority: %s", gnutls_strerror(rc));
		dtls_gnutls_data_destroy(d);
		return 0;
	}

*/
	rc = gnutls_priority_set_direct(d->session,conn->dtls_cipher,&errpos);
	if (rc < 0) {
		cw_log(LOG_ERR, "DTLS - Can't init ciphers '%s' at '%s' : %s", conn->dtls_cipher,
		       errpos, gnutls_strerror(rc));
		dtls_gnutls_data_destroy(d);
		return 0;
	}

	


	rc = gnutls_credentials_set(d->session, GNUTLS_CRD_CERTIFICATE, d->x509_cred);
	if (rc < 0) {
		cw_log(LOG_ERR, "DTLS - Can't set x.509 credentials: %s", gnutls_strerror(rc));
		dtls_gnutls_data_destroy(d);
		return 0;
	}

	gnutls_certificate_set_verify_function(d->x509_cred,verify_cert);
	gnutls_session_set_ptr(d->session, conn);
	gnutls_transport_set_ptr(d->session, conn);
	gnutls_transport_set_pull_function(d->session, dtls_gnutls_bio_read);
	gnutls_transport_set_push_function(d->session, dtls_gnutls_bio_write);
	gnutls_transport_set_pull_timeout_function(d->session, dtls_gnutls_bio_wait);


#if GNUTLS_VERSION_NUMBER >= 0x030100
	gnutls_handshake_set_timeout(d->session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
	gnutls_dtls_set_data_mtu(d->session, conn->dtls_mtu);
#endif
	gnutls_dtls_set_mtu(d->session, conn->dtls_mtu);




	return d;
}
示例#26
0
文件: gnutls.c 项目: tsdmgz/inadyn
int ssl_open(http_t *client, char *msg)
{
	int ret;
	char buf[256];
	size_t len;
	const char *sn, *err;
	const gnutls_datum_t *cert_list;
	unsigned int cert_list_size = 0;
	gnutls_x509_crt_t cert;

	if (!client->ssl_enabled)
		return tcp_init(&client->tcp, msg);

	/* Initialize TLS session */
	logit(LOG_INFO, "%s, initiating HTTPS ...", msg);
	gnutls_init(&client->ssl, GNUTLS_CLIENT);

	/* SSL SNI support: tell the servername we want to speak to */
	http_get_remote_name(client, &sn);
	gnutls_session_set_ptr(client->ssl, (void *)sn);
	if (gnutls_server_name_set(client->ssl, GNUTLS_NAME_DNS, sn, strlen(sn)))
		return RC_HTTPS_SNI_ERROR;

	/* Use default priorities */
	ret = gnutls_priority_set_direct(client->ssl, "NORMAL", &err);
	if (ret < 0) {
		if (ret == GNUTLS_E_INVALID_REQUEST)
			logit(LOG_ERR, "Syntax error at: %s", err);

		return RC_HTTPS_INVALID_REQUEST;
	}

	/* put the x509 credentials to the current session */
	gnutls_credentials_set(client->ssl, GNUTLS_CRD_CERTIFICATE, xcred);

	/* connect to the peer */
	tcp_set_port(&client->tcp, HTTPS_DEFAULT_PORT);
	DO(tcp_init(&client->tcp, msg));

	/* Forward TCP socket to GnuTLS, the set_int() API is perhaps too new still ... since 3.1.9 */
//	gnutls_transport_set_int(client->ssl, client->tcp.ip.socket);
	gnutls_transport_set_ptr(client->ssl, (gnutls_transport_ptr_t)(intptr_t)client->tcp.ip.socket);

	/* Perform the TLS handshake, ignore non-fatal errors. */
	do {
		ret = gnutls_handshake(client->ssl);
	}
	while (ret != 0 && !gnutls_error_is_fatal(ret));

	if (gnutls_error_is_fatal(ret)) {
		logit(LOG_ERR, "SSL handshake with %s failed: %s", sn, gnutls_strerror(ret));
		return RC_HTTPS_FAILED_CONNECT;
	}

	ssl_get_info(client);

	/* Get server's certificate (note: beware of dynamic allocation) - opt */
	cert_list = gnutls_certificate_get_peers(client->ssl, &cert_list_size);
	if (cert_list_size > 0) {
		if (gnutls_x509_crt_init(&cert))
			return RC_HTTPS_FAILED_GETTING_CERT;

		gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER);

		len = sizeof(buf);
		gnutls_x509_crt_get_dn(cert, buf, &len);
		logit(LOG_INFO, "SSL server cert subject: %s", buf);

		len = sizeof(buf);
		gnutls_x509_crt_get_issuer_dn(cert, buf, &len);
		logit(LOG_INFO, "SSL server cert issuer: %s", buf);

		gnutls_x509_crt_deinit(cert);
	}

	return 0;
}
示例#27
0
int main(void)
{
        int ret, sd, ii;
        gnutls_session_t session;
        char buffer[MAX_BUF + 1];
        const char *err;
        gnutls_certificate_credentials_t xcred;

        if (gnutls_check_version("3.1.4") == NULL) {
                fprintf(stderr, "GnuTLS 3.1.4 or later is required for this example\n");
                exit(1);
        }

        /* for backwards compatibility with gnutls < 3.3.0 */
        gnutls_global_init();

        /* X509 stuff */
        gnutls_certificate_allocate_credentials(&xcred);

        /* sets the trusted cas file
         */
        gnutls_certificate_set_x509_trust_file(xcred, CAFILE,
                                               GNUTLS_X509_FMT_PEM);
        gnutls_certificate_set_verify_function(xcred,
                                               _verify_certificate_callback);

        /* If client holds a certificate it can be set using the following:
         *
         gnutls_certificate_set_x509_key_file (xcred, 
         "cert.pem", "key.pem", 
         GNUTLS_X509_FMT_PEM); 
         */

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

        gnutls_session_set_ptr(session, (void *) "my_host_name");

        gnutls_server_name_set(session, GNUTLS_NAME_DNS, "my_host_name",
                               strlen("my_host_name"));

        /* use default priorities */
        gnutls_set_default_priority(session);
#if 0
	/* if more fine-graned control is required */
        ret = gnutls_priority_set_direct(session, 
                                         "NORMAL", &err);
        if (ret < 0) {
                if (ret == GNUTLS_E_INVALID_REQUEST) {
                        fprintf(stderr, "Syntax error at: %s\n", err);
                }
                exit(1);
        }
#endif

        /* put the x509 credentials to the current session
         */
        gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);

        /* connect to the peer
         */
        sd = tcp_connect();

        gnutls_transport_set_int(session, sd);
        gnutls_handshake_set_timeout(session,
                                     GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);

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

        if (ret < 0) {
                fprintf(stderr, "*** Handshake failed\n");
                gnutls_perror(ret);
                goto end;
        } else {
                char *desc;

                desc = gnutls_session_get_desc(session);
                printf("- Session info: %s\n", desc);
                gnutls_free(desc);
        }

        gnutls_record_send(session, MSG, strlen(MSG));

        ret = gnutls_record_recv(session, buffer, MAX_BUF);
        if (ret == 0) {
                printf("- Peer has closed the TLS connection\n");
                goto end;
        } else if (ret < 0 && gnutls_error_is_fatal(ret) == 0) {
                fprintf(stderr, "*** Warning: %s\n", gnutls_strerror(ret));
        } else if (ret < 0) {
                fprintf(stderr, "*** Error: %s\n", gnutls_strerror(ret));
                goto end;
        }

        if (ret > 0) {
                printf("- Received %d bytes: ", ret);
                for (ii = 0; ii < ret; ii++) {
                        fputc(buffer[ii], stdout);
                }
                fputs("\n", stdout);
        }

        gnutls_bye(session, GNUTLS_SHUT_RDWR);

      end:

        tcp_close(sd);

        gnutls_deinit(session);

        gnutls_certificate_free_credentials(xcred);

        gnutls_global_deinit();

        return 0;
}
示例#28
0
 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;
	plist_t pair_record = NULL;

	userpref_read_pair_record(connection->udid, &pair_record);
	if (!pair_record) {
		debug_info("ERROR: Failed enabling SSL. Unable to read pair record for udid %s.", connection->udid);
		return ret;
	}

#ifdef HAVE_OPENSSL
	key_data_t root_cert = { NULL, 0 };
	key_data_t root_privkey = { NULL, 0 };

	pair_record_import_crt_with_name(pair_record, USERPREF_ROOT_CERTIFICATE_KEY, &root_cert);
	pair_record_import_key_with_name(pair_record, USERPREF_ROOT_PRIVATE_KEY_KEY, &root_privkey);

	if (pair_record)
		plist_free(pair_record);
	/* Set up OpenSSL */
	if (openssl_init_done == 0) {
		SSL_library_init();
		openssl_init_done = 1;
	}
	BIO *ssl_bio = BIO_new(BIO_s_socket());
	if (!ssl_bio) {
		debug_info("ERROR: Could not create SSL bio.");
		return ret;
	}
	BIO_set_fd(ssl_bio, (int)(long)connection->data, BIO_NOCLOSE);

	//SSL_CTX *ssl_ctx = SSL_CTX_new(SSLv3_method());
	SSL_CTX *ssl_ctx = SSL_CTX_new(SSLv3_client_method());
	if (ssl_ctx == NULL) {
		debug_info("ERROR: Could not create SSL context.");
		BIO_free(ssl_bio);
		return ret;
	}

	BIO* membp;
	X509* rootCert = NULL;
	membp = BIO_new_mem_buf(root_cert.data, root_cert.size);
	PEM_read_bio_X509(membp, &rootCert, NULL, NULL);
	BIO_free(membp);
	if (SSL_CTX_use_certificate(ssl_ctx, rootCert) != 1) {
		debug_info("WARNING: Could not load RootCertificate");
	}
	X509_free(rootCert);
	free(root_cert.data);

	RSA* rootPrivKey = NULL;
	membp = BIO_new_mem_buf(root_privkey.data, root_privkey.size);
	PEM_read_bio_RSAPrivateKey(membp, &rootPrivKey, NULL, NULL);
	BIO_free(membp);
	if (SSL_CTX_use_RSAPrivateKey(ssl_ctx, rootPrivKey) != 1) {
		debug_info("WARNING: Could not load RootPrivateKey");
	}
	RSA_free(rootPrivKey);
	free(root_privkey.data);

	SSL *ssl = SSL_new(ssl_ctx);
	if (!ssl) {
		debug_info("ERROR: Could not create SSL object");
		BIO_free(ssl_bio);
		SSL_CTX_free(ssl_ctx);
		return ret;
	}
	SSL_set_connect_state(ssl);
	SSL_set_verify(ssl, 0, ssl_verify_callback);
	SSL_set_bio(ssl, ssl_bio, ssl_bio);

	return_me = SSL_do_handshake(ssl);
	if (return_me != 1) {
		debug_info("ERROR in SSL_do_handshake: %s", ssl_error_to_string(SSL_get_error(ssl, return_me)));
		SSL_free(ssl);
		SSL_CTX_free(ssl_ctx);
	} else {
		ssl_data_t ssl_data_loc = (ssl_data_t)malloc(sizeof(struct ssl_data_private));
		ssl_data_loc->session = ssl;
		ssl_data_loc->ctx = ssl_ctx;
		connection->ssl_data = ssl_data_loc;
		ret = IDEVICE_E_SUCCESS;
		debug_info("SSL mode enabled, cipher: %s", SSL_get_cipher(ssl));
	}
	/* required for proper multi-thread clean up to prevent leaks */
#ifdef HAVE_ERR_REMOVE_THREAD_STATE
	ERR_remove_thread_state(NULL);
#else
	ERR_remove_state(0);
#endif
#else
	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_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);

	pair_record_import_crt_with_name(pair_record, USERPREF_ROOT_CERTIFICATE_KEY, ssl_data_loc->root_cert);
	pair_record_import_crt_with_name(pair_record, USERPREF_HOST_CERTIFICATE_KEY, ssl_data_loc->host_cert);
	pair_record_import_key_with_name(pair_record, USERPREF_ROOT_PRIVATE_KEY_KEY, ssl_data_loc->root_privkey);
	pair_record_import_key_with_name(pair_record, USERPREF_HOST_PRIVATE_KEY_KEY, ssl_data_loc->host_privkey);

	if (pair_record)
		plist_free(pair_record);

	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("WARNING: 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");
	}
#endif
	return ret;
}
示例#29
0
static struct mailstream_ssl_data * ssl_data_new(int fd, time_t timeout,
  void (* callback)(struct mailstream_ssl_context * ssl_context, void * cb_data), void * cb_data)
{
  struct mailstream_ssl_data * ssl_data;
  gnutls_session session;
  struct mailstream_cancel * cancel;
  gnutls_certificate_credentials_t xcred;
  int r;
  struct mailstream_ssl_context * ssl_context = NULL;
  
  mailstream_ssl_init();
  
  if (gnutls_certificate_allocate_credentials (&xcred) != 0)
    return NULL;

  r = gnutls_init(&session, GNUTLS_CLIENT);
  if (session == NULL || r != 0)
    return NULL;
  
  if (callback != NULL) {
    ssl_context = mailstream_ssl_context_new(session, fd);
    callback(ssl_context, cb_data);
  }
  
  gnutls_session_set_ptr(session, ssl_context);
  gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);
  gnutls_certificate_client_set_retrieve_function(xcred, mailstream_gnutls_client_cert_cb);

  gnutls_set_default_priority(session);
  gnutls_priority_set_direct(session, "NORMAL", NULL);

  gnutls_record_disable_padding(session);
  gnutls_dh_set_prime_bits(session, 512);

  gnutls_transport_set_ptr(session, (gnutls_transport_ptr) fd);

  /* lower limits on server key length restriction */
  gnutls_dh_set_prime_bits(session, 512);
  
  if (timeout == 0) {
		timeout_value = mailstream_network_delay.tv_sec * 1000 + timeout.tv_usec / 1000;
  }
  else {
		timeout_value = timeout;
  }
	gnutls_handshake_set_timeout(session, timeout_value);

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

  if (r < 0) {
    gnutls_perror(r);
    goto free_ssl_conn;
  }
  
  cancel = mailstream_cancel_new();
  if (cancel == NULL)
    goto free_ssl_conn;
  
  r = mailstream_prepare_fd(fd);
  if (r < 0)
    goto free_cancel;
  
  ssl_data = malloc(sizeof(* ssl_data));
  if (ssl_data == NULL)
    goto err;
  
  ssl_data->fd = fd;
  ssl_data->session = session;
  ssl_data->xcred = xcred;
  ssl_data->cancel = cancel;
  
  mailstream_ssl_context_free(ssl_context);

  return ssl_data;
  
 free_cancel:
  mailstream_cancel_free(cancel);
 free_ssl_conn:
  gnutls_certificate_free_credentials(xcred);
  mailstream_ssl_context_free(ssl_context);
  gnutls_deinit(session);
 err:
  return NULL;
}
示例#30
-1
static void
client (int fd, const char* prio, unsigned int text_size, struct test_st *test)
{
  int ret;
  char buffer[MAX_BUF + 1];
  char text[text_size];
  gnutls_certificate_credentials_t x509_cred;
  gnutls_session_t session;
  struct timespec start, stop;
  static unsigned long taken = 0;
  static unsigned long measurement;
  const char* err;

  global_init ();
  
  setpriority(PRIO_PROCESS, getpid(), -15);
  
  memset(text, 0, text_size);

#ifdef DEBUG
  gnutls_global_set_log_function (client_log_func);
  gnutls_global_set_log_level (6);
#endif

  gnutls_certificate_allocate_credentials (&x509_cred);

#ifdef REHANDSHAKE
restart:
#endif

  /* Initialize TLS session
   */
  gnutls_init (&session, GNUTLS_CLIENT);
  gnutls_session_set_ptr(session, test);
  cli_session = session;

  /* Use default priorities */
  if ((ret=gnutls_priority_set_direct (session, prio, &err)) < 0) {
    fprintf(stderr, "Error in priority string %s: %s\n", gnutls_strerror(ret), err);
    exit(1);
  }

  /* put the anonymous credentials to the current session
   */
  gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, x509_cred);
  gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) fd);

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

  if (ret < 0)
    {
      fprintf (stderr, "client: Handshake failed\n");
      gnutls_perror (ret);
      exit(1);
    }
   
  ret = gnutls_protocol_get_version(session);
  if (ret < GNUTLS_TLS1_1)
    {
      fprintf (stderr, "client: Handshake didn't negotiate TLS 1.1 (or later)\n");
      exit(1);
    }

  gnutls_transport_set_push_function (session, push_crippled);

#ifndef REHANDSHAKE
restart:
#endif
  do {
    ret = gnutls_record_send (session, text, sizeof(text));
  } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
  /* measure peer's processing time */
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);

#define TLS_RECV
#ifdef TLS_RECV
  do {
    ret = gnutls_record_recv(session, buffer, sizeof(buffer));
  } while(ret < 0 && (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED));
#else
  do {
    ret = recv(fd, buffer, sizeof(buffer), 0);
  } while(ret == -1 && errno == EAGAIN);
#endif

  if (taken < MAX_MEASUREMENTS(test->npoints) && ret > 0)
    {
      clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &stop);
      taken++;
      measurement = timespec_sub_ns(&stop, &start);
      prev_point_ptr->measurements[prev_point_ptr->midx] = measurement;

/*fprintf(stderr, "(%u,%u): %lu\n", (unsigned) prev_point_ptr->byte1,
 (unsigned) prev_point_ptr->byte2, measurements[taken]);*/
      memcpy(&measurement, buffer, sizeof(measurement));
      prev_point_ptr->smeasurements[prev_point_ptr->midx] = measurement;
      prev_point_ptr->midx++;

      /* read server's measurement */
      
#ifdef REHANDSHAKE
      gnutls_deinit(session);
#endif      
      goto restart;
    }
#ifndef TLS_RECV
  else if (ret < 0)
    {
      fprintf(stderr, "Error in recv()\n");
      exit(1);
    }
#endif

  gnutls_transport_set_push_function (session, push);
    
  gnutls_bye (session, GNUTLS_SHUT_WR);
  
  {
    double avg2, med, savg, smed;
    unsigned i;
    FILE* fp = NULL;
    
    if (test->file)
      fp = fopen(test->file, "w");
    
    if (fp) /* point, avg, median */
     fprintf(fp, "Delta,TimeAvg,TimeMedian,ServerAvg,ServerMedian\n");

    for (i=0;i<test->npoints;i++)
      {
        qsort( test->points[i].measurements, test->points[i].midx, 
               sizeof(test->points[i].measurements[0]), compar);

        qsort( test->points[i].smeasurements, test->points[i].midx, 
               sizeof(test->points[i].smeasurements[0]), compar);
     
        avg2 = calc_avg( test->points[i].measurements, test->points[i].midx);
        /*var = calc_var( test->points[i].measurements, test->points[i].midx, avg2);*/
        med = calc_median( test->points[i].measurements, test->points[i].midx);

        savg = calc_avg( test->points[i].smeasurements, test->points[i].midx);
        /*var = calc_var( test->points[i].measurements, test->points[i].midx, avg2);*/
        smed = calc_median( test->points[i].smeasurements, test->points[i].midx);
        /*min = calc_min( test->points[i].measurements, test->points[i].midx);*/
        
        if (fp) /* point, avg, median */
          fprintf(fp, "%u,%.2lf,%.2lf,%.2lf,%.2lf\n", (unsigned)test->points[i].byte1, 
                  avg2,med,savg, smed);
        
        /*printf("(%u) Avg: %.3f nanosec, Median: %.3f, Variance: %.3f\n", (unsigned)test->points[i].byte1, 
               avg2, med, var);*/
      }

    if (fp)
      fclose(fp);
  }

  if (test->desc)
    fprintf(stderr, "Description: %s\n", test->desc);

  close (fd);

  gnutls_deinit (session);

  gnutls_certificate_free_credentials (x509_cred);

  gnutls_global_deinit ();
}