*recognized = 1;
*layer_hint = thishop;
/* Keep current digest of this cell for the possible SENDME. */
- if (thishop->crypto.sendme_digest) {
- crypto_digest_free(thishop->crypto.sendme_digest);
- }
- thishop->crypto.sendme_digest =
- crypto_digest_dup(thishop->crypto.b_digest);
-
+ crypto_digest_get_digest(thishop->crypto.b_digest,
+ (char *) thishop->crypto.sendme_digest,
+ sizeof(thishop->crypto.sendme_digest));
return 0;
}
}
{
relay_set_digest(or_circ->crypto.b_digest, cell);
/* Keep a record of this cell, we might use it for validating the SENDME. */
- if (or_circ->crypto.sendme_digest) {
- crypto_digest_free(or_circ->crypto.sendme_digest);
- }
- or_circ->crypto.sendme_digest = crypto_digest_dup(or_circ->crypto.b_digest);
+ crypto_digest_get_digest(or_circ->crypto.b_digest,
+ (char *) or_circ->crypto.sendme_digest,
+ sizeof(or_circ->crypto.sendme_digest));
/* encrypt one layer */
relay_crypt_one_payload(or_circ->crypto.b_crypto, cell->payload);
}
crypto_cipher_free(crypto->b_crypto);
crypto_digest_free(crypto->f_digest);
crypto_digest_free(crypto->b_digest);
- crypto_digest_free(crypto->sendme_digest);
}
/** Initialize <b>crypto</b> from the key material in key_data.
struct crypto_digest_t *b_digest;
/** Digest used for the next SENDME cell if any. */
- struct crypto_digest_t *sendme_digest;
+ uint8_t sendme_digest[DIGEST_LEN];
};
#undef crypto_cipher_t
* Return the size in bytes of the encoded cell in payload. A negative value
* is returned on encoding failure. */
STATIC ssize_t
-build_cell_payload_v1(crypto_digest_t *cell_digest, uint8_t *payload)
+build_cell_payload_v1(const uint8_t *cell_digest, uint8_t *payload)
{
ssize_t len = -1;
sendme_cell_t *cell = NULL;
sendme_cell_set_data_len(cell, TRUNNEL_SENDME_V1_DIGEST_LEN);
/* Copy the digest into the data payload. */
- crypto_digest_get_digest(cell_digest,
- (char *) sendme_cell_getarray_data_v1_digest(cell),
- sendme_cell_get_data_len(cell));
+ memcpy(sendme_cell_getarray_data_v1_digest(cell), cell_digest,
+ sendme_cell_get_data_len(cell));
/* Finally, encode the cell into the payload. */
len = sendme_cell_encode(payload, RELAY_PAYLOAD_SIZE, cell);
* because we failed to send the cell on it. */
static int
send_circuit_level_sendme(circuit_t *circ, crypt_path_t *layer_hint,
- crypto_digest_t *cell_digest)
+ const uint8_t *cell_digest)
{
uint8_t emit_version;
uint8_t payload[RELAY_PAYLOAD_SIZE];
void
sendme_circuit_consider_sending(circuit_t *circ, crypt_path_t *layer_hint)
{
- crypto_digest_t *digest;
+ const uint8_t *digest;
while ((layer_hint ? layer_hint->deliver_window : circ->deliver_window) <=
CIRCWINDOW_START - CIRCWINDOW_INCREMENT) {
void
sendme_note_cell_digest(circuit_t *circ)
{
- uint8_t *digest;
+ const uint8_t *digest;
tor_assert(circ);
return;
}
- /* Only note the digest if we actually have the digest of the previous cell
- * recorded. It should never happen in theory as we always record the last
- * digest for the v1 SENDME. */
- if (TO_OR_CIRCUIT(circ)->crypto.sendme_digest) {
- digest = tor_malloc_zero(TRUNNEL_SENDME_V1_DIGEST_LEN);
- crypto_digest_get_digest(TO_OR_CIRCUIT(circ)->crypto.sendme_digest,
- (char *) digest, TRUNNEL_SENDME_V1_DIGEST_LEN);
- if (circ->sendme_last_digests == NULL) {
- circ->sendme_last_digests = smartlist_new();
- }
- smartlist_add(circ->sendme_last_digests, digest);
+ /* Add the digest to the last seen list in the circuit. */
+ digest = TO_OR_CIRCUIT(circ)->crypto.sendme_digest;
+ if (circ->sendme_last_digests == NULL) {
+ circ->sendme_last_digests = smartlist_new();
}
+ smartlist_add(circ->sendme_last_digests, tor_memdup(digest, DIGEST_LEN));
}
STATIC bool cell_version_is_valid(uint8_t cell_version);
-STATIC ssize_t build_cell_payload_v1(crypto_digest_t *cell_digest,
+STATIC ssize_t build_cell_payload_v1(const uint8_t *cell_digest,
uint8_t *payload);
STATIC bool sendme_is_valid(const circuit_t *circ,
const uint8_t *cell_payload,
circ = helper_create_origin_circuit(CIRCUIT_PURPOSE_C_GENERAL, 0);
circ->cpath->state = CPATH_STATE_AWAITING_KEYS;
circ->cpath->deliver_window = CIRCWINDOW_START;
- circ->cpath->crypto.sendme_digest = crypto_digest_new();
entryconn1 = fake_entry_conn(circ, 1);
edgeconn = ENTRY_TO_EDGE_CONN(entryconn1);
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/networkstatus_st.h"
+#include "lib/crypt_ops/crypto_digest.h"
+
#include "test/test.h"
#include "test/log_test_helpers.h"
circuit_free_(circ);
/* Points it to the OR circuit now. */
circ = TO_CIRCUIT(or_circ);
- or_circ->crypto.sendme_digest = crypto_digest_new();
/* The package window has to be a multiple of CIRCWINDOW_INCREMENT minus 1
* in order to catched the CIRCWINDOW_INCREMENT-nth cell. Try something that
static void
test_v1_build_cell(void *arg)
{
- uint8_t payload[RELAY_PAYLOAD_SIZE];
+ uint8_t payload[RELAY_PAYLOAD_SIZE], digest[DIGEST_LEN];
ssize_t ret;
crypto_digest_t *cell_digest = NULL;
or_circuit_t *or_circ = NULL;
circ = TO_CIRCUIT(or_circ);
cell_digest = crypto_digest_new();
- crypto_digest_add_bytes(cell_digest, "AAAAAAAAAAAAAAAAAAAA", 20);
tt_assert(cell_digest);
+ crypto_digest_add_bytes(cell_digest, "AAAAAAAAAAAAAAAAAAAA", 20);
+ crypto_digest_get_digest(cell_digest, (char *) digest, sizeof(digest));
/* SENDME v1 payload is 3 bytes + 20 bytes digest. See spec. */
- ret = build_cell_payload_v1(cell_digest, payload);
+ ret = build_cell_payload_v1(digest, payload);
tt_int_op(ret, OP_EQ, 23);
/* Validation. */
teardown_capture_of_logs();
/* Note the wrong digest in the circuit, cell should fail validation. */
- or_circ->crypto.sendme_digest = crypto_digest_new();
circ->package_window = CIRCWINDOW_INCREMENT + 1;
sendme_note_cell_digest(circ);
tt_int_op(smartlist_len(circ->sendme_last_digests), OP_EQ, 1);
expect_log_msg_containing("SENDME v1 cell digest do not match.");
teardown_capture_of_logs();
- /* Cleanup */
- crypto_digest_free(or_circ->crypto.sendme_digest);
-
/* Record the cell digest into the circuit, cell should validate. */
- or_circ->crypto.sendme_digest = crypto_digest_dup(cell_digest);
+ memcpy(or_circ->crypto.sendme_digest, digest, sizeof(digest));
circ->package_window = CIRCWINDOW_INCREMENT + 1;
sendme_note_cell_digest(circ);
tt_int_op(smartlist_len(circ->sendme_last_digests), OP_EQ, 1);