Beispiel #1
0
/**
 * gnutls_deinit:
 * @session: is a #gnutls_session_t structure.
 *
 * This function clears all buffers associated with the @session.
 * This function will also remove session data from the session
 * database if the session was terminated abnormally.
 **/
void gnutls_deinit(gnutls_session_t session)
{
	unsigned int i;

	if (session == NULL)
		return;

	_gnutls_rnd_refresh();

	/* remove auth info firstly */
	_gnutls_free_auth_info(session);

	_gnutls_handshake_internal_state_clear(session);
	_gnutls_handshake_io_buffer_clear(session);
	_gnutls_ext_free_session_data(session);

	for (i = 0; i < MAX_EPOCH_INDEX; i++)
		if (session->record_parameters[i] != NULL) {
			_gnutls_epoch_free(session,
					   session->record_parameters[i]);
			session->record_parameters[i] = NULL;
		}

	_gnutls_buffer_clear(&session->internals.handshake_hash_buffer);
	_gnutls_buffer_clear(&session->internals.hb_remote_data);
	_gnutls_buffer_clear(&session->internals.hb_local_data);
	_gnutls_buffer_clear(&session->internals.record_presend_buffer);

	_mbuffer_head_clear(&session->internals.record_buffer);
	_mbuffer_head_clear(&session->internals.record_recv_buffer);
	_mbuffer_head_clear(&session->internals.record_send_buffer);

	gnutls_credentials_clear(session);
	_gnutls_selected_certs_deinit(session);

	gnutls_pk_params_release(&session->key.ecdh_params);
	gnutls_pk_params_release(&session->key.dh_params);
	zrelease_temp_mpi_key(&session->key.ecdh_x);
	zrelease_temp_mpi_key(&session->key.ecdh_y);

	zrelease_temp_mpi_key(&session->key.client_Y);

	zrelease_temp_mpi_key(&session->key.srp_p);
	zrelease_temp_mpi_key(&session->key.srp_g);
	zrelease_temp_mpi_key(&session->key.srp_key);

	zrelease_temp_mpi_key(&session->key.u);
	zrelease_temp_mpi_key(&session->key.a);
	zrelease_temp_mpi_key(&session->key.x);
	zrelease_temp_mpi_key(&session->key.A);
	zrelease_temp_mpi_key(&session->key.B);
	zrelease_temp_mpi_key(&session->key.b);

	/* RSA */
	zrelease_temp_mpi_key(&session->key.rsa[0]);
	zrelease_temp_mpi_key(&session->key.rsa[1]);

	_gnutls_free_temp_key_datum(&session->key.key);

	gnutls_free(session);
}
Beispiel #2
0
/* just read A and put it to session */
int
_gnutls_proc_srp_client_kx(gnutls_session_t session, uint8_t * data,
			   size_t _data_size)
{
	ssize_t _n_A;
	ssize_t data_size = _data_size;
	int ret;

	DECR_LEN(data_size, 2);
	_n_A = _gnutls_read_uint16(&data[0]);

	DECR_LEN(data_size, _n_A);
	if (_gnutls_mpi_init_scan_nz(&A, &data[2], _n_A) || A == NULL) {
		gnutls_assert();
		return GNUTLS_E_MPI_SCAN_FAILED;
	}

	_gnutls_mpi_log("SRP A: ", A);
	_gnutls_mpi_log("SRP B: ", B);

	/* Checks if A % n == 0.
	 */
	if ((ret = check_param_mod_n(A, N, 1)) < 0) {
		gnutls_assert();
		return ret;
	}

	/* Start the SRP calculations.
	 * - Calculate u 
	 */
	session->key.u = _gnutls_calc_srp_u(A, B, N);
	if (session->key.u == NULL) {
		gnutls_assert();
		return GNUTLS_E_MEMORY_ERROR;
	}

	_gnutls_mpi_log("SRP U: ", session->key.u);

	/* S = (A * v^u) ^ b % N 
	 */
	S = _gnutls_calc_srp_S1(A, _b, session->key.u, V, N);
	if (S == NULL) {
		gnutls_assert();
		return GNUTLS_E_MEMORY_ERROR;
	}

	_gnutls_mpi_log("SRP S: ", S);

	_gnutls_mpi_release(&A);
	zrelease_temp_mpi_key(&_b);
	zrelease_temp_mpi_key(&V);
	zrelease_temp_mpi_key(&session->key.u);
	zrelease_temp_mpi_key(&B);

	ret = _gnutls_mpi_dprint(session->key.srp_key, &session->key.key);
	zrelease_temp_mpi_key(&S);

	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	return 0;
}
Beispiel #3
0
static void deinit_keys(gnutls_session_t session)
{
	gnutls_pk_params_release(&session->key.ecdh_params);
	gnutls_pk_params_release(&session->key.dh_params);
	zrelease_temp_mpi_key(&session->key.ecdh_x);
	zrelease_temp_mpi_key(&session->key.ecdh_y);
	_gnutls_free_temp_key_datum(&session->key.ecdhx);

	zrelease_temp_mpi_key(&session->key.client_Y);

	/* SRP */
	zrelease_temp_mpi_key(&session->key.srp_p);
	zrelease_temp_mpi_key(&session->key.srp_g);
	zrelease_temp_mpi_key(&session->key.srp_key);

	zrelease_temp_mpi_key(&session->key.u);
	zrelease_temp_mpi_key(&session->key.a);
	zrelease_temp_mpi_key(&session->key.x);
	zrelease_temp_mpi_key(&session->key.A);
	zrelease_temp_mpi_key(&session->key.B);
	zrelease_temp_mpi_key(&session->key.b);

	_gnutls_free_temp_key_datum(&session->key.key);
	_gnutls_free_temp_key_datum(&session->key.key);
}
Beispiel #4
0
/* return A = g^a % N */
int
_gnutls_gen_srp_client_kx(gnutls_session_t session,
			  gnutls_buffer_st * data)
{
	int ret;
	char *username, *password;
	gnutls_srp_client_credentials_t cred;
	extension_priv_data_t epriv;
	srp_ext_st *priv;

	ret =
	    _gnutls_ext_get_session_data(session, GNUTLS_EXTENSION_SRP,
					 &epriv);
	if (ret < 0) {		/* peer didn't send a username */
		gnutls_assert();
		return GNUTLS_E_UNKNOWN_SRP_USERNAME;
	}
	priv = epriv;

	cred = (gnutls_srp_client_credentials_t)
	    _gnutls_get_cred(session, GNUTLS_CRD_SRP);

	if (cred == NULL) {
		gnutls_assert();
		return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
	}

	if (priv->username == NULL) {
		username = cred->username;
		password = cred->password;
	} else {

		username = priv->username;
		password = priv->password;
	}

	if (username == NULL || password == NULL) {
		gnutls_assert();
		return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
	}

	/* calc A = g^a % N 
	 */
	if (G == NULL || N == NULL) {
		gnutls_assert();
		return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
	}

	A = _gnutls_calc_srp_A(&_a, G, N);
	if (A == NULL) {
		gnutls_assert();
		return GNUTLS_E_MEMORY_ERROR;
	}

	/* Rest of SRP calculations 
	 */

	/* calculate u */
	session->key.u = _gnutls_calc_srp_u(A, B, N);
	if (session->key.u == NULL) {
		gnutls_assert();
		return GNUTLS_E_MEMORY_ERROR;
	}

	_gnutls_mpi_log("SRP U: ", session->key.u);

	/* S = (B - g^x) ^ (a + u * x) % N */
	S = _gnutls_calc_srp_S2(B, G, session->key.x, _a, session->key.u,
				N);
	if (S == NULL) {
		gnutls_assert();
		return GNUTLS_E_MEMORY_ERROR;
	}

	_gnutls_mpi_log("SRP B: ", B);

	zrelease_temp_mpi_key(&_b);
	zrelease_temp_mpi_key(&V);
	zrelease_temp_mpi_key(&session->key.u);
	zrelease_temp_mpi_key(&B);

	ret = _gnutls_mpi_dprint(session->key.srp_key, &session->key.key);
	zrelease_temp_mpi_key(&S);

	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	ret = _gnutls_buffer_append_mpi(data, 16, A, 0);
	if (ret < 0)
		return gnutls_assert_val(ret);

	_gnutls_mpi_log("SRP A: ", A);

	_gnutls_mpi_release(&A);

	return data->length;
}
Beispiel #5
0
/* This is used for DH or ECDH key derivation. In DH for example
 * it is given the peers Y and our x, and calculates Y^x 
 */
