Exemplo n.º 1
0
static mod_context *mod_gnutls_context_new(liServer *srv) {
	mod_context *ctx = g_slice_new0(mod_context);
	int r;

	if (GNUTLS_E_SUCCESS > (r = gnutls_certificate_allocate_credentials(&ctx->server_cert))) {
		ERROR(srv, "gnutls_certificate_allocate_credentials failed(%s): %s",
			gnutls_strerror_name(r), gnutls_strerror(r));
		goto error0;
	}

	if (GNUTLS_E_SUCCESS > (r = gnutls_priority_init(&ctx->server_priority, "NORMAL", NULL))) {
		ERROR(srv, "gnutls_priority_init('NORMAL') failed(%s): %s",
			gnutls_strerror_name(r), gnutls_strerror(r));
		goto error1;
	}

	if (GNUTLS_E_SUCCESS > (r = gnutls_priority_init(&ctx->server_priority_beast, "NORMAL:-CIPHER-ALL:+ARCFOUR-128", NULL))) {
		int r1;
		if (GNUTLS_E_SUCCESS > (r1 = gnutls_priority_init(&ctx->server_priority_beast, "NORMAL", NULL))) {
			ERROR(srv, "gnutls_priority_init('NORMAL') failed(%s): %s",
				gnutls_strerror_name(r1), gnutls_strerror(r1));
			goto error2;
		} else {
			ERROR(srv, "gnutls_priority_init('NORMAL:-CIPHER-ALL:+ARCFOUR-128') failed(%s): %s. Using 'NORMAL' instead (BEAST mitigation not available)",
				gnutls_strerror_name(r), gnutls_strerror(r));
		}
	}

#ifdef HAVE_SESSION_TICKET
	if (GNUTLS_E_SUCCESS > (r = gnutls_session_ticket_key_generate(&ctx->ticket_key))) {
		ERROR(srv, "gnutls_session_ticket_key_generate failed(%s): %s",
			gnutls_strerror_name(r), gnutls_strerror(r));
		goto error3;
	}
#endif

	ctx->srv = srv;

	ctx->ocsp = li_gnutls_ocsp_new();

	ctx->refcount = 1;
	ctx->protect_against_beast = 1;

	return ctx;

error3:
	gnutls_priority_deinit(ctx->server_priority_beast);

error2:
	gnutls_priority_deinit(ctx->server_priority);

error1:
	gnutls_certificate_free_credentials(ctx->server_cert);

error0:
	g_slice_free(mod_context, ctx);
	return NULL;
}
Exemplo n.º 2
0
/* @t is the lifetime of the first ticket, @s is the
 * time to wait before asking for a ticket the last try */
static void start(const char *name, const char *prio, unsigned t, unsigned s)
{
	gnutls_datum_t sdata, ndata, skey;
	unsigned ret;
	struct hsk_st h;
	memset(&h, 0, sizeof(h));

	success("trying %s\n", name);

	assert(gnutls_session_ticket_key_generate(&skey)>=0);

	/* step1: get a fresh ticket */
	ret = handshake(prio, t, NULL, &sdata, &skey, &h);
	assert(ret == 0);
	assert(h.sent_nst != 0);
	memset(&h, 0, sizeof(h));

	if (debug)
		success("completed first handshake\n");

	if (s)
		virt_sec_sleep(s);

	/* step2: get a ticket from the resumed session of the first */
	ret = handshake(prio, t, &sdata, &ndata, &skey, &h);
	assert(ret != 0);
	assert(h.sent_nst != 0);
	memset(&h, 0, sizeof(h));

	/* wait until the ticket we got in step1 is invalid, although
	 * the ticket we got in step2 is valid */

	if (debug)
		success("completed second handshake\n");

	if (s)
		virt_sec_sleep(s);

	ret = handshake(prio, t, &ndata, NULL, &skey, &h);

	if (s) {
		if (ret != 0)
			fail("server resumed session even if ticket expired!\n");

		/* we shouldn't have sent the PSK extension as the ticket was expired */
		assert(h.sent_psk == 0);
	}

	gnutls_free(ndata.data);
	gnutls_free(sdata.data);
	gnutls_free(skey.data);
}
Exemplo n.º 3
0
/* @t is the lifetime of the first ticket, @s is the
 * time to wait before asking for a ticket the last try
 *
 * This makes the ticket to expire during handshake (after resumtion),
 * but before the client receives the new session ticket. In that
 * case the server shouldn't send a session ticket.
 */
