Ejemplo n.º 1
0
static void client(int fd, const char *prio)
{
	int ret;
	gnutls_anon_client_credentials_t anoncred;
	gnutls_certificate_credentials_t x509_cred;
	gnutls_session_t session;
	/* Need to enable anonymous KX specifically. */

	gnutls_global_init();

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

	gnutls_anon_allocate_client_credentials(&anoncred);
	gnutls_certificate_allocate_credentials(&x509_cred);

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

	/* Use default priorities */
	gnutls_priority_set_direct(session, prio, NULL);

	/* put the anonymous credentials to the current session
	 */
	gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred);
	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 (gnutls_ecc_curve_get(session) == 0xffffffff) {
		fprintf(stderr, "memory was overwritten\n");
		kill(getpid(), SIGSEGV);
	}

	if (ret < 0) {
		fprintf(stderr, "client: Handshake failed (expected)\n");
		gnutls_perror(ret);
		exit(0);
	} else {
		if (debug)
			fprintf(stderr, "client: Handshake was completed\n");
	}

	close(fd);

	gnutls_deinit(session);

	gnutls_anon_free_client_credentials(anoncred);
	gnutls_certificate_free_credentials(x509_cred);

	gnutls_global_deinit();
}
Ejemplo n.º 2
0
/*
 * This function is called to shut down the SSL layer but keep the
 * socket open (CCC - Clear Command Channel)
 */