static int _wrap_nettle_pk_derive(gnutls_pk_algorithm_t algo,
				  gnutls_datum_t * out,
				  const gnutls_pk_params_st * priv,
				  const gnutls_pk_params_st * pub)
{
	int ret;

	switch (algo) {
	case GNUTLS_PK_DH: {
		bigint_t f, x, prime;
		bigint_t k = NULL, ff = NULL;
		unsigned int bits;

		f = pub->params[DH_Y];
		x = priv->params[DH_X];
		prime = priv->params[DH_P];

		ret = _gnutls_mpi_init_multi(&k, &ff, NULL);
		if (ret < 0)
			return gnutls_assert_val(ret);

		ret = _gnutls_mpi_modm(ff, f, prime);
		if (ret < 0) {
			gnutls_assert();
			goto dh_cleanup;
		}

		ret = _gnutls_mpi_add_ui(ff, ff, 1);
		if (ret < 0) {
			gnutls_assert();
			goto dh_cleanup;
		}

		/* check if f==0,1,p-1. 
		 * or (ff=f+1) equivalently ff==1,2,p */
		if ((_gnutls_mpi_cmp_ui(ff, 2) == 0)
		    || (_gnutls_mpi_cmp_ui(ff, 1) == 0)
		    || (_gnutls_mpi_cmp(ff, prime) == 0)) {
			gnutls_assert();
			ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
			goto dh_cleanup;
		}

		/* prevent denial of service */
		bits = _gnutls_mpi_get_nbits(prime);
		if (bits == 0 || bits > MAX_DH_BITS) {
			gnutls_assert();
			ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
			goto dh_cleanup;
		}


		ret = _gnutls_mpi_powm(k, f, x, prime);
		if (ret < 0) {
			gnutls_assert();
			goto dh_cleanup;
		}

		ret = _gnutls_mpi_dprint(k, out);
		if (ret < 0) {
			gnutls_assert();
			goto dh_cleanup;
		}

		ret = 0;
dh_cleanup:
		_gnutls_mpi_release(&ff);
		zrelease_temp_mpi_key(&k);
		if (ret < 0)
			goto cleanup;

		break;
	}
	case GNUTLS_PK_EC:
		{
			struct ecc_scalar ecc_priv;
			struct ecc_point ecc_pub;
			const struct ecc_curve *curve;

			out->data = NULL;

			curve = get_supported_curve(priv->flags);
			if (curve == NULL)
				return
				    gnutls_assert_val
				    (GNUTLS_E_ECC_UNSUPPORTED_CURVE);

			ret = _ecc_params_to_pubkey(pub, &ecc_pub, curve);
			if (ret < 0)
				return gnutls_assert_val(ret);

			ret =
			    _ecc_params_to_privkey(priv, &ecc_priv, curve);
			if (ret < 0) {
				ecc_point_clear(&ecc_pub);
				return gnutls_assert_val(ret);
			}

			out->size = gnutls_ecc_curve_get_size(priv->flags);
			/*ecc_size(curve)*sizeof(mp_limb_t); */
			out->data = gnutls_malloc(out->size);
			if (out->data == NULL) {
				ret =
				    gnutls_assert_val
				    (GNUTLS_E_MEMORY_ERROR);
				goto ecc_cleanup;
			}

			ecc_shared_secret(&ecc_priv, &ecc_pub, out->data,
					  out->size);

		      ecc_cleanup:
			ecc_point_clear(&ecc_pub);
			ecc_scalar_zclear(&ecc_priv);
			if (ret < 0)
				goto cleanup;
			break;
		}
	default:
		gnutls_assert();
		ret = GNUTLS_E_INTERNAL_ERROR;
		goto cleanup;
	}

	ret = 0;

      cleanup:

	return ret;
}