1 /* Copyright (c) 2016-2020, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
5 * \file test_hs_descriptor.c
6 * \brief Test hidden service descriptor encoding and decoding.
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
32 #include "test_hs_descriptor.inc"
33 ENABLE_GCC_WARNING("-Woverlength-strings")
35 /* Test certificate encoding put in a descriptor. */
37 test_cert_encoding(void *arg
)
42 ed25519_public_key_t signed_key
;
43 ed25519_secret_key_t secret_key
;
44 tor_cert_t
*cert
= NULL
;
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
);
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];
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-----");
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);
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. */
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
104 const char *msg
= "fire";
105 /* Move us forward 4 hours so that the the certificate is definitely
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
);
127 /* Test the descriptor padding. */
129 test_descriptor_padding(void *arg
)
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
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
,
148 tt_assert(padded_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
,
165 tt_assert(padded_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
,
182 tt_assert(padded_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
));
198 test_encode_descriptor(void *arg
)
201 ed25519_keypair_t signing_kp
;
202 hs_descriptor_t
*desc
= NULL
;
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);
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);
233 hs_descriptor_free(desc
);
237 test_decode_descriptor(void *arg
)
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
;
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
,
257 /* Give some bad stuff to the decoding function. */
258 ret
= hs_desc_decode_descriptor("hladfjlkjadf", &subcredential
,
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
);
266 ret
= hs_desc_decode_descriptor(encoded
, &subcredential
, NULL
, &decoded
);
267 tt_int_op(ret
, OP_EQ
, HS_DESC_DECODE_OK
);
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
,
279 desc_no_ip
= hs_helper_build_hs_desc_no_ip(&signing_kp_no_ip
);
280 tt_assert(desc_no_ip
);
282 ret
= hs_desc_encode_descriptor(desc_no_ip
, &signing_kp_no_ip
,
284 tt_int_op(ret
, OP_EQ
, 0);
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
);
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
,
313 /* Build and add the auth client to the descriptor. */
314 clients
= desc
->superencrypted_data
.clients
;
316 clients
= smartlist_new();
318 hs_desc_build_authorized_client(&subcredential
,
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. */
333 ret
= hs_desc_encode_descriptor(desc
, &signing_kp
,
334 descriptor_cookie
, &encoded
);
335 tt_int_op(ret
, OP_EQ
, 0);
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
,
342 tt_int_op(ret
, OP_EQ
, HS_DESC_DECODE_NEED_CLIENT_AUTH
);
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
);
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
);
359 hs_helper_desc_equal(desc
, decoded
);
363 hs_descriptor_free(desc
);
364 hs_descriptor_free(desc_no_ip
);
365 hs_descriptor_free(decoded
);
370 test_supported_version(void *arg
)
377 ret
= hs_desc_is_supported_version(42);
378 tt_int_op(ret
, OP_EQ
, 0);
380 ret
= hs_desc_is_supported_version(HS_DESC_SUPPORTED_FORMAT_VERSION_MIN
- 1);
381 tt_int_op(ret
, OP_EQ
, 0);
383 ret
= hs_desc_is_supported_version(HS_DESC_SUPPORTED_FORMAT_VERSION_MAX
+ 1);
384 tt_int_op(ret
, OP_EQ
, 0);
386 ret
= hs_desc_is_supported_version(3);
387 tt_int_op(ret
, OP_EQ
, 1);
394 test_encrypted_data_len(void *arg
)
401 /* No length, error. */
402 ret
= encrypted_data_length_is_valid(0);
403 tt_int_op(ret
, OP_EQ
, 0);
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);
414 test_decode_invalid_intro_point(void *arg
)
417 char *encoded_ip
= NULL
;
419 hs_desc_intro_point_t
*ip
= NULL
;
420 ed25519_keypair_t signing_kp
;
421 hs_descriptor_t
*desc
= NULL
;
425 /* Separate pieces of a valid encoded introduction point. */
426 const char *intro_point
=
427 "introduction-point AQIUMDI5OUYyNjhGQ0E5RDU1Q0QxNTc=";
428 const char *auth_key
=
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
=
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
);
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
);
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
);
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
=
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
);
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. */
578 test_decode_bad_signature(void *arg
)
580 hs_desc_plaintext_data_t desc_plaintext
;
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();
597 hs_desc_plaintext_data_free_contents(&desc_plaintext
);
601 test_decode_plaintext(void *arg
)
604 hs_desc_plaintext_data_t desc_plaintext
;
605 const char *bad_value
= "unicorn";
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" \
620 "-----BEGIN %s-----\n" \
622 "-----END MESSAGE-----\n" \
623 "signature m20WJH5agqvwhq7QeuEZ1mYyPWQDO+eJOZUjLhAiKu8DbL17DsDfJE6kXbWy" \
624 "HimbNj2we0enV3cCOOAsmPOaAw\n"
626 /* Invalid version. */
629 tor_asprintf(&plaintext
, template, bad_value
, "180", "42", "MESSAGE");
630 ret
= hs_desc_decode_plaintext(plaintext
, &desc_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
);
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
);
652 tt_int_op(ret
, OP_EQ
, HS_DESC_DECODE_PLAINTEXT_ERROR
);
655 /* Bad lifetime value. */
658 tor_asprintf(&plaintext
, template, "3", bad_value
, "42", "MESSAGE");
659 ret
= hs_desc_decode_plaintext(plaintext
, &desc_plaintext
);
661 tt_int_op(ret
, OP_EQ
, HS_DESC_DECODE_PLAINTEXT_ERROR
);
664 /* Huge lifetime value. */
667 tor_asprintf(&plaintext
, template, "3", "7181615", "42", "MESSAGE");
668 ret
= hs_desc_decode_plaintext(plaintext
, &desc_plaintext
);
670 tt_int_op(ret
, OP_EQ
, HS_DESC_DECODE_PLAINTEXT_ERROR
);
673 /* Invalid encrypted section. */
676 tor_asprintf(&plaintext
, template, "3", "180", "42", bad_value
);
677 ret
= hs_desc_decode_plaintext(plaintext
, &desc_plaintext
);
679 tt_int_op(ret
, OP_EQ
, HS_DESC_DECODE_PLAINTEXT_ERROR
);
682 /* Invalid revision counter. */
685 tor_asprintf(&plaintext
, template, "3", "180", bad_value
, "MESSAGE");
686 ret
= hs_desc_decode_plaintext(plaintext
, &desc_plaintext
);
688 tt_int_op(ret
, OP_EQ
, HS_DESC_DECODE_PLAINTEXT_ERROR
);
696 test_validate_cert(void *arg
)
699 time_t now
= time(NULL
);
700 ed25519_keypair_t kp
;
701 tor_cert_t
*cert
= NULL
;
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
);
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);
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);
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);
742 test_desc_signature(void *arg
)
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
;
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);
774 test_build_authorized_client(void *arg
)
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
;
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
),
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
),
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
,
827 test_memeq_hex((char *) desc_client
->iv
,
828 "01010101010101010101010101010101");
829 test_memeq_hex((char *) desc_client
->encrypted_cookie
,
830 "B21222BE13F385F355BD07B2381F9F29");
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
,
842 { "encode_descriptor", test_encode_descriptor
, TT_FORK
,
844 { "descriptor_padding", test_descriptor_padding
, TT_FORK
,
847 /* Decoding tests. */
848 { "decode_descriptor", test_decode_descriptor
, TT_FORK
,
850 { "encrypted_data_len", test_encrypted_data_len
, TT_FORK
,
852 { "decode_invalid_intro_point", test_decode_invalid_intro_point
, TT_FORK
,
854 { "decode_plaintext", test_decode_plaintext
, TT_FORK
,
856 { "decode_bad_signature", test_decode_bad_signature
, TT_FORK
,
860 { "version", test_supported_version
, TT_FORK
,
862 { "validate_cert", test_validate_cert
, TT_FORK
,
864 { "desc_signature", test_desc_signature
, TT_FORK
,
866 { "build_authorized_client", test_build_authorized_client
, TT_FORK
,