int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
{
  ssize_t result;
  int retval = 0;
  struct SessionHandle *data = conn->data;
  int done = 0;
  char buf[120];

  /* This has only been tested on the proftpd server, and the mod_tls code
     sends a close notify alert without waiting for a close notify alert in
     response. Thus we wait for a close notify alert from the server, but
     we do not send one. Let's hope other servers do the same... */

  if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
      gnutls_bye(conn->ssl[sockindex].session, GNUTLS_SHUT_WR);

  if(conn->ssl[sockindex].session) {
    while(!done) {
      int what = Curl_socket_ready(conn->sock[sockindex],
                                   CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
      if(what > 0) {
        /* Something to read, let's do it and hope that it is the close
           notify alert from the server */
        result = gnutls_record_recv(conn->ssl[sockindex].session,
                                    buf, sizeof(buf));
        switch(result) {
        case 0:
          /* This is the expected response. There was no data but only
             the close notify alert */
          done = 1;
          break;
        case GNUTLS_E_AGAIN:
        case GNUTLS_E_INTERRUPTED:
          infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED\n");
          break;
        default:
          retval = -1;
          done = 1;
          break;
        }
      }
      else if(0 == what) {
        /* timeout */
        failf(data, "SSL shutdown timeout");
        done = 1;
        break;
      }
      else {
        /* anything that gets here is fatally bad */
        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
        retval = -1;
        done = 1;
      }
    }
    gnutls_deinit(conn->ssl[sockindex].session);
  }
  gnutls_certificate_free_credentials(conn->ssl[sockindex].cred);

#ifdef USE_TLS_SRP
  if(data->set.ssl.authtype == CURL_TLSAUTH_SRP
     && data->set.ssl.username != NULL)
    gnutls_srp_free_client_credentials(conn->ssl[sockindex].srp_client_cred);
#endif

  conn->ssl[sockindex].cred = NULL;
  conn->ssl[sockindex].session = NULL;

  return retval;
}
Ejemplo n.º 3
0
static
void client_check(void)
{
	int exit_code = EXIT_SUCCESS;
	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;

	/* General init. */
	global_init();
	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(6);

	/* Init server */
	gnutls_certificate_allocate_credentials(&serverx509cred);
	gnutls_certificate_set_retrieve_function2(serverx509cred, cert_callback);

	gnutls_init(&server, GNUTLS_SERVER);
	gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE,
				serverx509cred);
	gnutls_priority_set_direct(server,
				   "NORMAL:-KX-ALL:+RSA:%DEBUG_ALLOW_KEY_USAGE_VIOLATIONS",
				   NULL);
	gnutls_transport_set_push_function(server, server_push);
	gnutls_transport_set_pull_function(server, server_pull);
	gnutls_transport_set_ptr(server, server);

	/* Init client */
	ret = gnutls_certificate_allocate_credentials(&clientx509cred);
	if (ret < 0)
		exit(1);

	ret = gnutls_certificate_set_x509_trust_mem(clientx509cred, &ca_cert, GNUTLS_X509_FMT_PEM);
	if (ret < 0)
		exit(1);

	ret = gnutls_init(&client, GNUTLS_CLIENT);
	if (ret < 0)
		exit(1);

	ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE,
				clientx509cred);
	if (ret < 0)
		exit(1);

	gnutls_priority_set_direct(client, "NORMAL:+RSA", NULL);
	gnutls_transport_set_push_function(client, client_push);
	gnutls_transport_set_pull_function(client, client_pull);
	gnutls_transport_set_ptr(client, client);

	HANDSHAKE_EXPECT(client, server, GNUTLS_E_KEY_USAGE_VIOLATION, GNUTLS_E_AGAIN);

	if (debug)
		success("client returned the expected code: %s\n", gnutls_strerror(cret));

	gnutls_deinit(client);
	gnutls_deinit(server);

	gnutls_certificate_free_credentials(serverx509cred);
	gnutls_certificate_free_credentials(clientx509cred);

	gnutls_global_deinit();

	if (debug > 0) {
		if (exit_code == 0)
			puts("Self-test successful");
		else
			puts("Self-test failed");
	}
}
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;
	}
}
Ejemplo n.º 5
0
void
doit (void)
{
    int exit_code = EXIT_SUCCESS;
    /* 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;

    /* General init. */
    gnutls_global_init ();
    gnutls_global_set_log_function (tls_log_func);
    if (debug)
        gnutls_global_set_log_level (2);

    /* Init server */
    gnutls_certificate_allocate_credentials (&serverx509cred);
    gnutls_certificate_set_x509_key_mem (serverx509cred,
                                         &server_cert, &server_key,
                                         GNUTLS_X509_FMT_PEM);
    gnutls_init (&server, GNUTLS_SERVER);
    gnutls_credentials_set (server, GNUTLS_CRD_CERTIFICATE, serverx509cred);
    gnutls_priority_set_direct (server, "NORMAL", NULL);
    gnutls_transport_set_push_function (server, server_push);
    gnutls_transport_set_pull_function (server, server_pull);
    gnutls_transport_set_ptr (server, (gnutls_transport_ptr_t)server);

    /* Init client */
    gnutls_certificate_allocate_credentials (&clientx509cred);
    gnutls_init (&client, GNUTLS_CLIENT);
    gnutls_credentials_set (client, GNUTLS_CRD_CERTIFICATE, clientx509cred);
    gnutls_priority_set_direct (client, "NORMAL", NULL);
    gnutls_transport_set_push_function (client, client_push);
    gnutls_transport_set_pull_function (client, client_pull);
    gnutls_transport_set_ptr (client, (gnutls_transport_ptr_t)client);

    HANDSHAKE(client, server);

    sret = gnutls_rehandshake (server);
    if (debug)
    {
        tls_log_func (0, "gnutls_rehandshake (server)...\n");
        tls_log_func (0, gnutls_strerror (sret));
        tls_log_func (0, "\n");
    }

    {
        ssize_t n;
        char b[1];
        n = gnutls_record_recv (client, b, 1);
        if (n != GNUTLS_E_REHANDSHAKE)
            abort ();
    }

    HANDSHAKE(client, server);

    gnutls_bye (client, GNUTLS_SHUT_RDWR);
    gnutls_bye (server, GNUTLS_SHUT_RDWR);

    gnutls_deinit (client);
    gnutls_deinit (server);

    gnutls_certificate_free_credentials (serverx509cred);
    gnutls_certificate_free_credentials (clientx509cred);

    gnutls_global_deinit ();

    if (debug)
    {
        if (exit_code == 0)
            puts ("Self-test successful");
        else
            puts ("Self-test failed");
    }
}
Ejemplo n.º 6
0
void doit(void)
{
	gnutls_certificate_credentials_t x509_cred;
	int ret;
	unsigned int i;
	gnutls_x509_crt_t issuer;
	gnutls_x509_crt_t list[LIST_SIZE];
	char dn[128];
	size_t dn_size;
	unsigned int list_size;
	size_t buf_size;

	gnutls_x509_privkey_t get_key;
	gnutls_x509_crt_t *get_crts;
	unsigned n_get_crts;
	gnutls_datum_t get_datum, chain_datum[2] = {server_ca3_cert, subca3_cert};
	gnutls_x509_trust_list_t trust_list;
	gnutls_x509_trust_list_iter_t trust_iter;
	gnutls_x509_crt_t get_ca_crt;
	unsigned n_get_ca_crts;

	/* 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_cert_chain,
					    &server_ca3_key,
					    GNUTLS_X509_FMT_PEM);

	/* test for gnutls_certificate_get_issuer() */

	/* check whether gnutls_x509_crt_list_import will fail if given a single
	 * certificate */
	list_size = LIST_SIZE;
	ret =
	    gnutls_x509_crt_list_import(list, &list_size, &ca3_cert,
					GNUTLS_X509_FMT_PEM,
					GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED);
	if (ret < 0)
		fail("gnutls_x509_crt_list_import (failed with a single cert)");
	gnutls_x509_crt_deinit(list[0]);

	list_size = LIST_SIZE;
	ret =
	    gnutls_x509_crt_list_import(list, &list_size, &cli_ca3_cert_chain,
					GNUTLS_X509_FMT_PEM,
					GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED);
	if (ret < 0)
		fail("gnutls_x509_crt_list_import");

	ret =
	    gnutls_certificate_get_issuer(x509_cred, list[list_size-1], &issuer, 0);
	if (ret < 0)
		fail("gnutls_certificate_get_isser");

	ret =
	    gnutls_certificate_get_issuer(x509_cred, list[list_size-1], &issuer, GNUTLS_TL_GET_COPY);
	if (ret < 0)
		fail("gnutls_certificate_get_isser");

	dn_size = sizeof(dn);
	ret = gnutls_x509_crt_get_dn(issuer, dn, &dn_size);
	if (ret < 0)
		fail("gnutls_certificate_get_dn");
	gnutls_x509_crt_deinit(issuer);

	if (dn_size != strlen(dn)) {
		fail("gnutls_x509_crt_get_dn: lengths don't match\n");
		exit(1);
	}

	if (debug)
		fprintf(stderr, "Issuer's DN: %s\n", dn);

	/* test the getter functions of gnutls_certificate_credentials_t */

	ret =
	    gnutls_certificate_get_x509_key(x509_cred, 0, &get_key);
	if (ret < 0)
		fail("gnutls_certificate_get_x509_key");

	ret =
	    gnutls_x509_privkey_export2(get_key,
					GNUTLS_X509_FMT_PEM,
					&get_datum);
	if (ret < 0)
		fail("gnutls_x509_privkey_export2");

	if (get_datum.size != server_ca3_key.size ||
	    memcmp(get_datum.data, server_ca3_key.data, get_datum.size) != 0) {
		fail(
		    "exported key %u vs. %u\n\n%s\n\nvs.\n\n%s",
		    get_datum.size, server_ca3_key.size,
		    get_datum.data, server_ca3_key.data);
	}

	if (strlen((char*)get_datum.data) != get_datum.size) {
		fail("exported key %u vs. %u\n\n%s\n",
		     get_datum.size, (unsigned)strlen((char*)get_datum.data),
		     get_datum.data);
	}

	gnutls_free(get_datum.data);

	buf_size = sizeof(buf);
	ret =
	    gnutls_x509_privkey_export(get_key,
					GNUTLS_X509_FMT_PEM,
					buf, &buf_size);
	if (ret < 0)
		fail("gnutls_x509_privkey_export");

	if (buf_size != get_datum.size ||
	    buf_size != strlen(buf) ||
	    memcmp(buf, server_ca3_key.data, buf_size) != 0) {
		fail(
		    "exported key %u vs. %u\n\n%s\n\nvs.\n\n%s",
		    (int)buf_size, server_ca3_key.size,
		    buf, server_ca3_key.data);
	}

	ret =
	    gnutls_certificate_get_x509_crt(x509_cred, 0, &get_crts, &n_get_crts);
	if (ret < 0)
		fail("gnutls_certificate_get_x509_crt");
	if (n_get_crts != 2)
		fail("gnutls_certificate_get_x509_crt: n_crts != 2");

	for (i = 0; i < n_get_crts; i++) {
		ret =
			gnutls_x509_crt_export2(get_crts[i],
						GNUTLS_X509_FMT_PEM,
						&get_datum);
		if (ret < 0)
			fail("gnutls_x509_crt_export2");

		if (get_datum.size != chain_datum[i].size ||
		    memcmp(get_datum.data, chain_datum[i].data, get_datum.size) != 0) {
			fail(
				"exported certificate %u vs. %u\n\n%s\n\nvs.\n\n%s",
				get_datum.size, chain_datum[i].size,
				get_datum.data, chain_datum[i].data);
		}

		gnutls_free(get_datum.data);
	}

	gnutls_certificate_get_trust_list(x509_cred, &trust_list);

	n_get_ca_crts = 0;
	trust_iter = NULL;
	while (gnutls_x509_trust_list_iter_get_ca(trust_list,
						  &trust_iter,
						  &get_ca_crt) !=
		GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
		ret =
		    gnutls_x509_crt_export2(get_ca_crt,
					    GNUTLS_X509_FMT_PEM,
					    &get_datum);
		if (ret < 0)
			fail("gnutls_x509_crt_export2");

		if (get_datum.size != ca3_cert.size ||
		    memcmp(get_datum.data, ca3_cert.data, get_datum.size) != 0) {
			fail(
			    "exported CA certificate %u vs. %u\n\n%s\n\nvs.\n\n%s",
			    get_datum.size, ca3_cert.size,
			    get_datum.data, ca3_cert.data);
		}

		gnutls_x509_crt_deinit(get_ca_crt);
		gnutls_free(get_datum.data);

		++n_get_ca_crts;
	}

	if (n_get_ca_crts != 1)
		fail("gnutls_x509_trust_list_iter_get_ca: n_cas != 1");
	if (trust_iter != NULL)
		fail("gnutls_x509_trust_list_iter_get_ca: iterator not NULL after iteration");

	gnutls_x509_privkey_deinit(get_key);
	for (i = 0; i < n_get_crts; i++)
		gnutls_x509_crt_deinit(get_crts[i]);
	gnutls_free(get_crts);

	for (i = 0; i < list_size; i++)
		gnutls_x509_crt_deinit(list[i]);
	gnutls_certificate_free_credentials(x509_cred);

	gnutls_global_deinit();

	if (debug)
		success("success");
}
Ejemplo n.º 7
0
void doit(void)
{
	/* 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;

	/* General init. */
	global_init();
	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(2);

	/* Init server */
	gnutls_certificate_allocate_credentials(&serverx509cred);
	gnutls_certificate_set_x509_key_mem(serverx509cred,
					    &server_cert, &server_key,
					    GNUTLS_X509_FMT_PEM);
	gnutls_init(&server, GNUTLS_SERVER);
	gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE,
			       serverx509cred);
	gnutls_priority_set_direct(server, "NORMAL", NULL);
	gnutls_transport_set_push_function(server, server_push);
	gnutls_transport_set_pull_function(server, server_pull);
	gnutls_transport_set_ptr(server, server);

	/* Init client */
	gnutls_certificate_allocate_credentials(&clientx509cred);
	gnutls_init(&client, GNUTLS_CLIENT);
	gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE,
			       clientx509cred);
	gnutls_priority_set_direct(client, "NORMAL", NULL);
	gnutls_transport_set_push_function(client, client_push);
	gnutls_transport_set_pull_function(client, client_pull);
	gnutls_transport_set_ptr(client, client);

	HANDSHAKE(client, server);

	if (!gnutls_safe_renegotiation_status(client) ||
	    !gnutls_safe_renegotiation_status(server)) {
		tls_log_func(0, "Session not using safe renegotiation!\n");
		exit(1);
	}

	if (!(gnutls_session_get_flags(client) & GNUTLS_SFLAGS_SAFE_RENEGOTIATION) ||
	    !(gnutls_session_get_flags(server) & GNUTLS_SFLAGS_SAFE_RENEGOTIATION)) {
		tls_log_func(0, "Session not using safe renegotiation!\n");
		exit(1);
	}

	sret = gnutls_rehandshake(server);
	if (debug) {
		tls_log_func(0, "gnutls_rehandshake (server)...\n");
		tls_log_func(0, gnutls_strerror(sret));
		tls_log_func(0, "\n");
	}

	{
		ssize_t n;
		char b[1];
		n = gnutls_record_recv(client, b, 1);
		if (n != GNUTLS_E_REHANDSHAKE)
			abort();
	}

	HANDSHAKE(client, server);

	if (!gnutls_safe_renegotiation_status(client) ||
	    !gnutls_safe_renegotiation_status(server)) {
		tls_log_func(0,
			     "Rehandshaked session not using safe renegotiation!\n");
		exit(1);
	}

	if (!(gnutls_session_get_flags(client) & GNUTLS_SFLAGS_SAFE_RENEGOTIATION) ||
	    !(gnutls_session_get_flags(server) & GNUTLS_SFLAGS_SAFE_RENEGOTIATION)) {
		tls_log_func(0,
			     "Rehandshaked session not using safe renegotiation!\n");
		exit(1);
	}

	gnutls_bye(client, GNUTLS_SHUT_RDWR);
	gnutls_bye(server, GNUTLS_SHUT_RDWR);

	gnutls_deinit(client);
	gnutls_deinit(server);

	gnutls_certificate_free_credentials(serverx509cred);
	gnutls_certificate_free_credentials(clientx509cred);

	gnutls_global_deinit();

	if (debug) {
		puts("Self-test successful");
	}

	return;
}
Ejemplo n.º 8
0
void tls_free(tls_t *tls)
{
    gnutls_deinit(tls->session);
    gnutls_certificate_free_credentials(tls->cred);
    xmpp_free(tls->ctx, tls);
}
Ejemplo n.º 9
0
int
main (void)
{
  int err, listen_sd;
  int sd, ret;
  struct sockaddr_in sa_serv;
  struct sockaddr_in sa_cli;
  socklen_t client_len;
  char topbuf[512];
  gnutls_session_t session;
  char buffer[MAX_BUF + 1];
  int optval = 1;
  char name[256];

  strcpy (name, "Echo Server");

  gnutls_global_init ();

  /* SRP_PASSWD a password file (created with the included srptool utility) 
   */
  gnutls_srp_allocate_server_credentials (&srp_cred);
  gnutls_srp_set_server_credentials_file (srp_cred, SRP_PASSWD,
                                          SRP_PASSWD_CONF);

  gnutls_certificate_allocate_credentials (&cert_cred);
  gnutls_certificate_set_x509_trust_file (cert_cred, CAFILE,
                                          GNUTLS_X509_FMT_PEM);
  gnutls_certificate_set_x509_key_file (cert_cred, CERTFILE, KEYFILE,
                                        GNUTLS_X509_FMT_PEM);

  /* TCP socket operations
   */
  listen_sd = socket (AF_INET, SOCK_STREAM, 0);
  SOCKET_ERR (listen_sd, "socket");

  memset (&sa_serv, '\0', sizeof (sa_serv));
  sa_serv.sin_family = AF_INET;
  sa_serv.sin_addr.s_addr = INADDR_ANY;
  sa_serv.sin_port = htons (PORT);      /* Server Port number */

  setsockopt (listen_sd, SOL_SOCKET, SO_REUSEADDR, (void *) &optval,
              sizeof (int));

  err = bind (listen_sd, (struct sockaddr *) & sa_serv, sizeof (sa_serv));
  SOCKET_ERR (err, "bind");
  err = listen (listen_sd, 1024);
  SOCKET_ERR (err, "listen");

  printf ("%s ready. Listening to port '%d'.\n\n", name, PORT);

  client_len = sizeof (sa_cli);
  for (;;)
    {
      session = initialize_tls_session ();

      sd = accept (listen_sd, (struct sockaddr *) & sa_cli, &client_len);

      printf ("- connection from %s, port %d\n",
              inet_ntop (AF_INET, &sa_cli.sin_addr, topbuf,
                         sizeof (topbuf)), ntohs (sa_cli.sin_port));

      gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd);

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

      if (ret < 0)
        {
          close (sd);
          gnutls_deinit (session);
          fprintf (stderr, "*** Handshake has failed (%s)\n\n",
                   gnutls_strerror (ret));
          continue;
        }
      printf ("- Handshake was completed\n");
      printf ("- User %s was connected\n", gnutls_srp_server_get_username(session));

      /* print_info(session); */

      for (;;)
        {
          memset (buffer, 0, MAX_BUF + 1);
          ret = gnutls_record_recv (session, buffer, MAX_BUF);

          if (ret == 0)
            {
              printf ("\n- Peer has closed the GnuTLS connection\n");
              break;
            }
          else if (ret < 0)
            {
              fprintf (stderr, "\n*** Received corrupted "
                       "data(%d). Closing the connection.\n\n", ret);
              break;
            }
          else if (ret > 0)
            {
              /* echo data back to the client
               */
              gnutls_record_send (session, buffer, strlen (buffer));
            }
        }
      printf ("\n");
      /* do not wait for the peer to close the connection. */
      gnutls_bye (session, GNUTLS_SHUT_WR);

      close (sd);
      gnutls_deinit (session);

    }
  close (listen_sd);

  gnutls_srp_free_server_credentials (srp_cred);
  gnutls_certificate_free_credentials (cert_cred);

  gnutls_global_deinit ();

  return 0;

}
Ejemplo n.º 10
0
int
main (void)
{
  int err, listen_sd, i;
  int sd, ret;
  struct sockaddr_in sa_serv;
  struct sockaddr_in sa_cli;
  int client_len;
  char topbuf[512];
  gnutls_session_t session;
  char buffer[MAX_BUF + 1];
  int optval = 1;

  /* to disallow usage of the blocking /dev/random 
   */
  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);

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

  gnutls_certificate_allocate_credentials (&x509_cred);
  gnutls_certificate_set_x509_trust_file (x509_cred, CAFILE,
					  GNUTLS_X509_FMT_PEM);

  gnutls_certificate_set_x509_crl_file (x509_cred, CRLFILE,
					GNUTLS_X509_FMT_PEM);

  gnutls_certificate_set_x509_key_file (x509_cred, CERTFILE, KEYFILE,
					GNUTLS_X509_FMT_PEM);

  gnutls_psk_allocate_server_credentials (&psk_cred);
  gnutls_psk_set_server_credentials_function (psk_cred, pskfunc);

  generate_dh_params ();

  gnutls_priority_init (&priority_cache, "NORMAL:PSK", NULL);


  gnutls_certificate_set_dh_params (x509_cred, dh_params);

  /* Socket operations
   */
  listen_sd = socket (AF_INET, SOCK_STREAM, 0);
  SOCKET_ERR (listen_sd, "socket");

  memset (&sa_serv, '\0', sizeof (sa_serv));
  sa_serv.sin_family = AF_INET;
  sa_serv.sin_addr.s_addr = INADDR_ANY;
  sa_serv.sin_port = htons (PORT);	/* Server Port number */

  setsockopt (listen_sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (int));

  err = bind (listen_sd, (SA *) & sa_serv, sizeof (sa_serv));
  SOCKET_ERR (err, "bind");
  err = listen (listen_sd, 1024);
  SOCKET_ERR (err, "listen");

  printf ("Server ready. Listening to port '%d'.\n\n", PORT);

  client_len = sizeof (sa_cli);
  for (;;)
    {
      session = initialize_tls_session ();

      sd = accept (listen_sd, (SA *) & sa_cli, &client_len);

      printf ("- connection from %s, port %d\n",
	      inet_ntop (AF_INET, &sa_cli.sin_addr, topbuf,
			 sizeof (topbuf)), ntohs (sa_cli.sin_port));

      gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd);
      ret = gnutls_handshake (session);
      if (ret < 0)
	{
	  close (sd);
	  gnutls_deinit (session);
	  fprintf (stderr, "*** Handshake has failed (%s)\n\n",
		   gnutls_strerror (ret));
	  continue;
	}
      printf ("- Handshake was completed\n");

      /* see the Getting peer's information example */
      /* print_info(session); */

      i = 0;
      for (;;)
	{
	  memset (buffer, 0, MAX_BUF + 1);
	  ret = gnutls_record_recv (session, buffer, MAX_BUF);

	  if (ret == 0)
	    {
	      printf ("\n- Peer has closed the GNUTLS connection\n");
	      break;
	    }
	  else if (ret < 0)
	    {
	      fprintf (stderr, "\n*** Received corrupted "
		       "data(%d). Closing the connection.\n\n", ret);
	      break;
	    }
	  else if (ret > 0)
	    {
	      /* echo data back to the client
	       */
	      gnutls_record_send (session, buffer, strlen (buffer));
	    }
	}
      printf ("\n");
      /* do not wait for the peer to close the connection.
       */
      gnutls_bye (session, GNUTLS_SHUT_WR);

      close (sd);
      gnutls_deinit (session);

    }
  close (listen_sd);

  gnutls_certificate_free_credentials (x509_cred);
  gnutls_psk_free_server_credentials (psk_cred);

  gnutls_priority_deinit (priority_cache);

  gnutls_global_deinit ();

  return 0;

}
Ejemplo n.º 11
0
TDSRET
tds_ssl_init(TDSSOCKET *tds)
{
	gnutls_session_t session;
	gnutls_certificate_credentials_t xcred;
	int ret;
	const char *tls_msg;

	xcred = NULL;
	session = NULL;	
	tls_msg = "initializing tls";

	if (!tls_initialized) {
		ret = 0;
		tds_mutex_lock(&tls_mutex);
		if (!tls_initialized) {
			tds_gcry_init();
			ret = gnutls_global_init();
			if (ret == 0)
				tls_initialized = 1;
		}
		tds_mutex_unlock(&tls_mutex);
		if (ret != 0)
			goto cleanup;
	}

	if (tds_write_dump && tls_initialized < 2) {
		gnutls_global_set_log_level(11);
		gnutls_global_set_log_function(tds_tls_log);
		tls_initialized = 2;
	}

	tls_msg = "allocating credentials";
	ret = gnutls_certificate_allocate_credentials(&xcred);
	if (ret != 0)
		goto cleanup;

	if (!tds_dstr_isempty(&tds->login->cafile)) {
		tls_msg = "loading CA file";
		if (strcasecmp(tds_dstr_cstr(&tds->login->cafile), "system") == 0)
			ret = gnutls_certificate_set_x509_system_trust(xcred);
		else
			ret = gnutls_certificate_set_x509_trust_file(xcred, tds_dstr_cstr(&tds->login->cafile), GNUTLS_X509_FMT_PEM);
		if (ret <= 0)
			goto cleanup;
		if (!tds_dstr_isempty(&tds->login->crlfile)) {
			tls_msg = "loading CRL file";
			ret = gnutls_certificate_set_x509_crl_file(xcred, tds_dstr_cstr(&tds->login->crlfile), GNUTLS_X509_FMT_PEM);
			if (ret <= 0)
				goto cleanup;
		}
#ifdef HAVE_GNUTLS_CERTIFICATE_SET_VERIFY_FUNCTION
		gnutls_certificate_set_verify_function(xcred, tds_verify_certificate);
#endif
	}

	/* Initialize TLS session */
	tls_msg = "initializing session";
	ret = gnutls_init(&session, GNUTLS_CLIENT);
	if (ret != 0)
		goto cleanup;

	gnutls_transport_set_ptr(session, tds);
	gnutls_transport_set_pull_function(session, tds_pull_func_login);
	gnutls_transport_set_push_function(session, tds_push_func_login);

	/* NOTE: there functions return int however they cannot fail */

	/* use default priorities... */
	gnutls_set_default_priority(session);

	/* ... but overwrite some */
	ret = gnutls_priority_set_direct (session, "NORMAL:%COMPAT:-VERS-SSL3.0", NULL);
	if (ret != 0)
		goto cleanup;

	/* mssql does not like padding too much */
#ifdef HAVE_GNUTLS_RECORD_DISABLE_PADDING
	gnutls_record_disable_padding(session);
#endif

	/* put the anonymous credentials to the current session */
	tls_msg = "setting credential";
	ret = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);
	if (ret != 0)
		goto cleanup;

	/* Perform the TLS handshake */
	tls_msg = "handshake";
	ret = gnutls_handshake (session);
	if (ret != 0)
		goto cleanup;

