static
int supp_client_send_func(gnutls_session_t session, gnutls_buffer_t buf)
{
	TLS_SUPPLEMENTALDATA_client_sent = 1;
	gnutls_buffer_append_data(buf, supp_data, sizeof(supp_data));
	return GNUTLS_E_SUCCESS;
}
Esempio n. 2
0
static int
_gnutls_dumbfw_send_params(gnutls_session_t session,
			 gnutls_buffer_st * extdata)
{
	int total_size = 0, ret;
	uint8_t pad[257];
	unsigned pad_size;

	if (session->security_parameters.entity == GNUTLS_SERVER ||
	    session->internals.priorities.dumbfw == 0 ||
	    IS_DTLS(session) != 0 ||
	    (extdata->length < 256 || extdata->length >= 512)) {
		return 0;
	} else {
		/* 256 <= extdata->length < 512 */
		pad_size = 512 - extdata->length;
		memset(pad, 0, pad_size);

		ret =
		    gnutls_buffer_append_data(extdata, pad,
						       pad_size);
		if (ret < 0)
			return gnutls_assert_val(ret);

		total_size += pad_size;
	}

	return total_size;
}
Esempio n. 3
0
static int
compute_psk_binder(gnutls_session_t session,
		   const mac_entry_st *prf, unsigned binders_length,
		   int exts_length, int ext_offset,
		   const gnutls_datum_t *psk, const gnutls_datum_t *client_hello,
		   bool resuming, void *out)
{
	int ret;
	unsigned client_hello_pos, extensions_len_pos;
	gnutls_buffer_st handshake_buf;
	uint8_t binder_key[MAX_HASH_SIZE];

	_gnutls_buffer_init(&handshake_buf);

	if (session->security_parameters.entity == GNUTLS_CLIENT) {
		if (session->internals.hsk_flags & HSK_HRR_RECEIVED) {
			ret = gnutls_buffer_append_data(&handshake_buf,
							(const void *) session->internals.handshake_hash_buffer.data,
							session->internals.handshake_hash_buffer.length);
			if (ret < 0) {
				gnutls_assert();
				goto error;
			}
		}

		client_hello_pos = handshake_buf.length;
		ret = gnutls_buffer_append_data(&handshake_buf, client_hello->data,
						client_hello->size);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}

		/* This is a ClientHello message */
		handshake_buf.data[client_hello_pos] = GNUTLS_HANDSHAKE_CLIENT_HELLO;

		/* At this point we have not yet added the binders to the ClientHello,
		 * but we have to overwrite the size field, pretending as if binders
		 * of the correct length were present.
		 */
		_gnutls_write_uint24(handshake_buf.length - client_hello_pos + binders_length - 2, &handshake_buf.data[client_hello_pos + 1]);
		_gnutls_write_uint16(handshake_buf.length - client_hello_pos + binders_length - ext_offset,
				     &handshake_buf.data[client_hello_pos + ext_offset]);
		extensions_len_pos = handshake_buf.length - client_hello_pos - exts_length - 2;
		_gnutls_write_uint16(exts_length + binders_length + 2,
				     &handshake_buf.data[client_hello_pos + extensions_len_pos]);
	} else {
		if (session->internals.hsk_flags & HSK_HRR_SENT) {
			if (unlikely(session->internals.handshake_hash_buffer.length <= client_hello->size)) {
				ret = gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
				goto error;
			}

			ret = gnutls_buffer_append_data(&handshake_buf,
							session->internals.handshake_hash_buffer.data,
							session->internals.handshake_hash_buffer.length - client_hello->size);
			if (ret < 0) {
				gnutls_assert();
				goto error;
			}
		}

		if (unlikely(client_hello->size <= binders_length)) {
			ret = gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
			goto error;
		}

		ret = gnutls_buffer_append_data(&handshake_buf,
						(const void *) client_hello->data,
						client_hello->size - binders_length);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}
	}

	ret = compute_binder_key(prf,
				 psk->data, psk->size, resuming,
				 binder_key);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret = _gnutls13_compute_finished(prf, binder_key,
					 &handshake_buf,
					 out);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret = 0;
