Line data Source code
1 : /* Copyright (c) 2016-2021, The Tor Project, Inc. */
2 : /* See LICENSE for licensing information */
3 :
4 : /**
5 : * \file test_hs_descriptor.c
6 : * \brief Test hidden service descriptor encoding and decoding.
7 : */
8 :
9 : #define HS_DESCRIPTOR_PRIVATE
10 :
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"
21 :
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"
26 :
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")
34 :
35 : /* Test certificate encoding put in a descriptor. */
36 : static void
37 1 : test_cert_encoding(void *arg)
38 : {
39 1 : int ret;
40 1 : char *encoded = NULL;
41 1 : ed25519_keypair_t kp;
42 1 : ed25519_public_key_t signed_key;
43 1 : ed25519_secret_key_t secret_key;
44 1 : tor_cert_t *cert = NULL;
45 :
46 1 : (void) arg;
47 :
48 : /* Change time to 03-01-2002 23:36 UTC */
49 1 : update_approx_time(1010101010);
50 1 : time_t now = approx_time();
51 :
52 1 : ret = ed25519_keypair_generate(&kp, 0);
53 1 : tt_int_op(ret, == , 0);
54 1 : ret = ed25519_secret_key_generate(&secret_key, 0);
55 1 : tt_int_op(ret, == , 0);
56 1 : ret = ed25519_public_key_generate(&signed_key, &secret_key);
57 1 : tt_int_op(ret, == , 0);
58 :
59 1 : cert = tor_cert_create_ed25519(&kp, CERT_TYPE_SIGNING_AUTH, &signed_key,
60 : now, 3600 * 2, CERT_FLAG_INCLUDE_SIGNING_KEY);
61 1 : tt_assert(cert);
62 :
63 : /* Test the certificate encoding function. */
64 1 : ret = tor_cert_encode_ed22519(cert, &encoded);
65 1 : tt_int_op(ret, OP_EQ, 0);
66 :
67 : /* Validated the certificate string. */
68 : {
69 1 : char *end, *pos = encoded;
70 1 : char *b64_cert, buf[256];
71 1 : size_t b64_cert_len;
72 1 : tor_cert_t *parsed_cert;
73 :
74 1 : tt_int_op(strcmpstart(pos, "-----BEGIN ED25519 CERT-----\n"), OP_EQ, 0);
75 1 : pos += strlen("-----BEGIN ED25519 CERT-----\n");
76 :
77 : /* Isolate the base64 encoded certificate and try to decode it. */
78 1 : end = strstr(pos, "-----END ED25519 CERT-----");
79 1 : tt_assert(end);
80 1 : b64_cert = pos;
81 1 : b64_cert_len = end - pos;
82 1 : ret = base64_decode(buf, sizeof(buf), b64_cert, b64_cert_len);
83 1 : tt_int_op(ret, OP_GT, 0);
84 : /* Parseable? */
85 1 : parsed_cert = tor_cert_parse((uint8_t *) buf, ret);
86 1 : tt_assert(parsed_cert);
87 : /* Signature is valid? */
88 1 : ret = tor_cert_checksig(parsed_cert, &kp.pubkey, now + 10);
89 1 : tt_int_op(ret, OP_EQ, 0);
90 1 : ret = tor_cert_eq(cert, parsed_cert);
91 1 : tt_int_op(ret, OP_EQ, 1);
92 : /* The cert did have the signing key? */
93 1 : ret= ed25519_pubkey_eq(&parsed_cert->signing_key, &kp.pubkey);
94 1 : tt_int_op(ret, OP_EQ, 1);
95 :
96 : /* Get to the end part of the certificate. */
97 1 : pos += b64_cert_len;
98 1 : tt_int_op(strcmpstart(pos, "-----END ED25519 CERT-----"), OP_EQ, 0);
99 1 : pos += strlen("-----END ED25519 CERT-----");
100 1 : tt_str_op(pos, OP_EQ, "");
101 :
102 : /* Check that certificate expiry works properly and emits the right log
103 : message */
104 1 : const char *msg = "fire";
105 : /* Move us forward 4 hours so that the the certificate is definitely
106 : expired */
107 1 : update_approx_time(approx_time() + 3600*4);
108 1 : setup_full_capture_of_logs(LOG_PROTOCOL_WARN);
109 1 : ret = cert_is_valid(parsed_cert, CERT_TYPE_SIGNING_AUTH, msg);
110 1 : 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 1 : expect_log_msg_containing("Invalid signature for fire: expired"
116 1 : " (2002-01-04 02:00:00)");
117 1 : teardown_capture_of_logs();
118 :
119 1 : tor_cert_free(parsed_cert);
120 : }
121 :
122 1 : done:
123 1 : tor_cert_free(cert);
124 1 : tor_free(encoded);
125 1 : }
126 :
127 : /* Test the descriptor padding. */
128 : static void
129 1 : test_descriptor_padding(void *arg)
130 : {
131 1 : char *plaintext;
132 1 : size_t plaintext_len, padded_len;
133 1 : uint8_t *padded_plaintext = NULL;
134 :
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
140 :
141 1 : (void) arg;
142 :
143 : { /* test #1: no padding */
144 1 : plaintext_len = HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE;
145 1 : plaintext = tor_malloc(plaintext_len);
146 1 : padded_len = build_plaintext_padding(plaintext, plaintext_len,
147 : &padded_plaintext);
148 1 : tt_assert(padded_plaintext);
149 1 : tor_free(plaintext);
150 : /* Make sure our padding has been zeroed. */
151 1 : tt_int_op(fast_mem_is_zero((char *) padded_plaintext + plaintext_len,
152 : padded_len - plaintext_len), OP_EQ, 1);
153 1 : tor_free(padded_plaintext);
154 : /* Never never have a padded length smaller than the plaintext. */
155 1 : tt_int_op(padded_len, OP_GE, plaintext_len);
156 1 : tt_int_op(padded_len, OP_EQ, PADDING_EXPECTED_LEN(plaintext_len));
157 : }
158 :
159 : { /* test #2: one byte padding? */
160 1 : plaintext_len = HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE - 1;
161 1 : plaintext = tor_malloc(plaintext_len);
162 1 : padded_plaintext = NULL;
163 1 : padded_len = build_plaintext_padding(plaintext, plaintext_len,
164 : &padded_plaintext);
165 1 : tt_assert(padded_plaintext);
166 1 : tor_free(plaintext);
167 : /* Make sure our padding has been zeroed. */
168 1 : tt_int_op(fast_mem_is_zero((char *) padded_plaintext + plaintext_len,
169 : padded_len - plaintext_len), OP_EQ, 1);
170 1 : tor_free(padded_plaintext);
171 : /* Never never have a padded length smaller than the plaintext. */
172 1 : tt_int_op(padded_len, OP_GE, plaintext_len);
173 1 : tt_int_op(padded_len, OP_EQ, PADDING_EXPECTED_LEN(plaintext_len));
174 : }
175 :
176 : { /* test #3: Lots more bytes of padding? */
177 1 : plaintext_len = HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE + 1;
178 1 : plaintext = tor_malloc(plaintext_len);
179 1 : padded_plaintext = NULL;
180 1 : padded_len = build_plaintext_padding(plaintext, plaintext_len,
181 : &padded_plaintext);
182 1 : tt_assert(padded_plaintext);
183 1 : tor_free(plaintext);
184 : /* Make sure our padding has been zeroed. */
185 1 : tt_int_op(fast_mem_is_zero((char *) padded_plaintext + plaintext_len,
186 : padded_len - plaintext_len), OP_EQ, 1);
187 1 : tor_free(padded_plaintext);
188 : /* Never never have a padded length smaller than the plaintext. */
189 1 : tt_int_op(padded_len, OP_GE, plaintext_len);
190 1 : tt_int_op(padded_len, OP_EQ, PADDING_EXPECTED_LEN(plaintext_len));
191 : }
192 :
193 1 : done:
194 1 : return;
195 : }
196 :
197 : static void
198 1 : test_encode_descriptor(void *arg)
199 : {
200 1 : int ret;
201 1 : ed25519_keypair_t signing_kp;
202 1 : hs_descriptor_t *desc = NULL;
203 :
204 1 : (void) arg;
205 :
206 1 : ret = ed25519_keypair_generate(&signing_kp, 0);
207 1 : tt_int_op(ret, OP_EQ, 0);
208 1 : desc = hs_helper_build_hs_desc_with_ip(&signing_kp);
209 :
210 : {
211 1 : char *encoded = NULL;
212 1 : ret = hs_desc_encode_descriptor(desc, &signing_kp, NULL, &encoded);
213 1 : tt_int_op(ret, OP_EQ, 0);
214 1 : tt_assert(encoded);
215 :
216 1 : tor_free(encoded);
217 : }
218 :
219 : {
220 1 : char *encoded = NULL;
221 1 : uint8_t descriptor_cookie[HS_DESC_DESCRIPTOR_COOKIE_LEN];
222 :
223 1 : crypto_strongest_rand(descriptor_cookie, sizeof(descriptor_cookie));
224 :
225 1 : ret = hs_desc_encode_descriptor(desc, &signing_kp,
226 : descriptor_cookie, &encoded);
227 1 : tt_int_op(ret, OP_EQ, 0);
228 1 : tt_assert(encoded);
229 :
230 1 : tor_free(encoded);
231 : }
232 1 : done:
233 1 : hs_descriptor_free(desc);
234 1 : }
235 :
236 : static void
237 1 : test_decode_descriptor(void *arg)
238 : {
239 1 : int ret;
240 1 : int i;
241 1 : char *encoded = NULL;
242 1 : ed25519_keypair_t signing_kp;
243 1 : hs_descriptor_t *desc = NULL;
244 1 : hs_descriptor_t *decoded = NULL;
245 1 : hs_descriptor_t *desc_no_ip = NULL;
246 1 : hs_subcredential_t subcredential;
247 :
248 1 : (void) arg;
249 :
250 1 : ret = ed25519_keypair_generate(&signing_kp, 0);
251 1 : tt_int_op(ret, OP_EQ, 0);
252 1 : desc = hs_helper_build_hs_desc_with_ip(&signing_kp);
253 :
254 1 : hs_helper_get_subcred_from_identity_keypair(&signing_kp,
255 : &subcredential);
256 :
257 : /* Give some bad stuff to the decoding function. */
258 1 : ret = hs_desc_decode_descriptor("hladfjlkjadf", &subcredential,
259 : NULL, &decoded);
260 1 : tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
261 :
262 1 : ret = hs_desc_encode_descriptor(desc, &signing_kp, NULL, &encoded);
263 1 : tt_int_op(ret, OP_EQ, HS_DESC_DECODE_OK);
264 1 : tt_assert(encoded);
265 :
266 1 : ret = hs_desc_decode_descriptor(encoded, &subcredential, NULL, &decoded);
267 1 : tt_int_op(ret, OP_EQ, HS_DESC_DECODE_OK);
268 1 : tt_assert(decoded);
269 :
270 1 : hs_helper_desc_equal(desc, decoded);
271 :
272 : /* Decode a descriptor with _no_ introduction points. */
273 : {
274 1 : ed25519_keypair_t signing_kp_no_ip;
275 1 : ret = ed25519_keypair_generate(&signing_kp_no_ip, 0);
276 1 : tt_int_op(ret, OP_EQ, 0);
277 1 : hs_helper_get_subcred_from_identity_keypair(&signing_kp_no_ip,
278 : &subcredential);
279 1 : desc_no_ip = hs_helper_build_hs_desc_no_ip(&signing_kp_no_ip);
280 1 : tt_assert(desc_no_ip);
281 1 : tor_free(encoded);
282 1 : ret = hs_desc_encode_descriptor(desc_no_ip, &signing_kp_no_ip,
283 : NULL, &encoded);
284 1 : tt_int_op(ret, OP_EQ, 0);
285 1 : tt_assert(encoded);
286 1 : hs_descriptor_free(decoded);
287 1 : ret = hs_desc_decode_descriptor(encoded, &subcredential, NULL, &decoded);
288 1 : tt_int_op(ret, OP_EQ, HS_DESC_DECODE_OK);
289 1 : tt_assert(decoded);
290 : }
291 :
292 : /* Decode a descriptor with auth clients. */
293 : {
294 1 : uint8_t descriptor_cookie[HS_DESC_DESCRIPTOR_COOKIE_LEN];
295 1 : curve25519_keypair_t auth_ephemeral_kp;
296 1 : curve25519_keypair_t client_kp, invalid_client_kp;
297 1 : smartlist_t *clients;
298 1 : hs_desc_authorized_client_t *client, *fake_client;
299 1 : client = tor_malloc_zero(sizeof(hs_desc_authorized_client_t));
300 :
301 : /* Prepare all the keys needed to build the auth client. */
302 1 : curve25519_keypair_generate(&auth_ephemeral_kp, 0);
303 1 : curve25519_keypair_generate(&client_kp, 0);
304 1 : curve25519_keypair_generate(&invalid_client_kp, 0);
305 1 : crypto_strongest_rand(descriptor_cookie, HS_DESC_DESCRIPTOR_COOKIE_LEN);
306 :
307 1 : memcpy(&desc->superencrypted_data.auth_ephemeral_pubkey,
308 : &auth_ephemeral_kp.pubkey, CURVE25519_PUBKEY_LEN);
309 :
310 1 : hs_helper_get_subcred_from_identity_keypair(&signing_kp,
311 : &subcredential);
312 :
313 : /* Build and add the auth client to the descriptor. */
314 1 : clients = desc->superencrypted_data.clients;
315 1 : if (!clients) {
316 0 : clients = smartlist_new();
317 : }
318 1 : hs_desc_build_authorized_client(&subcredential,
319 : &client_kp.pubkey,
320 : &auth_ephemeral_kp.seckey,
321 : descriptor_cookie, client);
322 1 : smartlist_add(clients, client);
323 :
324 : /* We need to add fake auth clients here. */
325 17 : for (i=0; i < 15; ++i) {
326 15 : fake_client = hs_desc_build_fake_authorized_client();
327 15 : smartlist_add(clients, fake_client);
328 : }
329 1 : desc->superencrypted_data.clients = clients;
330 :
331 : /* Test the encoding/decoding in the following lines. */
332 1 : tor_free(encoded);
333 1 : ret = hs_desc_encode_descriptor(desc, &signing_kp,
334 : descriptor_cookie, &encoded);
335 1 : tt_int_op(ret, OP_EQ, 0);
336 1 : tt_assert(encoded);
337 :
338 : /* If we do not have the client secret key, the decoding must fail. */
339 1 : hs_descriptor_free(decoded);
340 1 : ret = hs_desc_decode_descriptor(encoded, &subcredential,
341 : NULL, &decoded);
342 1 : tt_int_op(ret, OP_EQ, HS_DESC_DECODE_NEED_CLIENT_AUTH);
343 1 : tt_assert(!decoded);
344 :
345 : /* If we have an invalid client secret key, the decoding must fail. */
346 1 : hs_descriptor_free(decoded);
347 1 : ret = hs_desc_decode_descriptor(encoded, &subcredential,
348 : &invalid_client_kp.seckey, &decoded);
349 1 : tt_int_op(ret, OP_EQ, HS_DESC_DECODE_BAD_CLIENT_AUTH);
350 1 : tt_assert(!decoded);
351 :
352 : /* If we have the client secret key, the decoding must succeed and the
353 : * decoded descriptor must be correct. */
354 1 : ret = hs_desc_decode_descriptor(encoded, &subcredential,
355 : &client_kp.seckey, &decoded);
356 1 : tt_int_op(ret, OP_EQ, HS_DESC_DECODE_OK);
357 1 : tt_assert(decoded);
358 :
359 1 : hs_helper_desc_equal(desc, decoded);
360 : }
361 :
362 1 : done:
363 1 : hs_descriptor_free(desc);
364 1 : hs_descriptor_free(desc_no_ip);
365 1 : hs_descriptor_free(decoded);
366 1 : tor_free(encoded);
367 1 : }
368 :
369 : static void
370 1 : test_supported_version(void *arg)
371 : {
372 1 : int ret;
373 :
374 1 : (void) arg;
375 :
376 : /* Unsupported. */
377 1 : ret = hs_desc_is_supported_version(42);
378 1 : tt_int_op(ret, OP_EQ, 0);
379 : /* To early. */
380 1 : ret = hs_desc_is_supported_version(HS_DESC_SUPPORTED_FORMAT_VERSION_MIN - 1);
381 1 : tt_int_op(ret, OP_EQ, 0);
382 : /* One too new. */
383 1 : ret = hs_desc_is_supported_version(HS_DESC_SUPPORTED_FORMAT_VERSION_MAX + 1);
384 1 : tt_int_op(ret, OP_EQ, 0);
385 : /* Valid version. */
386 1 : ret = hs_desc_is_supported_version(3);
387 1 : tt_int_op(ret, OP_EQ, 1);
388 :
389 1 : done:
390 1 : ;
391 1 : }
392 :
393 : static void
394 1 : test_encrypted_data_len(void *arg)
395 : {
396 1 : int ret;
397 1 : size_t value;
398 :
399 1 : (void) arg;
400 :
401 : /* No length, error. */
402 1 : ret = encrypted_data_length_is_valid(0);
403 1 : tt_int_op(ret, OP_EQ, 0);
404 : /* Valid value. */
405 1 : value = HS_DESC_ENCRYPTED_SALT_LEN + DIGEST256_LEN + 1;
406 1 : ret = encrypted_data_length_is_valid(value);
407 1 : tt_int_op(ret, OP_EQ, 1);
408 :
409 1 : done:
410 1 : ;
411 1 : }
412 :
413 : static void
414 1 : test_decode_invalid_intro_point(void *arg)
415 : {
416 1 : int ret;
417 1 : char *encoded_ip = NULL;
418 1 : size_t len_out;
419 1 : hs_desc_intro_point_t *ip = NULL;
420 1 : ed25519_keypair_t signing_kp;
421 1 : hs_descriptor_t *desc = NULL;
422 :
423 1 : (void) arg;
424 :
425 : /* Separate pieces of a valid encoded introduction point. */
426 1 : const char *intro_point =
427 : "introduction-point AQIUMDI5OUYyNjhGQ0E5RDU1Q0QxNTc=";
428 1 : 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 1 : const char *enc_key =
436 : "enc-key ntor bpZKLsuhxP6woDQ3yVyjm5gUKSk7RjfAijT2qrzbQk0=";
437 1 : 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-----";
444 :
445 : /* Try to decode a junk string. */
446 : {
447 1 : hs_descriptor_free(desc);
448 1 : desc = NULL;
449 1 : ret = ed25519_keypair_generate(&signing_kp, 0);
450 1 : tt_int_op(ret, OP_EQ, 0);
451 1 : desc = hs_helper_build_hs_desc_with_ip(&signing_kp);
452 1 : const char *junk = "this is not a descriptor";
453 1 : ip = decode_introduction_point(desc, junk);
454 1 : tt_ptr_op(ip, OP_EQ, NULL);
455 1 : hs_desc_intro_point_free(ip);
456 1 : ip = NULL;
457 : }
458 :
459 : /* Invalid link specifiers. */
460 : {
461 1 : smartlist_t *lines = smartlist_new();
462 1 : const char *bad_line = "introduction-point blah";
463 1 : smartlist_add(lines, (char *) bad_line);
464 1 : smartlist_add(lines, (char *) auth_key);
465 1 : smartlist_add(lines, (char *) enc_key);
466 1 : smartlist_add(lines, (char *) enc_key_cert);
467 1 : encoded_ip = smartlist_join_strings(lines, "\n", 0, &len_out);
468 1 : tt_assert(encoded_ip);
469 1 : ip = decode_introduction_point(desc, encoded_ip);
470 1 : tt_ptr_op(ip, OP_EQ, NULL);
471 1 : tor_free(encoded_ip);
472 1 : smartlist_free(lines);
473 1 : hs_desc_intro_point_free(ip);
474 1 : ip = NULL;
475 : }
476 :
477 : /* Invalid auth key type. */
478 : {
479 1 : 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 1 : 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 1 : smartlist_add(lines, (char *) intro_point);
491 1 : smartlist_add(lines, (char *) bad_line);
492 1 : smartlist_add(lines, (char *) enc_key);
493 1 : smartlist_add(lines, (char *) enc_key_cert);
494 1 : encoded_ip = smartlist_join_strings(lines, "\n", 0, &len_out);
495 1 : tt_assert(encoded_ip);
496 1 : ip = decode_introduction_point(desc, encoded_ip);
497 1 : tt_ptr_op(ip, OP_EQ, NULL);
498 1 : tor_free(encoded_ip);
499 1 : smartlist_free(lines);
500 : }
501 :
502 : /* Invalid enc-key. */
503 : {
504 1 : smartlist_t *lines = smartlist_new();
505 1 : const char *bad_line =
506 : "enc-key unicorn bpZKLsuhxP6woDQ3yVyjm5gUKSk7RjfAijT2qrzbQk0=";
507 : /* Build intro point text. */
508 1 : smartlist_add(lines, (char *) intro_point);
509 1 : smartlist_add(lines, (char *) auth_key);
510 1 : smartlist_add(lines, (char *) bad_line);
511 1 : smartlist_add(lines, (char *) enc_key_cert);
512 1 : encoded_ip = smartlist_join_strings(lines, "\n", 0, &len_out);
513 1 : tt_assert(encoded_ip);
514 1 : ip = decode_introduction_point(desc, encoded_ip);
515 1 : tt_ptr_op(ip, OP_EQ, NULL);
516 1 : tor_free(encoded_ip);
517 1 : smartlist_free(lines);
518 : }
519 :
520 : /* Invalid enc-key object. */
521 : {
522 1 : smartlist_t *lines = smartlist_new();
523 1 : const char *bad_line = "enc-key ntor";
524 : /* Build intro point text. */
525 1 : smartlist_add(lines, (char *) intro_point);
526 1 : smartlist_add(lines, (char *) auth_key);
527 1 : smartlist_add(lines, (char *) bad_line);
528 1 : smartlist_add(lines, (char *) enc_key_cert);
529 1 : encoded_ip = smartlist_join_strings(lines, "\n", 0, &len_out);
530 1 : tt_assert(encoded_ip);
531 1 : ip = decode_introduction_point(desc, encoded_ip);
532 1 : tt_ptr_op(ip, OP_EQ, NULL);
533 1 : tor_free(encoded_ip);
534 1 : smartlist_free(lines);
535 : }
536 :
537 : /* Invalid enc-key base64 curv25519 key. */
538 : {
539 1 : smartlist_t *lines = smartlist_new();
540 1 : const char *bad_line = "enc-key ntor blah===";
541 : /* Build intro point text. */
542 1 : smartlist_add(lines, (char *) intro_point);
543 1 : smartlist_add(lines, (char *) auth_key);
544 1 : smartlist_add(lines, (char *) bad_line);
545 1 : smartlist_add(lines, (char *) enc_key_cert);
546 1 : encoded_ip = smartlist_join_strings(lines, "\n", 0, &len_out);
547 1 : tt_assert(encoded_ip);
548 1 : ip = decode_introduction_point(desc, encoded_ip);
549 1 : tt_ptr_op(ip, OP_EQ, NULL);
550 1 : tor_free(encoded_ip);
551 1 : smartlist_free(lines);
552 : }
553 :
554 : /* Invalid enc-key invalid legacy. */
555 : {
556 1 : smartlist_t *lines = smartlist_new();
557 1 : const char *bad_line = "legacy-key blah===";
558 : /* Build intro point text. */
559 1 : smartlist_add(lines, (char *) intro_point);
560 1 : smartlist_add(lines, (char *) auth_key);
561 1 : smartlist_add(lines, (char *) bad_line);
562 1 : smartlist_add(lines, (char *) enc_key_cert);
563 1 : encoded_ip = smartlist_join_strings(lines, "\n", 0, &len_out);
564 1 : tt_assert(encoded_ip);
565 1 : ip = decode_introduction_point(desc, encoded_ip);
566 1 : tt_ptr_op(ip, OP_EQ, NULL);
567 1 : tor_free(encoded_ip);
568 1 : smartlist_free(lines);
569 : }
570 :
571 1 : done:
572 1 : hs_descriptor_free(desc);
573 1 : hs_desc_intro_point_free(ip);
574 1 : }
575 :
576 : /** Make sure we fail gracefully when decoding the bad desc from #23233. */
577 : static void
578 1 : test_decode_bad_signature(void *arg)
579 : {
580 1 : hs_desc_plaintext_data_t desc_plaintext;
581 1 : int ret;
582 :
583 1 : (void) arg;
584 :
585 1 : memset(&desc_plaintext, 0, sizeof(desc_plaintext));
586 :
587 : /* Update approx time to dodge cert expiration */
588 1 : update_approx_time(1502661599);
589 :
590 1 : setup_full_capture_of_logs(LOG_WARN);
591 1 : ret = hs_desc_decode_plaintext(HS_DESC_BAD_SIG, &desc_plaintext);
592 1 : tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
593 1 : expect_log_msg_containing("Malformed signature line. Rejecting.");
594 1 : teardown_capture_of_logs();
595 :
596 1 : done:
597 1 : hs_desc_plaintext_data_free_contents(&desc_plaintext);
598 1 : }
599 :
600 : static void
601 1 : test_decode_plaintext(void *arg)
602 : {
603 1 : int ret;
604 1 : hs_desc_plaintext_data_t desc_plaintext;
605 1 : const char *bad_value = "unicorn";
606 :
607 1 : (void) arg;
608 :
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"
625 :
626 : /* Invalid version. */
627 : {
628 1 : char *plaintext;
629 1 : tor_asprintf(&plaintext, template, bad_value, "180", "42", "MESSAGE");
630 1 : ret = hs_desc_decode_plaintext(plaintext, &desc_plaintext);
631 1 : tor_free(plaintext);
632 1 : tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
633 : }
634 :
635 : /* Missing fields. */
636 : {
637 1 : const char *plaintext = "hs-descriptor 3\n";
638 1 : ret = hs_desc_decode_plaintext(plaintext, &desc_plaintext);
639 1 : tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
640 : }
641 :
642 : /* Max length. */
643 : {
644 1 : size_t big = 64000;
645 : /* Must always be bigger than HS_DESC_MAX_LEN. */
646 1 : tt_int_op(HS_DESC_MAX_LEN, OP_LT, big);
647 1 : char *plaintext = tor_malloc_zero(big);
648 1 : memset(plaintext, 'a', big);
649 1 : plaintext[big - 1] = '\0';
650 1 : ret = hs_desc_decode_plaintext(plaintext, &desc_plaintext);
651 1 : tor_free(plaintext);
652 1 : tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
653 : }
654 :
655 : /* Bad lifetime value. */
656 : {
657 1 : char *plaintext;
658 1 : tor_asprintf(&plaintext, template, "3", bad_value, "42", "MESSAGE");
659 1 : ret = hs_desc_decode_plaintext(plaintext, &desc_plaintext);
660 1 : tor_free(plaintext);
661 1 : tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
662 : }
663 :
664 : /* Huge lifetime value. */
665 : {
666 1 : char *plaintext;
667 1 : tor_asprintf(&plaintext, template, "3", "7181615", "42", "MESSAGE");
668 1 : ret = hs_desc_decode_plaintext(plaintext, &desc_plaintext);
669 1 : tor_free(plaintext);
670 1 : tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
671 : }
672 :
673 : /* Invalid encrypted section. */
674 : {
675 1 : char *plaintext;
676 1 : tor_asprintf(&plaintext, template, "3", "180", "42", bad_value);
677 1 : ret = hs_desc_decode_plaintext(plaintext, &desc_plaintext);
678 1 : tor_free(plaintext);
679 1 : tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
680 : }
681 :
682 : /* Invalid revision counter. */
683 : {
684 1 : char *plaintext;
685 1 : tor_asprintf(&plaintext, template, "3", "180", bad_value, "MESSAGE");
686 1 : ret = hs_desc_decode_plaintext(plaintext, &desc_plaintext);
687 1 : tor_free(plaintext);
688 1 : tt_int_op(ret, OP_EQ, HS_DESC_DECODE_PLAINTEXT_ERROR);
689 : }
690 :
691 1 : done:
692 1 : ;
693 1 : }
694 :
695 : static void
696 1 : test_validate_cert(void *arg)
697 : {
698 1 : int ret;
699 1 : time_t now = time(NULL);
700 1 : ed25519_keypair_t kp;
701 1 : tor_cert_t *cert = NULL;
702 :
703 1 : (void) arg;
704 :
705 1 : ret = ed25519_keypair_generate(&kp, 0);
706 1 : tt_int_op(ret, OP_EQ, 0);
707 :
708 : /* Cert of type CERT_TYPE_AUTH_HS_IP_KEY. */
709 1 : cert = tor_cert_create_ed25519(&kp, CERT_TYPE_AUTH_HS_IP_KEY,
710 : &kp.pubkey, now, 3600,
711 : CERT_FLAG_INCLUDE_SIGNING_KEY);
712 1 : tt_assert(cert);
713 : /* Test with empty certificate. */
714 1 : ret = cert_is_valid(NULL, CERT_TYPE_AUTH_HS_IP_KEY, "unicorn");
715 1 : tt_int_op(ret, OP_EQ, 0);
716 : /* Test with a bad type. */
717 1 : ret = cert_is_valid(cert, CERT_TYPE_SIGNING_HS_DESC, "unicorn");
718 1 : tt_int_op(ret, OP_EQ, 0);
719 : /* Normal validation. */
720 1 : ret = cert_is_valid(cert, CERT_TYPE_AUTH_HS_IP_KEY, "unicorn");
721 1 : tt_int_op(ret, OP_EQ, 1);
722 : /* Break signing key so signature verification will fails. */
723 1 : memset(&cert->signing_key, 0, sizeof(cert->signing_key));
724 1 : ret = cert_is_valid(cert, CERT_TYPE_AUTH_HS_IP_KEY, "unicorn");
725 1 : tt_int_op(ret, OP_EQ, 0);
726 1 : tor_cert_free(cert);
727 :
728 : /* Try a cert without including the signing key. */
729 1 : cert = tor_cert_create_ed25519(&kp, CERT_TYPE_AUTH_HS_IP_KEY,
730 : &kp.pubkey, now, 3600, 0);
731 :
732 1 : tt_assert(cert);
733 : /* Test with a bad type. */
734 1 : ret = cert_is_valid(cert, CERT_TYPE_AUTH_HS_IP_KEY, "unicorn");
735 1 : tt_int_op(ret, OP_EQ, 0);
736 :
737 1 : done:
738 1 : tor_cert_free(cert);
739 1 : }
740 :
741 : static void
742 1 : test_desc_signature(void *arg)
743 : {
744 1 : int ret;
745 1 : char *data = NULL, *desc = NULL;
746 1 : char sig_b64[ED25519_SIG_BASE64_LEN + 1];
747 1 : ed25519_keypair_t kp;
748 1 : ed25519_signature_t sig;
749 :
750 1 : (void) arg;
751 :
752 1 : ed25519_keypair_generate(&kp, 0);
753 : /* Setup a phoony descriptor but with a valid signature token that is the
754 : * signature is verifiable. */
755 1 : tor_asprintf(&data, "This is a signed descriptor\n");
756 1 : ret = ed25519_sign_prefixed(&sig, (const uint8_t *) data, strlen(data),
757 : "Tor onion service descriptor sig v3", &kp);
758 1 : tt_int_op(ret, OP_EQ, 0);
759 1 : ed25519_signature_to_base64(sig_b64, &sig);
760 : /* Build the descriptor that should be valid. */
761 1 : tor_asprintf(&desc, "%ssignature %s\n", data, sig_b64);
762 1 : ret = desc_sig_is_valid(sig_b64, &kp.pubkey, desc, strlen(desc));
763 1 : tt_int_op(ret, OP_EQ, 1);
764 : /* Junk signature. */
765 1 : ret = desc_sig_is_valid("JUNK", &kp.pubkey, desc, strlen(desc));
766 1 : tt_int_op(ret, OP_EQ, 0);
767 :
768 1 : done:
769 1 : tor_free(desc);
770 1 : tor_free(data);
771 1 : }
772 :
773 : static void
774 1 : test_build_authorized_client(void *arg)
775 : {
776 1 : int ret;
777 1 : hs_desc_authorized_client_t *desc_client = NULL;
778 1 : uint8_t descriptor_cookie[HS_DESC_DESCRIPTOR_COOKIE_LEN];
779 1 : curve25519_secret_key_t auth_ephemeral_sk;
780 1 : curve25519_secret_key_t client_auth_sk;
781 1 : curve25519_public_key_t client_auth_pk;
782 1 : const char ephemeral_sk_b16[] =
783 : "d023b674d993a5c8446bd2ca97e9961149b3c0e88c7dc14e8777744dd3468d6a";
784 1 : const char descriptor_cookie_b16[] =
785 : "07d087f1d8c68393721f6e70316d3b29";
786 1 : const char client_pubkey_b16[] =
787 : "8c1298fa6050e372f8598f6deca32e27b0ad457741422c2629ebb132cf7fae37";
788 1 : hs_subcredential_t subcredential;
789 1 : char *mem_op_hex_tmp=NULL;
790 :
791 1 : (void) arg;
792 :
793 1 : ret = curve25519_secret_key_generate(&auth_ephemeral_sk, 0);
794 1 : tt_int_op(ret, OP_EQ, 0);
795 :
796 1 : ret = curve25519_secret_key_generate(&client_auth_sk, 0);
797 1 : tt_int_op(ret, OP_EQ, 0);
798 1 : curve25519_public_key_generate(&client_auth_pk, &client_auth_sk);
799 :
800 1 : memset(subcredential.subcred, 42, sizeof(subcredential));
801 :
802 1 : desc_client = tor_malloc_zero(sizeof(hs_desc_authorized_client_t));
803 :
804 1 : base16_decode((char *) &auth_ephemeral_sk,
805 : sizeof(auth_ephemeral_sk),
806 : ephemeral_sk_b16,
807 : strlen(ephemeral_sk_b16));
808 :
809 1 : base16_decode((char *) descriptor_cookie,
810 : sizeof(descriptor_cookie),
811 : descriptor_cookie_b16,
812 : strlen(descriptor_cookie_b16));
813 :
814 1 : base16_decode((char *) &client_auth_pk,
815 : sizeof(client_auth_pk),
816 : client_pubkey_b16,
817 : strlen(client_pubkey_b16));
818 :
819 1 : testing_enable_prefilled_rng("\x01", 1);
820 :
821 1 : hs_desc_build_authorized_client(&subcredential,
822 : &client_auth_pk, &auth_ephemeral_sk,
823 : descriptor_cookie, desc_client);
824 :
825 1 : test_memeq_hex((char *) desc_client->client_id,
826 : "EC19B7FF4D2DDA13");
827 1 : test_memeq_hex((char *) desc_client->iv,
828 : "01010101010101010101010101010101");
829 1 : test_memeq_hex((char *) desc_client->encrypted_cookie,
830 : "B21222BE13F385F355BD07B2381F9F29");
831 :
832 1 : done:
833 1 : tor_free(desc_client);
834 1 : tor_free(mem_op_hex_tmp);
835 1 : testing_disable_prefilled_rng();
836 1 : }
837 :
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 },
846 :
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 },
858 :
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 },
868 :
869 : END_OF_TESTCASES
870 : };
|