#ifndef HAVE_GNUTLS_CERTIFICATE_SET_VERIFY_FUNCTION
	ret = tds_verify_certificate(session);
	if (ret != 0)
		goto cleanup;
#endif

	tdsdump_log(TDS_DBG_INFO1, "handshake succeeded!!\n");

	gnutls_transport_set_ptr(session, tds->conn);
	gnutls_transport_set_pull_function(session, tds_pull_func);
	gnutls_transport_set_push_function(session, tds_push_func);

	tds->conn->tls_session = session;
	tds->conn->tls_credentials = xcred;

	return TDS_SUCCESS;

cleanup:
	if (session)
		gnutls_deinit(session);
	if (xcred)
		gnutls_certificate_free_credentials(xcred);
	tdsdump_log(TDS_DBG_ERROR, "%s failed: %s\n", tls_msg, gnutls_strerror (ret));
	return TDS_FAIL;
}
Ejemplo n.º 12
0
int
main (int argc, char **argv)
{
  int ret;
  int ii, i, inp;
  char buffer[MAX_BUF + 1];
  char *session_data = NULL;
  char *session_id = NULL;
  size_t session_data_size;
  size_t session_id_size = 0;
  int user_term = 0, retval = 0;
  socket_st hd;
  ssize_t bytes;

  set_program_name (argv[0]);
  gaa_parser (argc, argv);

  gnutls_global_set_log_function (tls_log_func);
  gnutls_global_set_log_level (info.debug);

  if ((ret = gnutls_global_init ()) < 0)
    {
      fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret));
      exit (1);
    }

#ifdef ENABLE_PKCS11
  pkcs11_common ();
#endif

  if (hostname == NULL)
    {
      fprintf (stderr, "No hostname given\n");
      exit (1);
    }

  sockets_init ();

#ifndef _WIN32
  signal (SIGPIPE, SIG_IGN);
#endif

  init_global_tls_stuff ();

  socket_open (&hd, hostname, service);
  socket_connect (&hd);

  hd.session = init_tls_session (hostname);
  if (starttls)
    goto after_handshake;

  for (i = 0; i < 2; i++)
    {


      if (i == 1)
        {
          hd.session = init_tls_session (hostname);
          gnutls_session_set_data (hd.session, session_data,
                                   session_data_size);
          free (session_data);
        }

      ret = do_handshake (&hd);

      if (ret < 0)
        {
          fprintf (stderr, "*** Handshake has failed\n");
          gnutls_perror (ret);
          gnutls_deinit (hd.session);
          return 1;
        }
      else
        {
          printf ("- Handshake was completed\n");
          if (gnutls_session_is_resumed (hd.session) != 0)
            printf ("*** This is a resumed session\n");
        }

      if (resume != 0 && i == 0)
        {

          gnutls_session_get_data (hd.session, NULL, &session_data_size);
          session_data = malloc (session_data_size);

          gnutls_session_get_data (hd.session, session_data,
                                   &session_data_size);

          gnutls_session_get_id (hd.session, NULL, &session_id_size);

          session_id = malloc (session_id_size);
          gnutls_session_get_id (hd.session, session_id, &session_id_size);

          /* print some information */
          print_info (hd.session, hostname, info.insecure);

          printf ("- Disconnecting\n");
          socket_bye (&hd);

          printf
            ("\n\n- Connecting again- trying to resume previous session\n");
          socket_open (&hd, hostname, service);
          socket_connect (&hd);
        }
      else
        {
          break;
        }
    }

