Merge branch 'maint-0.4.5' into maint-0.4.6
[tor.git] / src / test / test_hs_descriptor.c
blobec6c8ba6b4e54c6771429f6714fd1ae763ebc2da
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
11 #include "lib/crypt_ops/crypto_ed25519.h"
12 #include "lib/crypt_ops/crypto_format.h"
13 #include "lib/crypt_ops/crypto_digest.h"
14 #include "lib/crypt_ops/crypto_rand.h"
15 #include "trunnel/ed25519_cert.h"
16 #include "core/or/or.h"
17 #include "app/config/config.h"
18 #include "feature/hs/hs_descriptor.h"
19 #include "test/test.h"
20 #include "feature/nodelist/torcert.h"
22 #include "test/hs_test_helpers.h"
23 #include "test/test_helpers.h"
24 #include "test/log_test_helpers.h"
25 #include "test/rng_test_helpers.h"
27 #ifdef HAVE_CFLAG_WOVERLENGTH_STRINGS
28 DISABLE_GCC_WARNING("-Woverlength-strings")
29 /* We allow huge string constants in the unit tests, but not in the code
30 * at large. */
31 #endif
32 #include "test_hs_descriptor.inc"
33 ENABLE_GCC_WARNING("-Woverlength-strings")
35 /* Test certificate encoding put in a descriptor. */
36 static void
37 test_cert_encoding(void *arg)
39 int ret;
40 char *encoded = NULL;
41 ed25519_keypair_t kp;
42 ed25519_public_key_t signed_key;
43 ed25519_secret_key_t secret_key;
44 tor_cert_t *cert = NULL;
46 (void) arg;
48 /* Change time to 03-01-2002 23:36 UTC */
49 update_approx_time(1010101010);
50 time_t now = approx_time();
52 ret = ed25519_keypair_generate(&kp, 0);
53 tt_int_op(ret, == , 0);
54 ret = ed25519_secret_key_generate(&secret_key, 0);
55 tt_int_op(ret, == , 0);
56 ret = ed25519_public_key_generate(&signed_key, &secret_key);
57 tt_int_op(ret, == , 0);
59 cert = tor_cert_create_ed25519(&kp, CERT_TYPE_SIGNING_AUTH, &signed_key,
60 now, 3600 * 2, CERT_FLAG_INCLUDE_SIGNING_KEY);
61 tt_assert(cert);
63 /* Test the certificate encoding function. */
64 ret = tor_cert_encode_ed22519(cert, &encoded);
65 tt_int_op(ret, OP_EQ, 0);
67 /* Validated the certificate string. */
69 char *end, *pos = encoded;
70 char *b64_cert, buf[256];
71 size_t b64_cert_len;
72 tor_cert_t *parsed_cert;
74 tt_int_op(strcmpstart(pos, "-----BEGIN ED25519 CERT-----\n"), OP_EQ, 0);
75 pos += strlen("-----BEGIN ED25519 CERT-----\n");
77 /* Isolate the base64 encoded certificate and try to decode it. */
78 end = strstr(pos, "-----END ED25519 CERT-----");
79 tt_assert(end);
80 b64_cert = pos;
81 b64_cert_len = end - pos;
82 ret = base64_decode(buf, sizeof(buf), b64_cert, b64_cert_len);
83 tt_int_op(ret, OP_GT, 0);
84 /* Parseable? */
85 parsed_cert = tor_cert_parse((uint8_t *) buf, ret);
86 tt_assert(parsed_cert);
87 /* Signature is valid? */
88 ret = tor_cert_checksig(parsed_cert, &kp.pubkey, now + 10);
89 tt_int_op(ret, OP_EQ, 0);
90 ret = tor_cert_eq(cert, parsed_cert);
91 tt_int_op(ret, OP_EQ, 1);
92 /* The cert did have the signing key? */
93 ret= ed25519_pubkey_eq(&parsed_cert->signing_key, &kp.pubkey);
94 tt_int_op(ret, OP_EQ, 1);
96 /* Get to the end part of the certificate. */
97 pos += b64_cert_len;
98 tt_int_op(strcmpstart(pos, "-----END ED25519 CERT-----"), OP_EQ, 0);
99 pos += strlen("-----END ED25519 CERT-----");
100 tt_str_op(pos, OP_EQ, "");
102 /* Check that certificate expiry works properly and emits the right log
103 message */
104 const char *msg = "fire";
105 /* Move us forward 4 hours so that the the certificate is definitely
106 expired */
107 update_approx_time(approx_time() + 3600*4);
108 setup_full_capture_of_logs(LOG_PROTOCOL_WARN);
109 ret = cert_is_valid(parsed_cert, CERT_TYPE_SIGNING_AUTH, msg);
110 tt_int_op(ret, OP_EQ, 0);
111 /* Since the current time at the creation of the cert was "03-01-2002
112 * 23:36", and the expiration date of the cert was two hours, the Tor code
113 * will ceiling that and make it 02:00. Make sure that the right log
114 * message is emitted */
115 expect_log_msg_containing("Invalid signature for fire: expired"
116 " (2002-01-04 02:00:00)");
117 teardown_capture_of_logs();
119 tor_cert_free(parsed_cert);
122 done:
123 tor_cert_free(cert);
124 tor_free(encoded);
127 /* Test the descriptor padding. */
128 static void
129 test_descriptor_padding(void *arg)
131 char *plaintext;
132 size_t plaintext_len, padded_len;
133 uint8_t *padded_plaintext = NULL;
135 /* Example: if l = 129, the ceiled division gives 2 and then multiplied by 128
136 * to give 256. With l = 127, ceiled division gives 1 then times 128. */
137 #define PADDING_EXPECTED_LEN(l) \
138 CEIL_DIV(l, HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE) * \
139 HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE
141 (void) arg;
143 { /* test #1: no padding */
144 plaintext_len = HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE;
145 plaintext = tor_malloc(plaintext_len);
146 padded_len = build_plaintext_padding(plaintext, plaintext_len,
147 &padded_plaintext);
148 tt_assert(padded_plaintext);
149 tor_free(plaintext);
150 /* Make sure our padding has been zeroed. */
151 tt_int_op(fast_mem_is_zero((char *) padded_plaintext + plaintext_len,
152 padded_len - plaintext_len), OP_EQ, 1);
153 tor_free(padded_plaintext);
154 /* Never never have a padded length smaller than the plaintext. */
155 tt_int_op(padded_len, OP_GE, plaintext_len);
156 tt_int_op(padded_len, OP_EQ, PADDING_EXPECTED_LEN(plaintext_len));
159 { /* test #2: one byte padding? */
160 plaintext_len = HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE - 1;
161 plaintext = tor_malloc(plaintext_len);
162 padded_plaintext = NULL;
163 padded_len = build_plaintext_padding(plaintext, plaintext_len,
164 &padded_plaintext);
165 tt_assert(padded_plaintext);
166 tor_free(plaintext);
167 /* Make sure our padding has been zeroed. */
168 tt_int_op(fast_mem_is_zero((char *) padded_plaintext + plaintext_len,
169 padded_len - plaintext_len), OP_EQ, 1);
170 tor_free(padded_plaintext);
171 /* Never never have a padded length smaller than the plaintext. */
172 tt_int_op(padded_len, OP_GE, plaintext_len);
173 tt_int_op(padded_len, OP_EQ, PADDING_EXPECTED_LEN(plaintext_len));
176 { /* test #3: Lots more bytes of padding? */
177 plaintext_len = HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE + 1;
178 plaintext = tor_malloc(plaintext_len);
179 padded_plaintext = NULL;
180 padded_len = build_plaintext_padding(plaintext, plaintext_len,
181 &padded_plaintext);
182 tt_assert(padded_plaintext);
183 tor_free(plaintext);
184 /* Make sure our padding has been zeroed. */
185 tt_int_op(fast_mem_is_zero((char *) padded_plaintext + plaintext_len,
186 padded_len - plaintext_len), OP_EQ, 1);
187 tor_free(padded_plaintext);
188 /* Never never have a padded length smaller than the plaintext. */
189 tt_int_op(padded_len, OP_GE, plaintext_len);
190 tt_int_op(padded_len, OP_EQ, PADDING_EXPECTED_LEN(plaintext_len));
193 done:
194 return;
197 static void
198 test_encode_descriptor(void *arg)
200 int ret;
201 ed25519_keypair_t signing_kp;
202 hs_descriptor_t *desc = NULL;
204 (void) arg;
206 ret = ed25519_keypair_generate(&signing_kp, 0);
207 tt_int_op(ret, OP_EQ, 0);
208 desc = hs_helper_build_hs_desc_with_ip(&signing_kp);
211 char *encoded = NULL;
212 ret = hs_desc_encode_descriptor(desc, &signing_kp, NULL, &encoded);
213 tt_int_op(ret, OP_EQ, 0);
214 tt_assert(encoded);
216 tor_free(encoded);
220 char *encoded = NULL;
221 uint8_t descriptor_cookie[HS_DESC_DESCRIPTOR_COOKIE_LEN];
223 crypto_strongest_rand(descriptor_cookie, sizeof(descriptor_cookie));
225 ret = hs_desc_encode_descriptor(desc, &signing_kp,
226 descriptor_cookie, &encoded);
227 tt_int_op(ret, OP_EQ, 0);
228 tt_assert(encoded);
230 tor_free(encoded);
232 done:
233 hs_descriptor_free(desc);
236 static void
237 test_decode_descriptor(void *arg)
239 int ret;
240 int i;
241 char *encoded = NULL;
242 ed25519_keypair_t signing_kp;
243 hs_descriptor_t *desc = NULL;
244 hs_descriptor_t *decoded = NULL;
245 hs_descriptor_t *desc_no_ip = NULL;
246 hs_subcredential_t subcredential;
248 (void) arg;
250 ret = ed25519_keypair_generate(&signing_kp, 0);
251 tt_int_op(ret, OP_EQ, 0);
252 desc = hs_helper_build_hs_desc_with_ip(&signing_kp);
254 hs_helper_get_subcred_from_identity_keypair(&signing_kp,
255 &subcredential);
257 /* Give some bad stuff to the decoding function. */
258 ret = hs_desc_decode_descriptor("hladfjlkjadf", &subcredential,
259 NULL, &decoded);
260 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
262 ret = hs_desc_encode_descriptor(desc, &signing_kp, NULL, &encoded);
263 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_OK);
264 tt_assert(encoded);
266 ret = hs_desc_decode_descriptor(encoded, &subcredential, NULL, &decoded);
267 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_OK);
268 tt_assert(decoded);
270 hs_helper_desc_equal(desc, decoded);
272 /* Decode a descriptor with _no_ introduction points. */
274 ed25519_keypair_t signing_kp_no_ip;
275 ret = ed25519_keypair_generate(&signing_kp_no_ip, 0);
276 tt_int_op(ret, OP_EQ, 0);
277 hs_helper_get_subcred_from_identity_keypair(&signing_kp_no_ip,
278 &subcredential);
279 desc_no_ip = hs_helper_build_hs_desc_no_ip(&signing_kp_no_ip);
280 tt_assert(desc_no_ip);
281 tor_free(encoded);
282 ret = hs_desc_encode_descriptor(desc_no_ip, &signing_kp_no_ip,
283 NULL, &encoded);
284 tt_int_op(ret, OP_EQ, 0);
285 tt_assert(encoded);
286 hs_descriptor_free(decoded);
287 ret = hs_desc_decode_descriptor(encoded, &subcredential, NULL, &decoded);
288 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_OK);
289 tt_assert(decoded);
292 /* Decode a descriptor with auth clients. */
294 uint8_t descriptor_cookie[HS_DESC_DESCRIPTOR_COOKIE_LEN];
295 curve25519_keypair_t auth_ephemeral_kp;
296 curve25519_keypair_t client_kp, invalid_client_kp;
297 smartlist_t *clients;
298 hs_desc_authorized_client_t *client, *fake_client;
299 client = tor_malloc_zero(sizeof(hs_desc_authorized_client_t));
301 /* Prepare all the keys needed to build the auth client. */
302 curve25519_keypair_generate(&auth_ephemeral_kp, 0);
303 curve25519_keypair_generate(&client_kp, 0);
304 curve25519_keypair_generate(&invalid_client_kp, 0);
305 crypto_strongest_rand(descriptor_cookie, HS_DESC_DESCRIPTOR_COOKIE_LEN);
307 memcpy(&desc->superencrypted_data.auth_ephemeral_pubkey,
308 &auth_ephemeral_kp.pubkey, CURVE25519_PUBKEY_LEN);
310 hs_helper_get_subcred_from_identity_keypair(&signing_kp,
311 &subcredential);
313 /* Build and add the auth client to the descriptor. */
314 clients = desc->superencrypted_data.clients;
315 if (!clients) {
316 clients = smartlist_new();
318 hs_desc_build_authorized_client(&subcredential,
319 &client_kp.pubkey,
320 &auth_ephemeral_kp.seckey,
321 descriptor_cookie, client);
322 smartlist_add(clients, client);
324 /* We need to add fake auth clients here. */
325 for (i=0; i < 15; ++i) {
326 fake_client = hs_desc_build_fake_authorized_client();
327 smartlist_add(clients, fake_client);
329 desc->superencrypted_data.clients = clients;
331 /* Test the encoding/decoding in the following lines. */
332 tor_free(encoded);
333 ret = hs_desc_encode_descriptor(desc, &signing_kp,
334 descriptor_cookie, &encoded);
335 tt_int_op(ret, OP_EQ, 0);
336 tt_assert(encoded);
338 /* If we do not have the client secret key, the decoding must fail. */
339 hs_descriptor_free(decoded);
340 ret = hs_desc_decode_descriptor(encoded, &subcredential,
341 NULL, &decoded);
342 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_NEED_CLIENT_AUTH);
343 tt_assert(!decoded);
345 /* If we have an invalid client secret key, the decoding must fail. */
346 hs_descriptor_free(decoded);
347 ret = hs_desc_decode_descriptor(encoded, &subcredential,
348 &invalid_client_kp.seckey, &decoded);
349 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_BAD_CLIENT_AUTH);
350 tt_assert(!decoded);
352 /* If we have the client secret key, the decoding must succeed and the
353 * decoded descriptor must be correct. */
354 ret = hs_desc_decode_descriptor(encoded, &subcredential,
355 &client_kp.seckey, &decoded);
356 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_OK);
357 tt_assert(decoded);
359 hs_helper_desc_equal(desc, decoded);
362 done:
363 hs_descriptor_free(desc);
364 hs_descriptor_free(desc_no_ip);
365 hs_descriptor_free(decoded);
366 tor_free(encoded);
369 static void
370 test_supported_version(void *arg)
372 int ret;
374 (void) arg;
376 /* Unsupported. */
377 ret = hs_desc_is_supported_version(42);
378 tt_int_op(ret, OP_EQ, 0);
379 /* To early. */
380 ret = hs_desc_is_supported_version(HS_DESC_SUPPORTED_FORMAT_VERSION_MIN - 1);
381 tt_int_op(ret, OP_EQ, 0);
382 /* One too new. */
383 ret = hs_desc_is_supported_version(HS_DESC_SUPPORTED_FORMAT_VERSION_MAX + 1);
384 tt_int_op(ret, OP_EQ, 0);
385 /* Valid version. */
386 ret = hs_desc_is_supported_version(3);
387 tt_int_op(ret, OP_EQ, 1);
389 done:
393 static void
394 test_encrypted_data_len(void *arg)
396 int ret;
397 size_t value;
399 (void) arg;
401 /* No length, error. */
402 ret = encrypted_data_length_is_valid(0);
403 tt_int_op(ret, OP_EQ, 0);
404 /* Valid value. */
405 value = HS_DESC_ENCRYPTED_SALT_LEN + DIGEST256_LEN + 1;
406 ret = encrypted_data_length_is_valid(value);
407 tt_int_op(ret, OP_EQ, 1);
409 done:
413 static void
414 test_decode_invalid_intro_point(void *arg)
416 int ret;
417 char *encoded_ip = NULL;
418 size_t len_out;
419 hs_desc_intro_point_t *ip = NULL;
420 ed25519_keypair_t signing_kp;
421 hs_descriptor_t *desc = NULL;
423 (void) arg;
425 /* Separate pieces of a valid encoded introduction point. */
426 const char *intro_point =
427 "introduction-point AQIUMDI5OUYyNjhGQ0E5RDU1Q0QxNTc=";
428 const char *auth_key =
429 "auth-key\n"
430 "-----BEGIN ED25519 CERT-----\n"
431 "AQkACOhAAQW8ltYZMIWpyrfyE/b4Iyi8CNybCwYs6ADk7XfBaxsFAQAgBAD3/BE4\n"
432 "XojGE/N2bW/wgnS9r2qlrkydGyuCKIGayYx3haZ39LD4ZTmSMRxwmplMAqzG/XNP\n"
433 "0Kkpg4p2/VnLFJRdU1SMFo1lgQ4P0bqw7Tgx200fulZ4KUM5z5V7m+a/mgY=\n"
434 "-----END ED25519 CERT-----";
435 const char *enc_key =
436 "enc-key ntor bpZKLsuhxP6woDQ3yVyjm5gUKSk7RjfAijT2qrzbQk0=";
437 const char *enc_key_cert =
438 "enc-key-cert\n"
439 "-----BEGIN ED25519 CERT-----\n"
440 "AQsACOhZAUpNvCZ1aJaaR49lS6MCdsVkhVGVrRqoj0Y2T4SzroAtAQAgBABFOcGg\n"
441 "lbTt1DF5nKTE/gU3Fr8ZtlCIOhu1A+F5LM7fqCUupfesg0KTHwyIZOYQbJuM5/he\n"
442 "/jDNyLy9woPJdjkxywaY2RPUxGjLYtMQV0E8PUxWyICV+7y52fTCYaKpYQw=\n"
443 "-----END ED25519 CERT-----";
445 /* Try to decode a junk string. */
447 hs_descriptor_free(desc);
448 desc = NULL;
449 ret = ed25519_keypair_generate(&signing_kp, 0);
450 tt_int_op(ret, OP_EQ, 0);
451 desc = hs_helper_build_hs_desc_with_ip(&signing_kp);
452 const char *junk = "this is not a descriptor";
453 ip = decode_introduction_point(desc, junk);
454 tt_ptr_op(ip, OP_EQ, NULL);
455 hs_desc_intro_point_free(ip);
456 ip = NULL;
459 /* Invalid link specifiers. */
461 smartlist_t *lines = smartlist_new();
462 const char *bad_line = "introduction-point blah";
463 smartlist_add(lines, (char *) bad_line);
464 smartlist_add(lines, (char *) auth_key);
465 smartlist_add(lines, (char *) enc_key);
466 smartlist_add(lines, (char *) enc_key_cert);
467 encoded_ip = smartlist_join_strings(lines, "\n", 0, &len_out);
468 tt_assert(encoded_ip);
469 ip = decode_introduction_point(desc, encoded_ip);
470 tt_ptr_op(ip, OP_EQ, NULL);
471 tor_free(encoded_ip);
472 smartlist_free(lines);
473 hs_desc_intro_point_free(ip);
474 ip = NULL;
477 /* Invalid auth key type. */
479 smartlist_t *lines = smartlist_new();
480 /* Try to put a valid object that our tokenize function will be able to
481 * parse but that has nothing to do with the auth_key. */
482 const char *bad_line =
483 "auth-key\n"
484 "-----BEGIN UNICORN CERT-----\n"
485 "MIGJAoGBAO4bATcW8kW4h6RQQAKEgg+aXCpF4JwbcO6vGZtzXTDB+HdPVQzwqkbh\n"
486 "XzFM6VGArhYw4m31wcP1Z7IwULir7UMnAFd7Zi62aYfU6l+Y1yAoZ1wzu1XBaAMK\n"
487 "ejpwQinW9nzJn7c2f69fVke3pkhxpNdUZ+vplSA/l9iY+y+v+415AgMBAAE=\n"
488 "-----END UNICORN CERT-----";
489 /* Build intro point text. */
490 smartlist_add(lines, (char *) intro_point);
491 smartlist_add(lines, (char *) bad_line);
492 smartlist_add(lines, (char *) enc_key);
493 smartlist_add(lines, (char *) enc_key_cert);
494 encoded_ip = smartlist_join_strings(lines, "\n", 0, &len_out);
495 tt_assert(encoded_ip);
496 ip = decode_introduction_point(desc, encoded_ip);
497 tt_ptr_op(ip, OP_EQ, NULL);
498 tor_free(encoded_ip);
499 smartlist_free(lines);
502 /* Invalid enc-key. */
504 smartlist_t *lines = smartlist_new();
505 const char *bad_line =
506 "enc-key unicorn bpZKLsuhxP6woDQ3yVyjm5gUKSk7RjfAijT2qrzbQk0=";
507 /* Build intro point text. */
508 smartlist_add(lines, (char *) intro_point);
509 smartlist_add(lines, (char *) auth_key);
510 smartlist_add(lines, (char *) bad_line);
511 smartlist_add(lines, (char *) enc_key_cert);
512 encoded_ip = smartlist_join_strings(lines, "\n", 0, &len_out);
513 tt_assert(encoded_ip);
514 ip = decode_introduction_point(desc, encoded_ip);
515 tt_ptr_op(ip, OP_EQ, NULL);
516 tor_free(encoded_ip);
517 smartlist_free(lines);
520 /* Invalid enc-key object. */
522 smartlist_t *lines = smartlist_new();
523 const char *bad_line = "enc-key ntor";
524 /* Build intro point text. */
525 smartlist_add(lines, (char *) intro_point);
526 smartlist_add(lines, (char *) auth_key);
527 smartlist_add(lines, (char *) bad_line);
528 smartlist_add(lines, (char *) enc_key_cert);
529 encoded_ip = smartlist_join_strings(lines, "\n", 0, &len_out);
530 tt_assert(encoded_ip);
531 ip = decode_introduction_point(desc, encoded_ip);
532 tt_ptr_op(ip, OP_EQ, NULL);
533 tor_free(encoded_ip);
534 smartlist_free(lines);
537 /* Invalid enc-key base64 curv25519 key. */
539 smartlist_t *lines = smartlist_new();
540 const char *bad_line = "enc-key ntor blah===";
541 /* Build intro point text. */
542 smartlist_add(lines, (char *) intro_point);
543 smartlist_add(lines, (char *) auth_key);
544 smartlist_add(lines, (char *) bad_line);
545 smartlist_add(lines, (char *) enc_key_cert);
546 encoded_ip = smartlist_join_strings(lines, "\n", 0, &len_out);
547 tt_assert(encoded_ip);
548 ip = decode_introduction_point(desc, encoded_ip);
549 tt_ptr_op(ip, OP_EQ, NULL);
550 tor_free(encoded_ip);
551 smartlist_free(lines);
554 /* Invalid enc-key invalid legacy. */
556 smartlist_t *lines = smartlist_new();
557 const char *bad_line = "legacy-key blah===";
558 /* Build intro point text. */
559 smartlist_add(lines, (char *) intro_point);
560 smartlist_add(lines, (char *) auth_key);
561 smartlist_add(lines, (char *) bad_line);
562 smartlist_add(lines, (char *) enc_key_cert);
563 encoded_ip = smartlist_join_strings(lines, "\n", 0, &len_out);
564 tt_assert(encoded_ip);
565 ip = decode_introduction_point(desc, encoded_ip);
566 tt_ptr_op(ip, OP_EQ, NULL);
567 tor_free(encoded_ip);
568 smartlist_free(lines);
571 done:
572 hs_descriptor_free(desc);
573 hs_desc_intro_point_free(ip);
576 /** Make sure we fail gracefully when decoding the bad desc from #23233. */
577 static void
578 test_decode_bad_signature(void *arg)
580 hs_desc_plaintext_data_t desc_plaintext;
581 int ret;
583 (void) arg;
585 memset(&desc_plaintext, 0, sizeof(desc_plaintext));
587 /* Update approx time to dodge cert expiration */
588 update_approx_time(1502661599);
590 setup_full_capture_of_logs(LOG_WARN);
591 ret = hs_desc_decode_plaintext(HS_DESC_BAD_SIG, &desc_plaintext);
592 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
593 expect_log_msg_containing("Malformed signature line. Rejecting.");
594 teardown_capture_of_logs();
596 done:
597 hs_desc_plaintext_data_free_contents(&desc_plaintext);
600 static void
601 test_decode_plaintext(void *arg)
603 int ret;
604 hs_desc_plaintext_data_t desc_plaintext;
605 const char *bad_value = "unicorn";
607 (void) arg;
609 #define template \
610 "hs-descriptor %s\n" \
611 "descriptor-lifetime %s\n" \
612 "descriptor-signing-key-cert\n" \
613 "-----BEGIN ED25519 CERT-----\n" \
614 "AQgABjvPAQaG3g+dc6oV/oJV4ODAtkvx56uBnPtBT9mYVuHVOhn7AQAgBABUg3mQ\n" \
615 "myBr4bu5LCr53wUEbW2EXui01CbUgU7pfo9LvJG3AcXRojj6HlfsUs9BkzYzYdjF\n" \
616 "A69Apikgu0ewHYkFFASt7Il+gB3w6J8YstQJZT7dtbtl+doM7ug8B68Qdg8=\n" \
617 "-----END ED25519 CERT-----\n" \
618 "revision-counter %s\n" \
619 "encrypted\n" \
620 "-----BEGIN %s-----\n" \
621 "UNICORN\n" \
622 "-----END MESSAGE-----\n" \
623 "signature m20WJH5agqvwhq7QeuEZ1mYyPWQDO+eJOZUjLhAiKu8DbL17DsDfJE6kXbWy" \
624 "HimbNj2we0enV3cCOOAsmPOaAw\n"
626 /* Invalid version. */
628 char *plaintext;
629 tor_asprintf(&plaintext, template, bad_value, "180", "42", "MESSAGE");
630 ret = hs_desc_decode_plaintext(plaintext, &desc_plaintext);
631 tor_free(plaintext);
632 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
635 /* Missing fields. */
637 const char *plaintext = "hs-descriptor 3\n";
638 ret = hs_desc_decode_plaintext(plaintext, &desc_plaintext);
639 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
642 /* Max length. */
644 size_t big = 64000;
645 /* Must always be bigger than HS_DESC_MAX_LEN. */
646 tt_int_op(HS_DESC_MAX_LEN, OP_LT, big);
647 char *plaintext = tor_malloc_zero(big);
648 memset(plaintext, 'a', big);
649 plaintext[big - 1] = '\0';
650 ret = hs_desc_decode_plaintext(plaintext, &desc_plaintext);
651 tor_free(plaintext);
652 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
655 /* Bad lifetime value. */
657 char *plaintext;
658 tor_asprintf(&plaintext, template, "3", bad_value, "42", "MESSAGE");
659 ret = hs_desc_decode_plaintext(plaintext, &desc_plaintext);
660 tor_free(plaintext);
661 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
664 /* Huge lifetime value. */
666 char *plaintext;
667 tor_asprintf(&plaintext, template, "3", "7181615", "42", "MESSAGE");
668 ret = hs_desc_decode_plaintext(plaintext, &desc_plaintext);
669 tor_free(plaintext);
670 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
673 /* Invalid encrypted section. */
675 char *plaintext;
676 tor_asprintf(&plaintext, template, "3", "180", "42", bad_value);
677 ret = hs_desc_decode_plaintext(plaintext, &desc_plaintext);
678 tor_free(plaintext);
679 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
682 /* Invalid revision counter. */
684 char *plaintext;
685 tor_asprintf(&plaintext, template, "3", "180", bad_value, "MESSAGE");
686 ret = hs_desc_decode_plaintext(plaintext, &desc_plaintext);
687 tor_free(plaintext);
688 tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
691 done:
695 static void
696 test_validate_cert(void *arg)
698 int ret;
699 time_t now = time(NULL);
700 ed25519_keypair_t kp;
701 tor_cert_t *cert = NULL;
703 (void) arg;
705 ret = ed25519_keypair_generate(&kp, 0);
706 tt_int_op(ret, OP_EQ, 0);
708 /* Cert of type CERT_TYPE_AUTH_HS_IP_KEY. */
709 cert = tor_cert_create_ed25519(&kp, CERT_TYPE_AUTH_HS_IP_KEY,
710 &kp.pubkey, now, 3600,
711 CERT_FLAG_INCLUDE_SIGNING_KEY);
712 tt_assert(cert);
713 /* Test with empty certificate. */
714 ret = cert_is_valid(NULL, CERT_TYPE_AUTH_HS_IP_KEY, "unicorn");
715 tt_int_op(ret, OP_EQ, 0);
716 /* Test with a bad type. */
717 ret = cert_is_valid(cert, CERT_TYPE_SIGNING_HS_DESC, "unicorn");
718 tt_int_op(ret, OP_EQ, 0);
719 /* Normal validation. */
720 ret = cert_is_valid(cert, CERT_TYPE_AUTH_HS_IP_KEY, "unicorn");
721 tt_int_op(ret, OP_EQ, 1);
722 /* Break signing key so signature verification will fails. */
723 memset(&cert->signing_key, 0, sizeof(cert->signing_key));
724 ret = cert_is_valid(cert, CERT_TYPE_AUTH_HS_IP_KEY, "unicorn");
725 tt_int_op(ret, OP_EQ, 0);
726 tor_cert_free(cert);
728 /* Try a cert without including the signing key. */
729 cert = tor_cert_create_ed25519(&kp, CERT_TYPE_AUTH_HS_IP_KEY,
730 &kp.pubkey, now, 3600, 0);
732 tt_assert(cert);
733 /* Test with a bad type. */
734 ret = cert_is_valid(cert, CERT_TYPE_AUTH_HS_IP_KEY, "unicorn");
735 tt_int_op(ret, OP_EQ, 0);
737 done:
738 tor_cert_free(cert);
741 static void
742 test_desc_signature(void *arg)
744 int ret;
745 char *data = NULL, *desc = NULL;
746 char sig_b64[ED25519_SIG_BASE64_LEN + 1];
747 ed25519_keypair_t kp;
748 ed25519_signature_t sig;
750 (void) arg;
752 ed25519_keypair_generate(&kp, 0);
753 /* Setup a phoony descriptor but with a valid signature token that is the
754 * signature is verifiable. */
755 tor_asprintf(&data, "This is a signed descriptor\n");
756 ret = ed25519_sign_prefixed(&sig, (const uint8_t *) data, strlen(data),
757 "Tor onion service descriptor sig v3", &kp);
758 tt_int_op(ret, OP_EQ, 0);
759 ed25519_signature_to_base64(sig_b64, &sig);
760 /* Build the descriptor that should be valid. */
761 tor_asprintf(&desc, "%ssignature %s\n", data, sig_b64);
762 ret = desc_sig_is_valid(sig_b64, &kp.pubkey, desc, strlen(desc));
763 tt_int_op(ret, OP_EQ, 1);
764 /* Junk signature. */
765 ret = desc_sig_is_valid("JUNK", &kp.pubkey, desc, strlen(desc));
766 tt_int_op(ret, OP_EQ, 0);
768 done:
769 tor_free(desc);
770 tor_free(data);
773 static void
774 test_build_authorized_client(void *arg)
776 int ret;
777 hs_desc_authorized_client_t *desc_client = NULL;
778 uint8_t descriptor_cookie[HS_DESC_DESCRIPTOR_COOKIE_LEN];
779 curve25519_secret_key_t auth_ephemeral_sk;
780 curve25519_secret_key_t client_auth_sk;
781 curve25519_public_key_t client_auth_pk;
782 const char ephemeral_sk_b16[] =
783 "d023b674d993a5c8446bd2ca97e9961149b3c0e88c7dc14e8777744dd3468d6a";
784 const char descriptor_cookie_b16[] =
785 "07d087f1d8c68393721f6e70316d3b29";
786 const char client_pubkey_b16[] =
787 "8c1298fa6050e372f8598f6deca32e27b0ad457741422c2629ebb132cf7fae37";
788 hs_subcredential_t subcredential;
789 char *mem_op_hex_tmp=NULL;
791 (void) arg;
793 ret = curve25519_secret_key_generate(&auth_ephemeral_sk, 0);
794 tt_int_op(ret, OP_EQ, 0);
796 ret = curve25519_secret_key_generate(&client_auth_sk, 0);
797 tt_int_op(ret, OP_EQ, 0);
798 curve25519_public_key_generate(&client_auth_pk, &client_auth_sk);
800 memset(subcredential.subcred, 42, sizeof(subcredential));
802 desc_client = tor_malloc_zero(sizeof(hs_desc_authorized_client_t));
804 base16_decode((char *) &auth_ephemeral_sk,
805 sizeof(auth_ephemeral_sk),
806 ephemeral_sk_b16,
807 strlen(ephemeral_sk_b16));
809 base16_decode((char *) descriptor_cookie,
810 sizeof(descriptor_cookie),
811 descriptor_cookie_b16,
812 strlen(descriptor_cookie_b16));
814 base16_decode((char *) &client_auth_pk,
815 sizeof(client_auth_pk),
816 client_pubkey_b16,
817 strlen(client_pubkey_b16));
819 testing_enable_prefilled_rng("\x01", 1);
821 hs_desc_build_authorized_client(&subcredential,
822 &client_auth_pk, &auth_ephemeral_sk,
823 descriptor_cookie, desc_client);
825 test_memeq_hex((char *) desc_client->client_id,
826 "EC19B7FF4D2DDA13");
827 test_memeq_hex((char *) desc_client->iv,
828 "01010101010101010101010101010101");
829 test_memeq_hex((char *) desc_client->encrypted_cookie,
830 "B21222BE13F385F355BD07B2381F9F29");
832 done:
833 tor_free(desc_client);
834 tor_free(mem_op_hex_tmp);
835 testing_disable_prefilled_rng();
838 struct testcase_t hs_descriptor[] = {
839 /* Encoding tests. */
840 { "cert_encoding", test_cert_encoding, TT_FORK,
841 NULL, NULL },
842 { "encode_descriptor", test_encode_descriptor, TT_FORK,
843 NULL, NULL },
844 { "descriptor_padding", test_descriptor_padding, TT_FORK,
845 NULL, NULL },
847 /* Decoding tests. */
848 { "decode_descriptor", test_decode_descriptor, TT_FORK,
849 NULL, NULL },
850 { "encrypted_data_len", test_encrypted_data_len, TT_FORK,
851 NULL, NULL },
852 { "decode_invalid_intro_point", test_decode_invalid_intro_point, TT_FORK,
853 NULL, NULL },
854 { "decode_plaintext", test_decode_plaintext, TT_FORK,
855 NULL, NULL },
856 { "decode_bad_signature", test_decode_bad_signature, TT_FORK,
857 NULL, NULL },
859 /* Misc. */
860 { "version", test_supported_version, TT_FORK,
861 NULL, NULL },
862 { "validate_cert", test_validate_cert, TT_FORK,
863 NULL, NULL },
864 { "desc_signature", test_desc_signature, TT_FORK,
865 NULL, NULL },
866 { "build_authorized_client", test_build_authorized_client, TT_FORK,
867 NULL, NULL },
869 END_OF_TESTCASES