Fix numerous memory leaks: some were almost impossible to trigger, and some almost...
[tor.git] / src / or / rendcommon.c
blob6562cdac9c20a0777302c11361c984b3c555ed5c
1 /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
2 * Copyright (c) 2007-2008, The Tor Project, Inc. */
3 /* See LICENSE for licensing information */
4 /* $Id$ */
5 const char rendcommon_c_id[] =
6 "$Id$";
8 /**
9 * \file rendcommon.c
10 * \brief Rendezvous implementation: shared code between
11 * introducers, services, clients, and rendezvous points.
12 **/
14 #include "or.h"
16 /** Return 0 if one and two are the same service ids, else -1 or 1 */
17 int
18 rend_cmp_service_ids(const char *one, const char *two)
20 return strcasecmp(one,two);
23 /** Free the storage held by the service descriptor <b>desc</b>.
25 void
26 rend_service_descriptor_free(rend_service_descriptor_t *desc)
28 if (desc->pk)
29 crypto_free_pk_env(desc->pk);
30 if (desc->intro_nodes) {
31 SMARTLIST_FOREACH(desc->intro_nodes, rend_intro_point_t *, intro,
32 rend_intro_point_free(intro););
33 smartlist_free(desc->intro_nodes);
35 tor_free(desc);
38 /** Length of the descriptor cookie that is used for versioned hidden
39 * service descriptors. */
40 #define REND_DESC_COOKIE_LEN 16
42 /** Length of the replica number that is used to determine the secret ID
43 * part of versioned hidden service descriptors. */
44 #define REND_REPLICA_LEN 1
46 /** Compute the descriptor ID for <b>service_id</b> of length
47 * <b>REND_SERVICE_ID_LEN</b> and <b>secret_id_part</b> of length
48 * <b>DIGEST_LEN</b>, and write it to <b>descriptor_id_out</b> of length
49 * <b>DIGEST_LEN</b>. */
50 void
51 rend_get_descriptor_id_bytes(char *descriptor_id_out,
52 const char *service_id,
53 const char *secret_id_part)
55 crypto_digest_env_t *digest = crypto_new_digest_env();
56 crypto_digest_add_bytes(digest, service_id, REND_SERVICE_ID_LEN);
57 crypto_digest_add_bytes(digest, secret_id_part, DIGEST_LEN);
58 crypto_digest_get_digest(digest, descriptor_id_out, DIGEST_LEN);
59 crypto_free_digest_env(digest);
62 /** Compute the secret ID part for time_period,
63 * a <b>descriptor_cookie</b> of length
64 * <b>REND_DESC_COOKIE_LEN</b> which may also be <b>NULL</b> if no
65 * descriptor_cookie shall be used, and <b>replica</b>, and write it to
66 * <b>secret_id_part</b> of length DIGEST_LEN. */
67 static void
68 get_secret_id_part_bytes(char *secret_id_part, uint32_t time_period,
69 const char *descriptor_cookie, uint8_t replica)
71 crypto_digest_env_t *digest = crypto_new_digest_env();
72 time_period = htonl(time_period);
73 crypto_digest_add_bytes(digest, (char*)&time_period, sizeof(uint32_t));
74 if (descriptor_cookie) {
75 crypto_digest_add_bytes(digest, descriptor_cookie,
76 REND_DESC_COOKIE_LEN);
78 crypto_digest_add_bytes(digest, (const char *)&replica, REND_REPLICA_LEN);
79 crypto_digest_get_digest(digest, secret_id_part, DIGEST_LEN);
80 crypto_free_digest_env(digest);
83 /** Return the time period for time <b>now</b> plus a potentially
84 * intended <b>deviation</b> of one or more periods, based on the first byte
85 * of <b>service_id</b>. */
86 static uint32_t
87 get_time_period(time_t now, uint8_t deviation, const char *service_id)
89 /* The time period is the number of REND_TIME_PERIOD_V2_DESC_VALIDITY
90 * intervals that have passed since the epoch, offset slightly so that
91 * each service's time periods start and end at a fraction of that
92 * period based on their first byte. */
93 return (uint32_t)
94 (now + ((uint8_t) *service_id) * REND_TIME_PERIOD_V2_DESC_VALIDITY / 256)
95 / REND_TIME_PERIOD_V2_DESC_VALIDITY + deviation;
98 /** Compute the time in seconds that a descriptor that is generated
99 * <b>now</b> for <b>service_id</b> will be valid. */
100 static uint32_t
101 get_seconds_valid(time_t now, const char *service_id)
103 uint32_t result = REND_TIME_PERIOD_V2_DESC_VALIDITY -
104 ((uint32_t)
105 (now + ((uint8_t) *service_id) * REND_TIME_PERIOD_V2_DESC_VALIDITY / 256)
106 % REND_TIME_PERIOD_V2_DESC_VALIDITY);
107 return result;
110 /** Compute the binary <b>desc_id_out</b> (DIGEST_LEN bytes long) for a given
111 * base32-encoded <b>service_id</b> and optional unencoded
112 * <b>descriptor_cookie</b> of length REND_DESC_COOKIE_LEN,
113 * at time <b>now</b> for replica number
114 * <b>replica</b>. <b>desc_id</b> needs to have <b>DIGEST_LEN</b> bytes
115 * free. Return 0 for success, -1 otherwise. */
117 rend_compute_v2_desc_id(char *desc_id_out, const char *service_id,
118 const char *descriptor_cookie, time_t now,
119 uint8_t replica)
121 char service_id_binary[REND_SERVICE_ID_LEN];
122 char secret_id_part[DIGEST_LEN];
123 uint32_t time_period;
124 if (!service_id ||
125 strlen(service_id) != REND_SERVICE_ID_LEN_BASE32) {
126 log_warn(LD_REND, "Could not compute v2 descriptor ID: "
127 "Illegal service ID: %s", safe_str(service_id));
128 return -1;
130 if (replica >= REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS) {
131 log_warn(LD_REND, "Could not compute v2 descriptor ID: "
132 "Replica number out of range: %d", replica);
133 return -1;
135 /* Convert service ID to binary. */
136 if (base32_decode(service_id_binary, REND_SERVICE_ID_LEN,
137 service_id, REND_SERVICE_ID_LEN_BASE32) < 0) {
138 log_warn(LD_REND, "Could not compute v2 descriptor ID: "
139 "Illegal characters in service ID: %s",
140 safe_str(service_id));
141 return -1;
143 /* Calculate current time-period. */
144 time_period = get_time_period(now, 0, service_id_binary);
145 /* Calculate secret-id-part = h(time-period + replica). */
146 get_secret_id_part_bytes(secret_id_part, time_period, descriptor_cookie,
147 replica);
148 /* Calculate descriptor ID. */
149 rend_get_descriptor_id_bytes(desc_id_out, service_id_binary, secret_id_part);
150 return 0;
153 /** Encode the introduction points in <b>desc</b> and write the result to a
154 * newly allocated string pointed to by <b>encoded</b>. Return 0 for
155 * success, -1 otherwise. */
156 static int
157 rend_encode_v2_intro_points(char **encoded, rend_service_descriptor_t *desc)
159 size_t unenc_len;
160 char *unenc = NULL;
161 size_t unenc_written = 0;
162 int i;
163 int r = -1;
164 /* Assemble unencrypted list of introduction points. */
165 unenc_len = smartlist_len(desc->intro_nodes) * 1000; /* too long, but ok. */
166 unenc = tor_malloc_zero(unenc_len);
167 for (i = 0; i < smartlist_len(desc->intro_nodes); i++) {
168 char id_base32[REND_INTRO_POINT_ID_LEN_BASE32 + 1];
169 char *onion_key = NULL;
170 size_t onion_key_len;
171 crypto_pk_env_t *intro_key;
172 char *service_key = NULL;
173 char *address = NULL;
174 size_t service_key_len;
175 int res;
176 rend_intro_point_t *intro = smartlist_get(desc->intro_nodes, i);
177 /* Obtain extend info with introduction point details. */
178 extend_info_t *info = intro->extend_info;
179 /* Encode introduction point ID. */
180 base32_encode(id_base32, sizeof(id_base32),
181 info->identity_digest, DIGEST_LEN);
182 /* Encode onion key. */
183 if (crypto_pk_write_public_key_to_string(info->onion_key, &onion_key,
184 &onion_key_len) < 0) {
185 log_warn(LD_REND, "Could not write onion key.");
186 goto done;
188 /* Encode intro key. */
189 intro_key = intro->intro_key;
190 if (!intro_key ||
191 crypto_pk_write_public_key_to_string(intro_key, &service_key,
192 &service_key_len) < 0) {
193 log_warn(LD_REND, "Could not write intro key.");
194 tor_free(onion_key);
195 goto done;
197 /* Assemble everything for this introduction point. */
198 address = tor_dup_addr(&info->addr);
199 res = tor_snprintf(unenc + unenc_written, unenc_len - unenc_written,
200 "introduction-point %s\n"
201 "ip-address %s\n"
202 "onion-port %d\n"
203 "onion-key\n%s"
204 "service-key\n%s",
205 id_base32,
206 address,
207 info->port,
208 onion_key,
209 service_key);
210 tor_free(address);
211 tor_free(onion_key);
212 tor_free(service_key);
213 if (res < 0) {
214 log_warn(LD_REND, "Not enough space for writing introduction point "
215 "string.");
216 goto done;
218 /* Update total number of written bytes for unencrypted intro points. */
219 unenc_written += res;
221 /* Finalize unencrypted introduction points. */
222 if (unenc_len < unenc_written + 2) {
223 log_warn(LD_REND, "Not enough space for finalizing introduction point "
224 "string.");
225 goto done;
227 unenc[unenc_written++] = '\n';
228 unenc[unenc_written++] = 0;
229 *encoded = unenc;
230 r = 0;
231 done:
232 if (r<0)
233 tor_free(unenc);
234 return r;
237 /** Encrypt the encoded introduction points in <b>encoded</b> using
238 * authorization type 'basic' with <b>client_cookies</b> and write the
239 * result to a newly allocated string pointed to by <b>encrypted_out</b> of
240 * length <b>encrypted_len_out</b>. Return 0 for success, -1 otherwise. */
241 static int
242 rend_encrypt_v2_intro_points_basic(char **encrypted_out,
243 size_t *encrypted_len_out,
244 const char *encoded,
245 smartlist_t *client_cookies)
247 int r = -1, i, pos, enclen, client_blocks;
248 size_t len, client_entries_len;
249 char *enc = NULL, iv[CIPHER_IV_LEN], *client_part = NULL,
250 session_key[CIPHER_KEY_LEN];
251 smartlist_t *encrypted_session_keys = NULL;
252 crypto_digest_env_t *digest;
253 crypto_cipher_env_t *cipher;
254 tor_assert(encoded);
255 tor_assert(client_cookies && smartlist_len(client_cookies) > 0);
257 /* Generate session key. */
258 if (crypto_rand(session_key, CIPHER_KEY_LEN) < 0) {
259 log_warn(LD_REND, "Unable to generate random session key to encrypt "
260 "introduction point string.");
261 goto done;
264 /* Determine length of encrypted introduction points including session
265 * keys. */
266 client_blocks = 1 + ((smartlist_len(client_cookies) - 1) /
267 REND_BASIC_AUTH_CLIENT_MULTIPLE);
268 client_entries_len = client_blocks * REND_BASIC_AUTH_CLIENT_MULTIPLE *
269 REND_BASIC_AUTH_CLIENT_ENTRY_LEN;
270 len = 2 + client_entries_len + CIPHER_IV_LEN + strlen(encoded);
271 if (client_blocks >= 256) {
272 log_warn(LD_REND, "Too many clients in introduction point string.");
273 goto done;
275 enc = tor_malloc_zero(len);
276 enc[0] = 0x01; /* type of authorization. */
277 enc[1] = (uint8_t)client_blocks;
279 /* Encrypt with random session key. */
280 cipher = crypto_create_init_cipher(session_key, 1);
281 enclen = crypto_cipher_encrypt_with_iv(cipher,
282 enc + 2 + client_entries_len,
283 CIPHER_IV_LEN + strlen(encoded), encoded, strlen(encoded));
284 crypto_free_cipher_env(cipher);
285 if (enclen < 0) {
286 log_warn(LD_REND, "Could not encrypt introduction point string.");
287 goto done;
289 memcpy(iv, enc + 2 + client_entries_len, CIPHER_IV_LEN);
291 /* Encrypt session key for cookies, determine client IDs, and put both
292 * in a smartlist. */
293 encrypted_session_keys = smartlist_create();
294 SMARTLIST_FOREACH_BEGIN(client_cookies, const char *, cookie) {
295 client_part = tor_malloc_zero(REND_BASIC_AUTH_CLIENT_ENTRY_LEN);
296 /* Encrypt session key. */
297 cipher = crypto_create_init_cipher(cookie, 1);
298 if (crypto_cipher_encrypt(cipher, client_part +
299 REND_BASIC_AUTH_CLIENT_ID_LEN,
300 session_key, CIPHER_KEY_LEN) < 0) {
301 log_warn(LD_REND, "Could not encrypt session key for client.");
302 crypto_free_cipher_env(cipher);
303 tor_free(client_part);
304 goto done;
306 crypto_free_cipher_env(cipher);
308 /* Determine client ID. */
309 digest = crypto_new_digest_env();
310 crypto_digest_add_bytes(digest, cookie, REND_DESC_COOKIE_LEN);
311 crypto_digest_add_bytes(digest, iv, CIPHER_IV_LEN);
312 crypto_digest_get_digest(digest, client_part,
313 REND_BASIC_AUTH_CLIENT_ID_LEN);
314 crypto_free_digest_env(digest);
316 /* Put both together. */
317 smartlist_add(encrypted_session_keys, client_part);
318 } SMARTLIST_FOREACH_END(cookie);
320 /* Add some fake client IDs and encrypted session keys. */
321 for (i = (smartlist_len(client_cookies) - 1) %
322 REND_BASIC_AUTH_CLIENT_MULTIPLE;
323 i < REND_BASIC_AUTH_CLIENT_MULTIPLE - 1; i++) {
324 client_part = tor_malloc_zero(REND_BASIC_AUTH_CLIENT_ENTRY_LEN);
325 if (crypto_rand(client_part, REND_BASIC_AUTH_CLIENT_ENTRY_LEN) < 0) {
326 log_warn(LD_REND, "Unable to generate fake client entry.");
327 tor_free(client_part);
328 goto done;
330 smartlist_add(encrypted_session_keys, client_part);
332 /* Sort smartlist and put elements in result in order. */
333 smartlist_sort_digests(encrypted_session_keys);
334 pos = 2;
335 SMARTLIST_FOREACH(encrypted_session_keys, const char *, entry, {
336 memcpy(enc + pos, entry, REND_BASIC_AUTH_CLIENT_ENTRY_LEN);
337 pos += REND_BASIC_AUTH_CLIENT_ENTRY_LEN;
339 *encrypted_out = enc;
340 *encrypted_len_out = len;
341 enc = NULL; /* prevent free. */
342 r = 0;
343 done:
344 tor_free(enc);
345 if (encrypted_session_keys) {
346 SMARTLIST_FOREACH(encrypted_session_keys, char *, d, tor_free(d););
347 smartlist_free(encrypted_session_keys);
349 return r;
352 /** Encrypt the encoded introduction points in <b>encoded</b> using
353 * authorization type 'stealth' with <b>descriptor_cookie</b> of length
354 * REND_DESC_COOKIE_LEN and write the result to a newly allocated string
355 * pointed to by <b>encrypted_out</b> of length <b>encrypted_len_out</b>.
356 * Return 0 for success, -1 otherwise. */
357 static int
358 rend_encrypt_v2_intro_points_stealth(char **encrypted_out,
359 size_t *encrypted_len_out,
360 const char *encoded,
361 const char *descriptor_cookie)
363 int r = -1, enclen;
364 crypto_cipher_env_t *cipher;
365 char *enc;
366 tor_assert(encoded);
367 tor_assert(descriptor_cookie);
369 enc = tor_malloc_zero(1 + CIPHER_IV_LEN + strlen(encoded));
370 enc[0] = 0x02; /* Auth type */
371 cipher = crypto_create_init_cipher(descriptor_cookie, 1);
372 enclen = crypto_cipher_encrypt_with_iv(cipher, enc + 1,
373 CIPHER_IV_LEN+strlen(encoded),
374 encoded, strlen(encoded));
375 crypto_free_cipher_env(cipher);
376 if (enclen < 0) {
377 log_warn(LD_REND, "Could not encrypt introduction point string.");
378 goto done;
380 *encrypted_out = enc;
381 *encrypted_len_out = enclen;
382 enc = NULL; /* prevent free */
383 r = 0;
384 done:
385 tor_free(enc);
386 return r;
389 /** Attempt to parse the given <b>desc_str</b> and return true if this
390 * succeeds, false otherwise. */
391 static int
392 rend_desc_v2_is_parsable(rend_encoded_v2_service_descriptor_t *desc)
394 rend_service_descriptor_t *test_parsed = NULL;
395 char test_desc_id[DIGEST_LEN];
396 char *test_intro_content = NULL;
397 size_t test_intro_size;
398 size_t test_encoded_size;
399 const char *test_next;
400 int res = rend_parse_v2_service_descriptor(&test_parsed, test_desc_id,
401 &test_intro_content,
402 &test_intro_size,
403 &test_encoded_size,
404 &test_next, desc->desc_str);
405 if (test_parsed)
406 rend_service_descriptor_free(test_parsed);
407 tor_free(test_intro_content);
408 return (res >= 0);
411 /** Free the storage held by an encoded v2 service descriptor. */
412 void
413 rend_encoded_v2_service_descriptor_free(
414 rend_encoded_v2_service_descriptor_t *desc)
416 tor_free(desc->desc_str);
417 tor_free(desc);
420 /** Free the storage held by an introduction point info. */
421 void
422 rend_intro_point_free(rend_intro_point_t *intro)
424 if (intro->extend_info)
425 extend_info_free(intro->extend_info);
426 if (intro->intro_key)
427 crypto_free_pk_env(intro->intro_key);
428 tor_free(intro);
431 /** Encode a set of rend_encoded_v2_service_descriptor_t's for <b>desc</b>
432 * at time <b>now</b> using <b>service_key</b>, depending on
433 * <b>auth_type</b> a <b>descriptor_cookie</b> and a list of
434 * <b>client_cookies</b> (which are both <b>NULL</b> if no client
435 * authorization is performed), and <b>period</b> (e.g. 0 for the current
436 * period, 1 for the next period, etc.) and add them to the existing list
437 * <b>descs_out</b>; return the number of seconds that the descriptors will
438 * be found by clients, or -1 if the encoding was not successful. */
440 rend_encode_v2_descriptors(smartlist_t *descs_out,
441 rend_service_descriptor_t *desc, time_t now,
442 uint8_t period, rend_auth_type_t auth_type,
443 crypto_pk_env_t *client_key,
444 smartlist_t *client_cookies)
446 char service_id[DIGEST_LEN];
447 uint32_t time_period;
448 char *ipos_base64 = NULL, *ipos = NULL, *ipos_encrypted = NULL,
449 *descriptor_cookie = NULL;
450 size_t ipos_len = 0, ipos_encrypted_len = 0;
451 int k;
452 uint32_t seconds_valid;
453 crypto_pk_env_t *service_key = auth_type == REND_STEALTH_AUTH ?
454 client_key : desc->pk;
455 tor_assert(service_key);
456 if (auth_type == REND_STEALTH_AUTH) {
457 descriptor_cookie = smartlist_get(client_cookies, 0);
458 tor_assert(descriptor_cookie);
460 if (!desc) {
461 log_warn(LD_REND, "Could not encode v2 descriptor: No desc given.");
462 return -1;
464 /* Obtain service_id from public key. */
465 crypto_pk_get_digest(service_key, service_id);
466 /* Calculate current time-period. */
467 time_period = get_time_period(now, period, service_id);
468 /* Determine how many seconds the descriptor will be valid. */
469 seconds_valid = period * REND_TIME_PERIOD_V2_DESC_VALIDITY +
470 get_seconds_valid(now, service_id);
471 /* Assemble, possibly encrypt, and encode introduction points. */
472 if (smartlist_len(desc->intro_nodes) > 0) {
473 if (rend_encode_v2_intro_points(&ipos, desc) < 0) {
474 log_warn(LD_REND, "Encoding of introduction points did not succeed.");
475 return -1;
477 switch (auth_type) {
478 case REND_NO_AUTH:
479 ipos_len = strlen(ipos);
480 break;
481 case REND_BASIC_AUTH:
482 if (rend_encrypt_v2_intro_points_basic(&ipos_encrypted,
483 &ipos_encrypted_len, ipos,
484 client_cookies) < 0) {
485 log_warn(LD_REND, "Encrypting of introduction points did not "
486 "succeed.");
487 tor_free(ipos);
488 return -1;
490 tor_free(ipos);
491 ipos = ipos_encrypted;
492 ipos_len = ipos_encrypted_len;
493 break;
494 case REND_STEALTH_AUTH:
495 if (rend_encrypt_v2_intro_points_stealth(&ipos_encrypted,
496 &ipos_encrypted_len, ipos,
497 descriptor_cookie) < 0) {
498 log_warn(LD_REND, "Encrypting of introduction points did not "
499 "succeed.");
500 tor_free(ipos);
501 return -1;
503 tor_free(ipos);
504 ipos = ipos_encrypted;
505 ipos_len = ipos_encrypted_len;
506 break;
507 default:
508 log_warn(LD_REND|LD_BUG, "Unrecognized authorization type %d",
509 (int)auth_type);
510 tor_free(ipos);
511 return -1;
513 /* Base64-encode introduction points. */
514 ipos_base64 = tor_malloc_zero(ipos_len * 2);
515 if (base64_encode(ipos_base64, ipos_len * 2, ipos, ipos_len)<0) {
516 log_warn(LD_REND, "Could not encode introduction point string to "
517 "base64. length=%d", (int)ipos_len);
518 tor_free(ipos_base64);
519 tor_free(ipos);
520 return -1;
522 tor_free(ipos);
524 /* Encode REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS descriptors. */
525 for (k = 0; k < REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS; k++) {
526 char secret_id_part[DIGEST_LEN];
527 char secret_id_part_base32[REND_SECRET_ID_PART_LEN_BASE32 + 1];
528 char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
529 char *permanent_key = NULL;
530 size_t permanent_key_len;
531 char published[ISO_TIME_LEN+1];
532 int i;
533 char protocol_versions_string[16]; /* max len: "0,1,2,3,4,5,6,7\0" */
534 size_t protocol_versions_written;
535 size_t desc_len;
536 char *desc_str = NULL;
537 int result = 0;
538 size_t written = 0;
539 char desc_digest[DIGEST_LEN];
540 rend_encoded_v2_service_descriptor_t *enc =
541 tor_malloc_zero(sizeof(rend_encoded_v2_service_descriptor_t));
542 /* Calculate secret-id-part = h(time-period + cookie + replica). */
543 get_secret_id_part_bytes(secret_id_part, time_period, descriptor_cookie,
545 base32_encode(secret_id_part_base32, sizeof(secret_id_part_base32),
546 secret_id_part, DIGEST_LEN);
547 /* Calculate descriptor ID. */
548 rend_get_descriptor_id_bytes(enc->desc_id, service_id, secret_id_part);
549 base32_encode(desc_id_base32, sizeof(desc_id_base32),
550 enc->desc_id, DIGEST_LEN);
551 /* PEM-encode the public key */
552 if (crypto_pk_write_public_key_to_string(service_key, &permanent_key,
553 &permanent_key_len) < 0) {
554 log_warn(LD_BUG, "Could not write public key to string.");
555 rend_encoded_v2_service_descriptor_free(enc);
556 goto err;
558 /* Encode timestamp. */
559 format_iso_time(published, desc->timestamp);
560 /* Write protocol-versions bitmask to comma-separated value string. */
561 protocol_versions_written = 0;
562 for (i = 0; i < 8; i++) {
563 if (desc->protocols & 1 << i) {
564 tor_snprintf(protocol_versions_string + protocol_versions_written,
565 16 - protocol_versions_written, "%d,", i);
566 protocol_versions_written += 2;
569 if (protocol_versions_written)
570 protocol_versions_string[protocol_versions_written - 1] = '\0';
571 else
572 protocol_versions_string[0]= '\0';
573 /* Assemble complete descriptor. */
574 desc_len = 2000 + smartlist_len(desc->intro_nodes) * 1000; /* far too long,
575 but okay.*/
576 enc->desc_str = desc_str = tor_malloc_zero(desc_len);
577 result = tor_snprintf(desc_str, desc_len,
578 "rendezvous-service-descriptor %s\n"
579 "version 2\n"
580 "permanent-key\n%s"
581 "secret-id-part %s\n"
582 "publication-time %s\n"
583 "protocol-versions %s\n",
584 desc_id_base32,
585 permanent_key,
586 secret_id_part_base32,
587 published,
588 protocol_versions_string);
589 tor_free(permanent_key);
590 if (result < 0) {
591 log_warn(LD_BUG, "Descriptor ran out of room.");
592 rend_encoded_v2_service_descriptor_free(enc);
593 goto err;
595 written = result;
596 /* Add introduction points. */
597 if (ipos_base64) {
598 result = tor_snprintf(desc_str + written, desc_len - written,
599 "introduction-points\n"
600 "-----BEGIN MESSAGE-----\n%s"
601 "-----END MESSAGE-----\n",
602 ipos_base64);
603 if (result < 0) {
604 log_warn(LD_BUG, "could not write introduction points.");
605 rend_encoded_v2_service_descriptor_free(enc);
606 goto err;
608 written += result;
610 /* Add signature. */
611 strlcpy(desc_str + written, "signature\n", desc_len - written);
612 written += strlen(desc_str + written);
613 if (crypto_digest(desc_digest, desc_str, written) < 0) {
614 log_warn(LD_BUG, "could not create digest.");
615 rend_encoded_v2_service_descriptor_free(enc);
616 goto err;
618 if (router_append_dirobj_signature(desc_str + written,
619 desc_len - written,
620 desc_digest, service_key) < 0) {
621 log_warn(LD_BUG, "Couldn't sign desc.");
622 rend_encoded_v2_service_descriptor_free(enc);
623 goto err;
625 written += strlen(desc_str+written);
626 if (written+2 > desc_len) {
627 log_warn(LD_BUG, "Could not finish desc.");
628 rend_encoded_v2_service_descriptor_free(enc);
629 goto err;
631 desc_str[written++] = '\n';
632 desc_str[written++] = 0;
633 /* Check if we can parse our own descriptor. */
634 if (!rend_desc_v2_is_parsable(enc)) {
635 log_warn(LD_BUG, "Could not parse my own descriptor: %s", desc_str);
636 rend_encoded_v2_service_descriptor_free(enc);
637 goto err;
639 smartlist_add(descs_out, enc);
642 log_info(LD_REND, "Successfully encoded a v2 descriptor and "
643 "confirmed that it is parsable.");
644 goto done;
646 err:
647 SMARTLIST_FOREACH(descs_out, rend_encoded_v2_service_descriptor_t *, d,
648 rend_encoded_v2_service_descriptor_free(d););
649 smartlist_clear(descs_out);
650 seconds_valid = -1;
652 done:
653 tor_free(ipos_base64);
654 return seconds_valid;
657 /** Encode a service descriptor for <b>desc</b>, and sign it with
658 * <b>key</b>. Store the descriptor in *<b>str_out</b>, and set
659 * *<b>len_out</b> to its length.
662 rend_encode_service_descriptor(rend_service_descriptor_t *desc,
663 crypto_pk_env_t *key,
664 char **str_out, size_t *len_out)
666 char *cp;
667 char *end;
668 int i, r;
669 size_t asn1len;
670 size_t buflen =
671 PK_BYTES*2*(smartlist_len(desc->intro_nodes)+2);/*Too long, but ok*/
672 cp = *str_out = tor_malloc(buflen);
673 end = cp + PK_BYTES*2*(smartlist_len(desc->intro_nodes)+1);
674 r = crypto_pk_asn1_encode(desc->pk, cp+2, end-(cp+2));
675 if (r < 0) {
676 tor_free(*str_out);
677 return -1;
679 asn1len = r;
680 set_uint16(cp, htons((uint16_t)asn1len));
681 cp += 2+asn1len;
682 set_uint32(cp, htonl((uint32_t)desc->timestamp));
683 cp += 4;
684 set_uint16(cp, htons((uint16_t)smartlist_len(desc->intro_nodes)));
685 cp += 2;
686 for (i=0; i < smartlist_len(desc->intro_nodes); ++i) {
687 rend_intro_point_t *intro = smartlist_get(desc->intro_nodes, i);
688 char ipoint[HEX_DIGEST_LEN+2];
689 ipoint[0] = '$';
690 base16_encode(ipoint+1, HEX_DIGEST_LEN+1,
691 intro->extend_info->identity_digest,
692 DIGEST_LEN);
693 tor_assert(buflen + *str_out >= cp); /* XXX021 This assert is a kludge. */
694 strlcpy(cp, ipoint, buflen-(cp-*str_out));
695 cp += strlen(ipoint)+1;
697 note_crypto_pk_op(REND_SERVER);
698 r = crypto_pk_private_sign_digest(key, cp, *str_out, cp-*str_out);
699 if (r<0) {
700 tor_free(*str_out);
701 return -1;
703 cp += r;
704 *len_out = (size_t)(cp-*str_out);
705 return 0;
708 /** Parse a service descriptor at <b>str</b> (<b>len</b> bytes). On
709 * success, return a newly alloced service_descriptor_t. On failure,
710 * return NULL.
712 rend_service_descriptor_t *
713 rend_parse_service_descriptor(const char *str, size_t len)
715 rend_service_descriptor_t *result = NULL;
716 int i, n_intro_points;
717 size_t keylen, asn1len;
718 const char *end, *cp, *eos;
719 rend_intro_point_t *intro;
721 result = tor_malloc_zero(sizeof(rend_service_descriptor_t));
722 cp = str;
723 end = str+len;
724 if (end-cp<2) goto truncated;
725 result->version = 0;
726 if (end-cp < 2) goto truncated;
727 asn1len = ntohs(get_uint16(cp));
728 cp += 2;
729 if ((size_t)(end-cp) < asn1len) goto truncated;
730 result->pk = crypto_pk_asn1_decode(cp, asn1len);
731 if (!result->pk) goto truncated;
732 cp += asn1len;
733 if (end-cp < 4) goto truncated;
734 result->timestamp = (time_t) ntohl(get_uint32(cp));
735 cp += 4;
736 result->protocols = 1<<2; /* always use intro format 2 */
737 if (end-cp < 2) goto truncated;
738 n_intro_points = ntohs(get_uint16(cp));
739 cp += 2;
741 result->intro_nodes = smartlist_create();
742 for (i=0;i<n_intro_points;++i) {
743 if (end-cp < 2) goto truncated;
744 eos = (const char *)memchr(cp,'\0',end-cp);
745 if (!eos) goto truncated;
746 /* Write nickname to extend info, but postpone the lookup whether
747 * we know that router. It's not part of the parsing process. */
748 intro = tor_malloc_zero(sizeof(rend_intro_point_t));
749 intro->extend_info = tor_malloc_zero(sizeof(extend_info_t));
750 strlcpy(intro->extend_info->nickname, cp,
751 sizeof(intro->extend_info->nickname));
752 smartlist_add(result->intro_nodes, intro);
753 cp = eos+1;
755 keylen = crypto_pk_keysize(result->pk);
756 tor_assert(end-cp >= 0);
757 if ((size_t)(end-cp) < keylen) goto truncated;
758 if ((size_t)(end-cp) > keylen) {
759 log_warn(LD_PROTOCOL,
760 "Signature is %d bytes too long on service descriptor.",
761 (int)((size_t)(end-cp) - keylen));
762 goto error;
764 note_crypto_pk_op(REND_CLIENT);
765 if (crypto_pk_public_checksig_digest(result->pk,
766 (char*)str,cp-str, /* data */
767 (char*)cp,end-cp /* signature*/
768 )<0) {
769 log_warn(LD_PROTOCOL, "Bad signature on service descriptor.");
770 goto error;
773 return result;
774 truncated:
775 log_warn(LD_PROTOCOL, "Truncated service descriptor.");
776 error:
777 rend_service_descriptor_free(result);
778 return NULL;
781 /** Sets <b>out</b> to the first 10 bytes of the digest of <b>pk</b>,
782 * base32 encoded. NUL-terminates out. (We use this string to
783 * identify services in directory requests and .onion URLs.)
786 rend_get_service_id(crypto_pk_env_t *pk, char *out)
788 char buf[DIGEST_LEN];
789 tor_assert(pk);
790 if (crypto_pk_get_digest(pk, buf) < 0)
791 return -1;
792 base32_encode(out, REND_SERVICE_ID_LEN_BASE32+1, buf, REND_SERVICE_ID_LEN);
793 return 0;
796 /* ==== Rendezvous service descriptor cache. */
798 /** How old do we let hidden service descriptors get before discarding
799 * them as too old? */
800 #define REND_CACHE_MAX_AGE (2*24*60*60)
801 /** How wrong do we assume our clock may be when checking whether hidden
802 * services are too old or too new? */
803 #define REND_CACHE_MAX_SKEW (24*60*60)
805 /** Map from service id (as generated by rend_get_service_id) to
806 * rend_cache_entry_t. */
807 static strmap_t *rend_cache = NULL;
809 /** Map from descriptor id to rend_cache_entry_t; only for hidden service
810 * directories. */
811 static digestmap_t *rend_cache_v2_dir = NULL;
813 /** Initializes the service descriptor cache.
815 void
816 rend_cache_init(void)
818 rend_cache = strmap_new();
819 rend_cache_v2_dir = digestmap_new();
822 /** Helper: free storage held by a single service descriptor cache entry. */
823 static void
824 _rend_cache_entry_free(void *p)
826 rend_cache_entry_t *e = p;
827 rend_service_descriptor_free(e->parsed);
828 tor_free(e->desc);
829 tor_free(e);
832 /** Free all storage held by the service descriptor cache. */
833 void
834 rend_cache_free_all(void)
836 strmap_free(rend_cache, _rend_cache_entry_free);
837 digestmap_free(rend_cache_v2_dir, _rend_cache_entry_free);
838 rend_cache = NULL;
839 rend_cache_v2_dir = NULL;
842 /** Removes all old entries from the service descriptor cache.
844 void
845 rend_cache_clean(void)
847 strmap_iter_t *iter;
848 const char *key;
849 void *val;
850 rend_cache_entry_t *ent;
851 time_t cutoff;
852 cutoff = time(NULL) - REND_CACHE_MAX_AGE - REND_CACHE_MAX_SKEW;
853 for (iter = strmap_iter_init(rend_cache); !strmap_iter_done(iter); ) {
854 strmap_iter_get(iter, &key, &val);
855 ent = (rend_cache_entry_t*)val;
856 if (ent->parsed->timestamp < cutoff) {
857 iter = strmap_iter_next_rmv(rend_cache, iter);
858 _rend_cache_entry_free(ent);
859 } else {
860 iter = strmap_iter_next(rend_cache, iter);
865 /** Remove all old v2 descriptors and those for which this hidden service
866 * directory is not responsible for any more. */
867 void
868 rend_cache_clean_v2_descs_as_dir(void)
870 digestmap_iter_t *iter;
871 time_t cutoff = time(NULL) - REND_CACHE_MAX_AGE - REND_CACHE_MAX_SKEW;
872 for (iter = digestmap_iter_init(rend_cache_v2_dir);
873 !digestmap_iter_done(iter); ) {
874 const char *key;
875 void *val;
876 rend_cache_entry_t *ent;
877 digestmap_iter_get(iter, &key, &val);
878 ent = val;
879 if (ent->parsed->timestamp < cutoff ||
880 !hid_serv_responsible_for_desc_id(key)) {
881 char key_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
882 base32_encode(key_base32, sizeof(key_base32), key, DIGEST_LEN);
883 log_info(LD_REND, "Removing descriptor with ID '%s' from cache",
884 safe_str(key_base32));
885 iter = digestmap_iter_next_rmv(rend_cache_v2_dir, iter);
886 _rend_cache_entry_free(ent);
887 } else {
888 iter = digestmap_iter_next(rend_cache_v2_dir, iter);
893 /** Determines whether <b>a</b> is in the interval of <b>b</b> (excluded) and
894 * <b>c</b> (included) in a circular digest ring; returns 1 if this is the
895 * case, and 0 otherwise.
898 rend_id_is_in_interval(const char *a, const char *b, const char *c)
900 int a_b, b_c, c_a;
901 tor_assert(a);
902 tor_assert(b);
903 tor_assert(c);
905 /* There are five cases in which a is outside the interval ]b,c]: */
906 a_b = memcmp(a,b,DIGEST_LEN);
907 if (a_b == 0)
908 return 0; /* 1. a == b (b is excluded) */
909 b_c = memcmp(b,c,DIGEST_LEN);
910 if (b_c == 0)
911 return 0; /* 2. b == c (interval is empty) */
912 else if (a_b <= 0 && b_c < 0)
913 return 0; /* 3. a b c */
914 c_a = memcmp(c,a,DIGEST_LEN);
915 if (c_a < 0 && a_b <= 0)
916 return 0; /* 4. c a b */
917 else if (b_c < 0 && c_a < 0)
918 return 0; /* 5. b c a */
920 /* In the other cases (a c b; b a c; c b a), a is inside the interval. */
921 return 1;
924 /** Return true iff <b>query</b> is a syntactically valid service ID (as
925 * generated by rend_get_service_id). */
927 rend_valid_service_id(const char *query)
929 if (strlen(query) != REND_SERVICE_ID_LEN_BASE32)
930 return 0;
932 if (strspn(query, BASE32_CHARS) != REND_SERVICE_ID_LEN_BASE32)
933 return 0;
935 return 1;
938 /** If we have a cached rend_cache_entry_t for the service ID <b>query</b>
939 * with <b>version</b>, set *<b>e</b> to that entry and return 1.
940 * Else return 0. If <b>version</b> is nonnegative, only return an entry
941 * in that descriptor format version. Otherwise (if <b>version</b> is
942 * negative), return the most recent format we have.
945 rend_cache_lookup_entry(const char *query, int version, rend_cache_entry_t **e)
947 char key[REND_SERVICE_ID_LEN_BASE32+2]; /* <version><query>\0 */
948 tor_assert(rend_cache);
949 if (!rend_valid_service_id(query))
950 return -1;
951 *e = NULL;
952 if (version != 0) {
953 tor_snprintf(key, sizeof(key), "2%s", query);
954 *e = strmap_get_lc(rend_cache, key);
956 if (!*e && version != 2) {
957 tor_snprintf(key, sizeof(key), "0%s", query);
958 *e = strmap_get_lc(rend_cache, key);
960 if (!*e)
961 return 0;
962 return 1;
965 /** <b>query</b> is a base-32'ed service id. If it's malformed, return -1.
966 * Else look it up.
967 * - If it is found, point *desc to it, and write its length into
968 * *desc_len, and return 1.
969 * - If it is not found, return 0.
970 * Note: calls to rend_cache_clean or rend_cache_store may invalidate
971 * *desc.
974 rend_cache_lookup_desc(const char *query, int version, const char **desc,
975 size_t *desc_len)
977 rend_cache_entry_t *e;
978 int r;
979 r = rend_cache_lookup_entry(query,version,&e);
980 if (r <= 0) return r;
981 *desc = e->desc;
982 *desc_len = e->len;
983 return 1;
986 /** Lookup the v2 service descriptor with base32-encoded <b>desc_id</b> and
987 * copy the pointer to it to *<b>desc</b>. Return 1 on success, 0 on
988 * well-formed-but-not-found, and -1 on failure.
991 rend_cache_lookup_v2_desc_as_dir(const char *desc_id, const char **desc)
993 rend_cache_entry_t *e;
994 char desc_id_digest[DIGEST_LEN];
995 tor_assert(rend_cache_v2_dir);
996 if (base32_decode(desc_id_digest, DIGEST_LEN,
997 desc_id, REND_DESC_ID_V2_LEN_BASE32) < 0) {
998 log_warn(LD_REND, "Descriptor ID contains illegal characters: %s",
999 safe_str(desc_id));
1000 return -1;
1002 /* Determine if we are responsible. */
1003 if (hid_serv_responsible_for_desc_id(desc_id_digest) < 0) {
1004 log_info(LD_REND, "Could not answer fetch request for v2 descriptor; "
1005 "either we are no hidden service directory, or we are "
1006 "not responsible for the requested ID.");
1007 return -1;
1009 /* Lookup descriptor and return. */
1010 e = digestmap_get(rend_cache_v2_dir, desc_id_digest);
1011 if (e) {
1012 *desc = e->desc;
1013 return 1;
1015 return 0;
1018 /** Parse *desc, calculate its service id, and store it in the cache.
1019 * If we have a newer v0 descriptor with the same ID, ignore this one.
1020 * If we have an older descriptor with the same ID, replace it.
1021 * If we are acting as client due to the published flag and have any v2
1022 * descriptor with the same ID, reject this one in order to not get
1023 * confused with having both versions for the same service.
1024 * Return -1 if it's malformed or otherwise rejected; return 0 if
1025 * it's the same or older than one we've already got; return 1 if
1026 * it's novel. The published flag tells us if we store the descriptor
1027 * in our role as directory (1) or if we cache it as client (0).
1030 rend_cache_store(const char *desc, size_t desc_len, int published)
1032 rend_cache_entry_t *e;
1033 rend_service_descriptor_t *parsed;
1034 char query[REND_SERVICE_ID_LEN_BASE32+1];
1035 char key[REND_SERVICE_ID_LEN_BASE32+2]; /* 0<query>\0 */
1036 time_t now;
1037 or_options_t *options = get_options();
1038 tor_assert(rend_cache);
1039 parsed = rend_parse_service_descriptor(desc,desc_len);
1040 if (!parsed) {
1041 log_warn(LD_PROTOCOL,"Couldn't parse service descriptor.");
1042 return -1;
1044 if (rend_get_service_id(parsed->pk, query)<0) {
1045 log_warn(LD_BUG,"Couldn't compute service ID.");
1046 rend_service_descriptor_free(parsed);
1047 return -1;
1049 now = time(NULL);
1050 if (parsed->timestamp < now-REND_CACHE_MAX_AGE-REND_CACHE_MAX_SKEW) {
1051 log_fn(LOG_PROTOCOL_WARN, LD_REND,
1052 "Service descriptor %s is too old.", safe_str(query));
1053 rend_service_descriptor_free(parsed);
1054 return -1;
1056 if (parsed->timestamp > now+REND_CACHE_MAX_SKEW) {
1057 log_fn(LOG_PROTOCOL_WARN, LD_REND,
1058 "Service descriptor %s is too far in the future.", safe_str(query));
1059 rend_service_descriptor_free(parsed);
1060 return -1;
1062 /* Do we have a v2 descriptor and fetched this descriptor as a client? */
1063 tor_snprintf(key, sizeof(key), "2%s", query);
1064 if (!published && strmap_get_lc(rend_cache, key)) {
1065 log_info(LD_REND, "We already have a v2 descriptor for service %s.",
1066 safe_str(query));
1067 rend_service_descriptor_free(parsed);
1068 return -1;
1070 /* report novel publication to statistics */
1071 if (published && options->HSAuthorityRecordStats) {
1072 hs_usage_note_publish_total(query, now);
1074 tor_snprintf(key, sizeof(key), "0%s", query);
1075 e = (rend_cache_entry_t*) strmap_get_lc(rend_cache, key);
1076 if (e && e->parsed->timestamp > parsed->timestamp) {
1077 log_info(LD_REND,"We already have a newer service descriptor %s with the "
1078 "same ID and version.", safe_str(query));
1079 rend_service_descriptor_free(parsed);
1080 return 0;
1082 if (e && e->len == desc_len && !memcmp(desc,e->desc,desc_len)) {
1083 log_info(LD_REND,"We already have this service descriptor %s.",
1084 safe_str(query));
1085 e->received = time(NULL);
1086 rend_service_descriptor_free(parsed);
1087 return 0;
1089 if (!e) {
1090 e = tor_malloc_zero(sizeof(rend_cache_entry_t));
1091 strmap_set_lc(rend_cache, key, e);
1092 /* report novel publication to statistics */
1093 if (published && options->HSAuthorityRecordStats) {
1094 hs_usage_note_publish_novel(query, now);
1096 } else {
1097 rend_service_descriptor_free(e->parsed);
1098 tor_free(e->desc);
1100 e->received = time(NULL);
1101 e->parsed = parsed;
1102 e->len = desc_len;
1103 e->desc = tor_malloc(desc_len);
1104 memcpy(e->desc, desc, desc_len);
1106 log_debug(LD_REND,"Successfully stored rend desc '%s', len %d.",
1107 safe_str(query), (int)desc_len);
1108 return 1;
1111 /** Parse the v2 service descriptor(s) in <b>desc</b> and store it/them to the
1112 * local rend cache. Don't attempt to decrypt the included list of introduction
1113 * points (as we don't have a descriptor cookie for it).
1115 * If we have a newer descriptor with the same ID, ignore this one.
1116 * If we have an older descriptor with the same ID, replace it.
1117 * Return -2 if we are not acting as hidden service directory;
1118 * return -1 if the descriptor(s) were not parsable; return 0 if all
1119 * descriptors are the same or older than those we've already got;
1120 * return a positive number for the number of novel stored descriptors.
1123 rend_cache_store_v2_desc_as_dir(const char *desc)
1125 rend_service_descriptor_t *parsed;
1126 char desc_id[DIGEST_LEN];
1127 char *intro_content;
1128 size_t intro_size;
1129 size_t encoded_size;
1130 char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
1131 int number_parsed = 0, number_stored = 0;
1132 const char *current_desc = desc;
1133 const char *next_desc;
1134 rend_cache_entry_t *e;
1135 time_t now = time(NULL);
1136 tor_assert(rend_cache_v2_dir);
1137 tor_assert(desc);
1138 if (!hid_serv_acting_as_directory()) {
1139 /* Cannot store descs, because we are (currently) not acting as
1140 * hidden service directory. */
1141 log_info(LD_REND, "Cannot store descs: Not acting as hs dir");
1142 return -2;
1144 while (rend_parse_v2_service_descriptor(&parsed, desc_id, &intro_content,
1145 &intro_size, &encoded_size,
1146 &next_desc, current_desc) >= 0) {
1147 number_parsed++;
1148 /* We don't care about the introduction points. */
1149 tor_free(intro_content);
1150 /* For pretty log statements. */
1151 base32_encode(desc_id_base32, sizeof(desc_id_base32),
1152 desc_id, DIGEST_LEN);
1153 /* Is desc ID in the range that we are (directly or indirectly) responsible
1154 * for? */
1155 if (!hid_serv_responsible_for_desc_id(desc_id)) {
1156 log_info(LD_REND, "Service descriptor with desc ID %s is not in "
1157 "interval that we are responsible for.",
1158 safe_str(desc_id_base32));
1159 goto skip;
1161 /* Is descriptor too old? */
1162 if (parsed->timestamp < now - REND_CACHE_MAX_AGE-REND_CACHE_MAX_SKEW) {
1163 log_info(LD_REND, "Service descriptor with desc ID %s is too old.",
1164 safe_str(desc_id_base32));
1165 goto skip;
1167 /* Is descriptor too far in the future? */
1168 if (parsed->timestamp > now + REND_CACHE_MAX_SKEW) {
1169 log_info(LD_REND, "Service descriptor with desc ID %s is too far in the "
1170 "future.",
1171 safe_str(desc_id_base32));
1172 goto skip;
1174 /* Do we already have a newer descriptor? */
1175 e = digestmap_get(rend_cache_v2_dir, desc_id);
1176 if (e && e->parsed->timestamp > parsed->timestamp) {
1177 log_info(LD_REND, "We already have a newer service descriptor with the "
1178 "same desc ID %s and version.",
1179 safe_str(desc_id_base32));
1180 goto skip;
1182 /* Do we already have this descriptor? */
1183 if (e && !strcmp(desc, e->desc)) {
1184 log_info(LD_REND, "We already have this service descriptor with desc "
1185 "ID %s.", safe_str(desc_id_base32));
1186 e->received = time(NULL);
1187 goto skip;
1189 /* Store received descriptor. */
1190 if (!e) {
1191 e = tor_malloc_zero(sizeof(rend_cache_entry_t));
1192 digestmap_set(rend_cache_v2_dir, desc_id, e);
1193 } else {
1194 rend_service_descriptor_free(e->parsed);
1195 tor_free(e->desc);
1197 e->received = time(NULL);
1198 e->parsed = parsed;
1199 e->desc = tor_strndup(current_desc, encoded_size);
1200 e->len = encoded_size;
1201 log_info(LD_REND, "Successfully stored service descriptor with desc ID "
1202 "'%s' and len %d.",
1203 safe_str(desc_id_base32), (int)encoded_size);
1204 number_stored++;
1205 goto advance;
1206 skip:
1207 rend_service_descriptor_free(parsed);
1208 advance:
1209 /* advance to next descriptor, if available. */
1210 current_desc = next_desc;
1211 /* check if there is a next descriptor. */
1212 if (!current_desc ||
1213 strcmpstart(current_desc, "rendezvous-service-descriptor "))
1214 break;
1216 if (!number_parsed) {
1217 log_info(LD_REND, "Could not parse any descriptor.");
1218 return -1;
1220 log_info(LD_REND, "Parsed %d and added %d descriptor%s.",
1221 number_parsed, number_stored, number_stored != 1 ? "s" : "");
1222 return number_stored;
1225 /** Parse the v2 service descriptor in <b>desc</b>, decrypt the included list
1226 * of introduction points with <b>descriptor_cookie</b> (which may also be
1227 * <b>NULL</b> if decryption is not necessary), and store the descriptor to
1228 * the local cache under its version and service id.
1230 * If we have a newer v2 descriptor with the same ID, ignore this one.
1231 * If we have an older descriptor with the same ID, replace it.
1232 * If we have any v0 descriptor with the same ID, reject this one in order
1233 * to not get confused with having both versions for the same service.
1234 * Return -2 if it's malformed or otherwise rejected; return -1 if we
1235 * already have a v0 descriptor here; return 0 if it's the same or older
1236 * than one we've already got; return 1 if it's novel.
1239 rend_cache_store_v2_desc_as_client(const char *desc,
1240 const char *descriptor_cookie)
1242 /*XXXX this seems to have a bit of duplicate code with
1243 * rend_cache_store_v2_desc_as_dir(). Fix that. */
1244 /* Though having similar elements, both functions were separated on
1245 * purpose:
1246 * - dirs don't care about encoded/encrypted introduction points, clients
1247 * do.
1248 * - dirs store descriptors in a separate cache by descriptor ID, whereas
1249 * clients store them by service ID; both caches are different data
1250 * structures and have different access methods.
1251 * - dirs store a descriptor only if they are responsible for its ID,
1252 * clients do so in every way (because they have requested it before).
1253 * - dirs can process multiple concatenated descriptors which is required
1254 * for replication, whereas clients only accept a single descriptor.
1255 * Thus, combining both methods would result in a lot of if statements
1256 * which probably would not improve, but worsen code readability. -KL */
1257 rend_service_descriptor_t *parsed = NULL;
1258 char desc_id[DIGEST_LEN];
1259 char *intro_content = NULL;
1260 size_t intro_size;
1261 size_t encoded_size;
1262 const char *next_desc;
1263 time_t now = time(NULL);
1264 char key[REND_SERVICE_ID_LEN_BASE32+2];
1265 char service_id[REND_SERVICE_ID_LEN_BASE32+1];
1266 rend_cache_entry_t *e;
1267 tor_assert(rend_cache);
1268 tor_assert(desc);
1269 (void) descriptor_cookie; /* We don't use it, yet. */
1270 /* Parse the descriptor. */
1271 if (rend_parse_v2_service_descriptor(&parsed, desc_id, &intro_content,
1272 &intro_size, &encoded_size,
1273 &next_desc, desc) < 0) {
1274 if (parsed) rend_service_descriptor_free(parsed);
1275 tor_free(intro_content);
1276 log_warn(LD_REND, "Could not parse descriptor.");
1277 return -2;
1279 /* Compute service ID from public key. */
1280 if (rend_get_service_id(parsed->pk, service_id)<0) {
1281 log_warn(LD_REND, "Couldn't compute service ID.");
1282 rend_service_descriptor_free(parsed);
1283 tor_free(intro_content);
1284 return -2;
1286 /* Decode/decrypt introduction points. */
1287 if (intro_content) {
1288 if (rend_parse_introduction_points(parsed, intro_content,
1289 intro_size) < 0) {
1290 log_warn(LD_PROTOCOL,"Couldn't decode/decrypt introduction points.");
1291 rend_service_descriptor_free(parsed);
1292 tor_free(intro_content);
1293 return -2;
1295 } else {
1296 parsed->intro_nodes = smartlist_create();
1298 /* We don't need the encoded/encrypted introduction points any longer. */
1299 tor_free(intro_content);
1300 /* Is descriptor too old? */
1301 if (parsed->timestamp < now - REND_CACHE_MAX_AGE-REND_CACHE_MAX_SKEW) {
1302 log_warn(LD_REND, "Service descriptor with service ID %s is too old.",
1303 safe_str(service_id));
1304 rend_service_descriptor_free(parsed);
1305 return -2;
1307 /* Is descriptor too far in the future? */
1308 if (parsed->timestamp > now + REND_CACHE_MAX_SKEW) {
1309 log_warn(LD_REND, "Service descriptor with service ID %s is too far in "
1310 "the future.", safe_str(service_id));
1311 rend_service_descriptor_free(parsed);
1312 return -2;
1314 /* Do we have a v0 descriptor? */
1315 tor_snprintf(key, sizeof(key), "0%s", service_id);
1316 if (strmap_get_lc(rend_cache, key)) {
1317 log_info(LD_REND, "We already have a v0 descriptor for service ID %s.",
1318 safe_str(service_id));
1319 return -1;
1321 /* Do we already have a newer descriptor? */
1322 tor_snprintf(key, sizeof(key), "2%s", service_id);
1323 e = (rend_cache_entry_t*) strmap_get_lc(rend_cache, key);
1324 if (e && e->parsed->timestamp > parsed->timestamp) {
1325 log_info(LD_REND, "We already have a newer service descriptor for "
1326 "service ID %s with the same desc ID and version.",
1327 safe_str(service_id));
1328 rend_service_descriptor_free(parsed);
1329 return 0;
1331 /* Do we already have this descriptor? */
1332 if (e && !strcmp(desc, e->desc)) {
1333 log_info(LD_REND,"We already have this service descriptor %s.",
1334 safe_str(service_id));
1335 e->received = time(NULL);
1336 rend_service_descriptor_free(parsed);
1337 return 0;
1339 if (!e) {
1340 e = tor_malloc_zero(sizeof(rend_cache_entry_t));
1341 strmap_set_lc(rend_cache, key, e);
1342 } else {
1343 rend_service_descriptor_free(e->parsed);
1344 tor_free(e->desc);
1346 e->received = time(NULL);
1347 e->parsed = parsed;
1348 e->desc = tor_malloc_zero(encoded_size + 1);
1349 strlcpy(e->desc, desc, encoded_size + 1);
1350 e->len = encoded_size;
1351 log_debug(LD_REND,"Successfully stored rend desc '%s', len %d.",
1352 safe_str(service_id), (int)encoded_size);
1353 return 1;
1356 /** Called when we get a rendezvous-related relay cell on circuit
1357 * <b>circ</b>. Dispatch on rendezvous relay command. */
1358 void
1359 rend_process_relay_cell(circuit_t *circ, int command, size_t length,
1360 const char *payload)
1362 or_circuit_t *or_circ = NULL;
1363 origin_circuit_t *origin_circ = NULL;
1364 int r = -2;
1365 if (CIRCUIT_IS_ORIGIN(circ))
1366 origin_circ = TO_ORIGIN_CIRCUIT(circ);
1367 else
1368 or_circ = TO_OR_CIRCUIT(circ);
1370 switch (command) {
1371 case RELAY_COMMAND_ESTABLISH_INTRO:
1372 if (or_circ)
1373 r = rend_mid_establish_intro(or_circ,payload,length);
1374 break;
1375 case RELAY_COMMAND_ESTABLISH_RENDEZVOUS:
1376 if (or_circ)
1377 r = rend_mid_establish_rendezvous(or_circ,payload,length);
1378 break;
1379 case RELAY_COMMAND_INTRODUCE1:
1380 if (or_circ)
1381 r = rend_mid_introduce(or_circ,payload,length);
1382 break;
1383 case RELAY_COMMAND_INTRODUCE2:
1384 if (origin_circ)
1385 r = rend_service_introduce(origin_circ,payload,length);
1386 break;
1387 case RELAY_COMMAND_INTRODUCE_ACK:
1388 if (origin_circ)
1389 r = rend_client_introduction_acked(origin_circ,payload,length);
1390 break;
1391 case RELAY_COMMAND_RENDEZVOUS1:
1392 if (or_circ)
1393 r = rend_mid_rendezvous(or_circ,payload,length);
1394 break;
1395 case RELAY_COMMAND_RENDEZVOUS2:
1396 if (origin_circ)
1397 r = rend_client_receive_rendezvous(origin_circ,payload,length);
1398 break;
1399 case RELAY_COMMAND_INTRO_ESTABLISHED:
1400 if (origin_circ)
1401 r = rend_service_intro_established(origin_circ,payload,length);
1402 break;
1403 case RELAY_COMMAND_RENDEZVOUS_ESTABLISHED:
1404 if (origin_circ)
1405 r = rend_client_rendezvous_acked(origin_circ,payload,length);
1406 break;
1407 default:
1408 tor_fragile_assert();
1411 if (r == -2)
1412 log_info(LD_PROTOCOL, "Dropping cell (type %d) for wrong circuit type.",
1413 command);
1416 /** Return the number of entries in our rendezvous descriptor cache. */
1418 rend_cache_size(void)
1420 return strmap_size(rend_cache);