after_handshake:

  /* Warning!  Do not touch this text string, it is used by external
     programs to search for when gnutls-cli has reached this point. */
  printf ("\n- Simple Client Mode:\n\n");

  if (rehandshake)
    {
      ret = do_handshake (&hd);

      if (ret < 0)
        {
          fprintf (stderr, "*** ReHandshake has failed\n");
          gnutls_perror (ret);
          gnutls_deinit (hd.session);
          return 1;
        }
      else
        {
          printf ("- ReHandshake was completed\n");
        }
    }

#ifndef _WIN32
  signal (SIGALRM, &starttls_alarm);
#endif

  fflush (stdout);
  fflush (stderr);

  /* do not buffer */
#if !(defined _WIN32 || defined __WIN32__)
  setbuf (stdin, NULL);
#endif
  setbuf (stdout, NULL);
  setbuf (stderr, NULL);

  for (;;)
    {
      if (starttls_alarmed && !hd.secure)
        {
          /* Warning!  Do not touch this text string, it is used by
             external programs to search for when gnutls-cli has
             reached this point. */
          fprintf (stderr, "*** Starting TLS handshake\n");
          ret = do_handshake (&hd);
          if (ret < 0)
            {
              fprintf (stderr, "*** Handshake has failed\n");
              user_term = 1;
              retval = 1;
              break;
            }
        }

      inp = check_net_or_keyboard_input(&hd);

      if (inp == IN_NET)
        {
          memset (buffer, 0, MAX_BUF + 1);
          ret = socket_recv (&hd, buffer, MAX_BUF);

          if (ret == 0)
            {
              printf ("- Peer has closed the GnuTLS connection\n");
              break;
            }
          else if (handle_error (&hd, ret) < 0 && user_term == 0)
            {
              fprintf (stderr,
                       "*** Server has terminated the connection abnormally.\n");
              retval = 1;
              break;
            }
          else if (ret > 0)
            {
              if (verbose != 0)
                printf ("- Received[%d]: ", ret);
              for (ii = 0; ii < ret; ii++)
                {
                  fputc (buffer[ii], stdout);
                }
              fflush (stdout);
            }

          if (user_term != 0)
            break;
        }

      if (inp == IN_KEYBOARD)
        {
          if ((bytes = read (fileno (stdin), buffer, MAX_BUF - 1)) <= 0)
            {
              if (hd.secure == 0)
                {
                  /* Warning!  Do not touch this text string, it is
                     used by external programs to search for when
                     gnutls-cli has reached this point. */
                  fprintf (stderr, "*** Starting TLS handshake\n");
                  ret = do_handshake (&hd);
                  clearerr (stdin);
                  if (ret < 0)
                    {
                      fprintf (stderr, "*** Handshake has failed\n");
                      user_term = 1;
                      retval = 1;
                      break;
                    }
                }
              else
                {
                  user_term = 1;
                  break;
                }
              continue;
            }

          buffer[bytes] = 0;
          if (crlf != 0)
            {
              char *b = strchr (buffer, '\n');
              if (b != NULL)
                {
                  strcpy (b, "\r\n");
                  bytes++;
                }
            }

          ret = socket_send (&hd, buffer, bytes);

          if (ret > 0)
            {
              if (verbose != 0)
                printf ("- Sent: %d bytes\n", ret);
            }
          else
            handle_error (&hd, ret);

        }
    }

  if (user_term != 0)
    socket_bye (&hd);
  else
    gnutls_deinit (hd.session);

#ifdef ENABLE_SRP
  if (srp_cred)
    gnutls_srp_free_client_credentials (srp_cred);
#endif
#ifdef ENABLE_PSK
  if (psk_cred)
    gnutls_psk_free_client_credentials (psk_cred);
#endif

  gnutls_certificate_free_credentials (xcred);

#ifdef ENABLE_ANON
  gnutls_anon_free_client_credentials (anon_cred);
#endif

  gnutls_global_deinit ();

  return retval;
}
Ejemplo n.º 13
0
/**
 * @short Creates a new listen point with HTTPS powers.
 * @memberof onion_https_t
 * 
 * Creates the HTTPS listen point.
 * 
 * Might be called with (O_SSL_NONE,NULL), and set up the certificate later with onion_https_set_certificate.
 * 
 * @param type Type of certificate to setup
 * @param filename File from where to get the data
 * @param ... More types and filenames until O_SSL_NONE.
 * @returns An onion_listen_point with the desired data, ready to start listening.
 */
