/* Return a heap allocated string that contains the given <b>srv</b> string * representation formatted for a networkstatus document using the * <b>key</b> as the start of the line. This doesn't return NULL. */ static char * srv_to_ns_string(const sr_srv_t *srv, const char *key) { char *srv_str; char srv_hash_encoded[SR_SRV_VALUE_BASE64_LEN + 1]; tor_assert(srv); tor_assert(key); sr_srv_encode(srv_hash_encoded, sizeof(srv_hash_encoded), srv); tor_asprintf(&srv_str, "%s %" PRIu64 " %s\n", key, srv->num_reveals, srv_hash_encoded); log_debug(LD_DIR, "SR: Consensus SRV line: %s", srv_str); return srv_str; }
/* From a valid srv object and an allocated config line, set the line's * value to the state string representation of a shared random value. */ static void disk_state_put_srv_line(const sr_srv_t *srv, config_line_t *line) { char encoded[SR_SRV_VALUE_BASE64_LEN + 1]; tor_assert(line); /* No SRV value thus don't add the line. This is possible since we might * not have a current or previous SRV value in our state. */ if (srv == NULL) { return; } sr_srv_encode(encoded, sizeof(encoded), srv); tor_asprintf(&line->value, "%" PRIu64 " %s", srv->num_reveals, encoded); }
/* Return a srv object that is built with the construction: * SRV = SHA3-256("shared-random" | INT_8(reveal_num) | * INT_4(version) | HASHED_REVEALS | previous_SRV) * This function cannot fail. */ static sr_srv_t * generate_srv(const char *hashed_reveals, uint64_t reveal_num, const sr_srv_t *previous_srv) { char msg[DIGEST256_LEN + SR_SRV_MSG_LEN] = {0}; size_t offset = 0; sr_srv_t *srv; tor_assert(hashed_reveals); /* Add the invariant token. */ memcpy(msg, SR_SRV_TOKEN, SR_SRV_TOKEN_LEN); offset += SR_SRV_TOKEN_LEN; set_uint64(msg + offset, tor_htonll(reveal_num)); offset += sizeof(uint64_t); set_uint32(msg + offset, htonl(SR_PROTO_VERSION)); offset += sizeof(uint32_t); memcpy(msg + offset, hashed_reveals, DIGEST256_LEN); offset += DIGEST256_LEN; if (previous_srv != NULL) { memcpy(msg + offset, previous_srv->value, sizeof(previous_srv->value)); } /* Ok we have our message and key for the HMAC computation, allocate our * srv object and do the last step. */ srv = tor_malloc_zero(sizeof(*srv)); crypto_digest256((char *) srv->value, msg, sizeof(msg), SR_DIGEST_ALG); srv->num_reveals = reveal_num; { /* Debugging. */ char srv_hash_encoded[SR_SRV_VALUE_BASE64_LEN + 1]; sr_srv_encode(srv_hash_encoded, sizeof(srv_hash_encoded), srv); log_info(LD_DIR, "SR: Generated SRV: %s", srv_hash_encoded); } return srv; }