예제 #1
0
파일: ecdhe.c 프로젝트: attilamolnar/gnutls
int
_gnutls_proc_ecdh_common_server_kx(gnutls_session_t session,
				   uint8_t * data, size_t _data_size)
{
	int i, ret, point_size;
	gnutls_ecc_curve_t curve;
	ssize_t data_size = _data_size;

	/* just in case we are resuming a session */
	gnutls_pk_params_release(&session->key.ecdh_params);

	gnutls_pk_params_init(&session->key.ecdh_params);

	i = 0;
	DECR_LEN(data_size, 1);
	if (data[i++] != 3)
		return gnutls_assert_val(GNUTLS_E_ECC_NO_SUPPORTED_CURVES);

	DECR_LEN(data_size, 2);
	curve = _gnutls_tls_id_to_ecc_curve(_gnutls_read_uint16(&data[i]));
	i += 2;

	ret = _gnutls_session_supports_ecc_curve(session, curve);
	if (ret < 0)
		return gnutls_assert_val(ret);

	_gnutls_session_ecc_curve_set(session, curve);

	DECR_LEN(data_size, 1);
	point_size = data[i];
	i++;

	DECR_LEN(data_size, point_size);
	ret =
	    _gnutls_ecc_ansi_x963_import(&data[i], point_size,
					 &session->key.ecdh_x,
					 &session->key.ecdh_y);
	if (ret < 0)
		return gnutls_assert_val(ret);

	i += point_size;

	return i;
}
예제 #2
0
파일: ecc.c 프로젝트: Distrotech/gnutls
/* 
 * In case of a server: if a SUPPORTED_ECC extension type is received then it stores
 * into the session security parameters the new value. The server may use gnutls_session_certificate_type_get(),
 * to access it.
 *
 * In case of a client: If a supported_eccs have been specified then we send the extension.
 *
 */
static int
_gnutls_supported_ecc_recv_params(gnutls_session_t session,
				  const uint8_t * data, size_t _data_size)
{
	int new_type = -1, ret, i;
	ssize_t data_size = _data_size;
	uint16_t len;
	const uint8_t *p = data;

	if (session->security_parameters.entity == GNUTLS_CLIENT) {
		/* A client shouldn't receive this extension, but of course
		 * there are servers out there that send it. Just ignore it. */
		_gnutls_debug_log("received SUPPORTED ECC extension on client side!!!\n");
		return 0;
	} else {		/* SERVER SIDE - we must check if the sent supported ecc type is the right one 
				 */
		if (data_size < 2)
			return
			    gnutls_assert_val
			    (GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION);

		DECR_LEN(data_size, 2);
		len = _gnutls_read_uint16(p);
		p += 2;

		if (len % 2 != 0)
			return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);

		DECR_LEN(data_size, len);

		for (i = 0; i < len; i += 2) {
			new_type =
			    _gnutls_tls_id_to_ecc_curve(_gnutls_read_uint16
							(&p[i]));
			if (new_type < 0)
				continue;

			/* Check if we support this supported_ecc */
			if ((ret =
			     _gnutls_session_supports_ecc_curve(session,
								new_type))
			    < 0) {
				continue;
			} else
				break;
			/* new_type is ok */
		}

		if (new_type < 0) {
			gnutls_assert();
			return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
		}

		if ((ret =
		     _gnutls_session_supports_ecc_curve(session,
							new_type)) < 0) {
			/* The peer has requested unsupported ecc
			 * types. Instead of failing, procceed normally.
			 * (the ciphersuite selection would fail, or a
			 * non certificate ciphersuite will be selected).
			 */
			return gnutls_assert_val(0);
		}

		_gnutls_session_ecc_curve_set(session, new_type);
	}

	return 0;
}