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