aboutsummaryrefslogtreecommitdiff
path: root/src/feature/hs/hs_common.h
blob: 94cdf5abc44d524c100d36e8e7c006aa7cb55221 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
/* Copyright (c) 2016-2019, The Tor Project, Inc. */
/* See LICENSE for licensing information */

/**
 * \file hs_common.h
 * \brief Header file containing common data for the whole HS subsytem.
 **/

#ifndef TOR_HS_COMMON_H
#define TOR_HS_COMMON_H

#include "core/or/or.h"
#include "lib/defs/x25519_sizes.h"

struct curve25519_public_key_t;
struct ed25519_public_key_t;
struct ed25519_keypair_t;

/* Trunnel */
#include "trunnel/ed25519_cert.h"

/* Protocol version 2. Use this instead of hardcoding "2" in the code base,
 * this adds a clearer semantic to the value when used. */
#define HS_VERSION_TWO 2
/* Version 3 of the protocol (prop224). */
#define HS_VERSION_THREE 3
/* Earliest and latest version we support. */
#define HS_VERSION_MIN HS_VERSION_THREE
#define HS_VERSION_MAX HS_VERSION_THREE

/** Try to maintain this many intro points per service by default. */
#define NUM_INTRO_POINTS_DEFAULT 3
/** Maximum number of intro points per generic and version 2 service. */
#define NUM_INTRO_POINTS_MAX 10
/** Number of extra intro points we launch if our set of intro nodes is empty.
 * See proposal 155, section 4. */
#define NUM_INTRO_POINTS_EXTRA 2

/** If we can't build our intro circuits, don't retry for this long. */
#define INTRO_CIRC_RETRY_PERIOD (60*5)
/** Don't try to build more than this many circuits before giving up for a
 * while.*/
#define MAX_INTRO_CIRCS_PER_PERIOD 10
/** How many times will a hidden service operator attempt to connect to a
 * requested rendezvous point before giving up? */
#define MAX_REND_FAILURES 1
/** How many seconds should we spend trying to connect to a requested
 * rendezvous point before giving up? */
#define MAX_REND_TIMEOUT 30

/* String prefix for the signature of ESTABLISH_INTRO */
#define ESTABLISH_INTRO_SIG_PREFIX "Tor establish-intro cell v1"

/* The default HS time period length */
#define HS_TIME_PERIOD_LENGTH_DEFAULT 1440 /* 1440 minutes == one day */
/* The minimum time period length as seen in prop224 section [TIME-PERIODS] */
#define HS_TIME_PERIOD_LENGTH_MIN 30 /* minutes */
/* The minimum time period length as seen in prop224 section [TIME-PERIODS] */
#define HS_TIME_PERIOD_LENGTH_MAX (60 * 24 * 10) /* 10 days or 14400 minutes */

/* Prefix of the onion address checksum. */
#define HS_SERVICE_ADDR_CHECKSUM_PREFIX ".onion checksum"
/* Length of the checksum prefix minus the NUL terminated byte. */
#define HS_SERVICE_ADDR_CHECKSUM_PREFIX_LEN \
  (sizeof(HS_SERVICE_ADDR_CHECKSUM_PREFIX) - 1)
/* Length of the resulting checksum of the address. The construction of this
 * checksum looks like:
 *   CHECKSUM = ".onion checksum" || PUBKEY || VERSION
 * where VERSION is 1 byte. This is pre-hashing. */
#define HS_SERVICE_ADDR_CHECKSUM_INPUT_LEN \
  (HS_SERVICE_ADDR_CHECKSUM_PREFIX_LEN + ED25519_PUBKEY_LEN + sizeof(uint8_t))
/* The amount of bytes we use from the address checksum. */
#define HS_SERVICE_ADDR_CHECKSUM_LEN_USED 2
/* Length of the binary encoded service address which is of course before the
 * base32 encoding. Construction is:
 *    PUBKEY || CHECKSUM || VERSION
 * with 1 byte VERSION and 2 bytes CHECKSUM. The following is 35 bytes. */
#define HS_SERVICE_ADDR_LEN \
  (ED25519_PUBKEY_LEN + HS_SERVICE_ADDR_CHECKSUM_LEN_USED + sizeof(uint8_t))
/* Length of 'y' portion of 'y.onion' URL. This is base32 encoded and the
 * length ends up to 56 bytes (not counting the terminated NUL byte.) */
#define HS_SERVICE_ADDR_LEN_BASE32 \
  (CEIL_DIV(HS_SERVICE_ADDR_LEN * 8, 5))

/* The default HS time period length */
#define HS_TIME_PERIOD_LENGTH_DEFAULT 1440 /* 1440 minutes == one day */
/* The minimum time period length as seen in prop224 section [TIME-PERIODS] */
#define HS_TIME_PERIOD_LENGTH_MIN 30 /* minutes */
/* The minimum time period length as seen in prop224 section [TIME-PERIODS] */
#define HS_TIME_PERIOD_LENGTH_MAX (60 * 24 * 10) /* 10 days or 14400 minutes */
/* The time period rotation offset as seen in prop224 section [TIME-PERIODS] */
#define HS_TIME_PERIOD_ROTATION_OFFSET (12 * 60) /* minutes */

