Esempio n. 1
0
TCPStream::TCPStream(int sd, gnutls_session_t* session, struct sockaddr_in* address):
    m_sd(sd) {

    char ip[50];
    inet_ntop(PF_INET, (struct in_addr*)&(address->sin_addr.s_addr), ip, sizeof(ip)-1);
    m_peerIP = ip;
    m_peerPort = ntohs(address->sin_port);
    secure = true;

    char *desc1;
    desc1 = gnutls_session_get_desc(*session);
    printf("- Session info: %s\n", desc1);
    gnutls_free(desc1);

    std::cout<<"Session addresss "<<session<<std::endl;

    m_session = session;

    char *desc2;
    desc2 = gnutls_session_get_desc(*m_session);
    printf("- Session info: %s\n", desc2);
    gnutls_free(desc2);

    std::cout<<"m_session addresss "<<m_session<<std::endl;

    /*m_session = (gnutls_session_t*) malloc(sizeof(gnutls_session_t)+1);
    memcpy(m_session, session, sizeof(gnutls_session_t));
    char *desc2;
    desc2 = gnutls_session_get_desc(*m_session);
    printf("- Session info: %s\n", desc2);
    gnutls_free(desc2);

    std::cout<<"m_session addresss "<<m_session<<std::endl;*/
}
Esempio n. 2
0
extern int xlibgnutls_tls_handshake(gnutls_session_t *session, int tcp_sd, unsigned verbose_level) {
	int ret, ii;
	/* Need to enable anonymous KX specifically. */

	gnutls_global_init();
	gnutls_anon_allocate_client_credentials(&anoncred);
	gnutls_init(session, GNUTLS_CLIENT);

	gnutls_priority_set_direct(*session, "NORMAL:+ANON-ECDH:+ANON-DH", NULL);
	gnutls_credentials_set(*session, GNUTLS_CRD_ANON, anoncred);
	gnutls_transport_set_int(*session, tcp_sd);
	gnutls_handshake_set_timeout(*session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);

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

	if (ret < 0) {
		print_error("handshake failed");
		gnutls_perror(ret);
	} else {
		char *desc;
		desc = gnutls_session_get_desc(*session);
		print_info("- Session info: %s\n", desc);
		gnutls_free(desc);
	}

	return ret;
}
Esempio n. 3
0
void ssl_get_info(http_t *client)
{
#ifndef gnutls_session_get_desc
	(void)client;
#else
	char *info;

	/* Available since 3.1.10  */
	info = gnutls_session_get_desc(client->ssl);
	logit(LOG_INFO, "SSL connection using: %s", info);
	gnutls_free(info);
#endif
}
Esempio n. 4
0
int main(void)
{
        int ret, sd, ii;
        gnutls_session_t session;
        char buffer[MAX_BUF + 1];
        const char *err;
        gnutls_certificate_credentials_t xcred;

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

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

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

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

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

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

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

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

        gnutls_transport_set_int(session, sd);

        /* set the connection MTU */
        gnutls_dtls_set_mtu(session, 1000);
        gnutls_handshake_set_timeout(session,
                                     GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);

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

        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 */
        gnutls_bye(session, GNUTLS_SHUT_WR);

      end:

        udp_close(sd);

        gnutls_deinit(session);

        gnutls_certificate_free_credentials(xcred);

        gnutls_global_deinit();

        return 0;
}
Esempio n. 5
0
int main(void)
{
        int ret, sd, ii;
        gnutls_session_t session;
        char buffer[MAX_BUF + 1];
        const char *err;
        gnutls_certificate_credentials_t xcred;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        gnutls_bye(session, GNUTLS_SHUT_RDWR);

      end:

        tcp_close(sd);

        gnutls_deinit(session);

        gnutls_certificate_free_credentials(xcred);

        gnutls_global_deinit();

        return 0;
}
Esempio n. 6
0
void TLSClient::connect (const std::string& host, const std::string& port)
{
  _host = host;
  _port = port;

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

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

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

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

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

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

    break;
  }

  free (res);

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

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

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

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

  if (_debug)
  {
#if GNUTLS_VERSION_NUMBER >= 0x03010a
    char* desc = gnutls_session_get_desc (_session);
    std::cout << "c: INFO Handshake was completed: " << desc << "\n";
    gnutls_free (desc);
#else
    std::cout << "c: INFO Handshake was completed.\n";
#endif
  }
}
Esempio n. 7
0
extern int xlibgnutls_dtls_handshake(gnutls_session_t *session, int udp_sd, unsigned verbose_level) {
	const char *CAFILE = "ca-cert.pem"; // TODO: use anoncred
	int ret;
	const char *err;

	if (gnutls_check_version("3.1.4") == NULL) {
		print_error("GnuTLS 3.1.4 or later is required");
		return -1;
	}

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

	if (verbose_level >= VERBOSE_LEVEL_GNUTLS) {
		gnutls_global_set_log_level(9999);
		gnutls_global_set_log_function(gnutls_log);
	}

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

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

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

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

	if (verbose_level >= VERBOSE_LEVEL_PACKETS) {
		gnutls_transport_set_push_function(*session, gnutls_push_func_custom);
		//gnutls_transport_set_pull_function(*session, gnutls_pull_func_custom);
		//gnutls_transport_set_pull_timeout_function(*session, gnutls_pull_timeout_func_custom);
	}

	gnutls_dtls_set_mtu(*session, 1 << 14);
	gnutls_set_default_priority(*session);
	/* if more fine-graned control is required */
	ret = gnutls_priority_set_direct(*session, "NORMAL", &err);
	if (ret < 0) {
		if (ret == GNUTLS_E_INVALID_REQUEST)
			print_error("syntax error at: %d", err);
		goto end;
	}

	gnutls_transport_set_int(*session, udp_sd);
	gnutls_handshake_set_timeout(*session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);

	if (verbose_level >= VERBOSE_LEVEL_CLIENT)
		print_info("handshake started");
	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 (verbose_level >= VERBOSE_LEVEL_CLIENT)
		print_info("handshake finished");

	if (ret < 0) {
		print_error("handshake failed with return code %d", ret);
		gnutls_perror(ret);
		goto end;
	} else {
		char *desc;
		desc = gnutls_session_get_desc(*session);
		if (verbose_level >= VERBOSE_LEVEL_CLIENT)
			print_info("session info: %s", desc);
		gnutls_free(desc);
	}

	ret = 0;

end:
	return ret;
}
Esempio n. 8
0
int print_info(gnutls_session_t session, int verbose, int print_cert)
{
	const char *tmp;
	gnutls_credentials_type_t cred;
	gnutls_kx_algorithm_t kx;
	unsigned char session_id[33];
	size_t session_id_size = sizeof(session_id);
	gnutls_srtp_profile_t srtp_profile;
	gnutls_datum_t p;
	char *desc;
	int rc;

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

	/* print session ID */
	gnutls_session_get_id(session, session_id, &session_id_size);
	printf("- Session ID: %s\n",
	       raw_to_string(session_id, session_id_size));

	/* print the key exchange's algorithm name
	 */
	kx = gnutls_kx_get(session);

	cred = gnutls_auth_get_type(session);
	switch (cred) {
#ifdef ENABLE_ANON
	case GNUTLS_CRD_ANON:
		if (kx == GNUTLS_KX_ANON_ECDH)
			print_ecdh_info(session, "Anonymous ");
		else
			print_dh_info(session, "Anonymous ", verbose);
		break;
#endif
#ifdef ENABLE_SRP
	case GNUTLS_CRD_SRP:
		/* This should be only called in server
		 * side.
		 */
		if (gnutls_srp_server_get_username(session) != NULL)
			printf("- SRP authentication. Connected as '%s'\n",
			       gnutls_srp_server_get_username(session));
		break;
#endif
#ifdef ENABLE_PSK
	case GNUTLS_CRD_PSK:
		/* This returns NULL in server side.
		 */
		if (gnutls_psk_client_get_hint(session) != NULL)
			printf("- PSK authentication. PSK hint '%s'\n",
			       gnutls_psk_client_get_hint(session));
		/* This returns NULL in client side.
		 */
		if (gnutls_psk_server_get_username(session) != NULL)
			printf("- PSK authentication. Connected as '%s'\n",
			       gnutls_psk_server_get_username(session));
		if (kx == GNUTLS_KX_DHE_PSK)
			print_dh_info(session, "Ephemeral ", verbose);
		if (kx == GNUTLS_KX_ECDHE_PSK)
			print_ecdh_info(session, "Ephemeral ");
		break;
#endif
	case GNUTLS_CRD_IA:
		printf("- TLS/IA authentication\n");
		break;
	case GNUTLS_CRD_CERTIFICATE:
		{
			char dns[256];
			size_t dns_size = sizeof(dns);
			unsigned int type;

			/* This fails in client side */
			if (gnutls_server_name_get
			    (session, dns, &dns_size, &type, 0) == 0) {
				printf("- Given server name[%d]: %s\n",
				       type, dns);
			}
		}

		if (print_cert)
			print_cert_info(session, verbose, print_cert);

		if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS)
			print_dh_info(session, "Ephemeral ", verbose);
		else if (kx == GNUTLS_KX_ECDHE_RSA
			 || kx == GNUTLS_KX_ECDHE_ECDSA)
			print_ecdh_info(session, "Ephemeral ");
	}

	tmp =
	    SU(gnutls_protocol_get_name
	       (gnutls_protocol_get_version(session)));
	printf("- Version: %s\n", tmp);

	tmp = SU(gnutls_kx_get_name(kx));
	printf("- Key Exchange: %s\n", tmp);

	if (gnutls_sign_algorithm_get(session) != GNUTLS_SIGN_UNKNOWN) {
		tmp =
		    SU(gnutls_sign_get_name
		       (gnutls_sign_algorithm_get(session)));
		printf("- Server Signature: %s\n", tmp);
	}

	if (gnutls_sign_algorithm_get_client(session) !=
	    GNUTLS_SIGN_UNKNOWN) {
		tmp =
		    SU(gnutls_sign_get_name
		       (gnutls_sign_algorithm_get_client(session)));
		printf("- Client Signature: %s\n", tmp);
	}

	tmp = SU(gnutls_cipher_get_name(gnutls_cipher_get(session)));
	printf("- Cipher: %s\n", tmp);

	tmp = SU(gnutls_mac_get_name(gnutls_mac_get(session)));
	printf("- MAC: %s\n", tmp);

	tmp =
	    SU(gnutls_compression_get_name
	       (gnutls_compression_get(session)));
	printf("- Compression: %s\n", tmp);