static void start2(const char *name, const char *prio, unsigned t, unsigned s)
{
	gnutls_datum_t sdata, ndata, skey;
	unsigned ret;
	struct hsk_st h;
	memset(&h, 0, sizeof(h));

	success("trying %s\n", name);

	assert(gnutls_session_ticket_key_generate(&skey)>=0);

	/* step1: get a fresh ticket */
	ret = handshake(prio, t, NULL, &sdata, &skey, &h);
	assert(ret == 0);
	assert(h.sent_nst != 0);
	memset(&h, 0, sizeof(h));

	/* step2: get a ticket from the resumed session of the first */
	ret = handshake(prio, t, &sdata, &ndata, &skey, &h);
	assert(ret != 0);
	assert(h.sent_nst != 0);
	memset(&h, 0, sizeof(h));

	/* wait until the ticket we got in step1 is invalid, although
	 * the ticket we got in step2 is valid */

	if (s)
		h.sleep_at_finished = s;

	ret = handshake(prio, t, &ndata, NULL, &skey, &h);

	assert(ret != 0);
	if (h.sent_nst != 0)
		fail("server sent session ticket even if ticket expired!\n");

	gnutls_free(ndata.data);
	gnutls_free(sdata.data);
	gnutls_free(skey.data);
}
Exemplo n.º 4
0
static void server(int sds[], struct params_res *params)
{
	gnutls_anon_server_credentials_t anoncred;
	static gnutls_datum_t session_ticket_key = { NULL, 0 };
	int ret;
	size_t t;
	gnutls_session_t session;

	/* this must be called once in the program, it is mostly for the server.
	 */
	if (debug) {
		gnutls_global_set_log_function(tls_log_func);
		gnutls_global_set_log_level(3);
	}

	global_init();
	gnutls_anon_allocate_server_credentials(&anoncred);

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

	gnutls_anon_set_server_dh_params(anoncred, dh_params);

	if (params->enable_db) {
		wrap_db_init();
	}

	if (params->enable_session_ticket_server)
		gnutls_session_ticket_key_generate(&session_ticket_key);

	for (t = 0; t < SESSIONS; t++) {
		int sd = sds[t];

		gnutls_init(&session, GNUTLS_SERVER | GNUTLS_DATAGRAM);

		gnutls_priority_set_direct(session,
				   "NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH",
				   NULL);

		gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred);
		gnutls_dh_set_prime_bits(session, DH_BITS);

		if (params->enable_db) {
			gnutls_db_set_retrieve_function(session, wrap_db_fetch);
			gnutls_db_set_remove_function(session, wrap_db_delete);
			gnutls_db_set_store_function(session, wrap_db_store);
			gnutls_db_set_ptr(session, NULL);
		}

		if (params->enable_session_ticket_server)
			gnutls_session_ticket_enable_server(session,
						    &session_ticket_key);

		gnutls_transport_set_int(session, sd);
		gnutls_dtls_set_timeouts(session, 3*1000, 240 * 1000);
		
		do {
			ret = gnutls_handshake(session);
		} while (ret < 0 && (ret == GNUTLS_E_INTERRUPTED||ret == GNUTLS_E_AGAIN));
		if (ret < 0) {
			close(sd);
			gnutls_deinit(session);
			kill(child, SIGTERM);
			fail("server: Handshake has failed (%s)\n\n",
			     gnutls_strerror(ret));
			return;
		}
		if (debug)
			success("server: 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) {
				if (debug)
					success
					    ("server: Peer has closed the GnuTLS connection\n");
				break;
			} else if (ret < 0) {
				kill(child, SIGTERM);
				fail("server: Received corrupted data(%d). Closing...\n", ret);
				break;
			} else if (ret > 0) {
				/* echo data back to the client
				 */
				gnutls_record_send(session, buffer,
						   strlen(buffer));
			}
		}
		/* do not wait for the peer to close the connection.
		 */
		gnutls_bye(session, GNUTLS_SHUT_WR);

		close(sd);

		gnutls_deinit(session);
	}

	if (params->enable_db) {
		wrap_db_deinit();
	}

	gnutls_free(session_ticket_key.data);
	session_ticket_key.data = NULL;
	gnutls_anon_free_server_credentials(anoncred);

	if (debug)
		success("server: finished\n");
}
Exemplo n.º 5
0
static Ecore_Con_Ssl_Error
_ecore_con_ssl_client_init_gnutls(Ecore_Con_Client *cl)
{
   const gnutls_datum_t *cert_list;
   unsigned int iter, cert_list_size;
   const char *priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0:+VERS-SSL3.0";
   int ret = 0;

   switch (cl->ssl_state)
     {
      case ECORE_CON_SSL_STATE_DONE:
        return ECORE_CON_SSL_ERROR_NONE;

      case ECORE_CON_SSL_STATE_INIT:
        if (cl->host_server->type & ECORE_CON_USE_SSL2) /* not supported because of security issues */
          return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;

        switch (cl->host_server->type & ECORE_CON_SSL)
          {
           case ECORE_CON_USE_SSL3:
           case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT:
             priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:!VERS-TLS1.0:!VERS-TLS1.1";
             break;

           case ECORE_CON_USE_TLS:
           case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT:
             priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:!VERS-SSL3.0";
             break;

           case ECORE_CON_USE_MIXED:
           case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT:
             break;

           default:
             return ECORE_CON_SSL_ERROR_NONE;
          }

        _client_connected++;

        SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_init(&cl->session, GNUTLS_SERVER));
        SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_session_ticket_key_generate(&cl->session_ticket));
        SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_session_ticket_enable_server(cl->session, &cl->session_ticket));
        INF("Applying priority string: %s", priority);
        SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_priority_set_direct(cl->session, priority, NULL));
        SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_CERTIFICATE, cl->host_server->cert));
        //  SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_PSK, cl->host_server->pskcred_s));
        if (!cl->host_server->use_cert)
          SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_ANON, cl->host_server->anoncred_s));

        gnutls_certificate_server_set_request(cl->session, GNUTLS_CERT_REQUEST);

        gnutls_dh_set_prime_bits(cl->session, 2048);
        gnutls_transport_set_ptr(cl->session, (gnutls_transport_ptr_t)((intptr_t)cl->fd));
        cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;

      case ECORE_CON_SSL_STATE_HANDSHAKING:
        if (!cl->session)
          {
             DBG("Client was previously lost, going to error condition");
             goto error;
          }
        DBG("calling gnutls_handshake()");
        ret = gnutls_handshake(cl->session);
        SSL_ERROR_CHECK_GOTO_ERROR(gnutls_error_is_fatal(ret));

        if (!ret)
          {
             cl->handshaking = EINA_FALSE;
             cl->ssl_state = ECORE_CON_SSL_STATE_DONE;
          }
        else
          {
             if (gnutls_record_get_direction(cl->session))
               ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE);
             else
               ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
             return ECORE_CON_SSL_ERROR_NONE;
          }

      default:
        break;
     }

   if (!cl->host_server->verify)
     /* not verifying certificates, so we're done! */
     return ECORE_CON_SSL_ERROR_NONE;
   ret = 0;
   /* use CRL/CA lists to verify */
   SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_certificate_verify_peers2(cl->session, &iter));
   if (iter & GNUTLS_CERT_INVALID)
     ERR("The certificate is not trusted.");
   else if (iter & GNUTLS_CERT_SIGNER_NOT_FOUND)
     ERR("The certificate hasn't got a known issuer.");
   else if (iter & GNUTLS_CERT_REVOKED)
     ERR("The certificate has been revoked.");
   else if (iter & GNUTLS_CERT_EXPIRED)
     ERR("The certificate has expired");
   else if (iter & GNUTLS_CERT_NOT_ACTIVATED)
     ERR("The certificate is not yet activated");

   if (iter)
     goto error;

   if (gnutls_certificate_type_get(cl->session) != GNUTLS_CRT_X509)
     {
        ERR("Warning: PGP certificates are not yet supported!");
        goto error;
     }

   SSL_ERROR_CHECK_GOTO_ERROR(!(cert_list = gnutls_certificate_get_peers(cl->session, &cert_list_size)));
   SSL_ERROR_CHECK_GOTO_ERROR(!cert_list_size);

   DBG("SSL certificate verification succeeded!");
   return ECORE_CON_SSL_ERROR_NONE;

