예제 #1
0
void send_addr_discover(ChordServer *srv, in6_addr *to_addr, ushort to_port)
{
	int ticket_len = pack_ticket(srv->ticket_salt, srv->ticket_salt_len,
								 srv->ticket_hash_len, ticket_buf, "c6s",
								 CHORD_ADDR_DISCOVER, to_addr, to_port);

	int len = pack_addr_discover(buf, ticket_buf, ticket_len);

	LOG_SEND();
	send_packet(srv, to_addr, to_port, len, buf);
}
예제 #2
0
void send_ping(ChordServer *srv, in6_addr *to_addr, ushort to_port, ulong time)
{
	int ticket_len = pack_ticket(srv->ticket_salt, srv->ticket_salt_len,
								 srv->ticket_hash_len, ticket_buf, "c6sl",
								 CHORD_PING, to_addr, to_port, time);

	int len = pack_ping(buf, ticket_buf, ticket_len, time);

	LOG_SEND();
	send_packet(srv, to_addr, to_port, len, buf);
}
예제 #3
0
void send_fs(ChordServer *srv, uchar ttl, in6_addr *to_addr, ushort to_port,
			 in6_addr *addr, ushort port)
{
	int ticket_len = pack_ticket(srv->ticket_salt, srv->ticket_salt_len,
								 srv->ticket_hash_len, ticket_buf, "c",
								 CHORD_FS);

	int len = pack_fs(buf, ticket_buf, ticket_len, ttl, addr, port);

	LOG_SEND();
	send_packet(srv, to_addr, to_port, len, buf);
}
예제 #4
0
int
_gnutls_encrypt_session_ticket(gnutls_session_t session,
			       const gnutls_datum_t *state,
			       gnutls_datum_t *ticket_data)
{
	cipher_hd_st cipher_hd;
	gnutls_datum_t IV;
	gnutls_datum_t encrypted_state = {NULL,0};
	uint8_t iv[TICKET_IV_SIZE];
	gnutls_datum_t stek_cipher_key, stek_mac_key, stek_key_name;
	struct ticket_st ticket;
	int ret;

	encrypted_state.size = ((state->size + TICKET_BLOCK_SIZE - 1) / TICKET_BLOCK_SIZE) * TICKET_BLOCK_SIZE;
	ticket_data->size = TICKET_KEY_NAME_SIZE + TICKET_IV_SIZE + 2 +
	    encrypted_state.size + TICKET_MAC_SIZE;
	ticket_data->data = gnutls_calloc(1, ticket_data->size);
	if (!ticket_data->data) {
		gnutls_assert();
		ret = GNUTLS_E_MEMORY_ERROR;
		goto cleanup;
	}
	encrypted_state.data = ticket_data->data + TICKET_KEY_NAME_SIZE + TICKET_IV_SIZE + 2;
	memcpy(encrypted_state.data, state->data, state->size);

	/* Retrieve ticket encryption keys */
	if (_gnutls_get_session_ticket_encryption_key(session,
						      &stek_key_name,
						      &stek_mac_key,
						      &stek_cipher_key) < 0) {
		ret = GNUTLS_E_ENCRYPTION_FAILED;
		goto cleanup;
	}

	/* Encrypt state */
	IV.data = iv;
	IV.size = TICKET_IV_SIZE;

	ret = gnutls_rnd(GNUTLS_RND_NONCE, iv, TICKET_IV_SIZE);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret =
	    _gnutls_cipher_init(&cipher_hd,
				cipher_to_entry(TICKET_CIPHER),
				&stek_cipher_key, &IV, 1);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret = _gnutls_cipher_encrypt(&cipher_hd, encrypted_state.data,
				     encrypted_state.size);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup2;
	}


	/* Fill the ticket structure to compute MAC. */
	memcpy(ticket.key_name, stek_key_name.data, stek_key_name.size);
	memcpy(ticket.IV, IV.data, IV.size);
	ticket.encrypted_state_len = encrypted_state.size;
	ticket.encrypted_state = encrypted_state.data;

	ret = digest_ticket(&stek_mac_key, &ticket, ticket.mac);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup2;
	}

	encrypted_state.data = NULL;

	pack_ticket(&ticket, ticket_data);

	ret = 0;

cleanup2:
	_gnutls_cipher_deinit(&cipher_hd);

cleanup:
	_gnutls_free_datum(&encrypted_state);

	return ret;
}
예제 #5
0
static int
generate_session_ticket(gnutls_session_t session, tls13_ticket_st *ticket)
{
	int ret;
	gnutls_datum_t packed = { NULL, 0 };
	struct timespec now;
	tls13_ticket_st ticket_data;

	gnutls_gettime(&now);
	if (session->internals.resumed != RESUME_FALSE) {
		/* If we are resuming ensure that we don't extend the lifetime
		 * of the ticket past the original session expiration time */
		if (now.tv_sec >= session->security_parameters.timestamp + session->internals.expire_time)
			return GNUTLS_E_INT_RET_0; /* don't send ticket */
		else
			ticket->lifetime = session->security_parameters.timestamp +
					   session->internals.expire_time - now.tv_sec;
	} else {
		/* Set ticket lifetime to the default expiration time */
		ticket->lifetime = session->internals.expire_time;
	}

	/* Generate a random 32-bit ticket nonce */
	ticket->nonce_size = 4;

	if ((ret = gnutls_rnd(GNUTLS_RND_NONCE,
			ticket->nonce, ticket->nonce_size)) < 0)
		return gnutls_assert_val(ret);

	if ((ret = gnutls_rnd(GNUTLS_RND_NONCE, &ticket->age_add, sizeof(uint32_t))) < 0)
		return gnutls_assert_val(ret);
	/* This is merely to produce the same binder value on
	 * different endian architectures. */
#ifdef WORDS_BIGENDIAN
	ticket->age_add = bswap_32(ticket->age_add);
#endif

	ticket->prf = session->security_parameters.prf;

	/* Encrypt the ticket and place the result in ticket->ticket */
	ticket_data.lifetime = ticket->lifetime;
	ticket_data.age_add = ticket->age_add;
	memcpy(&ticket_data.creation_time, &now, sizeof(struct timespec));
	memcpy(ticket_data.nonce, ticket->nonce, ticket->nonce_size);
	ticket_data.nonce_size = ticket->nonce_size;
	ticket_data.prf = ticket->prf;
	memcpy(&ticket_data.resumption_master_secret,
	       session->key.proto.tls13.ap_rms,
	       ticket->prf->output_size);

	ret = pack_ticket(session, &ticket_data, &packed);
	if (ret < 0)
		return gnutls_assert_val(ret);

	ret = _gnutls_encrypt_session_ticket(session, &packed, &ticket->ticket);
	_gnutls_free_datum(&packed);
	if (ret < 0)
		return gnutls_assert_val(ret);

	return 0;
}