Line data Source code
1 : /* Copyright (c) 2017-2021, The Tor Project, Inc. */
2 : /* See LICENSE for licensing information */
3 :
4 : #define HS_CLIENT_PRIVATE
5 :
6 : #include "core/or/or.h"
7 : #include "lib/crypt_ops/crypto_ed25519.h"
8 : #include "test/test.h"
9 : #include "feature/nodelist/torcert.h"
10 :
11 : #include "feature/hs/hs_client.h"
12 : #include "feature/hs/hs_common.h"
13 : #include "feature/hs/hs_service.h"
14 : #include "test/hs_test_helpers.h"
15 :
16 : /**
17 : * Create an introduction point taken straight out of an HSv3 descriptor.
18 : *
19 : * Use 'signing_kp' to sign the introduction point certificates.
20 : *
21 : * If 'intro_auth_kp' is provided use that as the introduction point
22 : * authentication keypair, otherwise generate one on the fly.
23 : *
24 : * If 'intro_enc_kp' is provided use that as the introduction point encryption
25 : * keypair, otherwise generate one on the fly.
26 : */
27 : hs_desc_intro_point_t *
28 89 : hs_helper_build_intro_point(const ed25519_keypair_t *signing_kp, time_t now,
29 : const char *addr, int legacy,
30 : const ed25519_keypair_t *intro_auth_kp,
31 : const curve25519_keypair_t *intro_enc_kp)
32 : {
33 89 : int ret;
34 89 : ed25519_keypair_t auth_kp;
35 89 : hs_desc_intro_point_t *intro_point = NULL;
36 89 : hs_desc_intro_point_t *ip = hs_desc_intro_point_new();
37 :
38 : /* For a usable intro point we need at least two link specifiers: One legacy
39 : * keyid and one ipv4 */
40 : {
41 89 : tor_addr_t a;
42 89 : tor_addr_make_unspec(&a);
43 89 : link_specifier_t *ls_legacy = link_specifier_new();
44 89 : link_specifier_t *ls_ip = link_specifier_new();
45 89 : link_specifier_set_ls_type(ls_legacy, LS_LEGACY_ID);
46 89 : memset(link_specifier_getarray_un_legacy_id(ls_legacy), 'C',
47 : link_specifier_getlen_un_legacy_id(ls_legacy));
48 89 : int family = tor_addr_parse(&a, addr);
49 89 : switch (family) {
50 67 : case AF_INET:
51 67 : link_specifier_set_ls_type(ls_ip, LS_IPV4);
52 67 : link_specifier_set_un_ipv4_addr(ls_ip, tor_addr_to_ipv4h(&a));
53 67 : link_specifier_set_un_ipv4_port(ls_ip, 9001);
54 67 : break;
55 22 : case AF_INET6:
56 22 : link_specifier_set_ls_type(ls_ip, LS_IPV6);
57 44 : memcpy(link_specifier_getarray_un_ipv6_addr(ls_ip),
58 22 : tor_addr_to_in6_addr8(&a),
59 : link_specifier_getlen_un_ipv6_addr(ls_ip));
60 22 : link_specifier_set_un_ipv6_port(ls_ip, 9001);
61 22 : break;
62 0 : default:
63 : /* Stop the test, not supposed to have an error.
64 : * Compare with -1 to show the actual family.
65 : */
66 0 : tt_int_op(family, OP_EQ, -1);
67 : }
68 89 : smartlist_add(ip->link_specifiers, ls_legacy);
69 89 : smartlist_add(ip->link_specifiers, ls_ip);
70 : }
71 :
72 89 : if (intro_auth_kp) {
73 1 : memcpy(&auth_kp, intro_auth_kp, sizeof(ed25519_keypair_t));
74 : } else {
75 88 : ret = ed25519_keypair_generate(&auth_kp, 0);
76 88 : tt_int_op(ret, OP_EQ, 0);
77 : }
78 89 : ip->auth_key_cert = tor_cert_create_ed25519(signing_kp,
79 : CERT_TYPE_AUTH_HS_IP_KEY,
80 : &auth_kp.pubkey, now,
81 : HS_DESC_CERT_LIFETIME,
82 : CERT_FLAG_INCLUDE_SIGNING_KEY);
83 89 : tt_assert(ip->auth_key_cert);
84 :
85 89 : if (legacy) {
86 44 : ip->legacy.key = crypto_pk_new();
87 44 : tt_assert(ip->legacy.key);
88 44 : ret = crypto_pk_generate_key(ip->legacy.key);
89 44 : tt_int_op(ret, OP_EQ, 0);
90 88 : ssize_t cert_len = tor_make_rsa_ed25519_crosscert(
91 44 : &signing_kp->pubkey, ip->legacy.key,
92 : now + HS_DESC_CERT_LIFETIME,
93 : &ip->legacy.cert.encoded);
94 44 : tt_assert(ip->legacy.cert.encoded);
95 44 : tt_u64_op(cert_len, OP_GT, 0);
96 44 : ip->legacy.cert.len = cert_len;
97 : }
98 :
99 : /* Encryption key. */
100 : {
101 89 : int signbit;
102 89 : curve25519_keypair_t curve25519_kp;
103 89 : ed25519_keypair_t ed25519_kp;
104 89 : tor_cert_t *cross_cert;
105 :
106 89 : if (intro_enc_kp) {
107 1 : memcpy(&curve25519_kp, intro_enc_kp, sizeof(curve25519_keypair_t));
108 : } else {
109 88 : ret = curve25519_keypair_generate(&curve25519_kp, 0);
110 88 : tt_int_op(ret, OP_EQ, 0);
111 : }
112 89 : ed25519_keypair_from_curve25519_keypair(&ed25519_kp, &signbit,
113 : &curve25519_kp);
114 89 : cross_cert = tor_cert_create_ed25519(signing_kp,
115 : CERT_TYPE_CROSS_HS_IP_KEYS,
116 : &ed25519_kp.pubkey, time(NULL),
117 : HS_DESC_CERT_LIFETIME,
118 : CERT_FLAG_INCLUDE_SIGNING_KEY);
119 89 : tt_assert(cross_cert);
120 89 : ip->enc_key_cert = cross_cert;
121 89 : memcpy(ip->enc_key.public_key, curve25519_kp.pubkey.public_key,
122 : CURVE25519_PUBKEY_LEN);
123 : }
124 :
125 89 : intro_point = ip;
126 89 : done:
127 89 : if (intro_point == NULL)
128 0 : tor_free(ip);
129 :
130 89 : return intro_point;
131 : }
132 :
133 : /* Return a valid hs_descriptor_t object. If no_ip is set, no introduction
134 : * points are added. */
135 : static hs_descriptor_t *
136 23 : hs_helper_build_hs_desc_impl(unsigned int no_ip,
137 : const ed25519_keypair_t *signing_kp,
138 : uint64_t rev_counter)
139 : {
140 23 : int ret;
141 23 : int i;
142 23 : time_t now = approx_time();
143 23 : ed25519_keypair_t blinded_kp;
144 23 : curve25519_keypair_t auth_ephemeral_kp;
145 23 : hs_descriptor_t *descp = NULL, *desc = tor_malloc_zero(sizeof(*desc));
146 :
147 23 : desc->plaintext_data.version = HS_DESC_SUPPORTED_FORMAT_VERSION_MAX;
148 :
149 : /* Copy only the public key into the descriptor. */
150 23 : memcpy(&desc->plaintext_data.signing_pubkey, &signing_kp->pubkey,
151 : sizeof(ed25519_public_key_t));
152 :
153 23 : uint64_t current_time_period = hs_get_time_period_num(0);
154 23 : hs_build_blinded_keypair(signing_kp, NULL, 0,
155 : current_time_period, &blinded_kp);
156 : /* Copy only the public key into the descriptor. */
157 23 : memcpy(&desc->plaintext_data.blinded_pubkey, &blinded_kp.pubkey,
158 : sizeof(ed25519_public_key_t));
159 :
160 46 : desc->plaintext_data.signing_key_cert =
161 23 : tor_cert_create_ed25519(&blinded_kp, CERT_TYPE_SIGNING_HS_DESC,
162 : &signing_kp->pubkey, now, 3600,
163 : CERT_FLAG_INCLUDE_SIGNING_KEY);
164 23 : tt_assert(desc->plaintext_data.signing_key_cert);
165 23 : desc->plaintext_data.revision_counter = rev_counter;
166 23 : desc->plaintext_data.lifetime_sec = 3 * 60 * 60;
167 :
168 23 : hs_get_subcredential(&signing_kp->pubkey, &blinded_kp.pubkey,
169 23 : &desc->subcredential);
170 :
171 : /* Setup superencrypted data section. */
172 23 : ret = curve25519_keypair_generate(&auth_ephemeral_kp, 0);
173 23 : tt_int_op(ret, OP_EQ, 0);
174 23 : memcpy(&desc->superencrypted_data.auth_ephemeral_pubkey,
175 : &auth_ephemeral_kp.pubkey,
176 : sizeof(curve25519_public_key_t));
177 :
178 23 : desc->superencrypted_data.clients = smartlist_new();
179 391 : for (i = 0; i < HS_DESC_AUTH_CLIENT_MULTIPLE; i++) {
180 368 : hs_desc_authorized_client_t *desc_client =
181 368 : hs_desc_build_fake_authorized_client();
182 368 : smartlist_add(desc->superencrypted_data.clients, desc_client);
183 : }
184 :
185 : /* Setup encrypted data section. */
186 23 : desc->encrypted_data.create2_ntor = 1;
187 23 : desc->encrypted_data.intro_auth_types = smartlist_new();
188 23 : desc->encrypted_data.single_onion_service = 1;
189 23 : smartlist_add(desc->encrypted_data.intro_auth_types, tor_strdup("ed25519"));
190 23 : desc->encrypted_data.intro_points = smartlist_new();
191 23 : if (!no_ip) {
192 : /* Add four intro points. */
193 22 : smartlist_add(desc->encrypted_data.intro_points,
194 22 : hs_helper_build_intro_point(signing_kp, now, "1.2.3.4", 0,
195 : NULL, NULL));
196 22 : smartlist_add(desc->encrypted_data.intro_points,
197 22 : hs_helper_build_intro_point(signing_kp, now, "[2600::1]", 0,
198 : NULL, NULL));
199 22 : smartlist_add(desc->encrypted_data.intro_points,
200 22 : hs_helper_build_intro_point(signing_kp, now, "3.2.1.4", 1,
201 : NULL, NULL));
202 22 : smartlist_add(desc->encrypted_data.intro_points,
203 22 : hs_helper_build_intro_point(signing_kp, now, "5.6.7.8", 1,
204 : NULL, NULL));
205 : }
206 :
207 : descp = desc;
208 23 : done:
209 0 : if (descp == NULL)
210 0 : tor_free(desc);
211 :
212 23 : return descp;
213 : }
214 :
215 : /** Helper function to get the HS subcredential using the identity keypair of
216 : * an HS. Used to decrypt descriptors in unittests. */
217 : void
218 6 : hs_helper_get_subcred_from_identity_keypair(ed25519_keypair_t *signing_kp,
219 : hs_subcredential_t *subcred_out)
220 : {
221 6 : ed25519_keypair_t blinded_kp;
222 6 : uint64_t current_time_period = hs_get_time_period_num(approx_time());
223 6 : hs_build_blinded_keypair(signing_kp, NULL, 0,
224 : current_time_period, &blinded_kp);
225 :
226 6 : hs_get_subcredential(&signing_kp->pubkey, &blinded_kp.pubkey,
227 : subcred_out);
228 6 : }
229 :
230 : /* Build a descriptor with a specific rev counter. */
231 : hs_descriptor_t *
232 4 : hs_helper_build_hs_desc_with_rev_counter(const ed25519_keypair_t *signing_kp,
233 : uint64_t revision_counter)
234 : {
235 4 : return hs_helper_build_hs_desc_impl(0, signing_kp, revision_counter);
236 : }
237 :
238 : /* Build a descriptor with introduction points. */
239 : hs_descriptor_t *
240 16 : hs_helper_build_hs_desc_with_ip(const ed25519_keypair_t *signing_kp)
241 : {
242 16 : return hs_helper_build_hs_desc_impl(0, signing_kp, 42);
243 : }
244 :
245 : /* Build a descriptor without any introduction points. */
246 : hs_descriptor_t *
247 1 : hs_helper_build_hs_desc_no_ip(const ed25519_keypair_t *signing_kp)
248 : {
249 1 : return hs_helper_build_hs_desc_impl(1, signing_kp, 42);
250 : }
251 :
252 : hs_descriptor_t *
253 2 : hs_helper_build_hs_desc_with_client_auth(
254 : const uint8_t *descriptor_cookie,
255 : const curve25519_public_key_t *client_pk,
256 : const ed25519_keypair_t *signing_kp)
257 : {
258 2 : curve25519_keypair_t auth_ephemeral_kp;
259 2 : hs_descriptor_t *desc = hs_helper_build_hs_desc_impl(0, signing_kp, 42);
260 2 : hs_desc_authorized_client_t *desc_client;
261 :
262 : /* The number of client authorized auth has tobe a multiple of
263 : * HS_DESC_AUTH_CLIENT_MULTIPLE so remove one that we'll replace. */
264 2 : desc_client = smartlist_get(desc->superencrypted_data.clients, 0);
265 2 : smartlist_remove(desc->superencrypted_data.clients, desc_client);
266 2 : hs_desc_authorized_client_free(desc_client);
267 :
268 2 : desc_client = tor_malloc_zero(sizeof(hs_desc_authorized_client_t));
269 :
270 2 : curve25519_keypair_generate(&auth_ephemeral_kp, 0);
271 2 : memcpy(&desc->superencrypted_data.auth_ephemeral_pubkey,
272 : &auth_ephemeral_kp.pubkey, sizeof(curve25519_public_key_t));
273 :
274 2 : hs_desc_build_authorized_client(&desc->subcredential, client_pk,
275 : &auth_ephemeral_kp.seckey,
276 : descriptor_cookie, desc_client);
277 2 : smartlist_add(desc->superencrypted_data.clients, desc_client);
278 2 : return desc;
279 : }
280 :
281 : void
282 3 : hs_helper_desc_equal(const hs_descriptor_t *desc1,
283 : const hs_descriptor_t *desc2)
284 : {
285 : /* Plaintext data section. */
286 3 : tt_int_op(desc1->plaintext_data.version, OP_EQ,
287 : desc2->plaintext_data.version);
288 3 : tt_uint_op(desc1->plaintext_data.lifetime_sec, OP_EQ,
289 : desc2->plaintext_data.lifetime_sec);
290 3 : tt_assert(tor_cert_eq(desc1->plaintext_data.signing_key_cert,
291 : desc2->plaintext_data.signing_key_cert));
292 3 : tt_mem_op(desc1->plaintext_data.signing_pubkey.pubkey, OP_EQ,
293 : desc2->plaintext_data.signing_pubkey.pubkey,
294 3 : ED25519_PUBKEY_LEN);
295 3 : tt_mem_op(desc1->plaintext_data.blinded_pubkey.pubkey, OP_EQ,
296 : desc2->plaintext_data.blinded_pubkey.pubkey,
297 3 : ED25519_PUBKEY_LEN);
298 3 : tt_u64_op(desc1->plaintext_data.revision_counter, OP_EQ,
299 : desc2->plaintext_data.revision_counter);
300 :
301 : /* NOTE: We can't compare the encrypted blob because when encoding the
302 : * descriptor, the object is immutable thus we don't update it with the
303 : * encrypted blob. As contrast to the decoding process where we populate a
304 : * descriptor object. */
305 :
306 : /* Superencrypted data section. */
307 3 : tt_mem_op(desc1->superencrypted_data.auth_ephemeral_pubkey.public_key, OP_EQ,
308 : desc2->superencrypted_data.auth_ephemeral_pubkey.public_key,
309 3 : CURVE25519_PUBKEY_LEN);
310 :
311 : /* Auth clients. */
312 : {
313 3 : tt_assert(desc1->superencrypted_data.clients);
314 3 : tt_assert(desc2->superencrypted_data.clients);
315 3 : tt_int_op(smartlist_len(desc1->superencrypted_data.clients), OP_EQ,
316 : smartlist_len(desc2->superencrypted_data.clients));
317 : for (int i=0;
318 67 : i < smartlist_len(desc1->superencrypted_data.clients);
319 64 : i++) {
320 64 : hs_desc_authorized_client_t
321 64 : *client1 = smartlist_get(desc1->superencrypted_data.clients, i),
322 64 : *client2 = smartlist_get(desc2->superencrypted_data.clients, i);
323 64 : tt_mem_op(client1->client_id, OP_EQ, client2->client_id,
324 64 : sizeof(client1->client_id));
325 64 : tt_mem_op(client1->iv, OP_EQ, client2->iv,
326 64 : sizeof(client1->iv));
327 64 : tt_mem_op(client1->encrypted_cookie, OP_EQ, client2->encrypted_cookie,
328 64 : sizeof(client1->encrypted_cookie));
329 : }
330 : }
331 :
332 : /* Encrypted data section. */
333 3 : tt_uint_op(desc1->encrypted_data.create2_ntor, OP_EQ,
334 : desc2->encrypted_data.create2_ntor);
335 :
336 : /* Authentication type. */
337 3 : tt_int_op(!!desc1->encrypted_data.intro_auth_types, OP_EQ,
338 : !!desc2->encrypted_data.intro_auth_types);
339 3 : if (desc1->encrypted_data.intro_auth_types &&
340 3 : desc2->encrypted_data.intro_auth_types) {
341 3 : tt_int_op(smartlist_len(desc1->encrypted_data.intro_auth_types), OP_EQ,
342 : smartlist_len(desc2->encrypted_data.intro_auth_types));
343 : for (int i = 0;
344 6 : i < smartlist_len(desc1->encrypted_data.intro_auth_types);
345 3 : i++) {
346 3 : tt_str_op(smartlist_get(desc1->encrypted_data.intro_auth_types, i),OP_EQ,
347 : smartlist_get(desc2->encrypted_data.intro_auth_types, i));
348 : }
349 : }
350 :
351 : /* Introduction points. */
352 : {
353 3 : tt_assert(desc1->encrypted_data.intro_points);
354 3 : tt_assert(desc2->encrypted_data.intro_points);
355 3 : tt_int_op(smartlist_len(desc1->encrypted_data.intro_points), OP_EQ,
356 : smartlist_len(desc2->encrypted_data.intro_points));
357 15 : for (int i=0; i < smartlist_len(desc1->encrypted_data.intro_points); i++) {
358 12 : hs_desc_intro_point_t *ip1 = smartlist_get(desc1->encrypted_data
359 : .intro_points, i),
360 12 : *ip2 = smartlist_get(desc2->encrypted_data
361 : .intro_points, i);
362 12 : tt_assert(tor_cert_eq(ip1->auth_key_cert, ip2->auth_key_cert));
363 12 : if (ip1->legacy.key) {
364 6 : tt_int_op(crypto_pk_cmp_keys(ip1->legacy.key, ip2->legacy.key),
365 : OP_EQ, 0);
366 : } else {
367 6 : tt_mem_op(&ip1->enc_key, OP_EQ, &ip2->enc_key, CURVE25519_PUBKEY_LEN);
368 : }
369 :
370 12 : tt_int_op(smartlist_len(ip1->link_specifiers), OP_EQ,
371 : smartlist_len(ip2->link_specifiers));
372 36 : for (int j = 0; j < smartlist_len(ip1->link_specifiers); j++) {
373 24 : link_specifier_t *ls1 = smartlist_get(ip1->link_specifiers, j),
374 24 : *ls2 = smartlist_get(ip2->link_specifiers, j);
375 24 : tt_int_op(link_specifier_get_ls_type(ls1), OP_EQ,
376 : link_specifier_get_ls_type(ls2));
377 24 : switch (link_specifier_get_ls_type(ls1)) {
378 9 : case LS_IPV4:
379 : {
380 9 : uint32_t addr1 = link_specifier_get_un_ipv4_addr(ls1);
381 9 : uint32_t addr2 = link_specifier_get_un_ipv4_addr(ls2);
382 9 : tt_int_op(addr1, OP_EQ, addr2);
383 9 : uint16_t port1 = link_specifier_get_un_ipv4_port(ls1);
384 9 : uint16_t port2 = link_specifier_get_un_ipv4_port(ls2);
385 9 : tt_int_op(port1, OP_EQ, port2);
386 : }
387 : break;
388 3 : case LS_IPV6:
389 : {
390 3 : const uint8_t *addr1 =
391 3 : link_specifier_getconstarray_un_ipv6_addr(ls1);
392 3 : const uint8_t *addr2 =
393 3 : link_specifier_getconstarray_un_ipv6_addr(ls2);
394 3 : tt_int_op(link_specifier_getlen_un_ipv6_addr(ls1), OP_EQ,
395 : link_specifier_getlen_un_ipv6_addr(ls2));
396 3 : tt_mem_op(addr1, OP_EQ, addr2,
397 3 : link_specifier_getlen_un_ipv6_addr(ls1));
398 3 : uint16_t port1 = link_specifier_get_un_ipv6_port(ls1);
399 3 : uint16_t port2 = link_specifier_get_un_ipv6_port(ls2);
400 3 : tt_int_op(port1, OP_EQ, port2);
401 : }
402 : break;
403 12 : case LS_LEGACY_ID:
404 : {
405 12 : const uint8_t *id1 =
406 12 : link_specifier_getconstarray_un_legacy_id(ls1);
407 12 : const uint8_t *id2 =
408 12 : link_specifier_getconstarray_un_legacy_id(ls2);
409 12 : tt_int_op(link_specifier_getlen_un_legacy_id(ls1), OP_EQ,
410 : link_specifier_getlen_un_legacy_id(ls2));
411 12 : tt_mem_op(id1, OP_EQ, id2,
412 : link_specifier_getlen_un_legacy_id(ls1));
413 : }
414 : break;
415 0 : default:
416 : /* Unknown type, caught it and print its value. */
417 24 : tt_int_op(link_specifier_get_ls_type(ls1), OP_EQ, -1);
418 : }
419 : }
420 : }
421 : }
422 :
423 3 : done:
424 3 : ;
425 3 : }
426 :
427 : void
428 1 : hs_helper_add_client_auth(const ed25519_public_key_t *service_pk,
429 : const curve25519_secret_key_t *client_sk)
430 : {
431 1 : digest256map_t *client_auths = get_hs_client_auths_map();
432 1 : if (client_auths == NULL) {
433 1 : client_auths = digest256map_new();
434 1 : set_hs_client_auths_map(client_auths);
435 : }
436 :
437 1 : hs_client_service_authorization_t *auth =
438 1 : tor_malloc_zero(sizeof(hs_client_service_authorization_t));
439 1 : memcpy(&auth->enc_seckey, client_sk, sizeof(curve25519_secret_key_t));
440 1 : hs_build_address(service_pk, HS_VERSION_THREE, auth->onion_address);
441 1 : digest256map_set(client_auths, service_pk->pubkey, auth);
442 1 : }
|