onion_listen_point *onion_https_new(){
	onion_listen_point *op=onion_listen_point_new();
	op->request_init=onion_https_request_init;
	op->free_user_data=onion_https_free_user_data;
	op->listen_stop=onion_https_listen_stop;
	op->read=onion_https_read;
	op->write=onion_https_write;
	op->close=onion_https_close;
	op->read_ready=onion_http_read_ready;
	op->secure = true;
	
	op->user_data=onion_low_calloc(1,sizeof(onion_https));
	onion_https *https=(onion_https*)op->user_data;
	
#ifdef HAVE_PTHREADS
	gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
#endif
	//if (!(o->flags&O_USE_DEV_RANDOM)){
		gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0);
	//}
	
	gnutls_global_init ();
	gnutls_certificate_allocate_credentials (&https->x509_cred);
	
	// set cert here??
	//onion_https_set_certificate(op,O_SSL_CERTIFICATE_KEY, "mycert.pem","mycert.pem");
	int e;
	int bits = gnutls_sec_param_to_pk_bits (GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LOW);
	e=gnutls_dh_params_init (&https->dh_params);
	if (e<0){
		ONION_ERROR("Error initializing HTTPS: %s", gnutls_strerror(e));
		gnutls_certificate_free_credentials (https->x509_cred);
		op->free_user_data=NULL;
		onion_listen_point_free(op);
		onion_low_free(https);
		return NULL;
	}
	e=gnutls_dh_params_generate2 (https->dh_params, bits);
	if (e<0){
		ONION_ERROR("Error initializing HTTPS: %s", gnutls_strerror(e));
		gnutls_certificate_free_credentials (https->x509_cred);
		op->free_user_data=NULL;
		onion_listen_point_free(op);
		onion_low_free(https);
		return NULL;
	}
	e=gnutls_priority_init (&https->priority_cache, "PERFORMANCE:%SAFE_RENEGOTIATION:-VERS-TLS1.0", NULL);
	if (e<0){
		ONION_ERROR("Error initializing HTTPS: %s", gnutls_strerror(e));
		gnutls_certificate_free_credentials (https->x509_cred);
		gnutls_dh_params_deinit(https->dh_params);
		op->free_user_data=NULL;
		onion_listen_point_free(op);
		onion_low_free(https);
		return NULL;
	}
	gnutls_certificate_set_dh_params (https->x509_cred, https->dh_params);
	gnutls_priority_init (&https->priority_cache, "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0:+VERS-SSL3.0:%COMPAT", NULL); // PERFORMANCE:%SAFE_RENEGOTIATION:-VERS-TLS1.0:%COMPAT"
	
	ONION_DEBUG("HTTPS connection ready");
	
	return op;
}
Ejemplo n.º 14
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;
}
Ejemplo n.º 15
0
int
main (void)
{
    int listen_sd;
    int sock, ret;
    struct sockaddr_in sa_serv;
    struct sockaddr_in cli_addr;
    socklen_t cli_addr_size;
    gnutls_session_t session;
    char buffer[MAX_BUFFER];
    priv_data_st priv;
    gnutls_datum_t cookie_key;
    gnutls_dtls_prestate_st prestate;
    int mtu = 1400;
    unsigned char sequence[8];

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

    gnutls_certificate_allocate_credentials (&x509_cred);
    gnutls_certificate_set_x509_trust_file (x509_cred, CAFILE,
                                            GNUTLS_X509_FMT_PEM);

    gnutls_certificate_set_x509_crl_file (x509_cred, CRLFILE,
                                          GNUTLS_X509_FMT_PEM);

    ret = gnutls_certificate_set_x509_key_file (x509_cred, CERTFILE, KEYFILE,
            GNUTLS_X509_FMT_PEM);
    if (ret < 0)
    {
        printf("No certificate or key were found\n");
        exit(1);
    }

    generate_dh_params ();

    gnutls_certificate_set_dh_params (x509_cred, dh_params);

    gnutls_priority_init (&priority_cache,
                          "PERFORMANCE:-VERS-TLS-ALL:+VERS-DTLS1.0:%SERVER_PRECEDENCE",
                          NULL);

    gnutls_key_generate (&cookie_key, GNUTLS_COOKIE_KEY_SIZE);

    /* Socket operations
     */
    listen_sd = socket (AF_INET, SOCK_DGRAM, 0);

    memset (&sa_serv, '\0', sizeof (sa_serv));
    sa_serv.sin_family = AF_INET;
    sa_serv.sin_addr.s_addr = INADDR_ANY;
    sa_serv.sin_port = htons (PORT);

    {   /* DTLS requires the IP don't fragment (DF) bit to be set */
#if defined(IP_DONTFRAG)
        int optval = 1;
        setsockopt (listen_sd, IPPROTO_IP, IP_DONTFRAG,
                    (const void *) &optval, sizeof (optval));
#elif defined(IP_MTU_DISCOVER)
        int optval = IP_PMTUDISC_DO;
        setsockopt(listen_sd, IPPROTO_IP, IP_MTU_DISCOVER,
                   (const void*) &optval, sizeof (optval));
#endif
    }

    bind (listen_sd, (struct sockaddr *) &sa_serv, sizeof (sa_serv));

    printf ("UDP server ready. Listening to port '%d'.\n\n", PORT);

    for (;;)
    {
        printf ("Waiting for connection...\n");
        sock = wait_for_connection (listen_sd);
        if (sock < 0)
            continue;

        cli_addr_size = sizeof (cli_addr);
        ret = recvfrom (sock, buffer, sizeof (buffer), MSG_PEEK,
                        (struct sockaddr *) &cli_addr, &cli_addr_size);
        if (ret > 0)
        {
            memset (&prestate, 0, sizeof (prestate));
            ret = gnutls_dtls_cookie_verify (&cookie_key, &cli_addr,
                                             sizeof (cli_addr), buffer, ret,
                                             &prestate);
            if (ret < 0)          /* cookie not valid */
            {
                priv_data_st s;

                memset (&s, 0, sizeof (s));
                s.fd = sock;
                s.cli_addr = (void *) &cli_addr;
                s.cli_addr_size = sizeof (cli_addr);

                printf ("Sending hello verify request to %s\n",
                        human_addr ((struct sockaddr *) &cli_addr,
                                    sizeof (cli_addr), buffer,
                                    sizeof (buffer)));

                gnutls_dtls_cookie_send (&cookie_key, &cli_addr,
                                         sizeof (cli_addr), &prestate,
                                         (gnutls_transport_ptr_t) & s,
                                         push_func);

                /* discard peeked data */
                recvfrom (sock, buffer, sizeof (buffer), 0,
                          (struct sockaddr *) &cli_addr, &cli_addr_size);
                usleep (100);
                continue;
            }
            printf ("Accepted connection from %s\n",
                    human_addr ((struct sockaddr *)
                                &cli_addr, sizeof (cli_addr), buffer,
                                sizeof (buffer)));
        }
        else
            continue;

        session = initialize_tls_session ();
        gnutls_dtls_prestate_set (session, &prestate);
        gnutls_dtls_set_mtu (session, mtu);

        priv.session = session;
        priv.fd = sock;
        priv.cli_addr = (struct sockaddr *) &cli_addr;
        priv.cli_addr_size = sizeof (cli_addr);

        gnutls_transport_set_ptr (session, &priv);
        gnutls_transport_set_push_function (session, push_func);
        gnutls_transport_set_pull_function (session, pull_func);
        gnutls_transport_set_pull_timeout_function (session, pull_timeout_func);

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

        if (ret < 0)
        {
            fprintf (stderr, "Error in handshake(): %s\n",
                     gnutls_strerror (ret));
            gnutls_deinit (session);
            continue;
        }

        printf ("- Handshake was completed\n");

        for (;;)
        {
            do
            {
                ret = gnutls_record_recv_seq (session, buffer, MAX_BUFFER,
                                              sequence);
            }
            while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);

            if (ret < 0)
            {
                fprintf (stderr, "Error in recv(): %s\n",
                         gnutls_strerror (ret));
                break;
            }
            if (ret == 0)
            {
                printf ("EOF\n\n");
                break;
            }
            buffer[ret] = 0;
            printf ("received[%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x]: %s\n",
                    sequence[0], sequence[1], sequence[2], sequence[3],
                    sequence[4], sequence[5], sequence[6], sequence[7], buffer);

            /* reply back */
            ret = gnutls_record_send (session, buffer, ret);
            if (ret < 0)
            {
                fprintf (stderr, "Error in send(): %s\n",
                         gnutls_strerror (ret));
                break;
            }
        }

        gnutls_bye (session, GNUTLS_SHUT_WR);
        gnutls_deinit (session);

    }
    close (listen_sd);

    gnutls_certificate_free_credentials (x509_cred);
    gnutls_priority_deinit (priority_cache);

    gnutls_global_deinit ();

    return 0;

}
Ejemplo n.º 16
0
int main(void)
{
	int ret, sd, ii;
	gnutls_session_t session;
	char buffer[MAX_BUF + 1];
	gnutls_certificate_credentials_t xcred;
	// Allow connections to servers that have X509
	const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };

	gnutls_global_init();

	gnutls_global_set_log_function(tls_log_func);
	gnutls_global_set_log_level(2);

	// X509 stuff
	gnutls_certificate_allocate_credentials(&xcred);

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

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

	// Use default priorities
	gnutls_set_default_priority(session);
	gnutls_certificate_type_set_priority(session, cert_type_priority);

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

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

	// pass the socket descriptor in non blocking
	tcp_nonblock(sd);
	// set all the custom read/write function
	gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t) sd);
	gnutls_transport_set_pull_function(session, tcp_read);
	gnutls_transport_set_push_function(session, tcp_write);

	// Perform the TLS handshake - until completed or error
	do {
		ret = gnutls_handshake(session);
		if(ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED)
			usleep(1000 * 10);
	}
	while(ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);

	if(ret < 0) {
		fprintf(stderr, "*** Handshake failed\n");
		goto end;
	} else {
		printf("- Handshake was completed\n");
	}
	
	// log to debug
	print_info(session);

	ssize_t		written_len;
	written_len	= gnutls_record_send(session, MSG, strlen(MSG));
	printf("written_len=%d\n", written_len);

	do{
		ret = gnutls_record_recv(session, buffer, MAX_BUF);
		if(ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED)
			usleep(1000 * 10);
	}while(ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);

	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;
}
Ejemplo n.º 17
0
int main(void)
{
	/* credentials */
	gnutls_anon_client_credentials_t c_anoncred;
	gnutls_certificate_credentials_t c_certcred;

	gnutls_session_t client;
	int sd, i;

	/* General init. */
	global_init();
	ecore_init();
//  gnutls_global_set_log_function (tls_log_func);
//  gnutls_global_set_log_level (6);

	/* Init client */
	gnutls_anon_allocate_client_credentials(&c_anoncred);
	gnutls_certificate_allocate_credentials(&c_certcred);


	for (i = 0; i < 5; i++) {

		gnutls_init(&client, GNUTLS_CLIENT);
		/* set very specific priorities */

		gnutls_handshake_set_timeout(client, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);

		gnutls_priority_set_direct(client, "NORMAL:+ANON-DH",
					   NULL);
		gnutls_credentials_set(client, GNUTLS_CRD_ANON,
				       c_anoncred);
		gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE,
				       c_certcred);
		gnutls_server_name_set(client, GNUTLS_NAME_DNS,
				       "localhost", strlen("localhost"));

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

		/* associate gnutls with socket */
		gnutls_transport_set_int(client, sd);
		/* add a callback for data being available for send/receive on socket */
		if (!ecore_main_fd_handler_add
		    (sd, ECORE_FD_READ | ECORE_FD_WRITE,
		     (Ecore_Fd_Cb) _process_data, client, NULL, NULL)) {
			print("could not create fd handler!");
			exit(1);
		}
		/* begin main loop */
		ecore_main_loop_begin();

		gnutls_bye(client, GNUTLS_SHUT_RDWR);

		gnutls_deinit(client);

		tcp_close(sd);
	}

	gnutls_anon_free_client_credentials(c_anoncred);
	gnutls_certificate_free_credentials(c_certcred);

	return 0;
}
Ejemplo n.º 18
0
int
main (void)
{
  int err, listen_sd;
  int sd, ret;
  struct sockaddr_in sa_serv;
  struct sockaddr_in sa_cli;
  int client_len;
  char topbuf[512];
  gnutls_session_t session;
  char buffer[MAX_BUF + 1];
  int optval = 1;
  char name[256];

  strcpy (name, "Echo Server");

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

  gnutls_certificate_allocate_credentials (&cred);
  gnutls_certificate_set_openpgp_keyring_file (cred, RINGFILE,
					       GNUTLS_OPENPGP_FMT_BASE64);

  gnutls_certificate_set_openpgp_key_file (cred, CERTFILE, KEYFILE,
					   GNUTLS_OPENPGP_FMT_BASE64);

  generate_dh_params ();

  gnutls_certificate_set_dh_params (cred, dh_params);

  /* Socket operations
   */
  listen_sd = socket (AF_INET, SOCK_STREAM, 0);
  SOCKET_ERR (listen_sd, "socket");

  memset (&sa_serv, '\0', sizeof (sa_serv));
  sa_serv.sin_family = AF_INET;
  sa_serv.sin_addr.s_addr = INADDR_ANY;
  sa_serv.sin_port = htons (PORT);	/* Server Port number */

  setsockopt (listen_sd, SOL_SOCKET, SO_REUSEADDR, (void *) &optval,
	      sizeof (int));

  err = bind (listen_sd, (SA *) & sa_serv, sizeof (sa_serv));
  SOCKET_ERR (err, "bind");
  err = listen (listen_sd, 1024);
  SOCKET_ERR (err, "listen");

  printf ("%s ready. Listening to port '%d'.\n\n", name, PORT);

  client_len = sizeof (sa_cli);
  for (;;)
    {
      session = initialize_tls_session ();

      sd = accept (listen_sd, (SA *) & sa_cli, &client_len);

      printf ("- connection from %s, port %d\n",
	      inet_ntop (AF_INET, &sa_cli.sin_addr, topbuf,
			 sizeof (topbuf)), ntohs (sa_cli.sin_port));

      gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd);
      ret = gnutls_handshake (session);
      if (ret < 0)
	{
	  close (sd);
	  gnutls_deinit (session);
	  fprintf (stderr, "*** Handshake has failed (%s)\n\n",
		   gnutls_strerror (ret));
	  continue;
	}
      printf ("- Handshake was completed\n");

      /* see the Getting peer's information example */
      /* print_info(session); */

      for (;;)
	{
	  memset (buffer, 0, MAX_BUF + 1);
	  ret = gnutls_record_recv (session, buffer, MAX_BUF);

	  if (ret == 0)
	    {
	      printf ("\n- Peer has closed the GnuTLS connection\n");
	      break;
	    }
	  else if (ret < 0)
	    {
	      fprintf (stderr, "\n*** Received corrupted "
		       "data(%d). Closing the connection.\n\n", ret);
	      break;
	    }
	  else if (ret > 0)
	    {
	      /* echo data back to the client
	       */
	      gnutls_record_send (session, buffer, strlen (buffer));
	    }
	}
      printf ("\n");
      /* do not wait for the peer to close the connection.
       */
      gnutls_bye (session, GNUTLS_SHUT_WR);

      close (sd);
      gnutls_deinit (session);

    }
  close (listen_sd);

  gnutls_certificate_free_credentials (cred);

  gnutls_global_deinit ();

  return 0;

}
Ejemplo n.º 19
0
int vnc_tls_client_setup(struct VncState *vs,
                         int needX509Creds) {

    VNC_DEBUG("Do TLS setup\n");
    if (vnc_tls_initialize() < 0) {
        VNC_DEBUG("Failed to init TLS\n");
        vnc_client_error(vs);
        return -1;
    }
    if (vs->tls.session == NULL) {
        if (gnutls_init(&vs->tls.session, GNUTLS_SERVER) < 0) {
            vnc_client_error(vs);
            return -1;
        }

        if (gnutls_set_default_priority(vs->tls.session) < 0) {
            gnutls_deinit(vs->tls.session);
            vs->tls.session = NULL;
            vnc_client_error(vs);
            return -1;
        }

        if (vnc_set_gnutls_priority(vs->tls.session, needX509Creds) < 0) {
            gnutls_deinit(vs->tls.session);
            vs->tls.session = NULL;
            vnc_client_error(vs);
            return -1;
        }

        if (needX509Creds) {
            gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs->vd);
            if (!x509_cred) {
                gnutls_deinit(vs->tls.session);
                vs->tls.session = NULL;
                vnc_client_error(vs);
                return -1;
            }
            if (gnutls_credentials_set(vs->tls.session, GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) {
                gnutls_deinit(vs->tls.session);
                vs->tls.session = NULL;
                gnutls_certificate_free_credentials(x509_cred);
                vnc_client_error(vs);
                return -1;
            }
            if (vs->vd->tls.x509verify) {
                VNC_DEBUG("Requesting a client certificate\n");
                gnutls_certificate_server_set_request (vs->tls.session, GNUTLS_CERT_REQUEST);
            }

        } else {
            gnutls_anon_server_credentials_t anon_cred = vnc_tls_initialize_anon_cred();
            if (!anon_cred) {
                gnutls_deinit(vs->tls.session);
                vs->tls.session = NULL;
                vnc_client_error(vs);
                return -1;
            }
            if (gnutls_credentials_set(vs->tls.session, GNUTLS_CRD_ANON, anon_cred) < 0) {
                gnutls_deinit(vs->tls.session);
                vs->tls.session = NULL;
                gnutls_anon_free_server_credentials(anon_cred);
                vnc_client_error(vs);
                return -1;
            }
        }

        gnutls_transport_set_ptr(vs->tls.session, (gnutls_transport_ptr_t)vs);
        gnutls_transport_set_push_function(vs->tls.session, vnc_tls_push);
        gnutls_transport_set_pull_function(vs->tls.session, vnc_tls_pull);
    }
    return 0;
}
Ejemplo n.º 20
0
void doit(void)
{
	int exit_code = EXIT_SUCCESS;
	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;
	gnutls_x509_crt_t *crts;
	unsigned int crts_size;
	unsigned i;
	gnutls_x509_privkey_t pkey;

	/* General init. */
	global_init();
	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(2);

	ret = gnutls_x509_crt_list_import2(&crts, &crts_size, &server_cert, GNUTLS_X509_FMT_PEM,
			GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_x509_privkey_init(&pkey);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	ret =
	    gnutls_x509_privkey_import(pkey, &server_key,
				       GNUTLS_X509_FMT_PEM);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	/* Init server */
	gnutls_certificate_allocate_credentials(&serverx509cred);
	gnutls_certificate_set_x509_key(serverx509cred, crts, crts_size, pkey);
	gnutls_x509_privkey_deinit(pkey);
	for (i=0;i<crts_size;i++)
		gnutls_x509_crt_deinit(crts[i]);
	gnutls_free(crts);

	gnutls_init(&server, GNUTLS_SERVER);
	gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE,
			       serverx509cred);
	gnutls_priority_set_direct(server,
				   "NORMAL:-CIPHER-ALL:+AES-128-GCM",
				   NULL);
	gnutls_transport_set_push_function(server, server_push);
	gnutls_transport_set_pull_function(server, server_pull);
	gnutls_transport_set_ptr(server, server);
	gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST);

	/* Init client */
	/* Init client */
	ret = gnutls_certificate_allocate_credentials(&clientx509cred);
	if (ret < 0)
		exit(1);

	ret = gnutls_certificate_set_x509_trust_mem(clientx509cred, &ca_cert, GNUTLS_X509_FMT_PEM);
	if (ret < 0)
		exit(1);

	gnutls_certificate_set_retrieve_function2(clientx509cred, cert_callback);

	ret = gnutls_init(&client, GNUTLS_CLIENT);
	if (ret < 0)
		exit(1);

	ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE,
			       clientx509cred);
	if (ret < 0)
		exit(1);

	gnutls_priority_set_direct(client, "NORMAL", NULL);
	gnutls_transport_set_push_function(client, client_push);
	gnutls_transport_set_pull_function(client, client_pull);
	gnutls_transport_set_ptr(client, client);

	HANDSHAKE(client, server);

	if (gnutls_certificate_get_ours(client) == NULL) {
		fail("client certificate was not sent!\n");
		exit(1);
	}

	/* check gnutls_certificate_get_ours() - server side */
	{
		const gnutls_datum_t *mcert;
		gnutls_datum_t scert;
		gnutls_x509_crt_t crt;

		mcert = gnutls_certificate_get_ours(server);
		if (mcert == NULL) {
			fail("gnutls_certificate_get_ours(): failed\n");
			exit(1);
		}

		gnutls_x509_crt_init(&crt);
		ret = gnutls_x509_crt_import(crt, &server_cert, GNUTLS_X509_FMT_PEM);
		if (ret < 0) {
			fail("gnutls_x509_crt_import: %s\n", gnutls_strerror(ret));
			exit(1);
		}

		ret = gnutls_x509_crt_export2(crt, GNUTLS_X509_FMT_DER, &scert);
		if (ret < 0) {
			fail("gnutls_x509_crt_export2: %s\n", gnutls_strerror(ret));
			exit(1);
		}
		gnutls_x509_crt_deinit(crt);

		if (scert.size != mcert->size || memcmp(scert.data, mcert->data, mcert->size) != 0) {
			fail("gnutls_certificate_get_ours output doesn't match cert\n");
			exit(1);
		}
		gnutls_free(scert.data);
	}

	/* check gnutls_certificate_get_ours() - client side */
	{
		const gnutls_datum_t *mcert;
		gnutls_datum_t ccert;
		gnutls_x509_crt_t crt;

		mcert = gnutls_certificate_get_ours(client);
		if (mcert == NULL) {
			fail("gnutls_certificate_get_ours(): failed\n");
			exit(1);
		}

		gnutls_x509_crt_init(&crt);
		ret = gnutls_x509_crt_import(crt, &cli_cert, GNUTLS_X509_FMT_PEM);
		if (ret < 0) {
			fail("gnutls_x509_crt_import: %s\n", gnutls_strerror(ret));
			exit(1);
		}

		ret = gnutls_x509_crt_export2(crt, GNUTLS_X509_FMT_DER, &ccert);
		if (ret < 0) {
			fail("gnutls_x509_crt_export2: %s\n", gnutls_strerror(ret));
			exit(1);
		}
		gnutls_x509_crt_deinit(crt);

		if (ccert.size != mcert->size || memcmp(ccert.data, mcert->data, mcert->size) != 0) {
			fail("gnutls_certificate_get_ours output doesn't match cert\n");
			exit(1);
		}
		gnutls_free(ccert.data);
	}

	/* check the number of certificates received */
	{
		unsigned cert_list_size = 0;
		gnutls_typed_vdata_st data[2];
		unsigned status;

		memset(data, 0, sizeof(data));

		/* check with wrong hostname */
		data[0].type = GNUTLS_DT_DNS_HOSTNAME;
		data[0].data = (void*)"localhost1";

		data[1].type = GNUTLS_DT_KEY_PURPOSE_OID;
		data[1].data = (void*)GNUTLS_KP_TLS_WWW_SERVER;

		gnutls_certificate_get_peers(client, &cert_list_size);
		if (cert_list_size < 2) {
			fprintf(stderr, "received a certificate list of %d!\n", cert_list_size);
			exit(1);
		}

		ret = gnutls_certificate_verify_peers(client, data, 2, &status);
		if (ret < 0) {
			fprintf(stderr, "could not verify certificate: %s\n", gnutls_strerror(ret));
			exit(1);
		}

		if (status == 0) {
			fprintf(stderr, "should not have accepted!\n");
			exit(1);
		}

		/* check with wrong purpose */
		data[0].type = GNUTLS_DT_DNS_HOSTNAME;
		data[0].data = (void*)"localhost";

		data[1].type = GNUTLS_DT_KEY_PURPOSE_OID;
		data[1].data = (void*)GNUTLS_KP_TLS_WWW_CLIENT;

		gnutls_certificate_get_peers(client, &cert_list_size);
		if (cert_list_size < 2) {
			fprintf(stderr, "received a certificate list of %d!\n", cert_list_size);
			exit(1);
		}

		ret = gnutls_certificate_verify_peers(client, data, 2, &status);
		if (ret < 0) {
			fprintf(stderr, "could not verify certificate: %s\n", gnutls_strerror(ret));
			exit(1);
		}

		if (status == 0) {
			fprintf(stderr, "should not have accepted!\n");
			exit(1);
		}

		/* check with correct purpose */
		data[0].type = GNUTLS_DT_DNS_HOSTNAME;
		data[0].data = (void*)"localhost";

		data[1].type = GNUTLS_DT_KEY_PURPOSE_OID;
		data[1].data = (void*)GNUTLS_KP_TLS_WWW_SERVER;

		ret = gnutls_certificate_verify_peers(client, data, 2, &status);
		if (ret < 0) {
			fprintf(stderr, "could not verify certificate: %s\n", gnutls_strerror(ret));
			exit(1);
		}

		if (status != 0) {
			fprintf(stderr, "could not verify certificate: %.4x\n", status);
			exit(1);
		}
	}

	if (gnutls_certificate_client_get_request_status(client) == 0) {
		fail("gnutls_certificate_client_get_request_status - 2 failed\n");
		exit(1);
	}

	gnutls_bye(client, GNUTLS_SHUT_RDWR);
	gnutls_bye(server, GNUTLS_SHUT_RDWR);

	gnutls_deinit(client);
	gnutls_deinit(server);

	gnutls_certificate_free_credentials(serverx509cred);
	gnutls_certificate_free_credentials(clientx509cred);

	gnutls_global_deinit();

	if (debug > 0) {
		if (exit_code == 0)
			puts("Self-test successful");
		else
			puts("Self-test failed");
	}
}
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;
}
Ejemplo n.º 22
0
int main(void)
{
        int ret, sd, ii;
        gnutls_session_t session;
        char buffer[MAX_BUF + 1];
        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 */
        CHECK(gnutls_global_init());

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

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

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

        /* Use default priorities */
        CHECK(gnutls_set_default_priority(session));

        /* put the x509 credentials to the current session */
        CHECK(gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred));
        CHECK(gnutls_server_name_set(session, GNUTLS_NAME_DNS, "my_host_name",
                                     strlen("my_host_name")));

        gnutls_session_set_verify_cert(session, "my_host_name", 0);

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

        gnutls_transport_set_int(session, sd);

        /* set the connection MTU */
        gnutls_dtls_set_mtu(session, 1000);
        /* gnutls_dtls_set_timeouts(session, 1000, 60000); */

        /* Perform the TLS handshake */
        do {
                ret = gnutls_handshake(session);
        }
        while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
        /* Note that DTLS may also receive GNUTLS_E_LARGE_PACKET */

        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);
        }

        CHECK(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);
        }

        /* It is suggested not to use GNUTLS_SHUT_RDWR in DTLS
         * connections because the peer's closure message might
         * be lost */
        CHECK(gnutls_bye(session, GNUTLS_SHUT_WR));

      end:

        udp_close(sd);

        gnutls_deinit(session);

        gnutls_certificate_free_credentials(xcred);

        gnutls_global_deinit();

        return 0;
}
Ejemplo n.º 23
0
int
main (void)
{
    int ret, sd, ii;
    gnutls_session_t session;
    gnutls_priority_t priorities_cache;
    char buffer[MAX_BUF + 1];
    gnutls_certificate_credentials_t xcred;
    /* Allow connections to servers that have OpenPGP keys as well.
     */

    gnutls_global_init ();

    load_keys ();

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

    /* priorities */
    gnutls_priority_init( &priorities_cache, "NORMAL", NULL);


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

    gnutls_certificate_client_set_retrieve_function (xcred, cert_callback);

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

    /* Use default priorities */
    gnutls_priority_set (session, priorities_cache);

    /* 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_priority_deinit( priorities_cache);

    gnutls_global_deinit ();

    return 0;
}
Ejemplo n.º 24
0
int
rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile)
{
    int ret;
    gnutls_datum_t *d_cert, *d_key;
    if (cert == NULL)
    {
        rb_lib_log("rb_setup_ssl_server: No certificate file");
        return 0;
    }

    if ((d_cert = rb_load_file_into_datum_t(cert)) == NULL)
    {
        rb_lib_log("rb_setup_ssl_server: Error loading certificate: %s", strerror(errno));
        return 0;
    }

    if ((d_key = rb_load_file_into_datum_t(keyfile)) == NULL)
    {
        rb_lib_log("rb_setup_ssl_server: Error loading key: %s", strerror(errno));
        return 0;
    }

    gnutls_certificate_free_credentials(x509);

    if (gnutls_certificate_allocate_credentials(&x509) != GNUTLS_E_SUCCESS)
    {
        rb_lib_log("rb_init_ssl: Unable to allocate SSL/TLS certificate credentials");
        return 0;
    }

    if ((ret =
                gnutls_certificate_set_x509_key_mem(x509, d_cert, d_key,
                                                    GNUTLS_X509_FMT_PEM)) != GNUTLS_E_SUCCESS)
    {
        rb_lib_log("rb_setup_ssl_server: Error loading certificate or key file: %s",
                   gnutls_strerror(ret));
        return 0;
    }
    rb_free_datum_t(d_cert);
    rb_free_datum_t(d_key);

    if (dhfile != NULL)
    {
        if (gnutls_dh_params_init(&dh_params) == GNUTLS_E_SUCCESS)
        {
            gnutls_datum_t *data;
            int xret;
            data = rb_load_file_into_datum_t(dhfile);
            if (data != NULL)
            {
                xret = gnutls_dh_params_import_pkcs3(dh_params, data,
                                                     GNUTLS_X509_FMT_PEM);
                if (xret < 0)
                    rb_lib_log
                    ("rb_setup_ssl_server: Error parsing DH file: %s\n",
                     gnutls_strerror(xret));
                rb_free_datum_t(data);
            }
            gnutls_certificate_set_dh_params(x509, dh_params);
        }
        else
            rb_lib_log("rb_setup_ssl_server: Unable to setup DH parameters");
    }
    return 1;
}
Ejemplo n.º 25
0
void doit(void)
{
	/* 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;

	/* General init. */
	global_init();
	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(2);

	/* Init server */
	gnutls_certificate_allocate_credentials(&serverx509cred);
	gnutls_certificate_set_x509_key_mem(serverx509cred,
					    &server_cert, &server_key,
					    GNUTLS_X509_FMT_PEM);
	gnutls_init(&server, GNUTLS_SERVER);
	gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE,
			       serverx509cred);
	gnutls_priority_set_direct(server, "NORMAL", NULL);
	gnutls_transport_set_push_function(server, server_push);
	gnutls_transport_set_pull_function(server, server_pull);
	gnutls_transport_set_ptr(server, server);
	gnutls_certificate_set_verify_function(serverx509cred,
					       server_callback);
	gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST);
	gnutls_handshake_set_post_client_hello_function(server,
							post_client_hello_callback);
	gnutls_handshake_set_hook_function(server, GNUTLS_HANDSHAKE_ANY,
					   GNUTLS_HOOK_POST,
					   handshake_callback);

	/* Init client */
	gnutls_certificate_allocate_credentials(&clientx509cred);
	gnutls_init(&client, GNUTLS_CLIENT);
	gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE,
			       clientx509cred);
	gnutls_priority_set_direct(client, "NORMAL", NULL);
	gnutls_transport_set_push_function(client, client_push);
	gnutls_transport_set_pull_function(client, client_pull);
	gnutls_transport_set_ptr(client, client);
	gnutls_certificate_set_verify_function(clientx509cred,
					       client_callback);

	HANDSHAKE(client, server);

	gnutls_bye(client, GNUTLS_SHUT_RDWR);
	gnutls_bye(server, GNUTLS_SHUT_RDWR);

	gnutls_deinit(client);
	gnutls_deinit(server);

	gnutls_certificate_free_credentials(serverx509cred);
	gnutls_certificate_free_credentials(clientx509cred);

	gnutls_global_deinit();

	if (pch_ok == 0)
		fail("Post client hello callback wasn't called\n");

	if (server_ok == 0)
		fail("Server certificate verify callback wasn't called\n");

	if (client_ok == 0)
		fail("Client certificate verify callback wasn't called\n");
}
Ejemplo n.º 26
0
int
main (int argc, char *argv[])
{
    int debug_level = argc - 1;
    int exit_code = EXIT_SUCCESS;
    /* 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;

    /* General init. */
    gnutls_global_init ();
    gnutls_global_set_log_function (tls_log_func);
    gnutls_global_set_log_level (debug_level);

    /* Init server */
    gnutls_certificate_allocate_credentials (&serverx509cred);
    gnutls_certificate_set_x509_key_mem (serverx509cred,
                                         &server_cert, &server_key,
                                         GNUTLS_X509_FMT_PEM);
    gnutls_init (&server, GNUTLS_SERVER);
    gnutls_credentials_set (server, GNUTLS_CRD_CERTIFICATE, serverx509cred);
    gnutls_priority_set_direct (server, "NORMAL:%DISABLE_SAFE_RENEGOTIATION",
                                NULL);
    gnutls_transport_set_push_function (server, server_push);
    gnutls_transport_set_pull_function (server, server_pull);

    /* Init client */
    gnutls_certificate_allocate_credentials (&clientx509cred);
    gnutls_init (&client, GNUTLS_CLIENT);
    gnutls_credentials_set (client, GNUTLS_CRD_CERTIFICATE, clientx509cred);
    gnutls_priority_set_direct (client, "NORMAL", NULL);
    gnutls_transport_set_push_function (client, client_push);
    gnutls_transport_set_pull_function (client, client_pull);

    /* Check that initially no session use the extension. */
    if (gnutls_safe_renegotiation_status (server)
            || gnutls_safe_renegotiation_status (client))
    {
        puts ("Client or server using extension before handshake?");
        abort ();
    }

    do
    {
        static int max_iter = 0;
        if (max_iter++ > 10)
            abort ();

        if (cret == GNUTLS_E_AGAIN)
        {
            cret = gnutls_handshake (client);
            if (debug_level > 0)
            {
                tls_log_func (0, "gnutls_handshake (client)...\n");
                tls_log_func (0, gnutls_strerror (cret));
                tls_log_func (0, "\n");
            }
        }

        if (sret == GNUTLS_E_AGAIN)
        {
            sret = gnutls_handshake (server);
            if (debug_level > 0)
            {
                tls_log_func (0, "gnutls_handshake (server)...\n");
                tls_log_func (0, gnutls_strerror (sret));
                tls_log_func (0, "\n");
            }
        }
    }
    while (
        /* Not done: */
        !(cret == GNUTLS_E_SUCCESS && sret == GNUTLS_E_SUCCESS)
        /* No error: */
        && (cret == GNUTLS_E_AGAIN || sret == GNUTLS_E_AGAIN));

    if (cret != GNUTLS_E_SUCCESS && sret != GNUTLS_E_SUCCESS)
        exit_code = EXIT_FAILURE;

    if (gnutls_safe_renegotiation_status (client) ||
            gnutls_safe_renegotiation_status (server))
    {
        tls_log_func (0, "Session using safe renegotiation but shouldn't?!\n");
        exit_code = EXIT_FAILURE;
    }

    sret = gnutls_rehandshake (server);
    if (debug_level > 0)
    {
        tls_log_func (0, "gnutls_rehandshake (server)...\n");
        tls_log_func (0, gnutls_strerror (sret));
        tls_log_func (0, "\n");
    }

    {
        ssize_t n;
        char b[1];
        n = gnutls_record_recv (client, b, 1);
        if (n != GNUTLS_E_REHANDSHAKE)
            abort ();
    }

    cret = GNUTLS_E_AGAIN;
    sret = GNUTLS_E_AGAIN;

    do
    {
        static int max_iter = 0;
        if (max_iter++ > 10)
            abort ();

        if (cret == GNUTLS_E_AGAIN)
        {
            cret = gnutls_handshake (client);
            if (debug_level > 0)
            {
                tls_log_func (0, "second gnutls_handshake (client)...\n");
                tls_log_func (0, gnutls_strerror (cret));
                tls_log_func (0, "\n");
            }
        }

        if (sret == GNUTLS_E_AGAIN)
        {
            sret = gnutls_handshake (server);
            if (debug_level > 0)
            {
                tls_log_func (0, "second gnutls_handshake (server)...\n");
                tls_log_func (0, gnutls_strerror (sret));
                tls_log_func (0, "\n");
            }
        }

        if (cret == GNUTLS_E_UNSAFE_RENEGOTIATION_DENIED)
            break;
    }
    while (
        /* Not done: */
        !(cret == GNUTLS_E_SUCCESS && sret == GNUTLS_E_SUCCESS)
        /* No error: */
        && (cret == GNUTLS_E_AGAIN || sret == GNUTLS_E_AGAIN));

    if (cret != GNUTLS_E_UNSAFE_RENEGOTIATION_DENIED
            && sret != GNUTLS_E_SUCCESS)
        exit_code = 1;

    if (gnutls_safe_renegotiation_status (client) ||
            gnutls_safe_renegotiation_status (server))
    {
        tls_log_func (0, "Rehandshaked worked and uses safe reneg?!\n");
        exit_code = EXIT_FAILURE;
    }

    gnutls_bye (client, GNUTLS_SHUT_RDWR);
    gnutls_bye (server, GNUTLS_SHUT_RDWR);

    gnutls_deinit (client);
    gnutls_deinit (server);

    free (to_server);
    free (to_client);

    gnutls_certificate_free_credentials (serverx509cred);

    gnutls_global_deinit ();

    if (debug_level > 0)
    {
        if (exit_code == 0)
            puts ("Self-test successful");
        else
            puts ("Self-test failed");
    }

    return exit_code;
}
Ejemplo n.º 27
0
 void TLSSocket::deinit() {
     gnutls_certificate_free_credentials(xcred); 
     gnutls_global_deinit();
 }