error:
	_gnutls_buffer_clear(&handshake_buf);
	return ret;
}
Esempio n. 4
0
static int _gnutls_server_cert_type_send_params(gnutls_session_t session,
						gnutls_buffer_st* data)
{
	int ret;
	uint8_t cert_type; // Holds an IANA cert type ID
	uint8_t i = 0, num_cert_types = 0;
	priority_st* cert_priorities;
	gnutls_datum_t tmp_cert_types; // For type conversion
	uint8_t cert_types[GNUTLS_CRT_MAX]; // The list with supported cert types. Inv: 0 <= cert type Id < 256

	/* Only activate this extension if we have cert credentials set
	 * and alternative cert types are allowed */
	if (!are_alternative_cert_types_allowed(session) ||
		(_gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE) == NULL))
		return 0;

	if (!IS_SERVER(session)) {	// Client mode
		// For brevity
		cert_priorities =
				&session->internals.priorities->server_ctype;

		/* Retrieve server certificate type priorities if any. If no
		 * priorities are set then the default server certificate type
		 * initialization values apply. This default is currently set to
		 * X.509 in which case we don't enable this extension.
		 */
		if (cert_priorities->num_priorities > 0) {	// Priorities are explicitly set
			/* If the certificate priority is explicitly set to only
			 * X.509 (default) then, according to spec we don't send
			 * this extension. We check this here to avoid further work in
			 * this routine. We also check it below after pruning supported
			 * types.
			 */
			if (cert_priorities->num_priorities == 1 &&
					cert_priorities->priorities[0] == DEFAULT_CERT_TYPE) {
				_gnutls_handshake_log
						("EXT[%p]: Server certificate type was set to default cert type (%s). "
						 "We therefore do not send this extension.\n",
						 session,
						 gnutls_certificate_type_get_name(DEFAULT_CERT_TYPE));

				// Explicitly set but default ctype, so don't send anything
				return 0;
			}

			/* We are only allowed to send certificate types that we support.
			 * Therefore we check this here and prune our original list.
			 * This check might seem redundant now because we don't check for
			 * credentials (they are not needed for a client) and only check the
			 * priorities over which we already iterate. In the future,
			 * additional checks might be necessary and they can be easily
			 * added in the ..type_supported() routine without modifying the
			 * structure of the code here.
			 */
			for (i = 0; i < cert_priorities->num_priorities; i++) {
				if (_gnutls_session_cert_type_supported
						(session, cert_priorities->priorities[i],
						 false, GNUTLS_CTYPE_SERVER) == 0) {
					/* Check whether we are allowed to store another cert type
					 * in our buffer. In other words, prevent a possible buffer
					 * overflow. This situation can occur when a user sets
					 * duplicate cert types in the priority strings. */
					if (num_cert_types >= GNUTLS_CRT_MAX)
						return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);

					// Convert to IANA representation
					ret = cert_type2IANA(cert_priorities->priorities[i]);

					if (ret < 0)
						return gnutls_assert_val(ret);

					cert_type = ret; // For readability

					// Add this cert type to our list with supported types
					cert_types[num_cert_types] = cert_type;
					num_cert_types++;

					_gnutls_handshake_log
							("EXT[%p]: Server certificate type %s (%d) was queued.\n",
							 session,
							 gnutls_certificate_type_get_name(cert_priorities->priorities[i]),
							 cert_type);
				}
			}

			/* Check whether there are any supported certificate types left
			 * after the previous pruning step. If not, we do not send this
			 * extension. Also, if the only supported type is the default type
			 * we do not send this extension (according to RFC7250).
			 */
			if (num_cert_types == 0) {	// For now, this should not occur since we only check priorities while pruning.
				_gnutls_handshake_log
						("EXT[%p]: Server certificate types were set but none of them is supported. "
						 "We do not send this extension.\n",
						 session);

				return 0;
			} else if (num_cert_types == 1 &&
					 IANA2cert_type(cert_types[0]) == DEFAULT_CERT_TYPE) {
				_gnutls_handshake_log
						("EXT[%p]: The only supported server certificate type is (%s) which is the default. "
						 "We therefore do not send this extension.\n",
						 session,
						 gnutls_certificate_type_get_name(DEFAULT_CERT_TYPE));

				return 0;
			}

			/* We have data to send and store a copy internally. We convert
			 * our list with supported cert types to a datum_t in order to
			 * be able to make the ..._set_datum call.
			 */
			tmp_cert_types.data = cert_types;
			tmp_cert_types.size = num_cert_types;

			_gnutls_hello_ext_set_datum(session,
								 GNUTLS_EXTENSION_SERVER_CERT_TYPE,
								 &tmp_cert_types);

			/* Serialize the certificate types into a sequence of octets
			 * uint8: length of sequence of cert types (1 octet)
			 * uint8: cert types (0 <= #octets <= 255)
			 */
			ret = _gnutls_buffer_append_data_prefix(data, 8,
								cert_types,
								num_cert_types);

			// Check for errors and cleanup in case of error
			if (ret < 0) {
				return gnutls_assert_val(ret);
			} else {
				// Number of bytes we are sending
				return num_cert_types + 1;
			}
		}
	} else {	// Server mode
		// Retrieve negotiated server certificate type and send it
		ret = cert_type2IANA(get_certificate_type(
					session, GNUTLS_CTYPE_SERVER));

		if (ret < 0)
			return gnutls_assert_val(ret);

		cert_type = ret; // For readability

		ret = gnutls_buffer_append_data(data, &cert_type, 1);

		if (ret < 0)
			return gnutls_assert_val(ret);

		return 1;	// sent one byte
	}

	// In all other cases don't enable this extension
	return 0;
}