Exemplo n.º 1
0
/**
 * Encrypt a cell <b>cell</b> that we are creating, and sending on
 * <b>circuit</b> to the origin.
 *
 * The integrity field and recognized field of <b>cell</b>'s relay headers
 * must be set to zero.
 */
void
relay_encrypt_cell_inbound(cell_t *cell,
                           or_circuit_t *or_circ)
{
  relay_set_digest(or_circ->crypto.b_digest, cell);
  /* encrypt one layer */
  relay_crypt_one_payload(or_circ->crypto.b_crypto, cell->payload);
}
Exemplo n.º 2
0
/**
 * Encrypt a cell <b>cell</b> that we are creating, and sending on
 * <b>circuit</b> to the origin.
 *
 * The integrity field and recognized field of <b>cell</b>'s relay headers
 * must be set to zero.
 */
void
relay_encrypt_cell_inbound(cell_t *cell,
                           or_circuit_t *or_circ)
{
  relay_set_digest(or_circ->crypto.b_digest, cell);

  /* Record cell digest as the SENDME digest if need be. */
  sendme_record_sending_cell_digest(TO_CIRCUIT(or_circ), NULL);

  /* encrypt one layer */
  relay_crypt_one_payload(or_circ->crypto.b_crypto, cell->payload);
}
Exemplo n.º 3
0
/**
 * Encrypt a cell <b>cell</b> that we are creating, and sending outbound on
 * <b>circ</b> until the hop corresponding to <b>layer_hint</b>.
 *
 * The integrity field and recognized field of <b>cell</b>'s relay headers
 * must be set to zero.
 */
void
relay_encrypt_cell_outbound(cell_t *cell,
                            origin_circuit_t *circ,
                            crypt_path_t *layer_hint)
{
  crypt_path_t *thishop; /* counter for repeated crypts */
  relay_set_digest(layer_hint->crypto.f_digest, cell);

  thishop = layer_hint;
  /* moving from farthest to nearest hop */
  do {
    tor_assert(thishop);
    log_debug(LD_OR,"encrypting a layer of the relay cell.");
    relay_crypt_one_payload(thishop->crypto.f_crypto, cell->payload);

    thishop = thishop->prev;
  } while (thishop != circ->cpath->prev);
}
Exemplo n.º 4
0
/** Do the appropriate en/decryptions for <b>cell</b> arriving on
 * <b>circ</b> in direction <b>cell_direction</b>.
 *
 * If cell_direction == CELL_DIRECTION_IN:
 *   - If we're at the origin (we're the OP), for hops 1..N,
 *     decrypt cell. If recognized, stop.
 *   - Else (we're not the OP), encrypt one hop. Cell is not recognized.
 *
 * If cell_direction == CELL_DIRECTION_OUT:
 *   - decrypt one hop. Check if recognized.
 *
 * If cell is recognized, set *recognized to 1, and set
 * *layer_hint to the hop that recognized it.
 *
 * Return -1 to indicate that we should mark the circuit for close,
 * else return 0.
 */
int
relay_decrypt_cell(circuit_t *circ, cell_t *cell,
                   cell_direction_t cell_direction,
                   crypt_path_t **layer_hint, char *recognized)
{
  relay_header_t rh;

  tor_assert(circ);
  tor_assert(cell);
  tor_assert(recognized);
  tor_assert(cell_direction == CELL_DIRECTION_IN ||
             cell_direction == CELL_DIRECTION_OUT);

  if (cell_direction == CELL_DIRECTION_IN) {
    if (CIRCUIT_IS_ORIGIN(circ)) { /* We're at the beginning of the circuit.
                                    * We'll want to do layered decrypts. */
      crypt_path_t *thishop, *cpath = TO_ORIGIN_CIRCUIT(circ)->cpath;
      thishop = cpath;
      if (thishop->state != CPATH_STATE_OPEN) {
        log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
               "Relay cell before first created cell? Closing.");
        return -1;
      }
      do { /* Remember: cpath is in forward order, that is, first hop first. */
        tor_assert(thishop);

        /* decrypt one layer */
        relay_crypt_one_payload(thishop->crypto.b_crypto, cell->payload);

        relay_header_unpack(&rh, cell->payload);
        if (rh.recognized == 0) {
          /* it's possibly recognized. have to check digest to be sure. */
          if (relay_digest_matches(thishop->crypto.b_digest, cell)) {
            *recognized = 1;
            *layer_hint = thishop;
            return 0;
          }
        }

        thishop = thishop->next;
      } while (thishop != cpath && thishop->state == CPATH_STATE_OPEN);
      log_fn(LOG_PROTOCOL_WARN, LD_OR,
             "Incoming cell at client not recognized. Closing.");
      return -1;
    } else {
      relay_crypto_t *crypto = &TO_OR_CIRCUIT(circ)->crypto;
      /* We're in the middle. Encrypt one layer. */
      relay_crypt_one_payload(crypto->b_crypto, cell->payload);
    }
  } else /* cell_direction == CELL_DIRECTION_OUT */ {
    /* We're in the middle. Decrypt one layer. */
    relay_crypto_t *crypto = &TO_OR_CIRCUIT(circ)->crypto;

    relay_crypt_one_payload(crypto->f_crypto, cell->payload);

    relay_header_unpack(&rh, cell->payload);
    if (rh.recognized == 0) {
      /* it's possibly recognized. have to check digest to be sure. */
      if (relay_digest_matches(crypto->f_digest, cell)) {
        *recognized = 1;
        return 0;
      }
    }
  }
  return 0;
}