Ejemplo n.º 28
0
static void start(const char *prio)
{
	int ret;
	/* Server stuff. */
	gnutls_certificate_credentials_t scred;
	gnutls_session_t server;
	gnutls_datum_t response;
	int sret = GNUTLS_E_AGAIN;
	/* Client stuff. */
	gnutls_certificate_credentials_t ccred;
	gnutls_session_t client;
	int cret = GNUTLS_E_AGAIN;

	success("testing %s\n", prio);

	/* General init. */
	global_init();
	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(4);

	/* Init server */
	gnutls_certificate_allocate_credentials(&scred);

	gnutls_certificate_set_retrieve_function3(scred,
						  server_cert_callback);

	gnutls_init(&server, GNUTLS_SERVER);
	gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, scred);
	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_certificate_server_set_request(server, GNUTLS_CERT_REQUEST);

	/* Init client */
	ret = gnutls_certificate_allocate_credentials(&ccred);
	if (ret < 0)
		exit(1);

	gnutls_certificate_set_verify_flags(ccred, GNUTLS_VERIFY_DISABLE_CRL_CHECKS);

	ret =
	    gnutls_certificate_set_x509_trust_mem(ccred, &ca3_cert,
						  GNUTLS_X509_FMT_PEM);
	if (ret < 0)
		exit(1);

	ret = gnutls_init(&client, GNUTLS_CLIENT);
	if (ret < 0)
		exit(1);

	ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE,
				     ccred);
	if (ret < 0)
		exit(1);

	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);

	HANDSHAKE(client, server);

	ret = gnutls_ocsp_status_request_get(client, &response);
	if (ret != 0)
		fail("no response was found: %s\n", gnutls_strerror(ret));

	assert(response.size == OCSP_SIZE);
	assert(memcmp(response.data, OCSP_DATA, OCSP_SIZE) == 0);

	if (gnutls_protocol_get_version(client) == GNUTLS_TLS1_3) {
		ret = gnutls_ocsp_status_request_get2(client, 1, &response);
		if (ret != 0)
			fail("no response was found for 1: %s\n", gnutls_strerror(ret));

		assert(response.size == OCSP_SIZE);
		assert(memcmp(response.data, OCSP_DATA, OCSP_SIZE) == 0);
	}

	ret = gnutls_ocsp_status_request_get2(client, 2, &response);
	if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
		fail("found response in index 2: %s\n", gnutls_strerror(ret));
	}

	gnutls_bye(client, GNUTLS_SHUT_WR);
	gnutls_bye(server, GNUTLS_SHUT_WR);

	gnutls_deinit(client);
	gnutls_deinit(server);

	gnutls_certificate_free_credentials(scred);
	gnutls_certificate_free_credentials(ccred);

	gnutls_global_deinit();

	reset_buffers();
}
Ejemplo n.º 29
0
/* tls_negotiate: After TLS state has been initialised, attempt to negotiate
 *   TLS over the wire, including certificate checks. */
