예제 #1
0
static int verify_certificate_callback (gnutls_session_t session)
{
  if (trust_override)
    return 0;

  // This verification function uses the trusted CAs in the credentials
  // structure. So you must have installed one or more CA certificates.
  unsigned int status = 0;
#if GNUTLS_VERSION_NUMBER >= 0x030104
  int ret = gnutls_certificate_verify_peers3 (session, NULL, &status);
#else
  int ret = gnutls_certificate_verify_peers2 (session, &status);
#endif
  if (ret < 0)
    return GNUTLS_E_CERTIFICATE_ERROR;

#if GNUTLS_VERSION_NUMBER >= 0x030105
  gnutls_certificate_type_t type = gnutls_certificate_type_get (session);
  gnutls_datum_t out;
  ret = gnutls_certificate_verification_status_print (status, type, &out, 0);
  if (ret < 0)
    return GNUTLS_E_CERTIFICATE_ERROR;

  gnutls_free (out.data);
#endif

  if (status != 0)
    return GNUTLS_E_CERTIFICATE_ERROR;

  // Continue handshake.
  return 0;
}
예제 #2
0
파일: dtls_echo.c 프로젝트: a34729t/exp
/* This function will verify the peer's certificate, and check
 * if the hostname matches, as well as the activation, expiration dates.
 */
extern int
verify_certificate_callback (gnutls_session_t session)
{
  unsigned int status;
  int ret, type;
  const char *hostname;
  gnutls_datum_t out;

  /* read hostname */
  hostname = gnutls_session_get_ptr (session);

  /* This verification function uses the trusted CAs in the credentials
   * structure. So you must have installed one or more CA certificates.
   */
  ret = gnutls_certificate_verify_peers3 (session, hostname, &status);
  if (ret < 0)
    {
      printf ("Error\n");
      return GNUTLS_E_CERTIFICATE_ERROR;
    }

  type = gnutls_certificate_type_get (session);

  ret = gnutls_certificate_verification_status_print( status, type, &out, 0);
  if (ret < 0)
    {
      printf ("Error\n");
      return GNUTLS_E_CERTIFICATE_ERROR;
    }
  
  printf ("%s", out.data);
  
  gnutls_free(out.data);

  if (status != 0) /* Certificate is not trusted */
      return GNUTLS_E_CERTIFICATE_ERROR;

  /* notify gnutls to continue handshake normally */
  return 0;
}
예제 #3
0
파일: common.c 프로젝트: randombit/hacrypto
/* returns false (0) if not verified, or true (1) otherwise 
 */
int cert_verify(gnutls_session_t session, const char *hostname)
{
	int rc;
	unsigned int status = 0;
	gnutls_datum_t out;
	int type;

	rc = gnutls_certificate_verify_peers3(session, hostname, &status);
	if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND) {
		printf("- Peer did not send any certificate.\n");
		return 0;
	}

	if (rc < 0) {
		printf("- Could not verify certificate (err: %s)\n",
		       gnutls_strerror(rc));
		return 0;
	}

	type = gnutls_certificate_type_get(session);
	rc = gnutls_certificate_verification_status_print(status, type,
							  &out, 0);
	if (rc < 0) {
		printf("- Could not print verification flags (err: %s)\n",
		       gnutls_strerror(rc));
		return 0;
	}

	printf("- Status: %s\n", out.data);

	gnutls_free(out.data);

	if (status)
		return 0;

	return 1;
}
예제 #4
0
파일: connect.c 프로젝트: baishakhir/ssl
/* This function will verify the peer's certificate, and check
 * if the hostname matches, as well as the activation, expiration dates.
 */
