Commit e17cc3f0 authored by George Kadianakis's avatar George Kadianakis Committed by Nick Mathewson
Browse files

prop224 prepwork: Finish decoupling old ESTABLISH_INTRO creation logic.

parent b5b34e62
Loading
Loading
Loading
Loading
+46 −21
Original line number Diff line number Diff line
@@ -2986,38 +2986,55 @@ count_intro_point_circuits(const rend_service_t *service)
  return num_ipos;
}

static size_t
/* Given a buffer of at least RELAY_PAYLOAD_SIZE bytes in <b>cell_body_out</b>,
   write the body of a legacy ESTABLISH_INTRO cell in it. Use <b>intro_key</b>
   as the intro point auth key, and <b>rend_circ_nonce</b> as the circuit
   crypto material. On success, fill <b>cell_body_out</b> and return the number
   of bytes written. On fail, return -1.
 */
STATIC ssize_t
encode_establish_intro_cell_legacy(char *cell_body_out, crypto_pk_t *intro_key,
                                   char *rend_circ_nonce)
{
/* Use the intro key instead of the service key in ESTABLISH_INTRO. */
  crypto_pk_t *intro_key = circuit->intro_key;
  int retval = -1;
  int r;
  int len = 0;
  char auth[DIGEST_LEN + 9];

  tor_assert(intro_key);
  tor_assert(rend_circ_nonce);

  /* Build the payload for a RELAY_ESTABLISH_INTRO cell. */
  r = crypto_pk_asn1_encode(intro_key, buf+2,
  r = crypto_pk_asn1_encode(intro_key, cell_body_out+2,
                            RELAY_PAYLOAD_SIZE-2);
  if (r < 0) {
    log_warn(LD_BUG, "Internal error; failed to establish intro point.");
    reason = END_CIRC_REASON_INTERNAL;
    goto err;
  }
  len = r;
  set_uint16(buf, htons((uint16_t)len));
  set_uint16(cell_body_out, htons((uint16_t)len));
  len += 2;
  memcpy(auth, circuit->cpath->prev->rend_circ_nonce, DIGEST_LEN);
  memcpy(auth, rend_circ_nonce, DIGEST_LEN);
  memcpy(auth+DIGEST_LEN, "INTRODUCE", 9);
  if (crypto_digest(buf+len, auth, DIGEST_LEN+9))

  if (crypto_digest(cell_body_out+len, auth, DIGEST_LEN+9))
    goto err;
  len += 20;
  note_crypto_pk_op(REND_SERVER);
  r = crypto_pk_private_sign_digest(intro_key, buf+len, sizeof(buf)-len,
                                    buf, len);
  r = crypto_pk_private_sign_digest(intro_key, cell_body_out+len,
                                    sizeof(cell_body_out)-len,
                                    cell_body_out, len);
  if (r<0) {
    log_warn(LD_BUG, "Internal error: couldn't sign introduction request.");
    reason = END_CIRC_REASON_INTERNAL;
    goto err;
  }
  len += r;

  retval = len;

 err:
  memwipe(auth, 0, sizeof(auth));

  return retval;
}

/** Called when we're done building a circuit to an introduction point:
@@ -3027,8 +3044,7 @@ void
rend_service_intro_has_opened(origin_circuit_t *circuit)
{
  rend_service_t *service;
  int r;
  char auth[DIGEST_LEN + 9];
  char buf[RELAY_PAYLOAD_SIZE];
  char serviceid[REND_SERVICE_ID_LEN_BASE32+1];
  int reason = END_CIRC_REASON_TORPROTOCOL;
  const char *rend_pk_digest;
@@ -3103,6 +3119,16 @@ rend_service_intro_has_opened(origin_circuit_t *circuit)
           (unsigned)circuit->base_.n_circ_id, serviceid);
  circuit_log_path(LOG_INFO, LD_REND, circuit);

  /* Send the ESTABLISH_INTRO cell */
  {
    ssize_t len;
    len = encode_establish_intro_cell_legacy(buf, circuit->intro_key,
                                        circuit->cpath->prev->rend_circ_nonce);
    if (len < 0) {
      reason = END_CIRC_REASON_INTERNAL;
      goto err;
    }

    if (relay_send_command_from_edge(0, TO_CIRCUIT(circuit),
                                     RELAY_COMMAND_ESTABLISH_INTRO,
                                     buf, len, circuit->cpath->prev)<0) {
@@ -3111,6 +3137,7 @@ rend_service_intro_has_opened(origin_circuit_t *circuit)
             serviceid, (unsigned)circuit->base_.n_circ_id);
      goto done;
    }
  }

  /* We've attempted to use this circuit */
  pathbias_count_use_attempt(circuit);
@@ -3121,7 +3148,6 @@ rend_service_intro_has_opened(origin_circuit_t *circuit)
  circuit_mark_for_close(TO_CIRCUIT(circuit), reason);
 done:
  memwipe(buf, 0, sizeof(buf));
  memwipe(auth, 0, sizeof(auth));
  memwipe(serviceid, 0, sizeof(serviceid));

  return;
@@ -4284,4 +4310,3 @@ rend_service_non_anonymous_mode_enabled(const or_options_t *options)
  tor_assert(rend_service_non_anonymous_mode_consistent(options));
  return options->HiddenServiceNonAnonymousMode ? 1 : 0;
}
+3 −1
Original line number Diff line number Diff line
@@ -119,7 +119,9 @@ typedef struct rend_service_t {

STATIC void rend_service_free(rend_service_t *service);
STATIC char *rend_service_sos_poison_path(const rend_service_t *service);

STATIC ssize_t encode_establish_intro_cell_legacy(char *cell_body_out,
                                                  crypto_pk_t *intro_key,
                                                  char *rend_circ_nonce);
#endif

int num_rend_services(void);