/* Keyblinding parameter construction is as follow:
 *    "key-blind" || INT_8(period_num) || INT_8(start_period_sec) */
#define HS_KEYBLIND_NONCE_PREFIX "key-blind"
#define HS_KEYBLIND_NONCE_PREFIX_LEN (sizeof(HS_KEYBLIND_NONCE_PREFIX) - 1)
#define HS_KEYBLIND_NONCE_LEN \
  (HS_KEYBLIND_NONCE_PREFIX_LEN + sizeof(uint64_t) + sizeof(uint64_t))

/* Credential and subcredential prefix value. */
#define HS_CREDENTIAL_PREFIX "credential"
#define HS_CREDENTIAL_PREFIX_LEN (sizeof(HS_CREDENTIAL_PREFIX) - 1)
#define HS_SUBCREDENTIAL_PREFIX "subcredential"
#define HS_SUBCREDENTIAL_PREFIX_LEN (sizeof(HS_SUBCREDENTIAL_PREFIX) - 1)

/* Node hidden service stored at index prefix value. */
#define HS_INDEX_PREFIX "store-at-idx"
#define HS_INDEX_PREFIX_LEN (sizeof(HS_INDEX_PREFIX) - 1)

/* Node hidden service directory index prefix value. */
#define HSDIR_INDEX_PREFIX "node-idx"
#define HSDIR_INDEX_PREFIX_LEN (sizeof(HSDIR_INDEX_PREFIX) - 1)

/* Prefix of the shared random value disaster mode. */
#define HS_SRV_DISASTER_PREFIX "shared-random-disaster"
#define HS_SRV_DISASTER_PREFIX_LEN (sizeof(HS_SRV_DISASTER_PREFIX) - 1)

/* Default value of number of hsdir replicas (hsdir_n_replicas). */
#define HS_DEFAULT_HSDIR_N_REPLICAS 2
/* Default value of hsdir spread store (hsdir_spread_store). */
#define HS_DEFAULT_HSDIR_SPREAD_STORE 4
/* Default value of hsdir spread fetch (hsdir_spread_fetch). */
#define HS_DEFAULT_HSDIR_SPREAD_FETCH 3

/* The size of a legacy RENDEZVOUS1 cell which adds up to 168 bytes. It is
 * bigger than the 84 bytes needed for version 3 so we need to pad up to that
 * length so it is indistinguishable between versions. */
#define HS_LEGACY_RENDEZVOUS_CELL_SIZE \
  (REND_COOKIE_LEN + DH1024_KEY_LEN + DIGEST_LEN)

/* Type of authentication key used by an introduction point. */
typedef enum {
  HS_AUTH_KEY_TYPE_LEGACY  = 1,
  HS_AUTH_KEY_TYPE_ED25519 = 2,
} hs_auth_key_type_t;

/* Return value when adding an ephemeral service through the ADD_ONION
 * control port command. Both v2 and v3 share these. */
typedef enum {
  RSAE_BADAUTH     = -5, /**< Invalid auth_type/auth_clients */
  RSAE_BADVIRTPORT = -4, /**< Invalid VIRTPORT/TARGET(s) */
  RSAE_ADDREXISTS  = -3, /**< Onion address collision */
  RSAE_BADPRIVKEY  = -2, /**< Invalid public key */
  RSAE_INTERNAL    = -1, /**< Internal error */
  RSAE_OKAY        = 0   /**< Service added as expected */
} hs_service_add_ephemeral_status_t;

/* Represents the mapping from a virtual port of a rendezvous service to a
 * real port on some IP. */
typedef struct rend_service_port_config_t {
  /* The incoming HS virtual port we're mapping */
  uint16_t virtual_port;
  /* Is this an AF_UNIX port? */
  unsigned int is_unix_addr:1;
  /* The outgoing TCP port to use, if !is_unix_addr */
  uint16_t real_port;
  /* The outgoing IPv4 or IPv6 address to use, if !is_unix_addr */
  tor_addr_t real_addr;
  /* The socket path to connect to, if is_unix_addr */
  char unix_addr[FLEXIBLE_ARRAY_MEMBER];
} rend_service_port_config_t;

void hs_init(void);
void hs_free_all(void);

void hs_cleanup_circ(circuit_t *circ);

int hs_check_service_private_dir(const char *username, const char *path,
                                 unsigned int dir_group_readable,
                                 unsigned int create);
int hs_get_service_max_rend_failures(void);

char *hs_path_from_filename(const char *directory, const char *filename);
void hs_build_address(const struct ed25519_public_key_t *key, uint8_t version,
                      char *addr_out);
int hs_address_is_valid(const char *address);
int hs_parse_address(const char *address, struct ed25519_public_key_t *key_out,
                     uint8_t *checksum_out, uint8_t *version_out);

