Export variables and functions for CC unit tests.
[tor.git] / src / test / test_hs_descriptor.c
blob89815f48580e35af14e887c086f674764d9d8e34
1 /* Copyright (c) 2016-2021, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 /**
5 * \file test_hs_descriptor.c
6 * \brief Test hidden service descriptor encoding and decoding.
7 */
9 #define HS_DESCRIPTOR_PRIVATE
10 #define TOR_CONGESTION_CONTROL_COMMON_PRIVATE
12 #include "lib/crypt_ops/crypto_ed25519.h"
13 #include "lib/crypt_ops/crypto_format.h"
14 #include "lib/crypt_ops/crypto_digest.h"
15 #include "lib/crypt_ops/crypto_rand.h"
16 #include "trunnel/ed25519_cert.h"
17 #include "core/or/or.h"
18 #include "app/config/config.h"
19 #include "feature/hs/hs_descriptor.h"
20 #include "test/test.h"
21 #include "feature/nodelist/torcert.h"
23 #include "test/hs_test_helpers.h"
24 #include "test/test_helpers.h"
25 #include "test/log_test_helpers.h"
26 #include "test/rng_test_helpers.h"
28 #define TOR_CONGESTION_CONTROL_PRIVATE
29 #include "core/or/congestion_control_st.h"
30 #include "core/or/congestion_control_common.h"
32 #ifdef HAVE_CFLAG_WOVERLENGTH_STRINGS
33 DISABLE_GCC_WARNING("-Woverlength-strings")
34 /* We allow huge string constants in the unit tests, but not in the code
35 * at large. */
36 #endif
37 #include "test_hs_descriptor.inc"
38 ENABLE_GCC_WARNING("-Woverlength-strings")
40 /* Test certificate encoding put in a descriptor. */
41 static void
42 test_cert_encoding(void *arg)
44 int ret;
45 char *encoded = NULL;
46 ed25519_keypair_t kp;
47 ed25519_public_key_t signed_key;
48 ed25519_secret_key_t secret_key;
49 tor_cert_t *cert = NULL;
51 (void) arg;
53 /* Change time to 03-01-2002 23:36 UTC */
54 update_approx_time(1010101010);
55 time_t now = approx_time();
57 ret = ed25519_keypair_generate(&kp, 0);
58 tt_int_op(ret, == , 0);
59 ret = ed25519_secret_key_generate(&secret_key, 0);
60 tt_int_op(ret, == , 0);
61 ret = ed25519_public_key_generate(&signed_key, &secret_key);
62 tt_int_op(ret, == , 0);
64 cert = tor_cert_create_ed25519(&kp, CERT_TYPE_SIGNING_AUTH, &signed_key,
65 now, 3600 * 2, CERT_FLAG_INCLUDE_SIGNING_KEY);
66 tt_assert(cert);
68 /* Test the certificate encoding function. */
69 ret = tor_cert_encode_ed22519(cert, &encoded);
70 tt_int_op(ret, OP_EQ, 0);
72 /* Validated the certificate string. */
74 char *end, *pos = encoded;
75 char *b64_cert, buf[256];
76 size_t b64_cert_len;
77 tor_cert_t *parsed_cert;
79 tt_int_op(strcmpstart(pos, "-----BEGIN ED25519 CERT-----\n"), OP_EQ, 0);
80 pos += strlen("-----BEGIN ED25519 CERT-----\n");
82 /* Isolate the base64 encoded certificate and try to decode it. */
83 end = strstr(pos, "-----END ED25519 CERT-----");
84 tt_assert(end);
85 b64_cert = pos;
86 b64_cert_len = end - pos;
87 ret = base64_decode(buf, sizeof(buf), b64_cert, b64_cert_len);
88 tt_int_op(ret, OP_GT, 0);
89 /* Parseable? */
90 parsed_cert = tor_cert_parse((uint8_t *) buf, ret);
91 tt_assert(parsed_cert);
92 /* Signature is valid? */
93 ret = tor_cert_checksig(parsed_cert, &kp.pubkey, now + 10);
94 tt_int_op(ret, OP_EQ, 0);
95 ret = tor_cert_eq(cert, parsed_cert);
96 tt_int_op(ret, OP_EQ, 1);
97 /* The cert did have the signing key? */
98 ret= ed25519_pubkey_eq(&parsed_cert->signing_key, &kp.pubkey);
99 tt_int_op(ret, OP_EQ, 1);
101 /* Get to the end part of the certificate. */
102 pos += b64_cert_len;
103 tt_int_op(strcmpstart(pos, "-----END ED25519 CERT-----"), OP_EQ, 0);
104 pos += strlen("-----END ED25519 CERT-----");
105 tt_str_op(pos, OP_EQ, "");
107 /* Check that certificate expiry works properly and emits the right log
108 message */
109 const char *msg = "fire";
110 /* Move us forward 4 hours so that the the certificate is definitely
111 expired */
112 update_approx_time(approx_time() + 3600*4);
113 setup_full_capture_of_logs(LOG_PROTOCOL_WARN);
114 ret = cert_is_valid(parsed_cert, CERT_TYPE_SIGNING_AUTH, msg);
115 tt_int_op(ret, OP_EQ, 0);
116 /* Since the current time at the creation of the cert was "03-01-2002
117 * 23:36", and the expiration date of the cert was two hours, the Tor code
118 * will ceiling that and make it 02:00. Make sure that the right log
119 * message is emitted */
120 expect_log_msg_containing("Invalid signature for fire: expired"
121 " (2002-01-04 02:00:00)");
122 teardown_capture_of_logs();
124 tor_cert_free(parsed_cert);
127 done:
128 tor_cert_free(cert);
129 tor_free(encoded);
132 /* Test the descriptor padding. */
133 static void
134 test_descriptor_padding(void *arg)
136 char *plaintext;
137 size_t plaintext_len, padded_len;
138 uint8_t *padded_plaintext = NULL;
140 /* Example: if l = 129, the ceiled division gives 2 and then multiplied by 128
141 * to give 256. With l = 127, ceiled division gives 1 then times 128. */
142 #define PADDING_EXPECTED_LEN(l) \
143 CEIL_DIV(l, HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE) * \
144 HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE
146 (void) arg;
148 { /* test #1: no padding */
149 plaintext_len = HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE;
150 plaintext = tor_malloc(plaintext_len);
151 padded_len = build_plaintext_padding(plaintext, plaintext_len,
152 &padded_plaintext);
153 tt_assert(padded_plaintext);
154 tor_free(plaintext);
155 /* Make sure our padding has been zeroed. */
156 tt_int_op(fast_mem_is_zero((char *) padded_plaintext + plaintext_len,
157 padded_len - plaintext_len), OP_EQ, 1);
158 tor_free(padded_plaintext);
159 /* Never never have a padded length smaller than the plaintext. */
160 tt_int_op(padded_len, OP_GE, plaintext_len);
161 tt_int_op(padded_len, OP_EQ, PADDING_EXPECTED_LEN(plaintext_len));
164 { /* test #2: one byte padding? */
165 plaintext_len = HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE - 1;
166 plaintext = tor_malloc(plaintext_len);
167 padded_plaintext = NULL;
168 padded_len = build_plaintext_padding(plaintext, plaintext_len,
169 &padded_plaintext);
170 tt_assert(padded_plaintext);
171 tor_free(plaintext);
172 /* Make sure our padding has been zeroed. */
173 tt_int_op(fast_mem_is_zero((char *) padded_plaintext + plaintext_len,
174 padded_len - plaintext_len), OP_EQ, 1);
175 tor_free(padded_plaintext);
176 /* Never never have a padded length smaller than the plaintext. */
177 tt_int_op(padded_len, OP_GE, plaintext_len);
178 tt_int_op(padded_len, OP_EQ, PADDING_EXPECTED_LEN(plaintext_len));
181 { /* test #3: Lots more bytes of padding? */
182 plaintext_len = HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE + 1;
183 plaintext = tor_malloc(plaintext_len);
184 padded_plaintext = NULL;
185 padded_len = build_plaintext_padding(plaintext, plaintext_len,
186 &padded_plaintext);
187 tt_assert(padded_plaintext);
188 tor_free(plaintext);
189 /* Make sure our padding has been zeroed. */
190 tt_int_op(fast_mem_is_zero((char *) padded_plaintext + plaintext_len,
191 padded_len - plaintext_len), OP_EQ, 1);
192 tor_free(padded_plaintext);
193 /* Never never have a padded length smaller than the plaintext. */
194 tt_int_op(padded_len, OP_GE, plaintext_len);
195 tt_int_op(padded_len, OP_EQ, PADDING_EXPECTED_LEN(plaintext_len));
198 done:
199 return;
202 static void
203 test_encode_descriptor(void *arg)
205 int ret;
206 ed25519_keypair_t signing_kp;
207 hs_descriptor_t *desc = NULL;
209 (void) arg;
211 ret = ed25519_keypair_generate(&signing_kp, 0);
212 tt_int_op(ret, OP_EQ, 0);
213 desc = hs_helper_build_hs_desc_with_ip(&signing_kp);
216 char *encoded = NULL;
217 ret = hs_desc_encode_descriptor(desc, &signing_kp, NULL, &encoded);
218 tt_int_op(ret, OP_EQ, 0);
219 tt_assert(encoded);
221 tor_free(encoded);
225 char *encoded = NULL;
226 uint8_t descriptor_cookie[HS_DESC_DESCRIPTOR_COOKIE_LEN];
228 crypto_strongest_rand(descriptor_cookie, sizeof(descriptor_cookie));
230 ret = hs_desc_encode_descriptor(desc, &signing_kp,
231 descriptor_cookie, &encoded);
232 tt_int_op(ret, OP_EQ, 0);
233 tt_assert(encoded);
235 tor_free(encoded);
237 done:
238 hs_descriptor_free(desc);
241 static void
242 test_decode_descriptor(void *arg)
244 int ret;
245 int i;
246 char *encoded = NULL;
247 ed25519_keypair_t signing_kp;
248 hs_descriptor_t *desc = NULL;
249 hs_descriptor_t *decoded = NULL;
250 hs_descriptor_t *desc_no_ip = NULL;
251 hs_subcredential_t subcredential;
253 (void) arg;
255 congestion_control_set_cc_enabled();
257 ret = ed25519_keypair_generate(&signing_kp, 0);
258 tt_int_op(ret, OP_EQ, 0);
259 desc = hs_helper_build_hs_desc_with_ip(&signing_kp);
261 hs_helper_get_subcred_from_identity_keypair(&signing_kp,
262 &subcredential);
264 /* Give some bad stuff to the decoding function. */
265 ret = hs_desc_decode_descriptor("hladfjlkjadf", &subcredential,
266 NULL, &decoded);
267 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
269 ret = hs_desc_encode_descriptor(desc, &signing_kp, NULL, &encoded);
270 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_OK);
271 tt_assert(encoded);
273 ret = hs_desc_decode_descriptor(encoded, &subcredential, NULL, &decoded);
274 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_OK);
275 tt_assert(decoded);
277 hs_helper_desc_equal(desc, decoded);
279 /* Decode a descriptor with _no_ introduction points. */
281 ed25519_keypair_t signing_kp_no_ip;
282 ret = ed25519_keypair_generate(&signing_kp_no_ip, 0);
283 tt_int_op(ret, OP_EQ, 0);
284 hs_helper_get_subcred_from_identity_keypair(&signing_kp_no_ip,
285 &subcredential);
286 desc_no_ip = hs_helper_build_hs_desc_no_ip(&signing_kp_no_ip);
287 tt_assert(desc_no_ip);
288 tor_free(encoded);
289 ret = hs_desc_encode_descriptor(desc_no_ip, &signing_kp_no_ip,
290 NULL, &encoded);
291 tt_int_op(ret, OP_EQ, 0);
292 tt_assert(encoded);
293 hs_descriptor_free(decoded);
294 ret = hs_desc_decode_descriptor(encoded, &subcredential, NULL, &decoded);
295 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_OK);
296 tt_assert(decoded);
299 /* Decode a descriptor with auth clients. */
301 uint8_t descriptor_cookie[HS_DESC_DESCRIPTOR_COOKIE_LEN];
302 curve25519_keypair_t auth_ephemeral_kp;
303 curve25519_keypair_t client_kp, invalid_client_kp;
304 smartlist_t *clients;
305 hs_desc_authorized_client_t *client, *fake_client;
306 client = tor_malloc_zero(sizeof(hs_desc_authorized_client_t));
308 /* Prepare all the keys needed to build the auth client. */
309 curve25519_keypair_generate(&auth_ephemeral_kp, 0);
310 curve25519_keypair_generate(&client_kp, 0);
311 curve25519_keypair_generate(&invalid_client_kp, 0);
312 crypto_strongest_rand(descriptor_cookie, HS_DESC_DESCRIPTOR_COOKIE_LEN);
314 memcpy(&desc->superencrypted_data.auth_ephemeral_pubkey,
315 &auth_ephemeral_kp.pubkey, CURVE25519_PUBKEY_LEN);
317 hs_helper_get_subcred_from_identity_keypair(&signing_kp,
318 &subcredential);
320 /* Build and add the auth client to the descriptor. */
321 clients = desc->superencrypted_data.clients;
322 if (!clients) {
323 clients = smartlist_new();
325 hs_desc_build_authorized_client(&subcredential,
326 &client_kp.pubkey,
327 &auth_ephemeral_kp.seckey,
328 descriptor_cookie, client);
329 smartlist_add(clients, client);
331 /* We need to add fake auth clients here. */
332 for (i=0; i < 15; ++i) {
333 fake_client = hs_desc_build_fake_authorized_client();
334 smartlist_add(clients, fake_client);
336 desc->superencrypted_data.clients = clients;
338 /* Test the encoding/decoding in the following lines. */
339 tor_free(encoded);
340 ret = hs_desc_encode_descriptor(desc, &signing_kp,
341 descriptor_cookie, &encoded);
342 tt_int_op(ret, OP_EQ, 0);
343 tt_assert(encoded);
345 /* If we do not have the client secret key, the decoding must fail. */
346 hs_descriptor_free(decoded);
347 ret = hs_desc_decode_descriptor(encoded, &subcredential,
348 NULL, &decoded);
349 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_NEED_CLIENT_AUTH);
350 tt_assert(!decoded);
352 /* If we have an invalid client secret key, the decoding must fail. */
353 hs_descriptor_free(decoded);
354 ret = hs_desc_decode_descriptor(encoded, &subcredential,
355 &invalid_client_kp.seckey, &decoded);
356 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_BAD_CLIENT_AUTH);
357 tt_assert(!decoded);
359 /* If we have the client secret key, the decoding must succeed and the
360 * decoded descriptor must be correct. */
361 ret = hs_desc_decode_descriptor(encoded, &subcredential,
362 &client_kp.seckey, &decoded);
363 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_OK);
364 tt_assert(decoded);
366 hs_helper_desc_equal(desc, decoded);
369 /* Decode a descriptor without auth clients, and with PoW data added via
370 * test_extra_plaintext to test both the normal case of PoW decoding and the
371 * extra plaintext mechanism itself. */
373 tor_assert(!desc->encrypted_data.pow_params);
375 char pow_seed_base64[HS_POW_SEED_LEN*2];
376 uint8_t pow_seed[HS_POW_SEED_LEN];
377 crypto_strongest_rand(pow_seed, sizeof pow_seed);
378 tt_int_op(base64_encode_nopad(pow_seed_base64, sizeof pow_seed_base64,
379 pow_seed, sizeof pow_seed), OP_GT, 0);
381 time_t expiration_time = time(NULL);
382 char time_buf[ISO_TIME_LEN + 1];
383 format_iso_time_nospace(time_buf, expiration_time);
385 const unsigned suggested_effort = 123456;
386 char *extra_plaintext = NULL;
387 tor_asprintf(&extra_plaintext,
388 "pow-params v1 %s %u %s\n",
389 pow_seed_base64, suggested_effort, time_buf);
391 tor_free(encoded);
392 desc->encrypted_data.test_extra_plaintext = extra_plaintext;
393 ret = hs_desc_encode_descriptor(desc, &signing_kp, NULL, &encoded);
394 tor_free(extra_plaintext);
395 desc->encrypted_data.test_extra_plaintext = extra_plaintext;
397 tt_int_op(ret, OP_EQ, 0);
398 tt_assert(encoded);
400 desc->encrypted_data.pow_params =
401 tor_malloc_zero(sizeof(hs_pow_desc_params_t));
402 desc->encrypted_data.pow_params->type = HS_POW_DESC_V1;
403 memcpy(desc->encrypted_data.pow_params->seed, pow_seed, HS_POW_SEED_LEN);
404 desc->encrypted_data.pow_params->suggested_effort = suggested_effort;
405 desc->encrypted_data.pow_params->expiration_time = expiration_time;
407 hs_descriptor_free(decoded);
408 ret = hs_desc_decode_descriptor(encoded, &subcredential, NULL, &decoded);
409 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_OK);
410 tt_assert(decoded);
412 hs_helper_desc_equal(desc, decoded);
414 tor_free(desc->encrypted_data.pow_params);
417 /* Now a version of the above that's expected to fail. This reproduces the
418 * issue from ticket tor#40793, in which pow_params gets too few parameters
419 * but this would cause an assert instead of an early validation fail.
420 * Make sure it fails to parse. Prior to the fix for #40793 this fails
421 * an assertion instead. */
423 tor_free(encoded);
424 tor_assert(!desc->encrypted_data.pow_params);
425 desc->encrypted_data.test_extra_plaintext = "pow-params v1 a a\n";
426 ret = hs_desc_encode_descriptor(desc, &signing_kp, NULL, &encoded);
427 desc->encrypted_data.test_extra_plaintext = NULL;
429 tt_int_op(ret, OP_EQ, 0);
430 tt_assert(encoded);
432 hs_descriptor_free(decoded);
433 ret = hs_desc_decode_descriptor(encoded, &subcredential, NULL, &decoded);
434 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_ENCRYPTED_ERROR);
435 tt_assert(!decoded);
438 done:
439 hs_descriptor_free(desc);
440 hs_descriptor_free(desc_no_ip);
441 hs_descriptor_free(decoded);
442 tor_free(encoded);
445 static void
446 test_supported_version(void *arg)
448 int ret;
450 (void) arg;
452 /* Unsupported. */
453 ret = hs_desc_is_supported_version(42);
454 tt_int_op(ret, OP_EQ, 0);
455 /* To early. */
456 ret = hs_desc_is_supported_version(HS_DESC_SUPPORTED_FORMAT_VERSION_MIN - 1);
457 tt_int_op(ret, OP_EQ, 0);
458 /* One too new. */
459 ret = hs_desc_is_supported_version(HS_DESC_SUPPORTED_FORMAT_VERSION_MAX + 1);
460 tt_int_op(ret, OP_EQ, 0);
461 /* Valid version. */
462 ret = hs_desc_is_supported_version(3);
463 tt_int_op(ret, OP_EQ, 1);
465 done:
469 static void
470 test_encrypted_data_len(void *arg)
472 int ret;
473 size_t value;
475 (void) arg;
477 /* No length, error. */
478 ret = encrypted_data_length_is_valid(0);
479 tt_int_op(ret, OP_EQ, 0);
480 /* Valid value. */
481 value = HS_DESC_ENCRYPTED_SALT_LEN + DIGEST256_LEN + 1;
482 ret = encrypted_data_length_is_valid(value);
483 tt_int_op(ret, OP_EQ, 1);
485 done:
489 static void
490 test_decode_invalid_intro_point(void *arg)
492 int ret;
493 char *encoded_ip = NULL;
494 size_t len_out;
495 hs_desc_intro_point_t *ip = NULL;
496 ed25519_keypair_t signing_kp;
497 hs_descriptor_t *desc = NULL;
499 (void) arg;
501 /* Separate pieces of a valid encoded introduction point. */
502 const char *intro_point =
503 "introduction-point AQIUMDI5OUYyNjhGQ0E5RDU1Q0QxNTc=";
504 const char *auth_key =
505 "auth-key\n"
506 "-----BEGIN ED25519 CERT-----\n"
507 "AQkACOhAAQW8ltYZMIWpyrfyE/b4Iyi8CNybCwYs6ADk7XfBaxsFAQAgBAD3/BE4\n"
508 "XojGE/N2bW/wgnS9r2qlrkydGyuCKIGayYx3haZ39LD4ZTmSMRxwmplMAqzG/XNP\n"
509 "0Kkpg4p2/VnLFJRdU1SMFo1lgQ4P0bqw7Tgx200fulZ4KUM5z5V7m+a/mgY=\n"
510 "-----END ED25519 CERT-----";
511 const char *enc_key =
512 "enc-key ntor bpZKLsuhxP6woDQ3yVyjm5gUKSk7RjfAijT2qrzbQk0=";
513 const char *enc_key_cert =
514 "enc-key-cert\n"
515 "-----BEGIN ED25519 CERT-----\n"
516 "AQsACOhZAUpNvCZ1aJaaR49lS6MCdsVkhVGVrRqoj0Y2T4SzroAtAQAgBABFOcGg\n"
517 "lbTt1DF5nKTE/gU3Fr8ZtlCIOhu1A+F5LM7fqCUupfesg0KTHwyIZOYQbJuM5/he\n"
518 "/jDNyLy9woPJdjkxywaY2RPUxGjLYtMQV0E8PUxWyICV+7y52fTCYaKpYQw=\n"
519 "-----END ED25519 CERT-----";
521 /* Try to decode a junk string. */
523 hs_descriptor_free(desc);
524 desc = NULL;
525 ret = ed25519_keypair_generate(&signing_kp, 0);
526 tt_int_op(ret, OP_EQ, 0);
527 desc = hs_helper_build_hs_desc_with_ip(&signing_kp);
528 const char *junk = "this is not a descriptor";
529 ip = decode_introduction_point(desc, junk);
530 tt_ptr_op(ip, OP_EQ, NULL);
531 hs_desc_intro_point_free(ip);
532 ip = NULL;
535 /* Invalid link specifiers. */
537 smartlist_t *lines = smartlist_new();
538 const char *bad_line = "introduction-point blah";
539 smartlist_add(lines, (char *) bad_line);
540 smartlist_add(lines, (char *) auth_key);
541 smartlist_add(lines, (char *) enc_key);
542 smartlist_add(lines, (char *) enc_key_cert);
543 encoded_ip = smartlist_join_strings(lines, "\n", 0, &len_out);
544 tt_assert(encoded_ip);
545 ip = decode_introduction_point(desc, encoded_ip);
546 tt_ptr_op(ip, OP_EQ, NULL);
547 tor_free(encoded_ip);
548 smartlist_free(lines);
549 hs_desc_intro_point_free(ip);
550 ip = NULL;
553 /* Invalid auth key type. */
555 smartlist_t *lines = smartlist_new();
556 /* Try to put a valid object that our tokenize function will be able to
557 * parse but that has nothing to do with the auth_key. */
558 const char *bad_line =
559 "auth-key\n"
560 "-----BEGIN UNICORN CERT-----\n"
561 "MIGJAoGBAO4bATcW8kW4h6RQQAKEgg+aXCpF4JwbcO6vGZtzXTDB+HdPVQzwqkbh\n"
562 "XzFM6VGArhYw4m31wcP1Z7IwULir7UMnAFd7Zi62aYfU6l+Y1yAoZ1wzu1XBaAMK\n"
563 "ejpwQinW9nzJn7c2f69fVke3pkhxpNdUZ+vplSA/l9iY+y+v+415AgMBAAE=\n"
564 "-----END UNICORN CERT-----";
565 /* Build intro point text. */
566 smartlist_add(lines, (char *) intro_point);
567 smartlist_add(lines, (char *) bad_line);
568 smartlist_add(lines, (char *) enc_key);
569 smartlist_add(lines, (char *) enc_key_cert);
570 encoded_ip = smartlist_join_strings(lines, "\n", 0, &len_out);
571 tt_assert(encoded_ip);
572 ip = decode_introduction_point(desc, encoded_ip);
573 tt_ptr_op(ip, OP_EQ, NULL);
574 tor_free(encoded_ip);
575 smartlist_free(lines);
578 /* Invalid enc-key. */
580 smartlist_t *lines = smartlist_new();
581 const char *bad_line =
582 "enc-key unicorn bpZKLsuhxP6woDQ3yVyjm5gUKSk7RjfAijT2qrzbQk0=";
583 /* Build intro point text. */
584 smartlist_add(lines, (char *) intro_point);
585 smartlist_add(lines, (char *) auth_key);
586 smartlist_add(lines, (char *) bad_line);
587 smartlist_add(lines, (char *) enc_key_cert);
588 encoded_ip = smartlist_join_strings(lines, "\n", 0, &len_out);
589 tt_assert(encoded_ip);
590 ip = decode_introduction_point(desc, encoded_ip);
591 tt_ptr_op(ip, OP_EQ, NULL);
592 tor_free(encoded_ip);
593 smartlist_free(lines);
596 /* Invalid enc-key object. */
598 smartlist_t *lines = smartlist_new();
599 const char *bad_line = "enc-key ntor";
600 /* Build intro point text. */
601 smartlist_add(lines, (char *) intro_point);
602 smartlist_add(lines, (char *) auth_key);
603 smartlist_add(lines, (char *) bad_line);
604 smartlist_add(lines, (char *) enc_key_cert);
605 encoded_ip = smartlist_join_strings(lines, "\n", 0, &len_out);
606 tt_assert(encoded_ip);
607 ip = decode_introduction_point(desc, encoded_ip);
608 tt_ptr_op(ip, OP_EQ, NULL);
609 tor_free(encoded_ip);
610 smartlist_free(lines);
613 /* Invalid enc-key base64 curv25519 key. */
615 smartlist_t *lines = smartlist_new();
616 const char *bad_line = "enc-key ntor blah===";
617 /* Build intro point text. */
618 smartlist_add(lines, (char *) intro_point);
619 smartlist_add(lines, (char *) auth_key);
620 smartlist_add(lines, (char *) bad_line);
621 smartlist_add(lines, (char *) enc_key_cert);
622 encoded_ip = smartlist_join_strings(lines, "\n", 0, &len_out);
623 tt_assert(encoded_ip);
624 ip = decode_introduction_point(desc, encoded_ip);
625 tt_ptr_op(ip, OP_EQ, NULL);
626 tor_free(encoded_ip);
627 smartlist_free(lines);
630 /* Invalid enc-key invalid legacy. */
632 smartlist_t *lines = smartlist_new();
633 const char *bad_line = "legacy-key blah===";
634 /* Build intro point text. */
635 smartlist_add(lines, (char *) intro_point);
636 smartlist_add(lines, (char *) auth_key);
637 smartlist_add(lines, (char *) bad_line);
638 smartlist_add(lines, (char *) enc_key_cert);
639 encoded_ip = smartlist_join_strings(lines, "\n", 0, &len_out);
640 tt_assert(encoded_ip);
641 ip = decode_introduction_point(desc, encoded_ip);
642 tt_ptr_op(ip, OP_EQ, NULL);
643 tor_free(encoded_ip);
644 smartlist_free(lines);
647 done:
648 hs_descriptor_free(desc);
649 hs_desc_intro_point_free(ip);
652 /** Make sure we fail gracefully when decoding the bad desc from #23233. */
653 static void
654 test_decode_bad_signature(void *arg)
656 hs_desc_plaintext_data_t desc_plaintext;
657 int ret;
659 (void) arg;
661 memset(&desc_plaintext, 0, sizeof(desc_plaintext));
663 /* Update approx time to dodge cert expiration */
664 update_approx_time(1502661599);
666 setup_full_capture_of_logs(LOG_WARN);
667 ret = hs_desc_decode_plaintext(HS_DESC_BAD_SIG, &desc_plaintext);
668 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
669 expect_log_msg_containing("Malformed signature line. Rejecting.");
670 teardown_capture_of_logs();
672 done:
673 hs_desc_plaintext_data_free_contents(&desc_plaintext);
676 static void
677 test_decode_plaintext(void *arg)
679 int ret;
680 hs_desc_plaintext_data_t desc_plaintext;
681 const char *bad_value = "unicorn";
683 (void) arg;
685 #define template \
686 "hs-descriptor %s\n" \
687 "descriptor-lifetime %s\n" \
688 "descriptor-signing-key-cert\n" \
689 "-----BEGIN ED25519 CERT-----\n" \
690 "AQgABjvPAQaG3g+dc6oV/oJV4ODAtkvx56uBnPtBT9mYVuHVOhn7AQAgBABUg3mQ\n" \
691 "myBr4bu5LCr53wUEbW2EXui01CbUgU7pfo9LvJG3AcXRojj6HlfsUs9BkzYzYdjF\n" \
692 "A69Apikgu0ewHYkFFASt7Il+gB3w6J8YstQJZT7dtbtl+doM7ug8B68Qdg8=\n" \
693 "-----END ED25519 CERT-----\n" \
694 "revision-counter %s\n" \
695 "encrypted\n" \
696 "-----BEGIN %s-----\n" \
697 "UNICORN\n" \
698 "-----END MESSAGE-----\n" \
699 "signature m20WJH5agqvwhq7QeuEZ1mYyPWQDO+eJOZUjLhAiKu8DbL17DsDfJE6kXbWy" \
700 "HimbNj2we0enV3cCOOAsmPOaAw\n"
702 /* Invalid version. */
704 char *plaintext;
705 tor_asprintf(&plaintext, template, bad_value, "180", "42", "MESSAGE");
706 ret = hs_desc_decode_plaintext(plaintext, &desc_plaintext);
707 tor_free(plaintext);
708 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
711 /* Missing fields. */
713 const char *plaintext = "hs-descriptor 3\n";
714 ret = hs_desc_decode_plaintext(plaintext, &desc_plaintext);
715 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
718 /* Max length. */
720 size_t big = 64000;
721 /* Must always be bigger than HS_DESC_MAX_LEN. */
722 tt_int_op(HS_DESC_MAX_LEN, OP_LT, big);
723 char *plaintext = tor_malloc_zero(big);
724 memset(plaintext, 'a', big);
725 plaintext[big - 1] = '\0';
726 ret = hs_desc_decode_plaintext(plaintext, &desc_plaintext);
727 tor_free(plaintext);
728 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
731 /* Bad lifetime value. */
733 char *plaintext;
734 tor_asprintf(&plaintext, template, "3", bad_value, "42", "MESSAGE");
735 ret = hs_desc_decode_plaintext(plaintext, &desc_plaintext);
736 tor_free(plaintext);
737 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
740 /* Huge lifetime value. */
742 char *plaintext;
743 tor_asprintf(&plaintext, template, "3", "7181615", "42", "MESSAGE");
744 ret = hs_desc_decode_plaintext(plaintext, &desc_plaintext);
745 tor_free(plaintext);
746 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
749 /* Invalid encrypted section. */
751 char *plaintext;
752 tor_asprintf(&plaintext, template, "3", "180", "42", bad_value);
753 ret = hs_desc_decode_plaintext(plaintext, &desc_plaintext);
754 tor_free(plaintext);
755 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
758 /* Invalid revision counter. */
760 char *plaintext;
761 tor_asprintf(&plaintext, template, "3", "180", bad_value, "MESSAGE");
762 ret = hs_desc_decode_plaintext(plaintext, &desc_plaintext);
763 tor_free(plaintext);
764 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
767 done:
771 static void
772 test_validate_cert(void *arg)
774 int ret;
775 time_t now = time(NULL);
776 ed25519_keypair_t kp;
777 tor_cert_t *cert = NULL;
779 (void) arg;
781 ret = ed25519_keypair_generate(&kp, 0);
782 tt_int_op(ret, OP_EQ, 0);
784 /* Cert of type CERT_TYPE_AUTH_HS_IP_KEY. */
785 cert = tor_cert_create_ed25519(&kp, CERT_TYPE_AUTH_HS_IP_KEY,
786 &kp.pubkey, now, 3600,
787 CERT_FLAG_INCLUDE_SIGNING_KEY);
788 tt_assert(cert);
789 /* Test with empty certificate. */
790 ret = cert_is_valid(NULL, CERT_TYPE_AUTH_HS_IP_KEY, "unicorn");
791 tt_int_op(ret, OP_EQ, 0);
792 /* Test with a bad type. */
793 ret = cert_is_valid(cert, CERT_TYPE_SIGNING_HS_DESC, "unicorn");
794 tt_int_op(ret, OP_EQ, 0);
795 /* Normal validation. */
796 ret = cert_is_valid(cert, CERT_TYPE_AUTH_HS_IP_KEY, "unicorn");
797 tt_int_op(ret, OP_EQ, 1);
798 /* Break signing key so signature verification will fails. */
799 memset(&cert->signing_key, 0, sizeof(cert->signing_key));
800 ret = cert_is_valid(cert, CERT_TYPE_AUTH_HS_IP_KEY, "unicorn");
801 tt_int_op(ret, OP_EQ, 0);
802 tor_cert_free(cert);
804 /* Try a cert without including the signing key. */
805 cert = tor_cert_create_ed25519(&kp, CERT_TYPE_AUTH_HS_IP_KEY,
806 &kp.pubkey, now, 3600, 0);
808 tt_assert(cert);
809 /* Test with a bad type. */
810 ret = cert_is_valid(cert, CERT_TYPE_AUTH_HS_IP_KEY, "unicorn");
811 tt_int_op(ret, OP_EQ, 0);
813 done:
814 tor_cert_free(cert);
817 static void
818 test_desc_signature(void *arg)
820 int ret;
821 char *data = NULL, *desc = NULL;
822 char sig_b64[ED25519_SIG_BASE64_LEN + 1];
823 ed25519_keypair_t kp;
824 ed25519_signature_t sig;
826 (void) arg;
828 ed25519_keypair_generate(&kp, 0);
829 /* Setup a phoony descriptor but with a valid signature token that is the
830 * signature is verifiable. */
831 tor_asprintf(&data, "This is a signed descriptor\n");
832 ret = ed25519_sign_prefixed(&sig, (const uint8_t *) data, strlen(data),
833 "Tor onion service descriptor sig v3", &kp);
834 tt_int_op(ret, OP_EQ, 0);
835 ed25519_signature_to_base64(sig_b64, &sig);
836 /* Build the descriptor that should be valid. */
837 tor_asprintf(&desc, "%ssignature %s\n", data, sig_b64);
838 ret = desc_sig_is_valid(sig_b64, &kp.pubkey, desc, strlen(desc));
839 tt_int_op(ret, OP_EQ, 1);
840 /* Junk signature. */
841 ret = desc_sig_is_valid("JUNK", &kp.pubkey, desc, strlen(desc));
842 tt_int_op(ret, OP_EQ, 0);
844 done:
845 tor_free(desc);
846 tor_free(data);
849 static void
850 test_build_authorized_client(void *arg)
852 int ret;
853 hs_desc_authorized_client_t *desc_client = NULL;
854 uint8_t descriptor_cookie[HS_DESC_DESCRIPTOR_COOKIE_LEN];
855 curve25519_secret_key_t auth_ephemeral_sk;
856 curve25519_secret_key_t client_auth_sk;
857 curve25519_public_key_t client_auth_pk;
858 const char ephemeral_sk_b16[] =
859 "d023b674d993a5c8446bd2ca97e9961149b3c0e88c7dc14e8777744dd3468d6a";
860 const char descriptor_cookie_b16[] =
861 "07d087f1d8c68393721f6e70316d3b29";
862 const char client_pubkey_b16[] =
863 "8c1298fa6050e372f8598f6deca32e27b0ad457741422c2629ebb132cf7fae37";
864 hs_subcredential_t subcredential;
865 char *mem_op_hex_tmp=NULL;
867 (void) arg;
869 ret = curve25519_secret_key_generate(&auth_ephemeral_sk, 0);
870 tt_int_op(ret, OP_EQ, 0);
872 ret = curve25519_secret_key_generate(&client_auth_sk, 0);
873 tt_int_op(ret, OP_EQ, 0);
874 curve25519_public_key_generate(&client_auth_pk, &client_auth_sk);
876 memset(subcredential.subcred, 42, sizeof(subcredential));
878 desc_client = tor_malloc_zero(sizeof(hs_desc_authorized_client_t));
880 base16_decode((char *) &auth_ephemeral_sk,
881 sizeof(auth_ephemeral_sk),
882 ephemeral_sk_b16,
883 strlen(ephemeral_sk_b16));
885 base16_decode((char *) descriptor_cookie,
886 sizeof(descriptor_cookie),
887 descriptor_cookie_b16,
888 strlen(descriptor_cookie_b16));
890 base16_decode((char *) &client_auth_pk,
891 sizeof(client_auth_pk),
892 client_pubkey_b16,
893 strlen(client_pubkey_b16));
895 testing_enable_prefilled_rng("\x01", 1);
897 hs_desc_build_authorized_client(&subcredential,
898 &client_auth_pk, &auth_ephemeral_sk,
899 descriptor_cookie, desc_client);
901 test_memeq_hex((char *) desc_client->client_id,
902 "EC19B7FF4D2DDA13");
903 test_memeq_hex((char *) desc_client->iv,
904 "01010101010101010101010101010101");
905 test_memeq_hex((char *) desc_client->encrypted_cookie,
906 "B21222BE13F385F355BD07B2381F9F29");
908 done:
909 tor_free(desc_client);
910 tor_free(mem_op_hex_tmp);
911 testing_disable_prefilled_rng();
914 static void
915 test_validate_sendme(void *arg)
917 (void)arg;
919 /* Test basic operation: +/- 1 in either direction are OK */
920 cc_sendme_inc = 31;
921 tt_assert(congestion_control_validate_sendme_increment(30));
922 tt_assert(congestion_control_validate_sendme_increment(32));
924 /* Test basic operation: Exceeding +/- 1 fails */
925 cc_sendme_inc = 31;
926 tt_assert(!congestion_control_validate_sendme_increment(29));
927 tt_assert(!congestion_control_validate_sendme_increment(33));
929 /* Test potential overflow conditions */
930 cc_sendme_inc = 254;
931 tt_assert(congestion_control_validate_sendme_increment(255));
932 tt_assert(congestion_control_validate_sendme_increment(253));
933 tt_assert(!congestion_control_validate_sendme_increment(252));
935 /* Test 0 case */
936 cc_sendme_inc = 1;
937 tt_assert(!congestion_control_validate_sendme_increment(0));
939 done:
943 struct testcase_t hs_descriptor[] = {
944 /* Encoding tests. */
945 { "cert_encoding", test_cert_encoding, TT_FORK,
946 NULL, NULL },
947 { "encode_descriptor", test_encode_descriptor, TT_FORK,
948 NULL, NULL },
949 { "descriptor_padding", test_descriptor_padding, TT_FORK,
950 NULL, NULL },
952 /* Decoding tests. */
953 { "decode_descriptor", test_decode_descriptor, TT_FORK,
954 NULL, NULL },
955 { "encrypted_data_len", test_encrypted_data_len, TT_FORK,
956 NULL, NULL },
957 { "decode_invalid_intro_point", test_decode_invalid_intro_point, TT_FORK,
958 NULL, NULL },
959 { "decode_plaintext", test_decode_plaintext, TT_FORK,
960 NULL, NULL },
961 { "decode_bad_signature", test_decode_bad_signature, TT_FORK,
962 NULL, NULL },
963 { "validate_sendme", test_validate_sendme, TT_FORK,
964 NULL, NULL },
966 /* Misc. */
967 { "version", test_supported_version, TT_FORK,
968 NULL, NULL },
969 { "validate_cert", test_validate_cert, TT_FORK,
970 NULL, NULL },
971 { "desc_signature", test_desc_signature, TT_FORK,
972 NULL, NULL },
973 { "build_authorized_client", test_build_authorized_client, TT_FORK,
974 NULL, NULL },
976 END_OF_TESTCASES