hs_circuit.c (63569B)
1 /* Copyright (c) 2017-2021, The Tor Project, Inc. */ 2 /* See LICENSE for licensing information */ 3 4 /** 5 * \file hs_circuit.c 6 **/ 7 8 #define HS_CIRCUIT_PRIVATE 9 10 #include "core/or/or.h" 11 #include "app/config/config.h" 12 #include "core/crypto/hs_ntor.h" 13 #include "core/or/circuitbuild.h" 14 #include "core/or/circuitlist.h" 15 #include "core/or/circuituse.h" 16 #include "core/or/policies.h" 17 #include "core/or/relay.h" 18 #include "core/or/crypt_path.h" 19 #include "core/or/extendinfo.h" 20 #include "core/or/congestion_control_common.h" 21 #include "core/crypto/onion_crypto.h" 22 #include "feature/client/circpathbias.h" 23 #include "feature/hs/hs_cell.h" 24 #include "feature/hs/hs_circuit.h" 25 #include "feature/hs/hs_common.h" 26 #include "feature/hs/hs_ob.h" 27 #include "feature/hs/hs_circuitmap.h" 28 #include "feature/hs/hs_client.h" 29 #include "feature/hs/hs_ident.h" 30 #include "feature/hs/hs_metrics.h" 31 #include "feature/hs/hs_service.h" 32 #include "feature/nodelist/describe.h" 33 #include "feature/nodelist/nodelist.h" 34 #include "feature/stats/rephist.h" 35 #include "lib/crypt_ops/crypto_dh.h" 36 #include "lib/crypt_ops/crypto_rand.h" 37 #include "lib/crypt_ops/crypto_util.h" 38 #include "lib/time/compat_time.h" 39 40 /* Trunnel. */ 41 #include "trunnel/ed25519_cert.h" 42 #include "trunnel/hs/cell_establish_intro.h" 43 44 #include "core/or/congestion_control_st.h" 45 #include "core/or/cpath_build_state_st.h" 46 #include "core/or/crypt_path_st.h" 47 #include "core/or/extend_info_st.h" 48 #include "feature/nodelist/node_st.h" 49 #include "core/or/origin_circuit_st.h" 50 51 /** Helper: Free a pending rend object. */ 52 static inline void 53 free_pending_rend(pending_rend_t *req) 54 { 55 if (!req) { 56 return; 57 } 58 link_specifier_smartlist_free(req->rdv_data.link_specifiers); 59 memwipe(req, 0, sizeof(pending_rend_t)); 60 tor_free(req); 61 } 62 63 /** A circuit is about to become an e2e rendezvous circuit. Check 64 * <b>circ_purpose</b> and ensure that it's properly set. Return true iff 65 * circuit purpose is properly set, otherwise return false. */ 66 static int 67 circuit_purpose_is_correct_for_rend(unsigned int circ_purpose, 68 int is_service_side) 69 { 70 if (is_service_side) { 71 if (circ_purpose != CIRCUIT_PURPOSE_S_CONNECT_REND) { 72 log_warn(LD_BUG, 73 "HS e2e circuit setup with wrong purpose (%d)", circ_purpose); 74 return 0; 75 } 76 } 77 78 if (!is_service_side) { 79 if (circ_purpose != CIRCUIT_PURPOSE_C_REND_READY && 80 circ_purpose != CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED) { 81 log_warn(LD_BUG, 82 "Client e2e circuit setup with wrong purpose (%d)", circ_purpose); 83 return 0; 84 } 85 } 86 87 return 1; 88 } 89 90 /** Create and return a crypt path for the final hop of a v3 prop224 rendezvous 91 * circuit. Initialize the crypt path crypto using the output material from the 92 * ntor key exchange at <b>ntor_key_seed</b>. 93 * 94 * If <b>is_service_side</b> is set, we are the hidden service and the final 95 * hop of the rendezvous circuit is the client on the other side. */ 96 static crypt_path_t * 97 create_rend_cpath(const uint8_t *ntor_key_seed, size_t seed_len, 98 int is_service_side) 99 { 100 uint8_t keys[HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN]; 101 crypt_path_t *cpath = NULL; 102 103 /* Do the key expansion */ 104 if (hs_ntor_circuit_key_expansion(ntor_key_seed, seed_len, 105 keys, sizeof(keys)) < 0) { 106 goto err; 107 } 108 109 /* Setup the cpath */ 110 cpath = tor_malloc_zero(sizeof(crypt_path_t)); 111 cpath->magic = CRYPT_PATH_MAGIC; 112 113 // TODO CGO: Pick relay cell format based on capabilities. 114 cpath->relay_cell_format = RELAY_CELL_FORMAT_V0; 115 relay_crypto_alg_t alg = is_service_side ? RELAY_CRYPTO_ALG_TOR1_HSS : 116 RELAY_CRYPTO_ALG_TOR1_HSC; 117 118 if (cpath_init_circuit_crypto(alg, cpath, (char*)keys, sizeof(keys)) < 0) { 119 tor_free(cpath); 120 goto err; 121 } 122 123 err: 124 memwipe(keys, 0, sizeof(keys)); 125 return cpath; 126 } 127 128 /** Append the final <b>hop</b> to the cpath of the rend <b>circ</b>, and mark 129 * <b>circ</b> ready for use to transfer HS relay cells. */ 130 static void 131 finalize_rend_circuit(origin_circuit_t *circ, crypt_path_t *hop, 132 int is_service_side) 133 { 134 tor_assert(circ); 135 tor_assert(hop); 136 137 /* Notify the circuit state machine that we are splicing this circuit */ 138 int new_circ_purpose = is_service_side ? 139 CIRCUIT_PURPOSE_S_REND_JOINED : CIRCUIT_PURPOSE_C_REND_JOINED; 140 circuit_change_purpose(TO_CIRCUIT(circ), new_circ_purpose); 141 142 /* All is well. Extend the circuit. */ 143 hop->state = CPATH_STATE_OPEN; 144 /* Set the windows to default. */ 145 hop->package_window = circuit_initial_package_window(); 146 hop->deliver_window = CIRCWINDOW_START; 147 148 /* If congestion control, transfer ccontrol onto the cpath. */ 149 if (TO_CIRCUIT(circ)->ccontrol) { 150 hop->ccontrol = TO_CIRCUIT(circ)->ccontrol; 151 TO_CIRCUIT(circ)->ccontrol = NULL; 152 } 153 154 /* Append the hop to the cpath of this circuit */ 155 cpath_extend_linked_list(&circ->cpath, hop); 156 157 /* Finally, mark circuit as ready to be used for client streams */ 158 if (!is_service_side) { 159 circuit_try_attaching_streams(circ); 160 } 161 } 162 163 /** For a given circuit and a service introduction point object, register the 164 * intro circuit to the circuitmap. */ 165 static void 166 register_intro_circ(const hs_service_intro_point_t *ip, 167 origin_circuit_t *circ) 168 { 169 tor_assert(ip); 170 tor_assert(circ); 171 172 hs_circuitmap_register_intro_circ_v3_service_side(circ, 173 &ip->auth_key_kp.pubkey); 174 } 175 176 /** Return the number of opened introduction circuit for the given circuit that 177 * is matching its identity key. */ 178 static unsigned int 179 count_opened_desc_intro_point_circuits(const hs_service_t *service, 180 const hs_service_descriptor_t *desc) 181 { 182 unsigned int count = 0; 183 184 tor_assert(service); 185 tor_assert(desc); 186 187 DIGEST256MAP_FOREACH(desc->intro_points.map, key, 188 const hs_service_intro_point_t *, ip) { 189 const circuit_t *circ; 190 const origin_circuit_t *ocirc = hs_circ_service_get_intro_circ(ip); 191 if (ocirc == NULL) { 192 continue; 193 } 194 circ = TO_CIRCUIT(ocirc); 195 tor_assert(circ->purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO || 196 circ->purpose == CIRCUIT_PURPOSE_S_INTRO); 197 /* Having a circuit not for the requested service is really bad. */ 198 tor_assert(ed25519_pubkey_eq(&service->keys.identity_pk, 199 ô->hs_ident->identity_pk)); 200 /* Only count opened circuit and skip circuit that will be closed. */ 201 if (!circ->marked_for_close && circ->state == CIRCUIT_STATE_OPEN) { 202 count++; 203 } 204 } DIGEST256MAP_FOREACH_END; 205 return count; 206 } 207 208 /** From a given service, rendezvous cookie and handshake info, create a 209 * rendezvous point circuit identifier. This can't fail. */ 210 STATIC hs_ident_circuit_t * 211 create_rp_circuit_identifier(const hs_service_t *service, 212 const uint8_t *rendezvous_cookie, 213 const curve25519_public_key_t *server_pk, 214 const hs_ntor_rend_cell_keys_t *keys) 215 { 216 hs_ident_circuit_t *ident; 217 uint8_t handshake_info[CURVE25519_PUBKEY_LEN + DIGEST256_LEN]; 218 219 tor_assert(service); 220 tor_assert(rendezvous_cookie); 221 tor_assert(server_pk); 222 tor_assert(keys); 223 224 ident = hs_ident_circuit_new(&service->keys.identity_pk); 225 /* Copy the RENDEZVOUS_COOKIE which is the unique identifier. */ 226 memcpy(ident->rendezvous_cookie, rendezvous_cookie, 227 sizeof(ident->rendezvous_cookie)); 228 /* Build the HANDSHAKE_INFO which looks like this: 229 * SERVER_PK [32 bytes] 230 * AUTH_INPUT_MAC [32 bytes] 231 */ 232 memcpy(handshake_info, server_pk->public_key, CURVE25519_PUBKEY_LEN); 233 memcpy(handshake_info + CURVE25519_PUBKEY_LEN, keys->rend_cell_auth_mac, 234 DIGEST256_LEN); 235 tor_assert(sizeof(ident->rendezvous_handshake_info) == 236 sizeof(handshake_info)); 237 memcpy(ident->rendezvous_handshake_info, handshake_info, 238 sizeof(ident->rendezvous_handshake_info)); 239 /* Finally copy the NTOR_KEY_SEED for e2e encryption on the circuit. */ 240 tor_assert(sizeof(ident->rendezvous_ntor_key_seed) == 241 sizeof(keys->ntor_key_seed)); 242 memcpy(ident->rendezvous_ntor_key_seed, keys->ntor_key_seed, 243 sizeof(ident->rendezvous_ntor_key_seed)); 244 return ident; 245 } 246 247 /** From a given service and service intro point, create an introduction point 248 * circuit identifier. This can't fail. */ 249 static hs_ident_circuit_t * 250 create_intro_circuit_identifier(const hs_service_t *service, 251 const hs_service_intro_point_t *ip) 252 { 253 hs_ident_circuit_t *ident; 254 255 tor_assert(service); 256 tor_assert(ip); 257 258 ident = hs_ident_circuit_new(&service->keys.identity_pk); 259 ed25519_pubkey_copy(&ident->intro_auth_pk, &ip->auth_key_kp.pubkey); 260 tor_assert_nonfatal(!ed25519_public_key_is_zero(&ident->intro_auth_pk)); 261 262 return ident; 263 } 264 265 /** For a given introduction point and an introduction circuit, send the 266 * ESTABLISH_INTRO cell. The service object is used for logging. This can fail 267 * and if so, the circuit is closed and the intro point object is flagged 268 * that the circuit is not established anymore which is important for the 269 * retry mechanism. */ 270 static void 271 send_establish_intro(const hs_service_t *service, 272 hs_service_intro_point_t *ip, origin_circuit_t *circ) 273 { 274 ssize_t cell_len; 275 uint8_t payload[RELAY_PAYLOAD_SIZE_MAX]; 276 277 tor_assert(service); 278 tor_assert(ip); 279 tor_assert(circ); 280 281 /* Encode establish intro cell. */ 282 cell_len = hs_cell_build_establish_intro(circ->cpath->prev->rend_circ_nonce, 283 &service->config, ip, payload); 284 if (cell_len < 0) { 285 log_warn(LD_REND, "Unable to encode ESTABLISH_INTRO cell for service %s " 286 "on circuit %u. Closing circuit.", 287 safe_str_client(service->onion_address), 288 TO_CIRCUIT(circ)->n_circ_id); 289 goto err; 290 } 291 292 /* Send the cell on the circuit. */ 293 if (relay_send_command_from_edge(CONTROL_CELL_ID, TO_CIRCUIT(circ), 294 RELAY_COMMAND_ESTABLISH_INTRO, 295 (char *) payload, cell_len, 296 circ->cpath->prev) < 0) { 297 log_info(LD_REND, "Unable to send ESTABLISH_INTRO cell for service %s " 298 "on circuit %u.", 299 safe_str_client(service->onion_address), 300 TO_CIRCUIT(circ)->n_circ_id); 301 /* On error, the circuit has been closed. */ 302 goto done; 303 } 304 305 /* Record the attempt to use this circuit. */ 306 pathbias_count_use_attempt(circ); 307 goto done; 308 309 err: 310 circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL); 311 done: 312 memwipe(payload, 0, sizeof(payload)); 313 } 314 315 /** Return a string constant describing the anonymity of service. */ 316 static const char * 317 get_service_anonymity_string(const hs_service_t *service) 318 { 319 if (service->config.is_single_onion) { 320 return "single onion"; 321 } else { 322 return "hidden"; 323 } 324 } 325 326 /** For a given service, the ntor onion key and a rendezvous cookie, launch a 327 * circuit to the rendezvous point specified by the link specifiers. On 328 * success, a circuit identifier is attached to the circuit with the needed 329 * data. This function will try to open a circuit for a maximum value of 330 * MAX_REND_FAILURES then it will give up. */ 331 MOCK_IMPL(STATIC void, 332 launch_rendezvous_point_circuit,(const hs_service_t *service, 333 const ed25519_public_key_t *ip_auth_pubkey, 334 const curve25519_keypair_t *ip_enc_key_kp, 335 const hs_cell_intro_rdv_data_t *rdv_data, 336 time_t now)) 337 { 338 int circ_needs_uptime; 339 extend_info_t *info = NULL; 340 origin_circuit_t *circ; 341 342 tor_assert(service); 343 tor_assert(ip_auth_pubkey); 344 tor_assert(ip_enc_key_kp); 345 tor_assert(rdv_data); 346 347 circ_needs_uptime = hs_service_requires_uptime_circ(service->config.ports); 348 349 /* Get the extend info data structure for the chosen rendezvous point 350 * specified by the given link specifiers. */ 351 info = hs_get_extend_info_from_lspecs(rdv_data->link_specifiers, 352 &rdv_data->onion_pk, 353 service->config.is_single_onion); 354 if (info == NULL) { 355 /* We are done here, we can't extend to the rendezvous point. */ 356 log_fn(LOG_PROTOCOL_WARN, LD_REND, 357 "Not enough info to open a circuit to a rendezvous point for " 358 "%s service %s.", 359 get_service_anonymity_string(service), 360 safe_str_client(service->onion_address)); 361 goto end; 362 } 363 364 for (int i = 0; i < MAX_REND_FAILURES; i++) { 365 int circ_flags = CIRCLAUNCH_NEED_CAPACITY | CIRCLAUNCH_IS_INTERNAL; 366 if (circ_needs_uptime) { 367 circ_flags |= CIRCLAUNCH_NEED_UPTIME; 368 } 369 /* Firewall and policies are checked when getting the extend info. 370 * 371 * We only use a one-hop path on the first attempt. If the first attempt 372 * fails, we use a 3-hop path for reachability / reliability. 373 * See the comment in retry_service_rendezvous_point() for details. */ 374 if (service->config.is_single_onion && i == 0) { 375 circ_flags |= CIRCLAUNCH_ONEHOP_TUNNEL; 376 } 377 378 circ = circuit_launch_by_extend_info(CIRCUIT_PURPOSE_S_CONNECT_REND, info, 379 circ_flags); 380 if (circ != NULL) { 381 /* Stop retrying, we have a circuit! */ 382 break; 383 } 384 } 385 if (circ == NULL) { 386 log_warn(LD_REND, "Giving up on launching a rendezvous circuit to %s " 387 "for %s service %s", 388 safe_str_client(extend_info_describe(info)), 389 get_service_anonymity_string(service), 390 safe_str_client(service->onion_address)); 391 goto end; 392 } 393 /* Update metrics with this new rendezvous circuit launched. */ 394 hs_metrics_new_rdv(&service->keys.identity_pk); 395 396 log_info(LD_REND, "Rendezvous circuit launched to %s with cookie %s " 397 "for %s service %s", 398 safe_str_client(extend_info_describe(info)), 399 safe_str_client(hex_str((const char *) 400 rdv_data->rendezvous_cookie, 401 REND_COOKIE_LEN)), 402 get_service_anonymity_string(service), 403 safe_str_client(service->onion_address)); 404 tor_assert(circ->build_state); 405 /* Rendezvous circuit have a specific timeout for the time spent on trying 406 * to connect to the rendezvous point. */ 407 circ->build_state->expiry_time = now + MAX_REND_TIMEOUT; 408 409 /* Create circuit identifier and key material. */ 410 { 411 hs_ntor_rend_cell_keys_t keys; 412 curve25519_keypair_t ephemeral_kp; 413 /* No need for extra strong, this is only for this circuit life time. This 414 * key will be used for the RENDEZVOUS1 cell that will be sent on the 415 * circuit once opened. */ 416 curve25519_keypair_generate(&ephemeral_kp, 0); 417 if (hs_ntor_service_get_rendezvous1_keys(ip_auth_pubkey, 418 ip_enc_key_kp, 419 &ephemeral_kp, 420 &rdv_data->client_pk, 421 &keys) < 0) { 422 /* This should not really happened but just in case, don't make tor 423 * freak out, close the circuit and move on. */ 424 log_info(LD_REND, "Unable to get RENDEZVOUS1 key material for " 425 "service %s", 426 safe_str_client(service->onion_address)); 427 circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL); 428 goto end; 429 } 430 circ->hs_ident = create_rp_circuit_identifier(service, 431 rdv_data->rendezvous_cookie, 432 &ephemeral_kp.pubkey, &keys); 433 memwipe(&ephemeral_kp, 0, sizeof(ephemeral_kp)); 434 memwipe(&keys, 0, sizeof(keys)); 435 tor_assert(circ->hs_ident); 436 } 437 438 /* Remember PoW state if this introduction included a valid proof of work 439 * client puzzle extension. */ 440 if (rdv_data->pow_effort > 0) { 441 circ->hs_pow_effort = rdv_data->pow_effort; 442 circ->hs_with_pow_circ = 1; 443 } 444 445 /* Setup congestion control if asked by the client from the INTRO cell. */ 446 if (rdv_data->cc_enabled) { 447 hs_circ_setup_congestion_control(circ, congestion_control_sendme_inc(), 448 service->config.is_single_onion); 449 } 450 451 end: 452 extend_info_free(info); 453 } 454 455 /** Return true iff the given service rendezvous circuit circ is allowed for a 456 * relaunch to the rendezvous point. */ 457 static int 458 can_relaunch_service_rendezvous_point(const origin_circuit_t *circ) 459 { 460 tor_assert(circ); 461 /* This is initialized when allocating an origin circuit. */ 462 tor_assert(circ->build_state); 463 tor_assert(TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_S_CONNECT_REND); 464 465 /* XXX: Retrying under certain condition. This is related to #22455. */ 466 467 /* We check failure_count >= hs_get_service_max_rend_failures()-1 below, and 468 * the -1 is because we increment the failure count for our current failure 469 * *after* this clause. */ 470 int max_rend_failures = hs_get_service_max_rend_failures() - 1; 471 472 /* A failure count that has reached maximum allowed or circuit that expired, 473 * we skip relaunching. */ 474 if (circ->build_state->failure_count > max_rend_failures || 475 circ->build_state->expiry_time <= time(NULL)) { 476 log_info(LD_REND, "Attempt to build a rendezvous circuit to %s has " 477 "failed with %d attempts and expiry time %ld. " 478 "Giving up building.", 479 safe_str_client( 480 extend_info_describe(circ->build_state->chosen_exit)), 481 circ->build_state->failure_count, 482 (long int) circ->build_state->expiry_time); 483 goto disallow; 484 } 485 486 /* Allowed to relaunch. */ 487 return 1; 488 disallow: 489 return 0; 490 } 491 492 /** Retry the rendezvous point of circ by launching a new circuit to it. */ 493 static void 494 retry_service_rendezvous_point(const origin_circuit_t *circ) 495 { 496 int flags = 0; 497 origin_circuit_t *new_circ; 498 cpath_build_state_t *bstate; 499 500 tor_assert(circ); 501 /* This is initialized when allocating an origin circuit. */ 502 tor_assert(circ->build_state); 503 tor_assert(TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_S_CONNECT_REND); 504 505 /* Ease our life. */ 506 bstate = circ->build_state; 507 508 log_info(LD_REND, "Retrying rendezvous point circuit to %s", 509 safe_str_client(extend_info_describe(bstate->chosen_exit))); 510 511 /* Get the current build state flags for the next circuit. */ 512 flags |= (bstate->need_uptime) ? CIRCLAUNCH_NEED_UPTIME : 0; 513 flags |= (bstate->need_capacity) ? CIRCLAUNCH_NEED_CAPACITY : 0; 514 flags |= (bstate->is_internal) ? CIRCLAUNCH_IS_INTERNAL : 0; 515 516 /* We do NOT add the onehop tunnel flag even though it might be a single 517 * onion service. The reason is that if we failed once to connect to the RP 518 * with a direct connection, we consider that chances are that we will fail 519 * again so try a 3-hop circuit and hope for the best. Because the service 520 * has no anonymity (single onion), this change of behavior won't affect 521 * security directly. */ 522 523 new_circ = circuit_launch_by_extend_info(CIRCUIT_PURPOSE_S_CONNECT_REND, 524 bstate->chosen_exit, flags); 525 if (new_circ == NULL) { 526 log_warn(LD_REND, "Failed to launch rendezvous circuit to %s", 527 safe_str_client(extend_info_describe(bstate->chosen_exit))); 528 529 hs_metrics_failed_rdv(&circ->hs_ident->identity_pk, 530 HS_METRICS_ERR_RDV_RETRY); 531 532 goto done; 533 } 534 535 /* Transfer build state information to the new circuit state in part to 536 * catch any other failures. */ 537 new_circ->build_state->failure_count = bstate->failure_count+1; 538 new_circ->build_state->expiry_time = bstate->expiry_time; 539 new_circ->hs_ident = hs_ident_circuit_dup(circ->hs_ident); 540 541 /* Setup congestion control if asked by the client from the INTRO cell. */ 542 if (TO_CIRCUIT(circ)->ccontrol) { 543 /* As per above, in this case, we are a full 3 hop rend, even if we're a 544 * single-onion service. */ 545 hs_circ_setup_congestion_control(new_circ, 546 TO_CIRCUIT(circ)->ccontrol->sendme_inc, 547 false); 548 } 549 550 done: 551 return; 552 } 553 554 /** Using the given descriptor intro point ip, the node of the 555 * rendezvous point rp_node and the service's subcredential, populate the 556 * already allocated intro1_data object with the needed key material and link 557 * specifiers. 558 * 559 * Return 0 on success or a negative value if we couldn't properly filled the 560 * introduce1 data from the RP node. In other word, it means the RP node is 561 * unusable to use in the introduction. */ 562 static int 563 setup_introduce1_data(const hs_desc_intro_point_t *ip, 564 const node_t *rp_node, 565 const hs_subcredential_t *subcredential, 566 hs_cell_introduce1_data_t *intro1_data) 567 { 568 int ret = -1; 569 smartlist_t *rp_lspecs; 570 571 tor_assert(ip); 572 tor_assert(rp_node); 573 tor_assert(subcredential); 574 tor_assert(intro1_data); 575 576 /* Build the link specifiers from the node at the end of the rendezvous 577 * circuit that we opened for this introduction. */ 578 rp_lspecs = node_get_link_specifier_smartlist(rp_node, 0); 579 if (smartlist_len(rp_lspecs) == 0) { 580 /* We can't rendezvous without link specifiers. */ 581 smartlist_free(rp_lspecs); 582 goto end; 583 } 584 585 /* Populate the introduce1 data object. */ 586 memset(intro1_data, 0, sizeof(hs_cell_introduce1_data_t)); 587 intro1_data->auth_pk = &ip->auth_key_cert->signed_key; 588 intro1_data->enc_pk = &ip->enc_key; 589 intro1_data->subcredential = subcredential; 590 intro1_data->link_specifiers = rp_lspecs; 591 intro1_data->onion_pk = node_get_curve25519_onion_key(rp_node); 592 if (intro1_data->onion_pk == NULL) { 593 /* We can't rendezvous without the curve25519 onion key. */ 594 goto end; 595 } 596 597 /* Success, we have valid introduce data. */ 598 ret = 0; 599 600 end: 601 return ret; 602 } 603 604 /** Helper: cleanup function for client circuit. This is for every HS version. 605 * It is called from hs_circ_cleanup_on_close() entry point. */ 606 static void 607 cleanup_on_close_client_circ(circuit_t *circ) 608 { 609 tor_assert(circ); 610 611 if (circuit_is_hs_v3(circ)) { 612 hs_client_circuit_cleanup_on_close(circ); 613 } 614 /* It is possible the circuit has an HS purpose but no identifier (hs_ident). 615 * Thus possible that this passes through. */ 616 } 617 618 /** Helper: cleanup function for client circuit. This is for every HS version. 619 * It is called from hs_circ_cleanup_on_free() entry point. */ 620 static void 621 cleanup_on_free_client_circ(circuit_t *circ) 622 { 623 tor_assert(circ); 624 625 if (circuit_is_hs_v3(circ)) { 626 hs_client_circuit_cleanup_on_free(circ); 627 } 628 /* It is possible the circuit has an HS purpose but no identifier (hs_ident). 629 * Thus possible that this passes through. */ 630 } 631 632 /** Return less than 0 if a precedes b, 0 if a equals b and greater than 0 if 633 * b precedes a. Note that *higher* effort is *earlier* in the pqueue. */ 634 static int 635 compare_rend_request_by_effort_(const void *_a, const void *_b) 636 { 637 const pending_rend_t *a = _a, *b = _b; 638 if (a->rdv_data.pow_effort > b->rdv_data.pow_effort) { 639 return -1; 640 } else if (a->rdv_data.pow_effort == b->rdv_data.pow_effort) { 641 /* tie-breaker! use the time it was added to the queue. older better. */ 642 if (a->enqueued_ts < b->enqueued_ts) 643 return -1; 644 if (a->enqueued_ts > b->enqueued_ts) 645 return 1; 646 return 0; 647 } else { 648 return 1; 649 } 650 } 651 652 /** Return 1 if a request waiting in our service-side pqueue is old 653 * enough that we should just discard it rather than trying to respond, 654 * or 0 if we still like it. As a heuristic, choose half of the total 655 * permitted time interval (so we don't approve trying to respond to 656 * requests when we will then give up on them a moment later). 657 */ 658 static int 659 queued_rend_request_is_too_old(pending_rend_t *req, time_t now) 660 { 661 if ((req->enqueued_ts + MAX_REND_TIMEOUT/2) < now) 662 return 1; 663 return 0; 664 } 665 666 /** Our rendezvous request priority queue is too full; keep the first 667 * pqueue_high_level/2 entries and discard the rest. 668 */ 669 static void 670 trim_rend_pqueue(hs_pow_service_state_t *pow_state, time_t now) 671 { 672 smartlist_t *old_pqueue = pow_state->rend_request_pqueue; 673 smartlist_t *new_pqueue = pow_state->rend_request_pqueue = smartlist_new(); 674 675 log_info(LD_REND, "Rendezvous request priority queue has " 676 "reached capacity (%d). Discarding the bottom half.", 677 smartlist_len(old_pqueue)); 678 679 while (smartlist_len(old_pqueue) && 680 smartlist_len(new_pqueue) < pow_state->pqueue_high_level/2) { 681 /* while there are still old ones, and the new one isn't full yet */ 682 pending_rend_t *req = 683 smartlist_pqueue_pop(old_pqueue, 684 compare_rend_request_by_effort_, 685 offsetof(pending_rend_t, idx)); 686 if (queued_rend_request_is_too_old(req, now)) { 687 log_info(LD_REND, "While trimming, rend request has been pending " 688 "for too long; discarding."); 689 690 pow_state->max_trimmed_effort = MAX(pow_state->max_trimmed_effort, 691 req->rdv_data.pow_effort); 692 693 free_pending_rend(req); 694 } else { 695 smartlist_pqueue_add(new_pqueue, 696 compare_rend_request_by_effort_, 697 offsetof(pending_rend_t, idx), req); 698 } 699 } 700 701 /* Ok, we have rescued all the entries we want to keep. The rest are 702 * all excess. */ 703 SMARTLIST_FOREACH_BEGIN(old_pqueue, pending_rend_t *, req) { 704 pow_state->max_trimmed_effort = MAX(pow_state->max_trimmed_effort, 705 req->rdv_data.pow_effort); 706 free_pending_rend(req); 707 } SMARTLIST_FOREACH_END(req); 708 smartlist_free(old_pqueue); 709 } 710 711 /** Count up how many pending outgoing (CIRCUIT_PURPOSE_S_CONNECT_REND) 712 * circuits there are for this service. Used in the PoW rate limiting 713 * world to decide whether it's time to launch any new ones. 714 */ 715 static int 716 count_service_rp_circuits_pending(hs_service_t *service) 717 { 718 origin_circuit_t *ocirc = NULL; 719 int count = 0; 720 while ((ocirc = circuit_get_next_by_purpose(ocirc, 721 CIRCUIT_PURPOSE_S_CONNECT_REND))) { 722 /* Count up circuits that are v3 and for this service. */ 723 if (ocirc->hs_ident != NULL && 724 ed25519_pubkey_eq(ô->hs_ident->identity_pk, 725 &service->keys.identity_pk)) { 726 count++; 727 } 728 } 729 return count; 730 } 731 732 /** Peek at the top entry on the pending rend pqueue, which must not be empty. 733 * If its level of effort is at least what we're suggesting for that service 734 * right now, return 1, else return 0. 735 */ 736 int 737 top_of_rend_pqueue_is_worthwhile(hs_pow_service_state_t *pow_state) 738 { 739 tor_assert(pow_state->rend_request_pqueue); 740 tor_assert(smartlist_len(pow_state->rend_request_pqueue)); 741 742 pending_rend_t *req = 743 smartlist_get(pow_state->rend_request_pqueue, 0); 744 745 if (req->rdv_data.pow_effort >= pow_state->suggested_effort) 746 return 1; 747 748 return 0; 749 } 750 751 /** Abandon and free all pending rend requests, leaving the pqueue empty. */ 752 void 753 rend_pqueue_clear(hs_pow_service_state_t *pow_state) 754 { 755 tor_assert(pow_state->rend_request_pqueue); 756 while (smartlist_len(pow_state->rend_request_pqueue)) { 757 pending_rend_t *req = smartlist_pop_last(pow_state->rend_request_pqueue); 758 free_pending_rend(req); 759 } 760 } 761 762 /** What is the threshold of in-progress (CIRCUIT_PURPOSE_S_CONNECT_REND) 763 * rendezvous responses above which we won't launch new low-effort rendezvous 764 * responses? (Intro2 cells with suitable PoW effort are not affected 765 * by this threshold.) */ 766 #define MAX_CHEAP_REND_CIRCUITS_IN_PROGRESS 16 767 768 static void 769 handle_rend_pqueue_cb(mainloop_event_t *ev, void *arg) 770 { 771 hs_service_t *service = arg; 772 hs_pow_service_state_t *pow_state = service->state.pow_state; 773 time_t now = time(NULL); 774 int in_flight = count_service_rp_circuits_pending(service); 775 776 (void) ev; /* Not using the returned event, make compiler happy. */ 777 778 log_info(LD_REND, "Considering launching more rendezvous responses. " 779 "%d in-flight, %d pending.", 780 in_flight, 781 smartlist_len(pow_state->rend_request_pqueue)); 782 783 /* Process only one rend request per callback, so that this work will not 784 * be prioritized over other event loop callbacks. We may need to retry 785 * in order to find one request that's still viable. */ 786 while (smartlist_len(pow_state->rend_request_pqueue) > 0) { 787 788 /* first, peek at the top result to see if we want to pop it */ 789 if (in_flight >= MAX_CHEAP_REND_CIRCUITS_IN_PROGRESS && 790 !top_of_rend_pqueue_is_worthwhile(pow_state)) { 791 /* We have queued requests, but they are all low priority, and also 792 * we have too many in-progress rendezvous responses. Don't launch 793 * any more. Schedule ourselves to reassess in a bit. */ 794 log_info(LD_REND, "Next request to launch is low priority, and " 795 "%d in-flight already. Waiting to launch more.", in_flight); 796 const struct timeval delay_tv = { 0, 100000 }; 797 mainloop_event_schedule(pow_state->pop_pqueue_ev, &delay_tv); 798 return; /* done here! no cleanup needed. */ 799 } 800 801 if (pow_state->using_pqueue_bucket) { 802 token_bucket_ctr_refill(&pow_state->pqueue_bucket, 803 (uint32_t) monotime_coarse_absolute_sec()); 804 805 if (token_bucket_ctr_get(&pow_state->pqueue_bucket) > 0) { 806 token_bucket_ctr_dec(&pow_state->pqueue_bucket, 1); 807 } else { 808 /* Waiting for pqueue rate limit to refill, come back later */ 809 const struct timeval delay_tv = { 0, 100000 }; 810 mainloop_event_schedule(pow_state->pop_pqueue_ev, &delay_tv); 811 return; 812 } 813 } 814 815 /* Pop next request by effort. */ 816 pending_rend_t *req = 817 smartlist_pqueue_pop(pow_state->rend_request_pqueue, 818 compare_rend_request_by_effort_, 819 offsetof(pending_rend_t, idx)); 820 821 hs_metrics_pow_pqueue_rdv(service, 822 smartlist_len(pow_state->rend_request_pqueue)); 823 824 log_info(LD_REND, "Dequeued pending rendezvous request with effort: %u. " 825 "Waited %d. " 826 "Remaining requests: %u", 827 req->rdv_data.pow_effort, 828 (int)(now - req->enqueued_ts), 829 smartlist_len(pow_state->rend_request_pqueue)); 830 831 if (queued_rend_request_is_too_old(req, now)) { 832 log_info(LD_REND, "Top rend request has been pending for too long; " 833 "discarding and moving to the next one."); 834 free_pending_rend(req); 835 continue; /* do not increment count, this one's free */ 836 } 837 838 /* Launch the rendezvous circuit. */ 839 launch_rendezvous_point_circuit(service, &req->ip_auth_pubkey, 840 &req->ip_enc_key_kp, &req->rdv_data, now); 841 free_pending_rend(req); 842 843 ++pow_state->rend_handled; 844 ++in_flight; 845 break; 846 } 847 848 /* If there are still some pending rendezvous circuits in the pqueue then 849 * reschedule the event in order to continue handling them. */ 850 if (smartlist_len(pow_state->rend_request_pqueue) > 0) { 851 mainloop_event_activate(pow_state->pop_pqueue_ev); 852 853 if (smartlist_len(pow_state->rend_request_pqueue) >= 854 pow_state->pqueue_low_level) { 855 pow_state->had_queue = 1; 856 } 857 } 858 } 859 860 /** Given the information needed to launch a rendezvous circuit and an 861 * effort value, enqueue the rendezvous request in the service's PoW priority 862 * queue with the effort being the priority. 863 * 864 * Return 0 if we successfully enqueued the request else -1. */ 865 static int 866 enqueue_rend_request(const hs_service_t *service, hs_service_intro_point_t *ip, 867 hs_cell_introduce2_data_t *data, time_t now) 868 { 869 hs_pow_service_state_t *pow_state = NULL; 870 pending_rend_t *req = NULL; 871 872 tor_assert(service); 873 tor_assert(ip); 874 tor_assert(data); 875 876 /* Ease our lives */ 877 pow_state = service->state.pow_state; 878 879 req = tor_malloc_zero(sizeof(pending_rend_t)); 880 881 /* Copy over the rendezvous request the needed data to launch a circuit. */ 882 ed25519_pubkey_copy(&req->ip_auth_pubkey, &ip->auth_key_kp.pubkey); 883 memcpy(&req->ip_enc_key_kp, &ip->enc_key_kp, sizeof(req->ip_enc_key_kp)); 884 memcpy(&req->rdv_data, &data->rdv_data, sizeof(req->rdv_data)); 885 /* Invalidate the link specifier pointer in the introduce2 data so it 886 * doesn't get freed under us. */ 887 data->rdv_data.link_specifiers = NULL; 888 req->idx = -1; 889 req->enqueued_ts = now; 890 891 /* Enqueue the rendezvous request. */ 892 smartlist_pqueue_add(pow_state->rend_request_pqueue, 893 compare_rend_request_by_effort_, 894 offsetof(pending_rend_t, idx), req); 895 896 hs_metrics_pow_pqueue_rdv(service, 897 smartlist_len(pow_state->rend_request_pqueue)); 898 899 log_info(LD_REND, "Enqueued rendezvous request with effort: %u. " 900 "Queued requests: %u", 901 req->rdv_data.pow_effort, 902 smartlist_len(pow_state->rend_request_pqueue)); 903 904 /* Initialize the priority queue event if it hasn't been done so already. */ 905 if (pow_state->pop_pqueue_ev == NULL) { 906 pow_state->pop_pqueue_ev = 907 mainloop_event_postloop_new(handle_rend_pqueue_cb, (void *)service); 908 } 909 910 /* Activate event, we just enqueued a rendezvous request. */ 911 mainloop_event_activate(pow_state->pop_pqueue_ev); 912 913 /* See if there are so many cells queued that we need to cull. */ 914 if (smartlist_len(pow_state->rend_request_pqueue) >= 915 pow_state->pqueue_high_level) { 916 trim_rend_pqueue(pow_state, now); 917 hs_metrics_pow_pqueue_rdv(service, 918 smartlist_len(pow_state->rend_request_pqueue)); 919 } 920 921 return 0; 922 } 923 924 /* ========== */ 925 /* Public API */ 926 /* ========== */ 927 928 /** Setup on the given circuit congestion control with the given parameters. 929 * 930 * This function assumes that congestion control is enabled on the network and 931 * so it is the caller responsability to make sure of it. */ 932 void 933 hs_circ_setup_congestion_control(origin_circuit_t *origin_circ, 934 uint8_t sendme_inc, bool is_single_onion) 935 { 936 circuit_t *circ = NULL; 937 circuit_params_t circ_params = {0}; 938 939 tor_assert(origin_circ); 940 941 /* Ease our lives */ 942 circ = TO_CIRCUIT(origin_circ); 943 944 circ_params.cc_enabled = true; 945 circ_params.sendme_inc_cells = sendme_inc; 946 947 /* It is setup on the circuit in order to indicate that congestion control is 948 * enabled. It will be transferred to the RP crypt_path_t once the handshake 949 * is finalized in finalize_rend_circuit() for both client and service 950 * because the final hop is not available until then. */ 951 952 if (is_single_onion) { 953 circ->ccontrol = congestion_control_new(&circ_params, CC_PATH_ONION_SOS); 954 } else { 955 if (get_options()->HSLayer3Nodes) { 956 circ->ccontrol = congestion_control_new(&circ_params, CC_PATH_ONION_VG); 957 } else { 958 circ->ccontrol = congestion_control_new(&circ_params, CC_PATH_ONION); 959 } 960 } 961 } 962 963 /** Return an introduction point circuit matching the given intro point object. 964 * NULL is returned is no such circuit can be found. */ 965 origin_circuit_t * 966 hs_circ_service_get_intro_circ(const hs_service_intro_point_t *ip) 967 { 968 tor_assert(ip); 969 970 return hs_circuitmap_get_intro_circ_v3_service_side(&ip->auth_key_kp.pubkey); 971 } 972 973 /** Return an introduction point established circuit matching the given intro 974 * point object. The circuit purpose has to be CIRCUIT_PURPOSE_S_INTRO. NULL 975 * is returned is no such circuit can be found. */ 976 origin_circuit_t * 977 hs_circ_service_get_established_intro_circ(const hs_service_intro_point_t *ip) 978 { 979 origin_circuit_t *circ; 980 981 tor_assert(ip); 982 983 circ = hs_circuitmap_get_intro_circ_v3_service_side(&ip->auth_key_kp.pubkey); 984 985 /* Only return circuit if it is established. */ 986 return (circ && TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_S_INTRO) ? 987 circ : NULL; 988 } 989 990 /** Called when we fail building a rendezvous circuit at some point other than 991 * the last hop: launches a new circuit to the same rendezvous point. 992 * 993 * We currently relaunch connections to rendezvous points if: 994 * - A rendezvous circuit timed out before connecting to RP. 995 * - The rendezvous circuit failed to connect to the RP. 996 * 997 * We avoid relaunching a connection to this rendezvous point if: 998 * - We have already tried MAX_REND_FAILURES times to connect to this RP, 999 * - We've been trying to connect to this RP for more than MAX_REND_TIMEOUT 1000 * seconds, or 1001 * - We've already retried this specific rendezvous circuit. 1002 */ 1003 void 1004 hs_circ_retry_service_rendezvous_point(const origin_circuit_t *circ) 1005 { 1006 tor_assert(circ); 1007 tor_assert(TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_S_CONNECT_REND); 1008 1009 /* Check if we are allowed to relaunch to the rendezvous point of circ. */ 1010 if (!can_relaunch_service_rendezvous_point(circ)) { 1011 goto done; 1012 } 1013 1014 /* Legacy services don't have a hidden service ident. */ 1015 if (circ->hs_ident) { 1016 retry_service_rendezvous_point(circ); 1017 } 1018 1019 done: 1020 return; 1021 } 1022 1023 /** For a given service and a service intro point, launch a circuit to the 1024 * extend info ei. If the service is a single onion, and direct_conn is true, 1025 * a one-hop circuit will be requested. 1026 * 1027 * Return 0 if the circuit was successfully launched and tagged 1028 * with the correct identifier. On error, a negative value is returned. */ 1029 int 1030 hs_circ_launch_intro_point(hs_service_t *service, 1031 const hs_service_intro_point_t *ip, 1032 extend_info_t *ei, 1033 bool direct_conn) 1034 { 1035 /* Standard flags for introduction circuit. */ 1036 int ret = -1, circ_flags = CIRCLAUNCH_NEED_UPTIME | CIRCLAUNCH_IS_INTERNAL; 1037 origin_circuit_t *circ; 1038 1039 tor_assert(service); 1040 tor_assert(ip); 1041 tor_assert(ei); 1042 1043 /* Update circuit flags in case of a single onion service that requires a 1044 * direct connection. */ 1045 tor_assert_nonfatal(ip->circuit_retries > 0); 1046 /* Only single onion services can make direct conns */ 1047 if (BUG(!service->config.is_single_onion && direct_conn)) { 1048 goto end; 1049 } 1050 /* We only use a one-hop path on the first attempt. If the first attempt 1051 * fails, we use a 3-hop path for reachability / reliability. */ 1052 if (direct_conn && ip->circuit_retries == 1) { 1053 circ_flags |= CIRCLAUNCH_ONEHOP_TUNNEL; 1054 } 1055 1056 log_info(LD_REND, "Launching a circuit to intro point %s for service %s.", 1057 safe_str_client(extend_info_describe(ei)), 1058 safe_str_client(service->onion_address)); 1059 1060 /* Note down the launch for the retry period. Even if the circuit fails to 1061 * be launched, we still want to respect the retry period to avoid stress on 1062 * the circuit subsystem. */ 1063 service->state.num_intro_circ_launched++; 1064 circ = circuit_launch_by_extend_info(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO, 1065 ei, circ_flags); 1066 if (circ == NULL) { 1067 goto end; 1068 } 1069 1070 /* Setup the circuit identifier and attach it to it. */ 1071 circ->hs_ident = create_intro_circuit_identifier(service, ip); 1072 tor_assert(circ->hs_ident); 1073 /* Register circuit in the global circuitmap. */ 1074 register_intro_circ(ip, circ); 1075 1076 /* Success. */ 1077 ret = 0; 1078 end: 1079 return ret; 1080 } 1081 1082 /** Called when a service introduction point circuit is done building. Given 1083 * the service and intro point object, this function will send the 1084 * ESTABLISH_INTRO cell on the circuit. Return 0 on success. Return 1 if the 1085 * circuit has been repurposed to General because we already have too many 1086 * opened. */ 1087 int 1088 hs_circ_service_intro_has_opened(hs_service_t *service, 1089 hs_service_intro_point_t *ip, 1090 const hs_service_descriptor_t *desc, 1091 origin_circuit_t *circ) 1092 { 1093 int ret = 0; 1094 unsigned int num_intro_circ, num_needed_circ; 1095 1096 tor_assert(service); 1097 tor_assert(ip); 1098 tor_assert(desc); 1099 tor_assert(circ); 1100 1101 /* Count opened circuits that have sent ESTABLISH_INTRO cells or are already 1102 * established introduction circuits */ 1103 num_intro_circ = count_opened_desc_intro_point_circuits(service, desc); 1104 num_needed_circ = service->config.num_intro_points; 1105 if (num_intro_circ > num_needed_circ) { 1106 /* There are too many opened valid intro circuit for what the service 1107 * needs so repurpose this one. */ 1108 1109 /* XXX: Legacy code checks options->ExcludeNodes and if not NULL it just 1110 * closes the circuit. I have NO idea why it does that so it hasn't been 1111 * added here. I can only assume in case our ExcludeNodes list changes but 1112 * in that case, all circuit are flagged unusable (config.c). --dgoulet */ 1113 1114 log_info(LD_CIRC | LD_REND, "Introduction circuit just opened but we " 1115 "have enough for service %s. Repurposing " 1116 "it to general and leaving internal.", 1117 safe_str_client(service->onion_address)); 1118 tor_assert(circ->build_state->is_internal); 1119 /* Remove it from the circuitmap. */ 1120 hs_circuitmap_remove_circuit(TO_CIRCUIT(circ)); 1121 /* Cleaning up the hidden service identifier and repurpose. */ 1122 hs_ident_circuit_free(circ->hs_ident); 1123 circ->hs_ident = NULL; 1124 if (circuit_should_use_vanguards(TO_CIRCUIT(circ)->purpose)) 1125 circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_HS_VANGUARDS); 1126 else 1127 circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_C_GENERAL); 1128 1129 /* Inform that this circuit just opened for this new purpose. */ 1130 circuit_has_opened(circ); 1131 /* This return value indicate to the caller that the IP object should be 1132 * removed from the service because it's corresponding circuit has just 1133 * been repurposed. */ 1134 ret = 1; 1135 goto done; 1136 } 1137 1138 log_info(LD_REND, "Introduction circuit %u established for service %s.", 1139 TO_CIRCUIT(circ)->n_circ_id, 1140 safe_str_client(service->onion_address)); 1141 circuit_log_path(LOG_INFO, LD_REND, circ); 1142 1143 /* Time to send an ESTABLISH_INTRO cell on this circuit. On error, this call 1144 * makes sure the circuit gets closed. */ 1145 send_establish_intro(service, ip, circ); 1146 1147 done: 1148 return ret; 1149 } 1150 1151 /** Called when a service rendezvous point circuit is done building. Given the 1152 * service and the circuit, this function will send a RENDEZVOUS1 cell on the 1153 * circuit using the information in the circuit identifier. If the cell can't 1154 * be sent, the circuit is closed. */ 1155 void 1156 hs_circ_service_rp_has_opened(const hs_service_t *service, 1157 origin_circuit_t *circ) 1158 { 1159 size_t payload_len; 1160 uint8_t payload[RELAY_PAYLOAD_SIZE_MAX] = {0}; 1161 1162 tor_assert(service); 1163 tor_assert(circ); 1164 tor_assert(circ->hs_ident); 1165 1166 /* Some useful logging. */ 1167 log_info(LD_REND, "Rendezvous circuit %u has opened with cookie %s " 1168 "for service %s", 1169 TO_CIRCUIT(circ)->n_circ_id, 1170 hex_str((const char *) circ->hs_ident->rendezvous_cookie, 1171 REND_COOKIE_LEN), 1172 safe_str_client(service->onion_address)); 1173 circuit_log_path(LOG_INFO, LD_REND, circ); 1174 1175 /* This can't fail. */ 1176 payload_len = hs_cell_build_rendezvous1( 1177 circ->hs_ident->rendezvous_cookie, 1178 sizeof(circ->hs_ident->rendezvous_cookie), 1179 circ->hs_ident->rendezvous_handshake_info, 1180 sizeof(circ->hs_ident->rendezvous_handshake_info), 1181 payload); 1182 1183 /* Pad the payload with random bytes so it matches the size of a legacy cell 1184 * which is normally always bigger. Also, the size of a legacy cell is 1185 * always smaller than the RELAY_PAYLOAD_SIZE so this is safe. */ 1186 if (payload_len < HS_LEGACY_RENDEZVOUS_CELL_SIZE) { 1187 crypto_rand((char *) payload + payload_len, 1188 HS_LEGACY_RENDEZVOUS_CELL_SIZE - payload_len); 1189 payload_len = HS_LEGACY_RENDEZVOUS_CELL_SIZE; 1190 } 1191 1192 if (relay_send_command_from_edge(CONTROL_CELL_ID, TO_CIRCUIT(circ), 1193 RELAY_COMMAND_RENDEZVOUS1, 1194 (const char *) payload, 1195 payload_len, 1196 circ->cpath->prev) < 0) { 1197 /* On error, circuit is closed. */ 1198 log_warn(LD_REND, "Unable to send RENDEZVOUS1 cell on circuit %u " 1199 "for service %s", 1200 TO_CIRCUIT(circ)->n_circ_id, 1201 safe_str_client(service->onion_address)); 1202 1203 hs_metrics_failed_rdv(&service->keys.identity_pk, 1204 HS_METRICS_ERR_RDV_RENDEZVOUS1); 1205 goto done; 1206 } 1207 1208 /* Setup end-to-end rendezvous circuit between the client and us. */ 1209 if (hs_circuit_setup_e2e_rend_circ(circ, 1210 circ->hs_ident->rendezvous_ntor_key_seed, 1211 sizeof(circ->hs_ident->rendezvous_ntor_key_seed), 1212 1) < 0) { 1213 log_warn(LD_GENERAL, "Failed to setup circ"); 1214 1215 hs_metrics_failed_rdv(&service->keys.identity_pk, HS_METRICS_ERR_RDV_E2E); 1216 goto done; 1217 } 1218 1219 done: 1220 memwipe(payload, 0, sizeof(payload)); 1221 } 1222 1223 /** Circ has been expecting an INTRO_ESTABLISHED cell that just arrived. Handle 1224 * the INTRO_ESTABLISHED cell payload of length payload_len arriving on the 1225 * given introduction circuit circ. The service is only used for logging 1226 * purposes. Return 0 on success else a negative value. */ 1227 int 1228 hs_circ_handle_intro_established(const hs_service_t *service, 1229 const hs_service_intro_point_t *ip, 1230 origin_circuit_t *circ, 1231 const uint8_t *payload, size_t payload_len) 1232 { 1233 int ret = -1; 1234 1235 tor_assert(service); 1236 tor_assert(ip); 1237 tor_assert(circ); 1238 tor_assert(payload); 1239 1240 if (BUG(TO_CIRCUIT(circ)->purpose != CIRCUIT_PURPOSE_S_ESTABLISH_INTRO)) { 1241 goto done; 1242 } 1243 1244 /* Try to parse the payload into a cell making sure we do actually have a 1245 * valid cell. */ 1246 if (hs_cell_parse_intro_established(payload, payload_len) < 0) { 1247 log_warn(LD_REND, "Unable to parse the INTRO_ESTABLISHED cell on " 1248 "circuit %u for service %s", 1249 TO_CIRCUIT(circ)->n_circ_id, 1250 safe_str_client(service->onion_address)); 1251 goto done; 1252 } 1253 1254 /* Switch the purpose to a fully working intro point. */ 1255 circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_S_INTRO); 1256 /* Getting a valid INTRODUCE_ESTABLISHED means we've successfully used the 1257 * circuit so update our pathbias subsystem. */ 1258 pathbias_mark_use_success(circ); 1259 /* Success. */ 1260 ret = 0; 1261 1262 done: 1263 return ret; 1264 } 1265 1266 /** 1267 * Go into <b>data</b> and add the right subcredential to be able to handle 1268 * this incoming cell. 1269 * 1270 * <b>desc_subcred</b> is the subcredential of the descriptor that corresponds 1271 * to the intro point that received this intro request. This subcredential 1272 * should be used if we are not an onionbalance instance. 1273 * 1274 * Return 0 if everything went well, or -1 in case of internal error. 1275 */ 1276 static int 1277 get_subcredential_for_handling_intro2_cell(const hs_service_t *service, 1278 hs_cell_introduce2_data_t *data, 1279 const hs_subcredential_t *desc_subcred) 1280 { 1281 /* Handle the simple case first: We are not an onionbalance instance and we 1282 * should just use the regular descriptor subcredential */ 1283 if (!hs_ob_service_is_instance(service)) { 1284 data->n_subcredentials = 1; 1285 data->subcredentials = desc_subcred; 1286 return 0; 1287 } 1288 1289 /* This should not happen since we should have made onionbalance 1290 * subcredentials when we created our descriptors. */ 1291 if (BUG(!service->state.ob_subcreds)) { 1292 return -1; 1293 } 1294 1295 /* We are an onionbalance instance: */ 1296 data->n_subcredentials = service->state.n_ob_subcreds; 1297 data->subcredentials = service->state.ob_subcreds; 1298 1299 return 0; 1300 } 1301 1302 /** We just received an INTRODUCE2 cell on the established introduction circuit 1303 * circ. Handle the INTRODUCE2 payload of size payload_len for the given 1304 * circuit and service. This cell is associated with the intro point object ip 1305 * and the subcredential. Return 0 on success else a negative value. */ 1306 int 1307 hs_circ_handle_introduce2(const hs_service_t *service, 1308 const origin_circuit_t *circ, 1309 hs_service_intro_point_t *ip, 1310 const hs_subcredential_t *subcredential, 1311 const uint8_t *payload, size_t payload_len) 1312 { 1313 int ret = -1; 1314 time_t elapsed; 1315 hs_cell_introduce2_data_t data; 1316 time_t now = time(NULL); 1317 1318 tor_assert(service); 1319 tor_assert(circ); 1320 tor_assert(ip); 1321 tor_assert(subcredential); 1322 tor_assert(payload); 1323 1324 /* Populate the data structure with everything we need for the cell to be 1325 * parsed, decrypted and key material computed correctly. */ 1326 data.auth_pk = &ip->auth_key_kp.pubkey; 1327 data.enc_kp = &ip->enc_key_kp; 1328 data.payload = payload; 1329 data.payload_len = payload_len; 1330 data.replay_cache = ip->replay_cache; 1331 data.rdv_data.link_specifiers = smartlist_new(); 1332 data.rdv_data.cc_enabled = 0; 1333 data.rdv_data.pow_effort = 0; 1334 1335 if (get_subcredential_for_handling_intro2_cell(service, &data, 1336 subcredential)) { 1337 hs_metrics_reject_intro_req(service, 1338 HS_METRICS_ERR_INTRO_REQ_SUBCREDENTIAL); 1339 goto done; 1340 } 1341 1342 if (hs_cell_parse_introduce2(&data, circ, service, ip) < 0) { 1343 hs_metrics_reject_intro_req(service, HS_METRICS_ERR_INTRO_REQ_INTRODUCE2); 1344 goto done; 1345 } 1346 1347 /* Check whether we've seen this REND_COOKIE before to detect repeats. */ 1348 if (replaycache_add_test_and_elapsed( 1349 service->state.replay_cache_rend_cookie, 1350 data.rdv_data.rendezvous_cookie, 1351 sizeof(data.rdv_data.rendezvous_cookie), 1352 &elapsed)) { 1353 /* A Tor client will send a new INTRODUCE1 cell with the same REND_COOKIE 1354 * as its previous one if its intro circ times out while in state 1355 * CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT. If we received the first 1356 * INTRODUCE1 cell (the intro-point relay converts it into an INTRODUCE2 1357 * cell), we are already trying to connect to that rend point (and may 1358 * have already succeeded); drop this cell. */ 1359 log_info(LD_REND, "We received an INTRODUCE2 cell with same REND_COOKIE " 1360 "field %ld seconds ago. Dropping cell.", 1361 (long int) elapsed); 1362 hs_metrics_reject_intro_req(service, 1363 HS_METRICS_ERR_INTRO_REQ_INTRODUCE2_REPLAY); 1364 goto done; 1365 } 1366 1367 /* At this point, we just confirmed that the full INTRODUCE2 cell is valid 1368 * so increment our counter that we've seen one on this intro point. */ 1369 ip->introduce2_count++; 1370 1371 /* Add the rendezvous request to the priority queue if PoW defenses are 1372 * enabled, otherwise rendezvous as usual. */ 1373 if (have_module_pow() && service->config.has_pow_defenses_enabled) { 1374 log_info(LD_REND, 1375 "Adding introduction request to pqueue with effort: %u", 1376 data.rdv_data.pow_effort); 1377 if (enqueue_rend_request(service, ip, &data, now) < 0) { 1378 goto done; 1379 } 1380 1381 /* Track the total effort in valid requests received this period */ 1382 service->state.pow_state->total_effort += data.rdv_data.pow_effort; 1383 1384 /* Successfully added rend circuit to priority queue. */ 1385 ret = 0; 1386 goto done; 1387 } 1388 1389 /* Launch rendezvous circuit with the onion key and rend cookie. */ 1390 launch_rendezvous_point_circuit(service, &ip->auth_key_kp.pubkey, 1391 &ip->enc_key_kp, &data.rdv_data, now); 1392 /* Success. */ 1393 ret = 0; 1394 1395 done: 1396 /* Note that if PoW defenses are enabled, this is NULL. */ 1397 link_specifier_smartlist_free(data.rdv_data.link_specifiers); 1398 memwipe(&data, 0, sizeof(data)); 1399 return ret; 1400 } 1401 1402 /** Circuit <b>circ</b> just finished the rend ntor key exchange. Use the key 1403 * exchange output material at <b>ntor_key_seed</b> and setup <b>circ</b> to 1404 * serve as a rendezvous end-to-end circuit between the client and the 1405 * service. If <b>is_service_side</b> is set, then we are the hidden service 1406 * and the other side is the client. 1407 * 1408 * Return 0 if the operation went well; in case of error return -1. */ 1409 int 1410 hs_circuit_setup_e2e_rend_circ(origin_circuit_t *circ, 1411 const uint8_t *ntor_key_seed, size_t seed_len, 1412 int is_service_side) 1413 { 1414 if (BUG(!circuit_purpose_is_correct_for_rend(TO_CIRCUIT(circ)->purpose, 1415 is_service_side))) { 1416 return -1; 1417 } 1418 1419 crypt_path_t *hop = create_rend_cpath(ntor_key_seed, seed_len, 1420 is_service_side); 1421 if (!hop) { 1422 log_warn(LD_REND, "Couldn't get v3 %s cpath!", 1423 is_service_side ? "service-side" : "client-side"); 1424 return -1; 1425 } 1426 1427 finalize_rend_circuit(circ, hop, is_service_side); 1428 1429 return 0; 1430 } 1431 1432 /** Given the introduction circuit intro_circ, the rendezvous circuit 1433 * rend_circ, a descriptor intro point object ip and the service's 1434 * subcredential, send an INTRODUCE1 cell on intro_circ. 1435 * 1436 * This will also setup the circuit identifier on rend_circ containing the key 1437 * material for the handshake and e2e encryption. Return 0 on success else 1438 * negative value. Because relay_send_command_from_edge() closes the circuit 1439 * on error, it is possible that intro_circ is closed on error. */ 1440 int 1441 hs_circ_send_introduce1(origin_circuit_t *intro_circ, 1442 origin_circuit_t *rend_circ, 1443 const hs_desc_intro_point_t *ip, 1444 const hs_subcredential_t *subcredential, 1445 const hs_pow_solution_t *pow_solution) 1446 { 1447 int ret = -1; 1448 ssize_t payload_len; 1449 uint8_t payload[RELAY_PAYLOAD_SIZE_MAX] = {0}; 1450 hs_cell_introduce1_data_t intro1_data; 1451 1452 tor_assert(intro_circ); 1453 tor_assert(rend_circ); 1454 tor_assert(ip); 1455 tor_assert(subcredential); 1456 1457 /* It is undefined behavior in hs_cell_introduce1_data_clear() if intro1_data 1458 * has been declared on the stack but not initialized. Here, we set it to 0. 1459 */ 1460 memset(&intro1_data, 0, sizeof(hs_cell_introduce1_data_t)); 1461 1462 /* This takes various objects in order to populate the introduce1 data 1463 * object which is used to build the content of the cell. */ 1464 const node_t *exit_node = build_state_get_exit_node(rend_circ->build_state); 1465 if (exit_node == NULL) { 1466 log_info(LD_REND, "Unable to get rendezvous point for circuit %u. " 1467 "Failing.", TO_CIRCUIT(intro_circ)->n_circ_id); 1468 goto done; 1469 } 1470 1471 /* We should never select an invalid rendezvous point in theory but if we 1472 * do, this function will fail to populate the introduce data. */ 1473 if (setup_introduce1_data(ip, exit_node, subcredential, &intro1_data) < 0) { 1474 log_info(LD_REND, "Unable to setup INTRODUCE1 data. The chosen rendezvous " 1475 "point is unusable. Closing circuit."); 1476 goto close; 1477 } 1478 1479 /* Set the PoW solution if any. */ 1480 intro1_data.pow_solution = pow_solution; 1481 1482 /* If the rend circ was set up for congestion control, add that to the 1483 * intro data, to signal it in an extension */ 1484 if (TO_CIRCUIT(rend_circ)->ccontrol) { 1485 intro1_data.cc_enabled = 1; 1486 } 1487 1488 /* Final step before we encode a cell, we setup the circuit identifier which 1489 * will generate both the rendezvous cookie and client keypair for this 1490 * connection. Those are put in the ident. */ 1491 intro1_data.rendezvous_cookie = rend_circ->hs_ident->rendezvous_cookie; 1492 intro1_data.client_kp = &rend_circ->hs_ident->rendezvous_client_kp; 1493 1494 memcpy(intro_circ->hs_ident->rendezvous_cookie, 1495 rend_circ->hs_ident->rendezvous_cookie, 1496 sizeof(intro_circ->hs_ident->rendezvous_cookie)); 1497 1498 /* From the introduce1 data object, this will encode the INTRODUCE1 cell 1499 * into payload which is then ready to be sent as is. */ 1500 payload_len = hs_cell_build_introduce1(&intro1_data, payload); 1501 if (BUG(payload_len < 0)) { 1502 goto close; 1503 } 1504 1505 if (relay_send_command_from_edge(CONTROL_CELL_ID, TO_CIRCUIT(intro_circ), 1506 RELAY_COMMAND_INTRODUCE1, 1507 (const char *) payload, payload_len, 1508 intro_circ->cpath->prev) < 0) { 1509 /* On error, circuit is closed. */ 1510 log_warn(LD_REND, "Unable to send INTRODUCE1 cell on circuit %u.", 1511 TO_CIRCUIT(intro_circ)->n_circ_id); 1512 goto done; 1513 } 1514 1515 /* Success. */ 1516 ret = 0; 1517 goto done; 1518 1519 close: 1520 circuit_mark_for_close(TO_CIRCUIT(rend_circ), END_CIRC_REASON_INTERNAL); 1521 done: 1522 hs_cell_introduce1_data_clear(&intro1_data); 1523 memwipe(payload, 0, sizeof(payload)); 1524 return ret; 1525 } 1526 1527 /** Send an ESTABLISH_RENDEZVOUS cell along the rendezvous circuit circ. On 1528 * success, 0 is returned else -1 and the circuit is marked for close. */ 1529 int 1530 hs_circ_send_establish_rendezvous(origin_circuit_t *circ) 1531 { 1532 ssize_t cell_len = 0; 1533 uint8_t cell[RELAY_PAYLOAD_SIZE_MAX] = {0}; 1534 1535 tor_assert(circ); 1536 tor_assert(TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND); 1537 1538 log_info(LD_REND, "Send an ESTABLISH_RENDEZVOUS cell on circuit %u", 1539 TO_CIRCUIT(circ)->n_circ_id); 1540 1541 /* Set timestamp_dirty, because circuit_expire_building expects it, 1542 * and the rend cookie also means we've used the circ. */ 1543 TO_CIRCUIT(circ)->timestamp_dirty = time(NULL); 1544 1545 /* We've attempted to use this circuit. Probe it if we fail */ 1546 pathbias_count_use_attempt(circ); 1547 1548 /* Generate the RENDEZVOUS_COOKIE and place it in the identifier so we can 1549 * complete the handshake when receiving the acknowledgement. */ 1550 crypto_rand((char *) circ->hs_ident->rendezvous_cookie, HS_REND_COOKIE_LEN); 1551 /* Generate the client keypair. No need to be extra strong, not long term */ 1552 curve25519_keypair_generate(&circ->hs_ident->rendezvous_client_kp, 0); 1553 1554 cell_len = 1555 hs_cell_build_establish_rendezvous(circ->hs_ident->rendezvous_cookie, 1556 cell); 1557 if (BUG(cell_len < 0)) { 1558 goto err; 1559 } 1560 1561 if (relay_send_command_from_edge(CONTROL_CELL_ID, TO_CIRCUIT(circ), 1562 RELAY_COMMAND_ESTABLISH_RENDEZVOUS, 1563 (const char *) cell, cell_len, 1564 circ->cpath->prev) < 0) { 1565 /* Circuit has been marked for close */ 1566 log_warn(LD_REND, "Unable to send ESTABLISH_RENDEZVOUS cell on " 1567 "circuit %u", TO_CIRCUIT(circ)->n_circ_id); 1568 memwipe(cell, 0, cell_len); 1569 goto err; 1570 } 1571 1572 memwipe(cell, 0, cell_len); 1573 return 0; 1574 err: 1575 return -1; 1576 } 1577 1578 /** Circuit cleanup strategy: 1579 * 1580 * What follows is a series of functions that notifies the HS subsystem of 3 1581 * different circuit cleanup phase: close, free and repurpose. 1582 * 1583 * Tor can call any of those in any orders so they have to be safe between 1584 * each other. In other words, the free should never depend on close to be 1585 * called before. 1586 * 1587 * The "on_close()" is called from circuit_mark_for_close() which is 1588 * considered the tor fast path and thus as little work as possible should 1589 * done in that function. Currently, we only remove the circuit from the HS 1590 * circuit map and move on. 1591 * 1592 * The "on_free()" is called from circuit circuit_free_() and it is very 1593 * important that at the end of the function, no state or objects related to 1594 * this circuit remains alive. 1595 * 1596 * The "on_repurpose()" is called from circuit_change_purpose() for which we 1597 * simply remove it from the HS circuit map. We do not have other cleanup 1598 * requirements after that. 1599 * 1600 * NOTE: The onion service code, specifically the service code, cleans up 1601 * lingering objects or state if any of its circuit disappear which is why 1602 * our cleanup strategy doesn't involve any service specific actions. As long 1603 * as the circuit is removed from the HS circuit map, it won't be used. 1604 */ 1605 1606 /** We are about to close this <b>circ</b>. Clean it up from any related HS 1607 * data structures. This function can be called multiple times safely for the 1608 * same circuit. */ 1609 void 1610 hs_circ_cleanup_on_close(circuit_t *circ) 1611 { 1612 tor_assert(circ); 1613 1614 if (circuit_purpose_is_hs_client(circ->purpose)) { 1615 cleanup_on_close_client_circ(circ); 1616 } 1617 1618 if (circuit_purpose_is_hs_service(circ->purpose)) { 1619 if (circuit_is_hs_v3(circ)) { 1620 hs_service_circuit_cleanup_on_close(circ); 1621 } 1622 } 1623 1624 /* On close, we simply remove it from the circuit map. It can not be used 1625 * anymore. We keep this code path fast and lean. */ 1626 1627 if (circ->hs_token) { 1628 hs_circuitmap_remove_circuit(circ); 1629 } 1630 } 1631 1632 /** We are about to free this <b>circ</b>. Clean it up from any related HS 1633 * data structures. This function can be called multiple times safely for the 1634 * same circuit. */ 1635 void 1636 hs_circ_cleanup_on_free(circuit_t *circ) 1637 { 1638 tor_assert(circ); 1639 1640 /* NOTE: Bulk of the work of cleaning up a circuit is done here. */ 1641 1642 if (circuit_purpose_is_hs_client(circ->purpose)) { 1643 cleanup_on_free_client_circ(circ); 1644 } 1645 1646 /* We have no assurance that the given HS circuit has been closed before and 1647 * thus removed from the HS map. This actually happens in unit tests. */ 1648 if (circ->hs_token) { 1649 hs_circuitmap_remove_circuit(circ); 1650 } 1651 } 1652 1653 /** We are about to repurpose this <b>circ</b>. Clean it up from any related 1654 * HS data structures. This function can be called multiple times safely for 1655 * the same circuit. */ 1656 void 1657 hs_circ_cleanup_on_repurpose(circuit_t *circ) 1658 { 1659 tor_assert(circ); 1660 1661 /* On repurpose, we simply remove it from the circuit map but we do not do 1662 * the on_free actions since we don't treat a repurpose as something we need 1663 * to report in the client cache failure. */ 1664 1665 if (circ->hs_token) { 1666 hs_circuitmap_remove_circuit(circ); 1667 } 1668 1669 switch (circ->purpose) { 1670 case CIRCUIT_PURPOSE_S_CONNECT_REND: 1671 /* This circuit was connecting to a rendezvous point but it is being 1672 * repurposed so we need to relaunch an attempt else the client will be 1673 * left hanging waiting for the rendezvous. */ 1674 hs_circ_retry_service_rendezvous_point(TO_ORIGIN_CIRCUIT(circ)); 1675 break; 1676 default: 1677 break; 1678 } 1679 } 1680 1681 /** Return true iff the given established client rendezvous circuit was sent 1682 * into the INTRODUCE1 cell. This is called so we can take a decision on 1683 * expiring or not the circuit. 1684 * 1685 * The caller MUST make sure the circuit is an established client rendezvous 1686 * circuit (purpose: CIRCUIT_PURPOSE_C_REND_READY). 1687 * 1688 * This function supports all onion service versions. */ 1689 bool 1690 hs_circ_is_rend_sent_in_intro1(const origin_circuit_t *circ) 1691 { 1692 tor_assert(circ); 1693 /* This can only be called for a rendezvous circuit that is an established 1694 * confirmed rendezsvous circuit but without an introduction ACK. */ 1695 tor_assert(TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_C_REND_READY); 1696 1697 /* When the INTRODUCE1 cell is sent, the introduction encryption public 1698 * key is copied in the rendezvous circuit hs identifier. If it is a valid 1699 * key, we know that this circuit is waiting the ACK on the introduction 1700 * circuit. We want to _not_ spare the circuit if the key was never set. */ 1701 1702 if (circ->hs_ident) { 1703 /* v3. */ 1704 if (curve25519_public_key_is_ok(&circ->hs_ident->intro_enc_pk)) { 1705 return true; 1706 } 1707 } else { 1708 /* A circuit with an HS purpose without an hs_ident in theory can not 1709 * happen. In case, scream loudly and return false to the caller that the 1710 * rendezvous was not sent in the INTRO1 cell. */ 1711 tor_assert_nonfatal_unreached(); 1712 } 1713 1714 /* The rendezvous has not been specified in the INTRODUCE1 cell. */ 1715 return false; 1716 }