Commit 53061b37 authored by Roger Dingledine's avatar Roger Dingledine
Browse files

fix endian issue: rh.integrity was getting sent wrong

now it's a char[4] rather than an int


svn:r966
parent c2e37901
Loading
Loading
Loading
Loading
+16 −13
Original line number Original line Diff line number Diff line
@@ -314,14 +314,15 @@ int circuit_stream_is_being_handled(connection_t *conn) {


/* update digest from the payload of cell. assign integrity part to cell. */
/* update digest from the payload of cell. assign integrity part to cell. */
static void relay_set_digest(crypto_digest_env_t *digest, cell_t *cell) {
static void relay_set_digest(crypto_digest_env_t *digest, cell_t *cell) {
  uint32_t integrity;
  char integrity[4];
  relay_header_t rh;
  relay_header_t rh;


  crypto_digest_add_bytes(digest, cell->payload, CELL_PAYLOAD_SIZE);
  crypto_digest_add_bytes(digest, cell->payload, CELL_PAYLOAD_SIZE);
  crypto_digest_get_digest(digest, (char *)&integrity, 4);
  crypto_digest_get_digest(digest, integrity, 4);
  log_fn(LOG_DEBUG,"Putting digest of %u into relay cell.",integrity);
  log_fn(LOG_DEBUG,"Putting digest of %u %u %u %u into relay cell.",
    integrity[0], integrity[1], integrity[2], integrity[3]);
  relay_header_unpack(&rh, cell->payload);
  relay_header_unpack(&rh, cell->payload);
  rh.integrity = integrity;
  memcpy(rh.integrity, integrity, 4);
  relay_header_pack(cell->payload, &rh);
  relay_header_pack(cell->payload, &rh);
}
}


@@ -330,29 +331,31 @@ static void relay_set_digest(crypto_digest_env_t *digest, cell_t *cell) {
 * and cell to their original state and return 0.
 * and cell to their original state and return 0.
 */
 */
static int relay_digest_matches(crypto_digest_env_t *digest, cell_t *cell) {
static int relay_digest_matches(crypto_digest_env_t *digest, cell_t *cell) {
  uint32_t received_integrity, calculated_integrity;
  char received_integrity[4], calculated_integrity[4];
  relay_header_t rh;
  relay_header_t rh;
  crypto_digest_env_t *backup_digest=NULL;
  crypto_digest_env_t *backup_digest=NULL;


  backup_digest = crypto_digest_dup(digest);
  backup_digest = crypto_digest_dup(digest);


  relay_header_unpack(&rh, cell->payload);
  relay_header_unpack(&rh, cell->payload);
  received_integrity = rh.integrity;
  memcpy(received_integrity, rh.integrity, 4);
  rh.integrity = 0;
  memset(rh.integrity, 0, 4);
  relay_header_pack(cell->payload, &rh);
  relay_header_pack(cell->payload, &rh);


  log_fn(LOG_DEBUG,"Reading digest of %u from relay cell.",received_integrity);
  log_fn(LOG_DEBUG,"Reading digest of %u %u %u %u from relay cell.",
    received_integrity[0], received_integrity[1],
    received_integrity[2], received_integrity[3]);


  crypto_digest_add_bytes(digest, cell->payload, CELL_PAYLOAD_SIZE);
  crypto_digest_add_bytes(digest, cell->payload, CELL_PAYLOAD_SIZE);
  crypto_digest_get_digest(digest, (char *)&calculated_integrity, 4);
  crypto_digest_get_digest(digest, calculated_integrity, 4);


  if(received_integrity != calculated_integrity) {
  if(memcmp(received_integrity, calculated_integrity, 4)) {
    log_fn(LOG_INFO,"Recognized=0 but bad digest. Not recognizing. (%d vs %d).",
    log_fn(LOG_INFO,"Recognized=0 but bad digest. Not recognizing.");
           received_integrity, calculated_integrity);
// (%d vs %d).", received_integrity, calculated_integrity);
    /* restore digest to its old form */
    /* restore digest to its old form */
    crypto_digest_assign(digest, backup_digest);
    crypto_digest_assign(digest, backup_digest);
    /* restore the relay header */
    /* restore the relay header */
    rh.integrity = received_integrity;
    memcpy(rh.integrity, received_integrity, 4);
    relay_header_pack(cell->payload, &rh);
    relay_header_pack(cell->payload, &rh);
    crypto_free_digest_env(backup_digest);
    crypto_free_digest_env(backup_digest);
    return 0;
    return 0;
+2 −2
Original line number Original line Diff line number Diff line
@@ -24,7 +24,7 @@ void relay_header_pack(char *dest, const relay_header_t *src) {
  *(uint8_t*)(dest)    = src->command;
  *(uint8_t*)(dest)    = src->command;
  *(uint16_t*)(dest+1) = htons(src->recognized);
  *(uint16_t*)(dest+1) = htons(src->recognized);
  *(uint16_t*)(dest+3) = htons(src->stream_id);
  *(uint16_t*)(dest+3) = htons(src->stream_id);
  *(uint32_t*)(dest+5) = htonl(src->integrity);
  memcpy(dest+5, src->integrity, 4);
  *(uint16_t*)(dest+9) = htons(src->length);
  *(uint16_t*)(dest+9) = htons(src->length);
}
}


@@ -32,7 +32,7 @@ void relay_header_unpack(relay_header_t *dest, const char *src) {
  dest->command    = *(uint8_t*)(src);
  dest->command    = *(uint8_t*)(src);
  dest->recognized = ntohs(*(uint16_t*)(src+1));
  dest->recognized = ntohs(*(uint16_t*)(src+1));
  dest->stream_id  = ntohs(*(uint16_t*)(src+3));
  dest->stream_id  = ntohs(*(uint16_t*)(src+3));
  dest->integrity  = ntohl(*(uint32_t*)(src+5));
  memcpy(dest->integrity, src+5, 4);
  dest->length     = ntohs(*(uint16_t*)(src+9));
  dest->length     = ntohs(*(uint16_t*)(src+9));
}
}


+1 −1
Original line number Original line Diff line number Diff line
@@ -283,7 +283,7 @@ typedef struct {
  uint8_t command;
  uint8_t command;
  uint16_t recognized;
  uint16_t recognized;
  uint16_t stream_id;
  uint16_t stream_id;
  uint32_t integrity;
  char integrity[4];
  uint16_t length;
  uint16_t length;
} relay_header_t;
} relay_header_t;