void hs_build_blinded_pubkey(const struct ed25519_public_key_t *pubkey,
                             const uint8_t *secret, size_t secret_len,
                             uint64_t time_period_num,
                             struct ed25519_public_key_t *pubkey_out);
void hs_build_blinded_keypair(const struct ed25519_keypair_t *kp,
                              const uint8_t *secret, size_t secret_len,
                              uint64_t time_period_num,
                              struct ed25519_keypair_t *kp_out);
int hs_service_requires_uptime_circ(const smartlist_t *ports);

void rend_data_free_(rend_data_t *data);
#define rend_data_free(data) \
  FREE_AND_NULL(rend_data_t, rend_data_free_, (data))
rend_data_t *rend_data_dup(const rend_data_t *data);
rend_data_t *rend_data_client_create(const char *onion_address,
                                     const char *desc_id,
                                     const char *cookie,
                                     rend_auth_type_t auth_type);
rend_data_t *rend_data_service_create(const char *onion_address,
                                      const char *pk_digest,
                                      const uint8_t *cookie,
                                      rend_auth_type_t auth_type);
const char *rend_data_get_address(const rend_data_t *rend_data);
const char *rend_data_get_desc_id(const rend_data_t *rend_data,
                                  uint8_t replica, size_t *len_out);
const uint8_t *rend_data_get_pk_digest(const rend_data_t *rend_data,
                                       size_t *len_out);

routerstatus_t *pick_hsdir(const char *desc_id, const char *desc_id_base32);

void hs_get_subcredential(const struct ed25519_public_key_t *identity_pk,
                          const struct ed25519_public_key_t *blinded_pk,
                          uint8_t *subcred_out);

uint64_t hs_get_previous_time_period_num(time_t now);
uint64_t hs_get_time_period_num(time_t now);
uint64_t hs_get_next_time_period_num(time_t now);
time_t hs_get_start_time_of_next_time_period(time_t now);

link_specifier_t *hs_link_specifier_dup(const link_specifier_t *lspec);

MOCK_DECL(int, hs_in_period_between_tp_and_srv,
          (const networkstatus_t *consensus, time_t now));

uint8_t *hs_get_current_srv(uint64_t time_period_num,
                            const networkstatus_t *ns);
uint8_t *hs_get_previous_srv(uint64_t time_period_num,
                             const networkstatus_t *ns);

void hs_build_hsdir_index(const struct ed25519_public_key_t *identity_pk,
                          const uint8_t *srv, uint64_t period_num,
                          uint8_t *hsdir_index_out);
void hs_build_hs_index(uint64_t replica,
                       const struct ed25519_public_key_t *blinded_pk,
                       uint64_t period_num, uint8_t *hs_index_out);

int32_t hs_get_hsdir_n_replicas(void);
int32_t hs_get_hsdir_spread_fetch(void);
int32_t hs_get_hsdir_spread_store(void);

void hs_get_responsible_hsdirs(const struct ed25519_public_key_t *blinded_pk,
                              uint64_t time_period_num,
                              int use_second_hsdir_index,
                              int for_fetching, smartlist_t *responsible_dirs);
routerstatus_t *hs_pick_hsdir(smartlist_t *responsible_dirs,
                              const char *req_key_str);

time_t hs_hsdir_requery_period(const or_options_t *options);
time_t hs_lookup_last_hid_serv_request(routerstatus_t *hs_dir,
                                       const char *desc_id_base32,
                                       time_t now, int set);
void hs_clean_last_hid_serv_requests(time_t now);
void hs_purge_hid_serv_from_last_hid_serv_requests(const char *desc_id);
void hs_purge_last_hid_serv_requests(void);

int hs_set_conn_addr_port(const smartlist_t *ports, edge_connection_t *conn);

void hs_inc_rdv_stream_counter(origin_circuit_t *circ);
void hs_dec_rdv_stream_counter(origin_circuit_t *circ);

extend_info_t *hs_get_extend_info_from_lspecs(const smartlist_t *lspecs,
                          const struct curve25519_public_key_t *onion_key,
                          int direct_conn);

#ifdef HS_COMMON_PRIVATE

STATIC void get_disaster_srv(uint64_t time_period_num, uint8_t *srv_out);

/** The period for which a hidden service directory cannot be queried for
 * the same descriptor ID again. */
#define REND_HID_SERV_DIR_REQUERY_PERIOD (15 * 60)
/** Test networks generate a new consensus every 5 or 10 seconds.
 * So allow them to requery HSDirs much faster. */
#define REND_HID_SERV_DIR_REQUERY_PERIOD_TESTING (5)

#ifdef TOR_UNIT_TESTS

STATIC strmap_t *get_last_hid_serv_requests(void);
STATIC uint64_t get_time_period_length(void);

STATIC uint8_t *get_first_cached_disaster_srv(void);
STATIC uint8_t *get_second_cached_disaster_srv(void);

#endif /* defined(TOR_UNIT_TESTS) */

#endif /* defined(HS_COMMON_PRIVATE) */

#endif /* !defined(TOR_HS_COMMON_H) */