#ifdef ENABLE_DTLS_SRTP
	rc = gnutls_srtp_get_selected_profile(session, &srtp_profile);
	if (rc == 0)
		printf("- SRTP profile: %s\n",
		       gnutls_srtp_get_profile_name(srtp_profile));
#endif

#ifdef ENABLE_ALPN
	rc = gnutls_alpn_get_selected_protocol(session, &p);
	if (rc == 0)
		printf("- Application protocol: %.*s\n", p.size, p.data);
#endif

	if (verbose) {
		gnutls_datum_t cb;

		rc = gnutls_session_channel_binding(session,
						    GNUTLS_CB_TLS_UNIQUE,
						    &cb);
		if (rc)
			fprintf(stderr, "Channel binding error: %s\n",
				gnutls_strerror(rc));
		else {
			size_t i;

			printf("- Channel binding 'tls-unique': ");
			for (i = 0; i < cb.size; i++)
				printf("%02x", cb.data[i]);
			printf("\n");
		}
	}

	/* Warning: Do not print anything more here. The 'Compression:'
	   output MUST be the last non-verbose output.  This is used by
	   Emacs starttls.el code. */

	fflush(stdout);

	return 0;
}
Esempio n. 9
0
int main(void)
{
        int ret, sd, ii;
        gnutls_session_t session;
        char buffer[MAX_BUF + 1];
        const char *err;
        gnutls_psk_client_credentials_t pskcred;
        const gnutls_datum_t key = { (void *) "DEADBEEF", 8 };

        CHECK(gnutls_global_init());

        CHECK(gnutls_psk_allocate_client_credentials(&pskcred));
        CHECK(gnutls_psk_set_client_credentials(pskcred, "test", &key,
                                                GNUTLS_PSK_KEY_HEX));

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

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

        /* put the x509 credentials to the current session
         */
        CHECK(gnutls_credentials_set(session, GNUTLS_CRD_PSK, pskcred));

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

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

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

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

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

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

        CHECK(gnutls_bye(session, GNUTLS_SHUT_RDWR));

      end:

        tcp_close(sd);

        gnutls_deinit(session);

        gnutls_psk_free_client_credentials(pskcred);

        gnutls_global_deinit();

        return 0;
}
Esempio n. 10
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 ();
  /* PKCS11 private key operations might require PIN.
   * Register a callback.
   */
  gnutls_pkcs11_set_pin_function (pin_callback, NULL);

  /* 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_set_x509_key_file (xcred, CERT_URL, KEY_URL, GNUTLS_X509_FMT_DER);

  /* 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_int (session, sd);

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

  if (ret < 0)
    {
      fprintf (stderr, "*** Handshake failed\n");
      gnutls_perror (ret);
      goto end;
    }
  else
    {
      char* desc;
      
      desc = gnutls_session_get_desc(session);
      printf ("- Session info: %s\n", desc);
      gnutls_free(desc);
    }

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

  ret = gnutls_record_recv (session, buffer, MAX_BUF);
  if (ret == 0)
    {
      printf ("- Peer has closed the TLS connection\n");
      goto end;
    }
  else if (ret < 0)
    {
      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;
}
Esempio n. 11
0
static void test_ciphersuite_kx(const char *cipher_prio, unsigned pk)
{
	/* Server stuff. */
	gnutls_anon_server_credentials_t s_anoncred;
	gnutls_session_t server;
	int sret, cret;
	const char *str;
	char *suite = NULL;
	/* Client stuff. */
	gnutls_anon_client_credentials_t c_anoncred;
	gnutls_certificate_credentials_t c_certcred, s_certcred;
	gnutls_session_t client;
	/* Need to enable anonymous KX specifically. */
	int ret;
	struct benchmark_st st;
	struct timespec tr_start, tr_stop;
	double avg, sstddev;
	gnutls_priority_t priority_cache;

	total_diffs_size = 0;

	/* Init server */
	gnutls_certificate_allocate_credentials(&s_certcred);
	gnutls_anon_allocate_server_credentials(&s_anoncred);

	ret = 0;
	if (pk == GNUTLS_PK_RSA_PSS)
		ret = gnutls_certificate_set_x509_key_mem(s_certcred, &server_rsa_pss_cert,
						    &server_key,
						    GNUTLS_X509_FMT_PEM);
	else if (pk == GNUTLS_PK_RSA)
		ret = gnutls_certificate_set_x509_key_mem(s_certcred, &server_cert,
						    &server_key,
						    GNUTLS_X509_FMT_PEM);
	if (ret < 0) {
		fprintf(stderr, "Error in %d: %s\n", __LINE__,
			gnutls_strerror(ret));
		exit(1);
	}

	ret = 0;
	if (pk == GNUTLS_PK_ECDSA)
		ret = gnutls_certificate_set_x509_key_mem(s_certcred, &server_ecc_cert,
						    &server_ecc_key,
						    GNUTLS_X509_FMT_PEM);
	else if (pk == GNUTLS_PK_EDDSA_ED25519)
		ret = gnutls_certificate_set_x509_key_mem(s_certcred, &server_ed25519_cert,
						    &server_ed25519_key,
						    GNUTLS_X509_FMT_PEM);
	if (ret < 0) {
		fprintf(stderr, "Error in %d: %s\n", __LINE__,
			gnutls_strerror(ret));
		exit(1);
	}

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

	start_benchmark(&st);

	ret = gnutls_priority_init(&priority_cache, cipher_prio, &str);
	if (ret < 0) {
		fprintf(stderr, "Error in %s\n", str);
		exit(1);
	}

	do {

		gnutls_init(&server, GNUTLS_SERVER);
		ret =
		    gnutls_priority_set(server, priority_cache);
		if (ret < 0) {
			fprintf(stderr, "Error in setting priority: %s\n", gnutls_strerror(ret));
			exit(1);
		}
		gnutls_credentials_set(server, GNUTLS_CRD_ANON,
				       s_anoncred);
		gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE,
				       s_certcred);
		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);
		reset_buffers();

		gnutls_init(&client, GNUTLS_CLIENT);

		ret =
		    gnutls_priority_set(client, priority_cache);
		if (ret < 0) {
			fprintf(stderr, "Error in setting priority: %s\n", gnutls_strerror(ret));
			exit(1);
		}
		gnutls_credentials_set(client, GNUTLS_CRD_ANON,
				       c_anoncred);
		gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE,
				       c_certcred);

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

		gettime(&tr_start);

		HANDSHAKE(client, server);

		gettime(&tr_stop);

		if (suite == NULL)
			suite =
			    gnutls_session_get_desc(server);

		gnutls_deinit(client);
		gnutls_deinit(server);

		total_diffs[total_diffs_size++] = timespec_sub_ms(&tr_stop, &tr_start);
		if (total_diffs_size > sizeof(total_diffs)/sizeof(total_diffs[0]))
			abort();

		st.size += 1;
	}
	while (benchmark_must_finish == 0);

	fprintf(stdout, "%38s  ", suite);
	gnutls_free(suite);
	stop_benchmark(&st, "transactions", 1);
	gnutls_priority_deinit(priority_cache);

	avg = calc_avg(total_diffs, total_diffs_size);
	sstddev = calc_sstdev(total_diffs, total_diffs_size, avg);

	printf("%32s %.2f ms, sample variance: %.2f)\n",
	       "(avg. handshake time:", avg, sstddev);

	gnutls_anon_free_client_credentials(c_anoncred);
	gnutls_anon_free_server_credentials(s_anoncred);
}
Esempio n. 12
0
void TLSClient::connect (const std::string& host, const std::string& port)
{
  // Store the host name, so the verification callback can access it during the
  // handshake below.
  gnutls_session_set_ptr (_session, (void*) host.c_str ());

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

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

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

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

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

    break;
  }

  free (res);

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

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

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

  if (_debug)
  {
#if GNUTLS_VERSION_NUMBER >= 0x03010a
    char* desc = gnutls_session_get_desc (_session);
    std::cout << "c: INFO Handshake was completed: " << desc << "\n";
    gnutls_free (desc);
#else
    std::cout << "c: INFO Handshake was completed.\n";
#endif
  }
}
Esempio n. 13
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 system trusted CAs for Internet PKI */
        CHECK(gnutls_certificate_set_x509_system_trust(xcred));

        /* 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, "www.example.com",
                                     strlen("www.example.com")));

        gnutls_session_set_verify_cert(session, "www.example.com", 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);
        }

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

        LOOP_CHECK(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;
}
Esempio n. 14
0
struct wpabuf * tls_connection_handshake(void *tls_ctx,
					 struct tls_connection *conn,
					 const struct wpabuf *in_data,
					 struct wpabuf **appl_data)
{
	struct tls_global *global = tls_ctx;
	struct wpabuf *out_data;
	int ret;

	if (appl_data)
		*appl_data = NULL;

	if (in_data && wpabuf_len(in_data) > 0) {
		if (conn->pull_buf) {
			wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in "
				   "pull_buf", __func__,
				   (unsigned long) wpabuf_len(conn->pull_buf));
			wpabuf_free(conn->pull_buf);
		}
		conn->pull_buf = wpabuf_dup(in_data);
		if (conn->pull_buf == NULL)
			return NULL;
		conn->pull_buf_offset = wpabuf_head(conn->pull_buf);
	}

	ret = gnutls_handshake(conn->session);
	if (ret < 0) {
		gnutls_alert_description_t alert;

		switch (ret) {
		case GNUTLS_E_AGAIN:
			if (global->server && conn->established &&
			    conn->push_buf == NULL) {
				/* Need to return something to trigger
				 * completion of EAP-TLS. */
				conn->push_buf = wpabuf_alloc(0);
			}
			break;
		case GNUTLS_E_FATAL_ALERT_RECEIVED:
			alert = gnutls_alert_get(conn->session);
			wpa_printf(MSG_DEBUG, "%s - received fatal '%s' alert",
				   __func__, gnutls_alert_get_name(alert));
			conn->read_alerts++;
			if (conn->global->event_cb != NULL) {
				union tls_event_data ev;

				os_memset(&ev, 0, sizeof(ev));
				ev.alert.is_local = 0;
				ev.alert.type = gnutls_alert_get_name(alert);
				ev.alert.description = ev.alert.type;
				conn->global->event_cb(conn->global->cb_ctx,
						       TLS_ALERT, &ev);
			}
			/* continue */
		default:
			wpa_printf(MSG_DEBUG, "%s - gnutls_handshake failed "
				   "-> %s", __func__, gnutls_strerror(ret));
			conn->failed++;
		}
	} else {
		size_t size;

		wpa_printf(MSG_DEBUG, "TLS: Handshake completed successfully");

#if GNUTLS_VERSION_NUMBER >= 0x03010a
		{
			char *desc;

			desc = gnutls_session_get_desc(conn->session);
			if (desc) {
				wpa_printf(MSG_DEBUG, "GnuTLS: %s", desc);
				gnutls_free(desc);
			}
		}
#endif /* GnuTLS 3.1.10 or newer */

		conn->established = 1;
		if (conn->push_buf == NULL) {
			/* Need to return something to get final TLS ACK. */
			conn->push_buf = wpabuf_alloc(0);
		}

		gnutls_session_get_data(conn->session, NULL, &size);
		if (global->session_data == NULL ||
		    global->session_data_size < size) {
			os_free(global->session_data);
			global->session_data = os_malloc(size);
		}
		if (global->session_data) {
			global->session_data_size = size;
			gnutls_session_get_data(conn->session,
						global->session_data,
						&global->session_data_size);
		}

		if (conn->pull_buf && appl_data)
			*appl_data = gnutls_get_appl_data(conn);
	}

	out_data = conn->push_buf;
	conn->push_buf = NULL;
	return out_data;
}
Esempio n. 15
0
void TLSTransaction::init (TLSServer& server)
{
  int ret = gnutls_init (&_session, GNUTLS_SERVER);
  if (ret < 0)
    throw format ("TLS server init error. {1}", gnutls_strerror (ret));

  ret = gnutls_priority_set (_session, server._priorities);
  if (ret < 0)
    throw format ("Error initializing TLS. {1}", gnutls_strerror (ret));

  // Apply the x509 credentials to the current session.
  ret = gnutls_credentials_set (_session, GNUTLS_CRD_CERTIFICATE, server._credentials);
  if (ret < 0)
    throw format ("TLS credentials error. {1}", gnutls_strerror (ret));

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

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

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

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

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

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

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

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

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

  if (_debug)
  {
#if GNUTLS_VERSION_NUMBER >= 0x03010a
    char* desc = gnutls_session_get_desc (_session);
    std::cout << "s: INFO Handshake was completed: " << desc << "\n";
    gnutls_free (desc);
#else
    std::cout << "s: INFO Handshake was completed.\n";
#endif
  }
}