static int tls_negotiate (CONNECTION * conn)
{
  tlssockdata *data;
  int err;

  data = (tlssockdata *) safe_calloc (1, sizeof (tlssockdata));
  conn->sockdata = data;
  err = gnutls_certificate_allocate_credentials (&data->xcred);
  if (err < 0)
  {
    FREE(&conn->sockdata);
    mutt_error ("gnutls_certificate_allocate_credentials: %s", gnutls_strerror(err));
    mutt_sleep (2);
    return -1;
  }

  gnutls_certificate_set_x509_trust_file (data->xcred, SslCertFile,
					  GNUTLS_X509_FMT_PEM);
  /* ignore errors, maybe file doesn't exist yet */

  if (SslCACertFile)
  {
    gnutls_certificate_set_x509_trust_file (data->xcred, SslCACertFile,
                                            GNUTLS_X509_FMT_PEM);
  }

  if (SslClientCert)
  {
    dprint (2, (debugfile, "Using client certificate %s\n", SslClientCert));
    gnutls_certificate_set_x509_key_file (data->xcred, SslClientCert,
                                          SslClientCert, GNUTLS_X509_FMT_PEM);
  }

  gnutls_init(&data->state, GNUTLS_CLIENT);

  /* set socket */
  gnutls_transport_set_ptr (data->state, (gnutls_transport_ptr)conn->fd);

  /* disable TLS/SSL protocols as needed */
  if (!option(OPTTLSV1) && !option(OPTSSLV3))
  {
    mutt_error (_("All available protocols for TLS/SSL connection disabled"));
    goto fail;
  }
  else if (!option(OPTTLSV1))
  {
    protocol_priority[0] = GNUTLS_SSL3;
    protocol_priority[1] = 0;
  }
  else if (!option(OPTSSLV3))
  {
    protocol_priority[0] = GNUTLS_TLS1;
    protocol_priority[1] = 0;
  }
  /*
  else
    use the list set above
  */

  /* We use default priorities (see gnutls documentation),
     except for protocol version */
  gnutls_set_default_priority (data->state);
  gnutls_protocol_set_priority (data->state, protocol_priority);

  if (SslDHPrimeBits > 0)
  {
    gnutls_dh_set_prime_bits (data->state, SslDHPrimeBits);
  }

/*
  gnutls_set_cred (data->state, GNUTLS_ANON, NULL);
*/

  gnutls_credentials_set (data->state, GNUTLS_CRD_CERTIFICATE, data->xcred);

  err = gnutls_handshake(data->state);

  while (err == GNUTLS_E_AGAIN || err == GNUTLS_E_INTERRUPTED)
  {
    err = gnutls_handshake(data->state);
  }
  if (err < 0) {
    if (err == GNUTLS_E_FATAL_ALERT_RECEIVED)
    {
      mutt_error("gnutls_handshake: %s(%s)", gnutls_strerror(err),
		 gnutls_alert_get_name(gnutls_alert_get(data->state)));
    }
    else
    {
      mutt_error("gnutls_handshake: %s", gnutls_strerror(err));
    }
    mutt_sleep (2);
    goto fail;
  }

  if (!tls_check_certificate(conn))
    goto fail;

  /* set Security Strength Factor (SSF) for SASL */
  /* NB: gnutls_cipher_get_key_size() returns key length in bytes */
  conn->ssf = gnutls_cipher_get_key_size (gnutls_cipher_get (data->state)) * 8;

  tls_get_client_cert (conn);

  if (!option(OPTNOCURSES)) {
    mutt_message (_("SSL/TLS connection using %s (%s/%s/%s)"),
                  gnutls_protocol_get_name (gnutls_protocol_get_version (data->state)),
                  gnutls_kx_get_name (gnutls_kx_get (data->state)),
                  gnutls_cipher_get_name (gnutls_cipher_get (data->state)),
                  gnutls_mac_get_name (gnutls_mac_get (data->state)));
    mutt_sleep (0);
  }

  return 0;

 fail:
  gnutls_certificate_free_credentials (data->xcred);
  gnutls_deinit (data->state);
  FREE(&conn->sockdata);
  return -1;
}
Ejemplo n.º 30
0
/*
	main - Asks for a list of relays, initializes a TLS server and starts a thread for every client.
*/
int main (void)
{
	int client_socket_descriptor;
	struct sockaddr_in sockaddr_client;
	socklen_t client_adress_length;
	char topbuf[512];
	int ret;
	int file;
	struct stat fileinfo;

	ret = stat(FILE_LIST_RELAYS, &fileinfo);
	if (ret != 0) {
		fprintf (stderr, "Impossible to find file \"%s\"\n", FILE_LIST_RELAYS);
		return -1;
	}

	nbr_relays = fileinfo.st_size/sizeof(MYSOCKET);

	list_relays = malloc (nbr_relays*sizeof(MYSOCKET));

	file = open (FILE_LIST_RELAYS, O_RDONLY);
	if (file == -1) {
		ret = errno;
		fprintf (stderr, "Impossible to open \"%s\", errno = %d\n", FILE_LIST_RELAYS, ret);
		free (list_relays);
		return -1;
	}

	ret = read (file, list_relays, sizeof(MYSOCKET)*nbr_relays);
	if (ret != sizeof(MYSOCKET)*nbr_relays) {
		fprintf (stderr, "Error in reading : %d bytes read instead of %d\n", ret, sizeof(MYSOCKET)*nbr_relays);
		free (list_relays);
		return -1;
	}
	int i;
	for (i=0;i<nbr_relays;i++)
	{
		int ip = ((MYSOCKET*)list_relays)[i].ip;
		printf("Relay[%i], ip=%d.%d.%d.%d, port=%i\n",i,(ip) & 0xFF,(ip>>8) & 0xFF,
		(ip>>16) & 0xFF, (ip>>24) & 0xFF,ntohs(((MYSOCKET*)list_relays)[i].port));
	}

	close (file);

	printf ("%d trusted relays successfully read from file \"%s\"\n", nbr_relays, FILE_LIST_RELAYS);	

	if (mytls_server_init (DIRECTORY_PORT, &xcred, &priority_cache, &listen_socket_descriptor, &sockaddr_server, 0) != 0) {
		return -1;
	}

	client_adress_length = sizeof (sockaddr_client);
	for (;;) {
		client_socket_descriptor = accept (listen_socket_descriptor, (struct sockaddr *) &sockaddr_client, &client_adress_length);
		printf ("- connection from %s, port %d\n", inet_ntop (AF_INET, &sockaddr_client.sin_addr, topbuf, sizeof (topbuf)),
			ntohs(sockaddr_client.sin_port));

		pthread_t thread;
		pthread_attr_t attr;
		pthread_attr_init(&attr);
		pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
		pthread_create(&thread, &attr, handle_connection, (void *)client_socket_descriptor);
	}
	close (listen_socket_descriptor);

	gnutls_certificate_free_credentials (xcred);
	gnutls_priority_deinit (priority_cache);

	gnutls_global_deinit ();

	free (list_relays);

	return 0;
}