hs_ob.c (12636B)
1 /* Copyright (c) 2017-2021, The Tor Project, Inc. */ 2 /* See LICENSE for licensing information */ 3 4 /** 5 * \file hs_ob.c 6 * \brief Implement Onion Balance specific code. 7 **/ 8 9 #define HS_OB_PRIVATE 10 11 #include "feature/hs/hs_service.h" 12 13 #include "feature/nodelist/networkstatus.h" 14 #include "feature/nodelist/networkstatus_st.h" 15 16 #include "lib/confmgt/confmgt.h" 17 #include "lib/encoding/confline.h" 18 19 #include "feature/hs/hs_ob.h" 20 21 /* Options config magic number. */ 22 #define OB_OPTIONS_MAGIC 0x631DE7EA 23 24 /* Helper macros. */ 25 #define VAR(varname, conftype, member, initvalue) \ 26 CONFIG_VAR_ETYPE(ob_options_t, varname, conftype, member, 0, initvalue) 27 #define V(member,conftype,initvalue) \ 28 VAR(#member, conftype, member, initvalue) 29 30 /* Dummy instance of ob_options_t, used for type-checking its members with 31 * CONF_CHECK_VAR_TYPE. */ 32 DUMMY_TYPECHECK_INSTANCE(ob_options_t); 33 34 /* Array of variables for the config file options. */ 35 static const config_var_t config_vars[] = { 36 V(MasterOnionAddress, LINELIST, NULL), 37 38 END_OF_CONFIG_VARS 39 }; 40 41 /* "Extra" variable in the state that receives lines we can't parse. This 42 * lets us preserve options from versions of Tor newer than us. */ 43 static const struct_member_t config_extra_vars = { 44 .name = "__extra", 45 .type = CONFIG_TYPE_LINELIST, 46 .offset = offsetof(ob_options_t, ExtraLines), 47 }; 48 49 /* Configuration format of ob_options_t. */ 50 static const config_format_t config_format = { 51 .size = sizeof(ob_options_t), 52 .magic = { 53 "ob_options_t", 54 OB_OPTIONS_MAGIC, 55 offsetof(ob_options_t, magic_), 56 }, 57 .vars = config_vars, 58 .extra = &config_extra_vars, 59 }; 60 61 /* Global configuration manager for the config file. */ 62 static config_mgr_t *config_options_mgr = NULL; 63 64 /* Return the configuration manager for the config file. */ 65 static const config_mgr_t * 66 get_config_options_mgr(void) 67 { 68 if (PREDICT_UNLIKELY(config_options_mgr == NULL)) { 69 config_options_mgr = config_mgr_new(&config_format); 70 config_mgr_freeze(config_options_mgr); 71 } 72 return config_options_mgr; 73 } 74 75 #define ob_option_free(val) \ 76 FREE_AND_NULL(ob_options_t, ob_option_free_, (val)) 77 78 /** Helper: Free a config options object. */ 79 static void 80 ob_option_free_(ob_options_t *opts) 81 { 82 if (opts == NULL) { 83 return; 84 } 85 config_free(get_config_options_mgr(), opts); 86 } 87 88 /** Return an allocated config options object. */ 89 static ob_options_t * 90 ob_option_new(void) 91 { 92 ob_options_t *opts = config_new(get_config_options_mgr()); 93 config_init(get_config_options_mgr(), opts); 94 return opts; 95 } 96 97 /** Helper function: From the configuration line value which is an onion 98 * address with the ".onion" extension, find the public key and put it in 99 * pkey_out. 100 * 101 * On success, true is returned. Else, false and pkey is untouched. */ 102 static bool 103 get_onion_public_key(const char *value, ed25519_public_key_t *pkey_out) 104 { 105 char address[HS_SERVICE_ADDR_LEN_BASE32 + 1]; 106 107 tor_assert(value); 108 tor_assert(pkey_out); 109 110 if (strcmpend(value, ".onion")) { 111 /* Not a .onion extension, bad format. */ 112 return false; 113 } 114 115 /* Length validation. The -1 is because sizeof() counts the NUL byte. */ 116 if (strlen(value) > 117 (HS_SERVICE_ADDR_LEN_BASE32 + sizeof(".onion") - 1)) { 118 /* Too long, bad format. */ 119 return false; 120 } 121 122 /* We don't want the .onion so we add 2 because size - 1 is copied with 123 * strlcpy() in order to accommodate the NUL byte and sizeof() counts the NUL 124 * byte so we need to remove them from the equation. */ 125 strlcpy(address, value, strlen(value) - sizeof(".onion") + 2); 126 127 if (hs_parse_address_no_log(address, pkey_out, NULL, NULL, NULL) < 0) { 128 return false; 129 } 130 131 /* Success. */ 132 return true; 133 } 134 135 /** Parse the given ob options in opts and set the service config object 136 * accordingly. 137 * 138 * Return 1 on success else 0. */ 139 static int 140 ob_option_parse(hs_service_config_t *config, const ob_options_t *opts) 141 { 142 int ret = 0; 143 config_line_t *line; 144 145 tor_assert(config); 146 tor_assert(opts); 147 148 for (line = opts->MasterOnionAddress; line; line = line->next) { 149 /* Allocate config list if need be. */ 150 if (!config->ob_master_pubkeys) { 151 config->ob_master_pubkeys = smartlist_new(); 152 } 153 ed25519_public_key_t *pubkey = tor_malloc_zero(sizeof(*pubkey)); 154 155 if (!get_onion_public_key(line->value, pubkey)) { 156 log_warn(LD_REND, "OnionBalance: MasterOnionAddress %s is invalid", 157 line->value); 158 tor_free(pubkey); 159 goto end; 160 } 161 smartlist_add(config->ob_master_pubkeys, pubkey); 162 log_notice(LD_REND, "OnionBalance: MasterOnionAddress %s registered", 163 line->value); 164 } 165 /* Success. */ 166 ret = 1; 167 168 end: 169 /* No keys added, we free the list since no list means no onion balance 170 * support for this tor instance. */ 171 if (smartlist_len(config->ob_master_pubkeys) == 0) { 172 smartlist_free(config->ob_master_pubkeys); 173 } 174 return ret; 175 } 176 177 /** For the given master public key and time period, compute the subcredential 178 * and put them into subcredential. The subcredential parameter needs to be at 179 * least DIGEST256_LEN in size. */ 180 static void 181 build_subcredential(const ed25519_public_key_t *pkey, uint64_t tp, 182 hs_subcredential_t *subcredential) 183 { 184 ed25519_public_key_t blinded_pubkey; 185 186 tor_assert(pkey); 187 tor_assert(subcredential); 188 189 hs_build_blinded_pubkey(pkey, NULL, 0, tp, &blinded_pubkey); 190 hs_get_subcredential(pkey, &blinded_pubkey, subcredential); 191 } 192 193 /* 194 * Public API. 195 */ 196 197 /** Return true iff the given service is configured as an onion balance 198 * instance. To satisfy that condition, there must at least be one master 199 * ed25519 public key configured. */ 200 bool 201 hs_ob_service_is_instance(const hs_service_t *service) 202 { 203 if (BUG(service == NULL)) { 204 return false; 205 } 206 207 /* No list, we are not an instance. */ 208 if (!service->config.ob_master_pubkeys) { 209 return false; 210 } 211 212 return smartlist_len(service->config.ob_master_pubkeys) > 0; 213 } 214 215 /** Read and parse the config file at fname on disk. The service config object 216 * is populated with the options if any. 217 * 218 * Return 1 on success else 0. This is to follow the "ok" convention in 219 * hs_config.c. */ 220 int 221 hs_ob_parse_config_file(hs_service_config_t *config) 222 { 223 static const char *fname = "ob_config"; 224 int ret = 0; 225 char *content = NULL, *errmsg = NULL, *config_file_path = NULL; 226 ob_options_t *options = NULL; 227 config_line_t *lines = NULL; 228 229 tor_assert(config); 230 231 /* Read file from disk. */ 232 config_file_path = hs_path_from_filename(config->directory_path, fname); 233 content = read_file_to_str(config_file_path, 0, NULL); 234 if (!content) { 235 log_warn(LD_FS, "OnionBalance: Unable to read config file %s", 236 escaped(config_file_path)); 237 goto end; 238 } 239 240 /* Parse lines. */ 241 if (config_get_lines(content, &lines, 0) < 0) { 242 goto end; 243 } 244 245 options = ob_option_new(); 246 config_assign(get_config_options_mgr(), options, lines, 0, &errmsg); 247 if (errmsg) { 248 log_warn(LD_REND, "OnionBalance: Unable to parse config file: %s", 249 errmsg); 250 tor_free(errmsg); 251 goto end; 252 } 253 254 /* Parse the options and set the service config object with the details. */ 255 ret = ob_option_parse(config, options); 256 257 end: 258 config_free_lines(lines); 259 ob_option_free(options); 260 tor_free(content); 261 tor_free(config_file_path); 262 return ret; 263 } 264 265 /** Compute all possible subcredentials for every onion master key in the given 266 * service config object. subcredentials_out is allocated and set as an 267 * continuous array containing all possible values. 268 * 269 * On success, return the number of subcredential put in the array which will 270 * correspond to an array of size: n * DIGEST256_LEN where DIGEST256_LEN is the 271 * length of a single subcredential. 272 * 273 * If the given configuration object has no OB master keys configured, 0 is 274 * returned and subcredentials_out is set to NULL. 275 * 276 * Otherwise, this can't fail. */ 277 STATIC size_t 278 compute_subcredentials(const hs_service_t *service, 279 hs_subcredential_t **subcredentials_out) 280 { 281 unsigned int num_pkeys, idx = 0; 282 hs_subcredential_t *subcreds = NULL; 283 const int steps[3] = {0, -1, 1}; 284 const unsigned int num_steps = ARRAY_LENGTH(steps); 285 const uint64_t tp = hs_get_time_period_num(0); 286 287 tor_assert(service); 288 tor_assert(subcredentials_out); 289 /* Our caller has checked these too */ 290 tor_assert(service->desc_current); 291 tor_assert(service->desc_next); 292 293 /* Make sure we are an OB instance, or bail out. */ 294 num_pkeys = smartlist_len(service->config.ob_master_pubkeys); 295 if (!num_pkeys) { 296 *subcredentials_out = NULL; 297 return 0; 298 } 299 300 /* Time to build all the subcredentials for each time period: two for each 301 * instance descriptor plus three for the onionbalance frontend service: the 302 * previous one (-1), the current one (0) and the next one (1) for each 303 * configured key in order to accommodate client and service consensus skew. 304 * 305 * If the client consensus after_time is at 23:00 but the service one is at 306 * 01:00, the client will be using the previous time period where the 307 * service will think it is the client next time period. Thus why we have 308 * to try them all. 309 * 310 * The normal use case works because the service gets the descriptor object 311 * that corresponds to the intro point's request, and because each 312 * descriptor corresponds to a specific subcredential, we get the right 313 * subcredential out of it, and use that to do the decryption. 314 * 315 * As a slight optimization, statistically, the current time period (0) will 316 * be the one to work first so we'll put them first in the array to maximize 317 * our chance of success. */ 318 319 /* We use a flat array, not a smartlist_t, in order to minimize memory 320 * allocation. 321 * 322 * Size of array is: length of a single subcredential multiplied by the 323 * number of time period we need to compute and finally multiplied by the 324 * total number of keys we are about to process. In other words, for each 325 * key, we allocate 3 subcredential slots. Then in the end we also add two 326 * subcredentials for this instance's active descriptors. */ 327 subcreds = 328 tor_calloc((num_steps * num_pkeys) + 2, sizeof(hs_subcredential_t)); 329 330 /* For each master pubkey we add 3 subcredentials: */ 331 for (unsigned int i = 0; i < num_steps; i++) { 332 SMARTLIST_FOREACH_BEGIN(service->config.ob_master_pubkeys, 333 const ed25519_public_key_t *, pkey) { 334 build_subcredential(pkey, tp + steps[i], &subcreds[idx]); 335 idx++; 336 } SMARTLIST_FOREACH_END(pkey); 337 } 338 339 /* And then in the end we add the two subcredentials of the current active 340 * instance descriptors */ 341 memcpy(&subcreds[idx++], &service->desc_current->desc->subcredential, 342 sizeof(hs_subcredential_t)); 343 memcpy(&subcreds[idx++], &service->desc_next->desc->subcredential, 344 sizeof(hs_subcredential_t)); 345 346 log_info(LD_REND, "Refreshing %u onionbalance keys (TP #%d).", 347 idx, (int)tp); 348 349 *subcredentials_out = subcreds; 350 return idx; 351 } 352 353 /** 354 * If we are an Onionbalance instance, refresh our keys. 355 * 356 * If we are not an Onionbalance instance or we are not ready to do so, this 357 * is a NOP. 358 * 359 * This function is called every time we build a new descriptor. That's 360 * because we want our Onionbalance keys to always use up-to-date 361 * subcredentials both for the instance (ourselves) and for the onionbalance 362 * frontend. 363 */ 364 void 365 hs_ob_refresh_keys(hs_service_t *service) 366 { 367 hs_subcredential_t *ob_subcreds = NULL; 368 size_t num_subcreds; 369 370 tor_assert(service); 371 372 /* Don't do any of this if we are not configured as an OB instance */ 373 if (!hs_ob_service_is_instance(service)) { 374 return; 375 } 376 377 /* We need both service descriptors created to make onionbalance keys. 378 * 379 * That's because we fetch our own (the instance's) subcredentials from our 380 * own descriptors which should always include the latest subcredentials that 381 * clients would use. 382 * 383 * This function is called with each descriptor build, so we will be 384 * eventually be called when both descriptors are created. */ 385 if (!service->desc_current || !service->desc_next) { 386 return; 387 } 388 389 /* Get a new set of subcreds */ 390 num_subcreds = compute_subcredentials(service, &ob_subcreds); 391 if (BUG(!num_subcreds)) { 392 return; 393 } 394 395 /* Delete old subcredentials if any */ 396 if (service->state.ob_subcreds) { 397 tor_free(service->state.ob_subcreds); 398 } 399 400 service->state.ob_subcreds = ob_subcreds; 401 service->state.n_ob_subcreds = num_subcreds; 402 } 403 404 /** Free any memory allocated by the onionblance subsystem. */ 405 void 406 hs_ob_free_all(void) 407 { 408 config_mgr_free(config_options_mgr); 409 }