tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

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 }