error:
   _gnutls_print_errors(ret);
   if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED) || (ret == GNUTLS_E_FATAL_ALERT_RECEIVED))
     ERR("Also received alert: %s", gnutls_alert_get_name(gnutls_alert_get(cl->session)));
   if (cl->session && (cl->ssl_state != ECORE_CON_SSL_STATE_DONE))
     {
        ERR("last out: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_out(cl->session)));
        ERR("last in: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_in(cl->session)));
     }
   _ecore_con_ssl_client_shutdown_gnutls(cl);
   return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
}
Exemplo n.º 6
0
static void
server (struct params_res *params)
{
  size_t t;

  /* this must be called once in the program, it is mostly for the server.
   */
  if (debug)
    {
      gnutls_global_set_log_function (tls_log_func);
      gnutls_global_set_log_level (2);
    }

  gnutls_global_init ();
  gnutls_anon_allocate_server_credentials (&anoncred);

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

  generate_dh_params ();

  gnutls_anon_set_server_dh_params (anoncred, dh_params);

  if (params->enable_db)
    {
      wrap_db_init ();
    }

  if (params->enable_session_ticket_server)
    gnutls_session_ticket_key_generate (&session_ticket_key);

  for (t = 0; t < 2; t++)
    {
      client_len = sizeof (sa_cli);

      session = initialize_tls_session (params);

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

      if (debug)
        success ("server: 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);
          fail ("server: Handshake has failed (%s)\n\n",
                gnutls_strerror (ret));
          return;
        }
      if (debug)
        success ("server: 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)
            {
              if (debug)
                success ("server: Peer has closed the GnuTLS connection\n");
              break;
            }
          else if (ret < 0)
            {
              fail ("server: Received corrupted data(%d). Closing...\n", ret);
              break;
            }
          else if (ret > 0)
            {
              /* echo data back to the client
               */
              gnutls_record_send (session, buffer, strlen (buffer));
            }
        }
      /* do not wait for the peer to close the connection.
       */
      gnutls_bye (session, GNUTLS_SHUT_WR);

      close (sd);

      gnutls_deinit (session);
    }

  close (listen_sd);

  if (params->enable_db)
    {
      wrap_db_deinit ();
    }

  gnutls_free (session_ticket_key.data);
  session_ticket_key.data = NULL;

  if (debug)
    success ("server: finished\n");
}
Exemplo n.º 7
0
static void server(int fd, const char *prio)
{
	int ret;
	char buffer[MAX_BUF + 1];
	gnutls_session_t session;
	gnutls_certificate_credentials_t x509_cred;
	gnutls_datum_t skey;

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

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

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

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

	assert(gnutls_session_ticket_key_generate(&skey)>=0);
	assert(gnutls_session_ticket_enable_server(session, &skey) >= 0);

	gnutls_handshake_set_hook_function(session, GNUTLS_HANDSHAKE_NEW_SESSION_TICKET,
					   GNUTLS_HOOK_POST,
					   handshake_callback);

	/* avoid calling all the priority functions, since the defaults
	 * are adequate.
	 */
	assert(gnutls_priority_set_direct(session, prio, NULL)>=0);

	gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);

	gnutls_transport_set_int(session, fd);

	do {
		ret = gnutls_handshake(session);
	} while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
	if (ret < 0) {
		/* failure is expected here */
		goto end;
	}

	if (debug) {
		success("server: Handshake was completed\n");
	}

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

	if (sent == 0) {
		fail("client: didn't send new sessiont ticket\n");
		terminate();
	}

	/* do not wait for the peer to close the connection.
	 */
	gnutls_bye(session, GNUTLS_SHUT_WR);

 end:
	close(fd);
	gnutls_deinit(session);
	gnutls_free(skey.data);

	gnutls_certificate_free_credentials(x509_cred);

	gnutls_global_deinit();

	if (debug)
		success("server: finished\n");
}