From cbcc570ff4a8e03fc08bfd020d6b4c7365d4d137 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Thu, 9 May 2019 12:45:17 -0400 Subject: [PATCH 1/7] hs: Remove usage of HS_INTRO_ACK_STATUS_CANT_RELAY The INTRODUCE1 trunnel definition file doesn't support that value so it can not be used else it leads to an assert on the intro point side if ever tried. Fortunately, it was impossible to reach that code path. Part of #30454 Signed-off-by: David Goulet --- src/or/hs_intropoint.c | 5 +++-- src/or/hs_intropoint.h | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/or/hs_intropoint.c b/src/or/hs_intropoint.c index ee79109ca9..e0ab27bd36 100644 --- a/src/or/hs_intropoint.c +++ b/src/or/hs_intropoint.c @@ -483,8 +483,9 @@ handle_introduce1(or_circuit_t *client_circ, const uint8_t *request, RELAY_COMMAND_INTRODUCE2, (char *) request, request_len, NULL)) { log_warn(LD_PROTOCOL, "Unable to send INTRODUCE2 cell to the service."); - /* Inform the client that we can't relay the cell. */ - status = HS_INTRO_ACK_STATUS_CANT_RELAY; + /* Inform the client that we can't relay the cell. Use the unknown ID + * status code since it means that we do not know the service. */ + status = HS_INTRO_ACK_STATUS_UNKNOWN_ID; goto send_ack; } diff --git a/src/or/hs_intropoint.h b/src/or/hs_intropoint.h index 749d1530e1..014f9339a6 100644 --- a/src/or/hs_intropoint.h +++ b/src/or/hs_intropoint.h @@ -24,7 +24,6 @@ typedef enum { HS_INTRO_ACK_STATUS_SUCCESS = 0x0000, HS_INTRO_ACK_STATUS_UNKNOWN_ID = 0x0001, HS_INTRO_ACK_STATUS_BAD_FORMAT = 0x0002, - HS_INTRO_ACK_STATUS_CANT_RELAY = 0x0003, } hs_intro_ack_status_t; /* Object containing introduction point common data between the service and From 590d97bc1065bdb93c70695c91de9c548ef802af Mon Sep 17 00:00:00 2001 From: David Goulet Date: Thu, 9 May 2019 12:55:52 -0400 Subject: [PATCH 2/7] hs: Define INTRODUCE_ACK status code in trunnel Remove the hs_intro_ack_status_t enum and move the value into trunnel. Only use these values from now on in the intro point code. Interestingly enough, the client side also re-define these values in hs_cell.h with the hs_cell_introd_ack_status_t enum. Next commit will fix that and force to use the trunnel ABI. Part of #30454 Signed-off-by: David Goulet --- src/or/hs_intropoint.c | 16 ++++++++-------- src/or/hs_intropoint.h | 7 ------- src/trunnel/hs/cell_introduce1.c | 13 +++++++------ src/trunnel/hs/cell_introduce1.h | 3 +++ src/trunnel/hs/cell_introduce1.trunnel | 9 ++++++++- 5 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/or/hs_intropoint.c b/src/or/hs_intropoint.c index e0ab27bd36..472e4afe98 100644 --- a/src/or/hs_intropoint.c +++ b/src/or/hs_intropoint.c @@ -336,7 +336,7 @@ hs_intro_received_establish_intro(or_circuit_t *circ, const uint8_t *request, * Return 0 on success else a negative value on error which will close the * circuit. */ static int -send_introduce_ack_cell(or_circuit_t *circ, hs_intro_ack_status_t status) +send_introduce_ack_cell(or_circuit_t *circ, uint16_t status) { int ret = -1; uint8_t *encoded_cell = NULL; @@ -433,7 +433,7 @@ handle_introduce1(or_circuit_t *client_circ, const uint8_t *request, int ret = -1; or_circuit_t *service_circ; trn_cell_introduce1_t *parsed_cell; - hs_intro_ack_status_t status = HS_INTRO_ACK_STATUS_SUCCESS; + uint16_t status = TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS; tor_assert(client_circ); tor_assert(request); @@ -448,14 +448,14 @@ handle_introduce1(or_circuit_t *client_circ, const uint8_t *request, "Rejecting %s INTRODUCE1 cell. Responding with NACK.", cell_size == -1 ? "invalid" : "truncated"); /* Inform client that the INTRODUCE1 has a bad format. */ - status = HS_INTRO_ACK_STATUS_BAD_FORMAT; + status = TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT; goto send_ack; } /* Once parsed validate the cell format. */ if (validate_introduce1_parsed_cell(parsed_cell) < 0) { /* Inform client that the INTRODUCE1 has bad format. */ - status = HS_INTRO_ACK_STATUS_BAD_FORMAT; + status = TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT; goto send_ack; } @@ -472,7 +472,7 @@ handle_introduce1(or_circuit_t *client_circ, const uint8_t *request, "Responding with NACK.", safe_str(b64_key), client_circ->p_circ_id); /* Inform the client that we don't know the requested service ID. */ - status = HS_INTRO_ACK_STATUS_UNKNOWN_ID; + status = TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID; goto send_ack; } } @@ -485,12 +485,12 @@ handle_introduce1(or_circuit_t *client_circ, const uint8_t *request, log_warn(LD_PROTOCOL, "Unable to send INTRODUCE2 cell to the service."); /* Inform the client that we can't relay the cell. Use the unknown ID * status code since it means that we do not know the service. */ - status = HS_INTRO_ACK_STATUS_UNKNOWN_ID; + status = TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID; goto send_ack; } /* Success! Send an INTRODUCE_ACK success status onto the client circuit. */ - status = HS_INTRO_ACK_STATUS_SUCCESS; + status = TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS; ret = 0; send_ack: @@ -501,7 +501,7 @@ handle_introduce1(or_circuit_t *client_circ, const uint8_t *request, /* Circuit has been closed on failure of transmission. */ goto done; } - if (status != HS_INTRO_ACK_STATUS_SUCCESS) { + if (status != TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS) { /* We just sent a NACK that is a non success status code so close the * circuit because it's not useful to keep it open. Remember, a client can * only send one INTRODUCE1 cell on a circuit. */ diff --git a/src/or/hs_intropoint.h b/src/or/hs_intropoint.h index 014f9339a6..1c2cc564ab 100644 --- a/src/or/hs_intropoint.h +++ b/src/or/hs_intropoint.h @@ -19,13 +19,6 @@ typedef enum { HS_INTRO_AUTH_KEY_TYPE_ED25519 = 0x02, } hs_intro_auth_key_type_t; -/* INTRODUCE_ACK status code. */ -typedef enum { - HS_INTRO_ACK_STATUS_SUCCESS = 0x0000, - HS_INTRO_ACK_STATUS_UNKNOWN_ID = 0x0001, - HS_INTRO_ACK_STATUS_BAD_FORMAT = 0x0002, -} hs_intro_ack_status_t; - /* Object containing introduction point common data between the service and * the client side. */ typedef struct hs_intropoint_t { diff --git a/src/trunnel/hs/cell_introduce1.c b/src/trunnel/hs/cell_introduce1.c index 358b355cda..b93add64c8 100644 --- a/src/trunnel/hs/cell_introduce1.c +++ b/src/trunnel/hs/cell_introduce1.c @@ -519,6 +519,7 @@ trn_cell_introduce_ack_new(void) trn_cell_introduce_ack_t *val = trunnel_calloc(1, sizeof(trn_cell_introduce_ack_t)); if (NULL == val) return NULL; + val->status = TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT; return val; } @@ -550,7 +551,7 @@ trn_cell_introduce_ack_get_status(const trn_cell_introduce_ack_t *inp) int trn_cell_introduce_ack_set_status(trn_cell_introduce_ack_t *inp, uint16_t val) { - if (! ((val == 0 || val == 1 || val == 2))) { + if (! ((val == TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT || val == TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS || val == TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID))) { TRUNNEL_SET_ERROR_CODE(inp); return -1; } @@ -587,7 +588,7 @@ trn_cell_introduce_ack_check(const trn_cell_introduce_ack_t *obj) return "Object was NULL"; if (obj->trunnel_error_code_) return "A set function failed on this object"; - if (! (obj->status == 0 || obj->status == 1 || obj->status == 2)) + if (! (obj->status == TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT || obj->status == TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS || obj->status == TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID)) return "Integer out of bounds"; { const char *msg; @@ -606,7 +607,7 @@ trn_cell_introduce_ack_encoded_len(const trn_cell_introduce_ack_t *obj) return -1; - /* Length of u16 status IN [0, 1, 2] */ + /* Length of u16 status IN [TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT, TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS, TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID] */ result += 2; /* Length of struct trn_cell_extension extensions */ @@ -638,7 +639,7 @@ trn_cell_introduce_ack_encode(uint8_t *output, const size_t avail, const trn_cel trunnel_assert(encoded_len >= 0); #endif - /* Encode u16 status IN [0, 1, 2] */ + /* Encode u16 status IN [TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT, TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS, TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID] */ trunnel_assert(written <= avail); if (avail - written < 2) goto truncated; @@ -687,11 +688,11 @@ trn_cell_introduce_ack_parse_into(trn_cell_introduce_ack_t *obj, const uint8_t * ssize_t result = 0; (void)result; - /* Parse u16 status IN [0, 1, 2] */ + /* Parse u16 status IN [TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT, TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS, TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID] */ CHECK_REMAINING(2, truncated); obj->status = trunnel_ntohs(trunnel_get_uint16(ptr)); remaining -= 2; ptr += 2; - if (! (obj->status == 0 || obj->status == 1 || obj->status == 2)) + if (! (obj->status == TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT || obj->status == TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS || obj->status == TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID)) goto fail; /* Parse struct trn_cell_extension extensions */ diff --git a/src/trunnel/hs/cell_introduce1.h b/src/trunnel/hs/cell_introduce1.h index fa218adc6d..1bec014b6f 100644 --- a/src/trunnel/hs/cell_introduce1.h +++ b/src/trunnel/hs/cell_introduce1.h @@ -12,6 +12,9 @@ struct trn_cell_extension_st; struct link_specifier_st; #define TRUNNEL_SHA1_LEN 20 #define TRUNNEL_REND_COOKIE_LEN 20 +#define TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS 0 +#define TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID 1 +#define TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT 2 #if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_TRN_CELL_INTRODUCE1) struct trn_cell_introduce1_st { uint8_t legacy_key_id[TRUNNEL_SHA1_LEN]; diff --git a/src/trunnel/hs/cell_introduce1.trunnel b/src/trunnel/hs/cell_introduce1.trunnel index 574382b163..6d924058f9 100644 --- a/src/trunnel/hs/cell_introduce1.trunnel +++ b/src/trunnel/hs/cell_introduce1.trunnel @@ -12,6 +12,11 @@ extern struct link_specifier; const TRUNNEL_SHA1_LEN = 20; const TRUNNEL_REND_COOKIE_LEN = 20; +/* Introduce ACK status code. */ +const TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS = 0x0000; +const TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID = 0x0001; +const TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT = 0x0002; + /* INTRODUCE1 payload. See details in section 3.2.1. */ struct trn_cell_introduce1 { /* Always zeroed. MUST be checked explicitly by the caller. */ @@ -32,7 +37,9 @@ struct trn_cell_introduce1 { /* INTRODUCE_ACK payload. See details in section 3.2.2. */ struct trn_cell_introduce_ack { /* Status of introduction. */ - u16 status IN [0x0000, 0x0001, 0x0002]; + u16 status IN [TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS, + TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID, + TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT]; /* Extension(s). Reserved fields. */ struct trn_cell_extension extensions; From dcc1d8d15bf11ca1c4e2760bbc47d5fa3df3814d Mon Sep 17 00:00:00 2001 From: David Goulet Date: Thu, 9 May 2019 13:01:15 -0400 Subject: [PATCH 3/7] hs: Get rid of duplicate hs_cell_introd_ack_status_t This enum was the exact same as hs_intro_ack_status_t that was removed at the previous commit. It was used client side when parsing the INTRODUCE_ACK cell. Now, the entire code dealing with the INTRODUCE_ACK cell (both sending and receiving) have been modified to all use the same ABI defined in the trunnel introduce1 file. Finally, the client will default to the normal behavior when receiving an unknown NACK status code which is to note down that we've failed and re-extend to the next intro point. This way, unknown status code won't trigger a different behavior client side. Part of #30454. Signed-off-by: David Goulet --- src/or/hs_cell.c | 4 ++-- src/or/hs_cell.h | 8 -------- src/or/hs_client.c | 18 +++++++++--------- 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/or/hs_cell.c b/src/or/hs_cell.c index 03273a44f9..ba80653a73 100644 --- a/src/or/hs_cell.c +++ b/src/or/hs_cell.c @@ -881,9 +881,9 @@ hs_cell_parse_introduce_ack(const uint8_t *payload, size_t payload_len) * do a special case. */ if (payload_len <= 1) { if (payload_len == 0) { - ret = HS_CELL_INTRO_ACK_SUCCESS; + ret = TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS; } else { - ret = HS_CELL_INTRO_ACK_FAILURE; + ret = TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID; } goto end; } diff --git a/src/or/hs_cell.h b/src/or/hs_cell.h index 958dde4ffc..ed4af3c5af 100644 --- a/src/or/hs_cell.h +++ b/src/or/hs_cell.h @@ -16,14 +16,6 @@ * 3.2.2 of the specification). Below this value, the cell must be padded. */ #define HS_CELL_INTRODUCE1_MIN_SIZE 246 -/* Status code of an INTRODUCE_ACK cell. */ -typedef enum { - HS_CELL_INTRO_ACK_SUCCESS = 0x0000, /* Cell relayed to service. */ - HS_CELL_INTRO_ACK_FAILURE = 0x0001, /* Service ID not recognized */ - HS_CELL_INTRO_ACK_BADFMT = 0x0002, /* Bad message format */ - HS_CELL_INTRO_ACK_NORELAY = 0x0003, /* Can't relay cell to service */ -} hs_cell_introd_ack_status_t; - /* Onion key type found in the INTRODUCE1 cell. */ typedef enum { HS_CELL_ONION_KEY_TYPE_NTOR = 1, diff --git a/src/or/hs_client.c b/src/or/hs_client.c index 8ecefc1209..7d44952e4d 100644 --- a/src/or/hs_client.c +++ b/src/or/hs_client.c @@ -35,6 +35,8 @@ #include "router.h" #include "routerset.h" +#include "trunnel/hs/cell_introduce1.h" + /* Return a human-readable string for the client fetch status code. */ static const char * fetch_status_to_string(hs_client_fetch_status_t status) @@ -1018,23 +1020,21 @@ handle_introduce_ack(origin_circuit_t *circ, const uint8_t *payload, status = hs_cell_parse_introduce_ack(payload, payload_len); switch (status) { - case HS_CELL_INTRO_ACK_SUCCESS: + case TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS: ret = 0; handle_introduce_ack_success(circ); goto end; - case HS_CELL_INTRO_ACK_FAILURE: - case HS_CELL_INTRO_ACK_BADFMT: - case HS_CELL_INTRO_ACK_NORELAY: + case TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID: + case TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT: + /* It is possible that the intro point can send us an unknown status code + * for the NACK that we do not know about like a new code for instance. + * Just fallthrough so we can note down the NACK and re-extend. */ + default: handle_introduce_ack_bad(circ, status); /* We are going to see if we have to close the circuits (IP and RP) or we * can re-extend to a new intro point. */ ret = close_or_reextend_intro_circ(circ); break; - default: - log_info(LD_PROTOCOL, "Unknown INTRODUCE_ACK status code %u from %s", - status, - safe_str_client(extend_info_describe(circ->build_state->chosen_exit))); - break; } end: From 79cfe2ddd7c030e679104588c7e4842c2ff6b239 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Thu, 9 May 2019 13:09:44 -0400 Subject: [PATCH 4/7] hs: Remove hs_intro_auth_key_type_t enum Like the previous commit about the INTRODUCE_ACK status code, change all auth key type to use the one defined in the trunnel file. Standardize the use of these auth type to a common ABI. Part of #30454 Signed-off-by: David Goulet --- src/or/hs_cell.c | 5 +++-- src/or/hs_intropoint.c | 10 +++++----- src/or/hs_intropoint.h | 7 ------- src/test/test_hs_cell.c | 2 +- src/test/test_hs_intropoint.c | 4 ++-- src/trunnel/hs/cell_introduce1.c | 13 +++++++------ src/trunnel/hs/cell_introduce1.h | 3 +++ src/trunnel/hs/cell_introduce1.trunnel | 9 ++++++++- 8 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/or/hs_cell.c b/src/or/hs_cell.c index ba80653a73..7bbefe8fd0 100644 --- a/src/or/hs_cell.c +++ b/src/or/hs_cell.c @@ -441,7 +441,8 @@ introduce1_set_auth_key(trn_cell_introduce1_t *cell, tor_assert(cell); tor_assert(data); /* There is only one possible type for a non legacy cell. */ - trn_cell_introduce1_set_auth_key_type(cell, HS_INTRO_AUTH_KEY_TYPE_ED25519); + trn_cell_introduce1_set_auth_key_type(cell, + TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519); trn_cell_introduce1_set_auth_key_len(cell, ED25519_PUBKEY_LEN); trn_cell_introduce1_setlen_auth_key(cell, ED25519_PUBKEY_LEN); memcpy(trn_cell_introduce1_getarray_auth_key(cell), @@ -514,7 +515,7 @@ hs_cell_build_establish_intro(const char *circ_nonce, /* Set AUTH_KEY_TYPE: 2 means ed25519 */ trn_cell_establish_intro_set_auth_key_type(cell, - HS_INTRO_AUTH_KEY_TYPE_ED25519); + TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519); /* Set AUTH_KEY and AUTH_KEY_LEN field. Must also set byte-length of * AUTH_KEY to match */ diff --git a/src/or/hs_intropoint.c b/src/or/hs_intropoint.c index 472e4afe98..a12a3210cb 100644 --- a/src/or/hs_intropoint.c +++ b/src/or/hs_intropoint.c @@ -75,7 +75,7 @@ verify_establish_intro_cell(const trn_cell_establish_intro_t *cell, /* We only reach this function if the first byte of the cell is 0x02 which * means that auth_key_type is of ed25519 type, hence this check should * always pass. See hs_intro_received_establish_intro(). */ - if (BUG(cell->auth_key_type != HS_INTRO_AUTH_KEY_TYPE_ED25519)) { + if (BUG(cell->auth_key_type != TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519)) { return -1; } @@ -315,10 +315,10 @@ hs_intro_received_establish_intro(or_circuit_t *circ, const uint8_t *request, * ESTABLISH_INTRO and pass it to the appropriate cell handler */ const uint8_t first_byte = request[0]; switch (first_byte) { - case HS_INTRO_AUTH_KEY_TYPE_LEGACY0: - case HS_INTRO_AUTH_KEY_TYPE_LEGACY1: + case TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY0: + case TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY1: return rend_mid_establish_intro_legacy(circ, request, request_len); - case HS_INTRO_AUTH_KEY_TYPE_ED25519: + case TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519: return handle_establish_intro(circ, request, request_len); default: log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, @@ -396,7 +396,7 @@ validate_introduce1_parsed_cell(const trn_cell_introduce1_t *cell) /* The auth key of an INTRODUCE1 should be of type ed25519 thus leading to a * known fixed length as well. */ if (trn_cell_introduce1_get_auth_key_type(cell) != - HS_INTRO_AUTH_KEY_TYPE_ED25519) { + TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519) { log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "Rejecting invalid INTRODUCE1 cell auth key type. " "Responding with NACK."); diff --git a/src/or/hs_intropoint.h b/src/or/hs_intropoint.h index 1c2cc564ab..1891bffacc 100644 --- a/src/or/hs_intropoint.h +++ b/src/or/hs_intropoint.h @@ -12,13 +12,6 @@ #include "crypto_curve25519.h" #include "torcert.h" -/* Authentication key type in an ESTABLISH_INTRO cell. */ -typedef enum { - HS_INTRO_AUTH_KEY_TYPE_LEGACY0 = 0x00, - HS_INTRO_AUTH_KEY_TYPE_LEGACY1 = 0x01, - HS_INTRO_AUTH_KEY_TYPE_ED25519 = 0x02, -} hs_intro_auth_key_type_t; - /* Object containing introduction point common data between the service and * the client side. */ typedef struct hs_intropoint_t { diff --git a/src/test/test_hs_cell.c b/src/test/test_hs_cell.c index 8e15184c2a..f754068a01 100644 --- a/src/test/test_hs_cell.c +++ b/src/test/test_hs_cell.c @@ -50,7 +50,7 @@ test_gen_establish_intro_cell(void *arg) /* Check the contents of the cell */ { /* First byte is the auth key type: make sure its correct */ - tt_int_op(buf[0], OP_EQ, HS_INTRO_AUTH_KEY_TYPE_ED25519); + tt_int_op(buf[0], OP_EQ, TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519); /* Next two bytes is auth key len */ tt_int_op(ntohs(get_uint16(buf+1)), OP_EQ, ED25519_PUBKEY_LEN); /* Skip to the number of extensions: no extensions */ diff --git a/src/test/test_hs_intropoint.c b/src/test/test_hs_intropoint.c index faa14d9015..f348a076fb 100644 --- a/src/test/test_hs_intropoint.c +++ b/src/test/test_hs_intropoint.c @@ -138,7 +138,7 @@ helper_create_introduce1_cell(void) { size_t auth_key_len = sizeof(auth_key_kp.pubkey); trn_cell_introduce1_set_auth_key_type(cell, - HS_INTRO_AUTH_KEY_TYPE_ED25519); + TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519); trn_cell_introduce1_set_auth_key_len(cell, auth_key_len); trn_cell_introduce1_setlen_auth_key(cell, auth_key_len); uint8_t *auth_key_ptr = trn_cell_introduce1_getarray_auth_key(cell); @@ -749,7 +749,7 @@ test_introduce1_validation(void *arg) ret = validate_introduce1_parsed_cell(cell); tt_int_op(ret, OP_EQ, -1); /* Reset is to correct value and make sure it's correct. */ - cell->auth_key_type = HS_INTRO_AUTH_KEY_TYPE_ED25519; + cell->auth_key_type = TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519; ret = validate_introduce1_parsed_cell(cell); tt_int_op(ret, OP_EQ, 0); diff --git a/src/trunnel/hs/cell_introduce1.c b/src/trunnel/hs/cell_introduce1.c index b93add64c8..1fdb954534 100644 --- a/src/trunnel/hs/cell_introduce1.c +++ b/src/trunnel/hs/cell_introduce1.c @@ -50,6 +50,7 @@ trn_cell_introduce1_new(void) trn_cell_introduce1_t *val = trunnel_calloc(1, sizeof(trn_cell_introduce1_t)); if (NULL == val) return NULL; + val->auth_key_type = TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519; return val; } @@ -121,7 +122,7 @@ trn_cell_introduce1_get_auth_key_type(const trn_cell_introduce1_t *inp) int trn_cell_introduce1_set_auth_key_type(trn_cell_introduce1_t *inp, uint8_t val) { - if (! ((val == 0 || val == 1 || val == 2))) { + if (! ((val == TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519 || val == TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY0 || val == TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY1))) { TRUNNEL_SET_ERROR_CODE(inp); return -1; } @@ -295,7 +296,7 @@ trn_cell_introduce1_check(const trn_cell_introduce1_t *obj) return "Object was NULL"; if (obj->trunnel_error_code_) return "A set function failed on this object"; - if (! (obj->auth_key_type == 0 || obj->auth_key_type == 1 || obj->auth_key_type == 2)) + if (! (obj->auth_key_type == TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519 || obj->auth_key_type == TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY0 || obj->auth_key_type == TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY1)) return "Integer out of bounds"; if (TRUNNEL_DYNARRAY_LEN(&obj->auth_key) != obj->auth_key_len) return "Length mismatch for auth_key"; @@ -319,7 +320,7 @@ trn_cell_introduce1_encoded_len(const trn_cell_introduce1_t *obj) /* Length of u8 legacy_key_id[TRUNNEL_SHA1_LEN] */ result += TRUNNEL_SHA1_LEN; - /* Length of u8 auth_key_type IN [0, 1, 2] */ + /* Length of u8 auth_key_type IN [TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519, TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY0, TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY1] */ result += 1; /* Length of u16 auth_key_len */ @@ -367,7 +368,7 @@ trn_cell_introduce1_encode(uint8_t *output, const size_t avail, const trn_cell_i memcpy(ptr, obj->legacy_key_id, TRUNNEL_SHA1_LEN); written += TRUNNEL_SHA1_LEN; ptr += TRUNNEL_SHA1_LEN; - /* Encode u8 auth_key_type IN [0, 1, 2] */ + /* Encode u8 auth_key_type IN [TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519, TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY0, TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY1] */ trunnel_assert(written <= avail); if (avail - written < 1) goto truncated; @@ -451,11 +452,11 @@ trn_cell_introduce1_parse_into(trn_cell_introduce1_t *obj, const uint8_t *input, memcpy(obj->legacy_key_id, ptr, TRUNNEL_SHA1_LEN); remaining -= TRUNNEL_SHA1_LEN; ptr += TRUNNEL_SHA1_LEN; - /* Parse u8 auth_key_type IN [0, 1, 2] */ + /* Parse u8 auth_key_type IN [TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519, TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY0, TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY1] */ CHECK_REMAINING(1, truncated); obj->auth_key_type = (trunnel_get_uint8(ptr)); remaining -= 1; ptr += 1; - if (! (obj->auth_key_type == 0 || obj->auth_key_type == 1 || obj->auth_key_type == 2)) + if (! (obj->auth_key_type == TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519 || obj->auth_key_type == TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY0 || obj->auth_key_type == TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY1)) goto fail; /* Parse u16 auth_key_len */ diff --git a/src/trunnel/hs/cell_introduce1.h b/src/trunnel/hs/cell_introduce1.h index 1bec014b6f..c94c7d5075 100644 --- a/src/trunnel/hs/cell_introduce1.h +++ b/src/trunnel/hs/cell_introduce1.h @@ -15,6 +15,9 @@ struct link_specifier_st; #define TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS 0 #define TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID 1 #define TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT 2 +#define TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY0 0 +#define TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY1 1 +#define TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519 2 #if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_TRN_CELL_INTRODUCE1) struct trn_cell_introduce1_st { uint8_t legacy_key_id[TRUNNEL_SHA1_LEN]; diff --git a/src/trunnel/hs/cell_introduce1.trunnel b/src/trunnel/hs/cell_introduce1.trunnel index 6d924058f9..69da2c1136 100644 --- a/src/trunnel/hs/cell_introduce1.trunnel +++ b/src/trunnel/hs/cell_introduce1.trunnel @@ -17,13 +17,20 @@ const TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS = 0x0000; const TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID = 0x0001; const TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT = 0x0002; +/* Authentication key type. */ +const TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY0 = 0x00; +const TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY1 = 0x01; +const TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519 = 0x02; + /* INTRODUCE1 payload. See details in section 3.2.1. */ struct trn_cell_introduce1 { /* Always zeroed. MUST be checked explicitly by the caller. */ u8 legacy_key_id[TRUNNEL_SHA1_LEN]; /* Authentication key material. */ - u8 auth_key_type IN [0x00, 0x01, 0x02]; + u8 auth_key_type IN [TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY0, + TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY1, + TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519]; u16 auth_key_len; u8 auth_key[auth_key_len]; From 9f52b875184098aef91bfdebcfd272a60b3b879e Mon Sep 17 00:00:00 2001 From: David Goulet Date: Thu, 9 May 2019 13:23:14 -0400 Subject: [PATCH 5/7] hs: Add changes file for #30454 Signed-off-by: David Goulet --- changes/ticket30454 | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 changes/ticket30454 diff --git a/changes/ticket30454 b/changes/ticket30454 new file mode 100644 index 0000000000..77c45d0feb --- /dev/null +++ b/changes/ticket30454 @@ -0,0 +1,10 @@ + o Major bugfixes (hidden service v3): + - An intro point could try to send an INTRODUCE_ACK with a status code + that it wasn't able to encode leading to a hard assert() of the relay. + Fortunately, that specific code path can not be reached thus this issue + can't be triggered. We've consolidated the ABI values into trunnel now. + Fixes bug 30454; bugfix on 0.3.0.1-alpha. + - HSv3 client will now be able to properly handle unknown status code from + a INTRODUCE_ACK cell (nack) even if they do not know it. The NACK + behavior will stay the same. This will allow us to extend status code if + we want in the future without breaking the normal client behavior. From 7d3e904a27ac714c33f9b1e14b4d1d18d4042147 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Wed, 15 May 2019 15:27:27 -0400 Subject: [PATCH 6/7] trunnel: Remove INTRODUCE1 status code IN statement We want to support parsing a cell with unknown status code so we are forward compatible. Part of #30454 Signed-off-by: David Goulet --- src/trunnel/hs/cell_introduce1.c | 18 +++--------------- src/trunnel/hs/cell_introduce1.trunnel | 4 +--- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/src/trunnel/hs/cell_introduce1.c b/src/trunnel/hs/cell_introduce1.c index 1fdb954534..cebfa28673 100644 --- a/src/trunnel/hs/cell_introduce1.c +++ b/src/trunnel/hs/cell_introduce1.c @@ -520,7 +520,6 @@ trn_cell_introduce_ack_new(void) trn_cell_introduce_ack_t *val = trunnel_calloc(1, sizeof(trn_cell_introduce_ack_t)); if (NULL == val) return NULL; - val->status = TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT; return val; } @@ -552,10 +551,6 @@ trn_cell_introduce_ack_get_status(const trn_cell_introduce_ack_t *inp) int trn_cell_introduce_ack_set_status(trn_cell_introduce_ack_t *inp, uint16_t val) { - if (! ((val == TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT || val == TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS || val == TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID))) { - TRUNNEL_SET_ERROR_CODE(inp); - return -1; - } inp->status = val; return 0; } @@ -589,8 +584,6 @@ trn_cell_introduce_ack_check(const trn_cell_introduce_ack_t *obj) return "Object was NULL"; if (obj->trunnel_error_code_) return "A set function failed on this object"; - if (! (obj->status == TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT || obj->status == TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS || obj->status == TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID)) - return "Integer out of bounds"; { const char *msg; if (NULL != (msg = trn_cell_extension_check(obj->extensions))) @@ -608,7 +601,7 @@ trn_cell_introduce_ack_encoded_len(const trn_cell_introduce_ack_t *obj) return -1; - /* Length of u16 status IN [TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT, TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS, TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID] */ + /* Length of u16 status */ result += 2; /* Length of struct trn_cell_extension extensions */ @@ -640,7 +633,7 @@ trn_cell_introduce_ack_encode(uint8_t *output, const size_t avail, const trn_cel trunnel_assert(encoded_len >= 0); #endif - /* Encode u16 status IN [TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT, TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS, TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID] */ + /* Encode u16 status */ trunnel_assert(written <= avail); if (avail - written < 2) goto truncated; @@ -689,12 +682,10 @@ trn_cell_introduce_ack_parse_into(trn_cell_introduce_ack_t *obj, const uint8_t * ssize_t result = 0; (void)result; - /* Parse u16 status IN [TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT, TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS, TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID] */ + /* Parse u16 status */ CHECK_REMAINING(2, truncated); obj->status = trunnel_ntohs(trunnel_get_uint16(ptr)); remaining -= 2; ptr += 2; - if (! (obj->status == TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT || obj->status == TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS || obj->status == TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID)) - goto fail; /* Parse struct trn_cell_extension extensions */ result = trn_cell_extension_parse(&obj->extensions, ptr, remaining); @@ -710,9 +701,6 @@ trn_cell_introduce_ack_parse_into(trn_cell_introduce_ack_t *obj, const uint8_t * relay_fail: trunnel_assert(result < 0); return result; - fail: - result = -1; - return result; } ssize_t diff --git a/src/trunnel/hs/cell_introduce1.trunnel b/src/trunnel/hs/cell_introduce1.trunnel index 69da2c1136..bbb091d2b8 100644 --- a/src/trunnel/hs/cell_introduce1.trunnel +++ b/src/trunnel/hs/cell_introduce1.trunnel @@ -44,9 +44,7 @@ struct trn_cell_introduce1 { /* INTRODUCE_ACK payload. See details in section 3.2.2. */ struct trn_cell_introduce_ack { /* Status of introduction. */ - u16 status IN [TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS, - TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID, - TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT]; + u16 status; /* Extension(s). Reserved fields. */ struct trn_cell_extension extensions; From 56908c6f1c63d32bef7011c811976e24156f17d3 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Wed, 15 May 2019 15:30:29 -0400 Subject: [PATCH 7/7] hs: Remove hs_cell_onion_key_type_t enum Unify this with the trunnel ABI so we don't duplicate. Part of #30454 Signed-off-by: David Goulet --- src/or/hs_cell.c | 7 ++++--- src/or/hs_cell.h | 5 ----- src/trunnel/hs/cell_introduce1.c | 14 +++++++------- src/trunnel/hs/cell_introduce1.h | 1 + src/trunnel/hs/cell_introduce1.trunnel | 5 ++++- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/or/hs_cell.c b/src/or/hs_cell.c index 7bbefe8fd0..7b7e9379c3 100644 --- a/src/or/hs_cell.c +++ b/src/or/hs_cell.c @@ -160,11 +160,12 @@ parse_introduce2_encrypted(const uint8_t *decrypted_data, } if (trn_cell_introduce_encrypted_get_onion_key_type(enc_cell) != - HS_CELL_ONION_KEY_TYPE_NTOR) { + TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR) { log_info(LD_REND, "INTRODUCE2 onion key type is invalid. Got %u but " "expected %u on circuit %u for service %s", trn_cell_introduce_encrypted_get_onion_key_type(enc_cell), - HS_CELL_ONION_KEY_TYPE_NTOR, TO_CIRCUIT(circ)->n_circ_id, + TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR, + TO_CIRCUIT(circ)->n_circ_id, safe_str_client(service->onion_address)); goto err; } @@ -257,7 +258,7 @@ introduce1_set_encrypted_onion_key(trn_cell_introduce_encrypted_t *cell, tor_assert(onion_pk); /* There is only one possible key type for a non legacy cell. */ trn_cell_introduce_encrypted_set_onion_key_type(cell, - HS_CELL_ONION_KEY_TYPE_NTOR); + TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR); trn_cell_introduce_encrypted_set_onion_key_len(cell, CURVE25519_PUBKEY_LEN); trn_cell_introduce_encrypted_setlen_onion_key(cell, CURVE25519_PUBKEY_LEN); memcpy(trn_cell_introduce_encrypted_getarray_onion_key(cell), onion_pk, diff --git a/src/or/hs_cell.h b/src/or/hs_cell.h index ed4af3c5af..49b29a43bf 100644 --- a/src/or/hs_cell.h +++ b/src/or/hs_cell.h @@ -16,11 +16,6 @@ * 3.2.2 of the specification). Below this value, the cell must be padded. */ #define HS_CELL_INTRODUCE1_MIN_SIZE 246 -/* Onion key type found in the INTRODUCE1 cell. */ -typedef enum { - HS_CELL_ONION_KEY_TYPE_NTOR = 1, -} hs_cell_onion_key_type_t; - /* This data structure contains data that we need to build an INTRODUCE1 cell * used by the INTRODUCE1 build function. */ typedef struct hs_cell_introduce1_data_t { diff --git a/src/trunnel/hs/cell_introduce1.c b/src/trunnel/hs/cell_introduce1.c index cebfa28673..53b3d299f2 100644 --- a/src/trunnel/hs/cell_introduce1.c +++ b/src/trunnel/hs/cell_introduce1.c @@ -723,7 +723,7 @@ trn_cell_introduce_encrypted_new(void) trn_cell_introduce_encrypted_t *val = trunnel_calloc(1, sizeof(trn_cell_introduce_encrypted_t)); if (NULL == val) return NULL; - val->onion_key_type = 1; + val->onion_key_type = TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR; return val; } @@ -827,7 +827,7 @@ trn_cell_introduce_encrypted_get_onion_key_type(const trn_cell_introduce_encrypt int trn_cell_introduce_encrypted_set_onion_key_type(trn_cell_introduce_encrypted_t *inp, uint8_t val) { - if (! ((val == 1))) { + if (! ((val == TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR))) { TRUNNEL_SET_ERROR_CODE(inp); return -1; } @@ -1069,7 +1069,7 @@ trn_cell_introduce_encrypted_check(const trn_cell_introduce_encrypted_t *obj) if (NULL != (msg = trn_cell_extension_check(obj->extensions))) return msg; } - if (! (obj->onion_key_type == 1)) + if (! (obj->onion_key_type == TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR)) return "Integer out of bounds"; if (TRUNNEL_DYNARRAY_LEN(&obj->onion_key) != obj->onion_key_len) return "Length mismatch for onion_key"; @@ -1102,7 +1102,7 @@ trn_cell_introduce_encrypted_encoded_len(const trn_cell_introduce_encrypted_t *o /* Length of struct trn_cell_extension extensions */ result += trn_cell_extension_encoded_len(obj->extensions); - /* Length of u8 onion_key_type IN [1] */ + /* Length of u8 onion_key_type IN [TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR] */ result += 1; /* Length of u16 onion_key_len */ @@ -1166,7 +1166,7 @@ trn_cell_introduce_encrypted_encode(uint8_t *output, const size_t avail, const t goto fail; /* XXXXXXX !*/ written += result; ptr += result; - /* Encode u8 onion_key_type IN [1] */ + /* Encode u8 onion_key_type IN [TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR] */ trunnel_assert(written <= avail); if (avail - written < 1) goto truncated; @@ -1270,11 +1270,11 @@ trn_cell_introduce_encrypted_parse_into(trn_cell_introduce_encrypted_t *obj, con trunnel_assert((size_t)result <= remaining); remaining -= result; ptr += result; - /* Parse u8 onion_key_type IN [1] */ + /* Parse u8 onion_key_type IN [TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR] */ CHECK_REMAINING(1, truncated); obj->onion_key_type = (trunnel_get_uint8(ptr)); remaining -= 1; ptr += 1; - if (! (obj->onion_key_type == 1)) + if (! (obj->onion_key_type == TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR)) goto fail; /* Parse u16 onion_key_len */ diff --git a/src/trunnel/hs/cell_introduce1.h b/src/trunnel/hs/cell_introduce1.h index c94c7d5075..986a531ca7 100644 --- a/src/trunnel/hs/cell_introduce1.h +++ b/src/trunnel/hs/cell_introduce1.h @@ -18,6 +18,7 @@ struct link_specifier_st; #define TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY0 0 #define TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY1 1 #define TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519 2 +#define TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR 1 #if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_TRN_CELL_INTRODUCE1) struct trn_cell_introduce1_st { uint8_t legacy_key_id[TRUNNEL_SHA1_LEN]; diff --git a/src/trunnel/hs/cell_introduce1.trunnel b/src/trunnel/hs/cell_introduce1.trunnel index bbb091d2b8..5911c695a2 100644 --- a/src/trunnel/hs/cell_introduce1.trunnel +++ b/src/trunnel/hs/cell_introduce1.trunnel @@ -22,6 +22,9 @@ const TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY0 = 0x00; const TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY1 = 0x01; const TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519 = 0x02; +/* Onion key type. */ +const TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR = 0x01; + /* INTRODUCE1 payload. See details in section 3.2.1. */ struct trn_cell_introduce1 { /* Always zeroed. MUST be checked explicitly by the caller. */ @@ -59,7 +62,7 @@ struct trn_cell_introduce_encrypted { struct trn_cell_extension extensions; /* Onion key material. */ - u8 onion_key_type IN [0x01]; + u8 onion_key_type IN [TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR]; u16 onion_key_len; u8 onion_key[onion_key_len];