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); }
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); }
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); }
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; }
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; }