static int
_verify_certificate_callback (gnutls_session_t session)
{
  unsigned int status;
  int ret, type;
  const char *hostname;
  gnutls_datum_t out;

  hostname = gnutls_session_get_ptr (session);
  ret = gnutls_certificate_verify_peers3 (session, NULL, &status);
  if (ret < 0) {
	  return GNUTLS_E_CERTIFICATE_ERROR;
  }

  type = gnutls_certificate_type_get (session);
  ret = gnutls_certificate_verification_status_print( status, type, &out, 0);

  if (status != 0) {
      error = out.data;
      verification_result = status;
      return GNUTLS_E_CERTIFICATE_ERROR;
  }
  return 0;
}
예제 #5
0
/* This function will verify the peer's certificate, and check
 * if the hostname matches, as well as the activation, expiration dates.
 */
static int _verify_certificate_callback(gnutls_session_t session)
{
        unsigned int status;
        int ret, type;
        const char *hostname;
        gnutls_datum_t out;

        /* read hostname */
        hostname = gnutls_session_get_ptr(session);

        /* This verification function uses the trusted CAs in the credentials
         * structure. So you must have installed one or more CA certificates.
         */

         /* The following demonstrate two different verification functions,
          * the more flexible gnutls_certificate_verify_peers(), as well
          * as the old gnutls_certificate_verify_peers3(). */
#if 1
        {
        gnutls_typed_vdata_st data[2];

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

        data[0].type = GNUTLS_DT_DNS_HOSTNAME;
        data[0].data = (void*)hostname;

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

        ret = gnutls_certificate_verify_peers(session, data, 2,
					      &status);
        }
#else
        ret = gnutls_certificate_verify_peers3(session, hostname,
					       &status);
#endif
        if (ret < 0) {
                printf("Error\n");
                return GNUTLS_E_CERTIFICATE_ERROR;
        }

        type = gnutls_certificate_type_get(session);

        ret =
            gnutls_certificate_verification_status_print(status, type,
                                                         &out, 0);
        if (ret < 0) {
                printf("Error\n");
                return GNUTLS_E_CERTIFICATE_ERROR;
        }

        printf("%s", out.data);

        gnutls_free(out.data);

        if (status != 0)        /* Certificate is not trusted */
                return GNUTLS_E_CERTIFICATE_ERROR;

        /* notify gnutls to continue handshake normally */
        return 0;
}
예제 #6
0
파일: utils-adv.c 프로젝트: komh/gnutls-os2
void
test_cli_serv(gnutls_certificate_credentials_t server_cred, const char *prio,
              const gnutls_datum_t *ca_cert, const char *host)
{
	int exit_code = EXIT_SUCCESS;
	int ret;
	/* Server stuff. */
	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. */
	reset_buffers();

	/* Init server */

	gnutls_init(&server, GNUTLS_SERVER);
	gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE,
			       server_cred);
	gnutls_priority_set_direct(server, prio, 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);


	assert(gnutls_server_name_set(client, GNUTLS_NAME_DNS, host, strlen(host))>=0);

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

	gnutls_priority_set_direct(client, prio, 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);

	/* check the number of certificates received and verify */
	{
		gnutls_typed_vdata_st data[2];
		unsigned status;

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

		data[0].type = GNUTLS_DT_DNS_HOSTNAME;
		data[0].data = (void*)host;

		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) {
			fail("could not verify certificate: %s\n", gnutls_strerror(ret));
			exit(1);
		}

		if (status != 0) {
			gnutls_datum_t t;
			assert(gnutls_certificate_verification_status_print(status, GNUTLS_CRT_X509, &t, 0)>=0);
			fail("could not verify certificate for '%s': %.4x: %s\n", host, status, t.data);
			gnutls_free(t.data);
			exit(1);
		}

		/* check gnutls_certificate_verify_peers3 */
		ret = gnutls_certificate_verify_peers3(client, host, &status);
		if (ret < 0) {
			fail("could not verify certificate: %s\n", gnutls_strerror(ret));
			exit(1);
		}

		if (status != 0) {
			gnutls_datum_t t;
			assert(gnutls_certificate_verification_status_print(status, GNUTLS_CRT_X509, &t, 0)>=0);
			fail("could not verify certificate3: %.4x: %s\n", status, t.data);
			gnutls_free(t.data);
			exit(1);
		}
	}

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

	gnutls_deinit(client);
	gnutls_deinit(server);

	gnutls_certificate_free_credentials(clientx509cred);

	if (debug > 0) {
		if (exit_code == 0)
			puts("Self-test successful");
		else
			puts("Self-test failed");
	}
}
예제 #7
0
int TLSClient::verify_certificate () const
{
  if (_trust == TLSClient::allow_all)
    return 0;

  // This verification function uses the trusted CAs in the credentials
  // structure. So you must have installed one or more CA certificates.
  unsigned int status = 0;
  const char* hostname = _host.c_str();
#if GNUTLS_VERSION_NUMBER >= 0x030104
  if (_trust == TLSClient::ignore_hostname)
    hostname = NULL;

  int ret = gnutls_certificate_verify_peers3 (_session, hostname, &status);
  if (ret < 0)
  {
    if (_debug)
      std::cout << "c: ERROR Certificate verification peers3 failed. " << gnutls_strerror (ret) << "\n";
    return GNUTLS_E_CERTIFICATE_ERROR;
  }
#else
  int ret = gnutls_certificate_verify_peers2 (_session, &status);
  if (ret < 0)
  {
    if (_debug)
      std::cout << "c: ERROR Certificate verification peers2 failed. " << gnutls_strerror (ret) << "\n";
    return GNUTLS_E_CERTIFICATE_ERROR;
  }

  if ((status == 0) && (_trust != TLSClient::ignore_hostname))
  {
    if (gnutls_certificate_type_get (_session) == GNUTLS_CRT_X509)
    {
      const gnutls_datum* cert_list;
      unsigned int cert_list_size;
      gnutls_x509_crt cert;

      cert_list = gnutls_certificate_get_peers (_session, &cert_list_size);
      if (cert_list_size == 0)
      {
        if (_debug)
          std::cout << "c: ERROR Certificate get peers failed. " << gnutls_strerror (ret) << "\n";
        return GNUTLS_E_CERTIFICATE_ERROR;
      }

      ret = gnutls_x509_crt_init (&cert);
      if (ret < 0)
      {
        if (_debug)
          std::cout << "c: ERROR x509 init failed. " << gnutls_strerror (ret) << "\n";
        return GNUTLS_E_CERTIFICATE_ERROR;
      }

      ret = gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER);
      if (ret < 0)
      {
        if (_debug)
          std::cout << "c: ERROR x509 cert import. " << gnutls_strerror (ret) << "\n";
        gnutls_x509_crt_deinit(cert);
        return GNUTLS_E_CERTIFICATE_ERROR;
      }

      if (gnutls_x509_crt_check_hostname (cert, hostname) == 0)
      {
        if (_debug)
          std::cout << "c: ERROR x509 cert check hostname. " << gnutls_strerror (ret) << "\n";
        gnutls_x509_crt_deinit(cert);
        return GNUTLS_E_CERTIFICATE_ERROR;
      }
    }
    else
      return GNUTLS_E_CERTIFICATE_ERROR;
  }
