"Fossies" - the Fresh Open Source Software Archive

Member "tor-0.4.1.6/src/test/hs_test_helpers.c" (10 Jun 2019, 13911 Bytes) of package /linux/misc/tor-0.4.1.6.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "hs_test_helpers.c": 0.4.0.5_vs_0.4.1.5.

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