#endif

#if GNUTLS_VERSION_NUMBER >= 0x030104
  gnutls_certificate_type_t type = gnutls_certificate_type_get (_session);
  gnutls_datum_t out;
  ret = gnutls_certificate_verification_status_print (status, type, &out, 0);
  if (ret < 0)
  {
    if (_debug)
      std::cout << "c: ERROR certificate verification status. " << gnutls_strerror (ret) << "\n";
    return GNUTLS_E_CERTIFICATE_ERROR;
  }

  if (_debug)
    std::cout << "c: INFO " << out.data << "\n";
  gnutls_free (out.data);
#endif

  if (status != 0)
    return GNUTLS_E_CERTIFICATE_ERROR;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		rfbssl_ctx* ctx = (rfbssl_ctx*) malloc(sizeof(struct rfbssl_ctx));
		ctx->peeklen = 0;
		ctx->peekstart = 0;
		ctx->session = session;
		ctx->x509_cred = credentials;
		ctx->dh_params = 0;
		
		cl->sslctx = (rfbSslCtx*)ctx;
	} catch (...) {
		//Irgendein Fehler trat auf, dann schließen.
		std::cerr << gtlsRet << ' ' << gnutls_error_is_fatal(gtlsRet) << std::endl;
		std::cerr << gnutls_strerror(gtlsRet) << std::endl;
		std::cerr << gnutls_alert_get_name(gnutls_alert_get(session)) << std::endl;
		if (session) gnutls_deinit(session);
		if (credentials) gnutls_certificate_free_credentials(credentials);
		
		return RFB_CLIENT_REFUSE;
	}
	
	return RFB_CLIENT_ACCEPT;
}
예제 #10
0
/* if @host is NULL certificate check is skipped */
static int
_test_cli_serv(gnutls_certificate_credentials_t server_cred,
	      gnutls_certificate_credentials_t client_cred,
	      const char *serv_prio, const char *cli_prio,
	      const char *host,
	      void *priv, callback_func *client_cb, callback_func *server_cb,
	      unsigned expect_verification_failure,
	      unsigned require_cert,
	      int serv_err,
	      int cli_err)
{
	int exit_code = EXIT_SUCCESS;
	int ret;
	/* Server stuff. */
	gnutls_session_t server;
	int sret = GNUTLS_E_AGAIN;
	/* Client stuff. */
	gnutls_session_t client;
	int cret = GNUTLS_E_AGAIN;

	/* General init. */
	reset_buffers();

	/* Init server */
	gnutls_init(&server, GNUTLS_SERVER);
	gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE,
				server_cred);
	gnutls_priority_set_direct(server, serv_prio, NULL);
	gnutls_transport_set_push_function(server, server_push);
	gnutls_transport_set_pull_function(server, server_pull);
	gnutls_transport_set_ptr(server, server);

	if (require_cert)
		gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUIRE);

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

	if (host) {
		if (strncmp(host, "raw:", 4) == 0) {
			assert(_gnutls_server_name_set_raw(client, GNUTLS_NAME_DNS, host+4, strlen(host+4))>=0);
			host += 4;
		} else {
			assert(gnutls_server_name_set(client, GNUTLS_NAME_DNS, host, strlen(host))>=0);
		}
	}

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

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

	if (cli_err == 0 && serv_err == 0) {
		HANDSHAKE(client, server);
	} else {
		HANDSHAKE_EXPECT(client, server, cli_err, serv_err);
	}

	/* check the number of certificates received and verify */
	if (host) {
		gnutls_typed_vdata_st data[2];
		unsigned status;

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

		data[0].type = GNUTLS_DT_DNS_HOSTNAME;
		data[0].data = (void*)host;

		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) {
			fail("could not verify certificate: %s\n", gnutls_strerror(ret));
			exit(1);
		}

		if (expect_verification_failure && status != 0) {
			ret = status;
			goto cleanup;
		} else if (expect_verification_failure && status == 0) {
			fail("expected verification failure but verification succeeded!\n");
		}

		if (status != 0) {
			gnutls_datum_t t;
			assert(gnutls_certificate_verification_status_print(status, GNUTLS_CRT_X509, &t, 0)>=0);
			fail("could not verify certificate for '%s': %.4x: %s\n", host, status, t.data);
			gnutls_free(t.data);
			exit(1);
		}

		/* check gnutls_certificate_verify_peers3 */
		ret = gnutls_certificate_verify_peers3(client, host, &status);
		if (ret < 0) {
			fail("could not verify certificate: %s\n", gnutls_strerror(ret));
			exit(1);
		}

		if (status != 0) {
			gnutls_datum_t t;
			assert(gnutls_certificate_verification_status_print(status, GNUTLS_CRT_X509, &t, 0)>=0);
			fail("could not verify certificate3: %.4x: %s\n", status, t.data);
			gnutls_free(t.data);
			exit(1);
		}
	}

	ret = 0;
 cleanup:
	if (client_cb)
		client_cb(client, priv);
	if (server_cb)
		server_cb(server, priv);

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

	gnutls_deinit(client);
	gnutls_deinit(server);

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

	return ret;
}