Esempio n. 1
0
/* Add all possible link specifiers in node to lspecs.
 * legacy ID is mandatory thus MUST be present in node. If the primary address
 * is not IPv4, log a BUG() warning, and return an empty smartlist.
 * Includes ed25519 id and IPv6 link specifiers if present in the node. */
static void
get_lspecs_from_node(const node_t *node, smartlist_t *lspecs)
{
  link_specifier_t *ls;
  tor_addr_port_t ap;

  tor_assert(node);
  tor_assert(lspecs);

  /* Get the relay's IPv4 address. */
  node_get_prim_orport(node, &ap);

  /* We expect the node's primary address to be a valid IPv4 address.
   * This conforms to the protocol, which requires either an IPv4 or IPv6
   * address (or both). */
  if (BUG(!tor_addr_is_v4(&ap.addr)) ||
      BUG(!tor_addr_port_is_valid_ap(&ap, 0))) {
    return;
  }

  ls = link_specifier_new();
  link_specifier_set_ls_type(ls, LS_IPV4);
  link_specifier_set_un_ipv4_addr(ls, tor_addr_to_ipv4h(&ap.addr));
  link_specifier_set_un_ipv4_port(ls, ap.port);
  /* Four bytes IPv4 and two bytes port. */
  link_specifier_set_ls_len(ls, sizeof(ap.addr.addr.in_addr) +
                            sizeof(ap.port));
  smartlist_add(lspecs, ls);

  /* Legacy ID is mandatory and will always be present in node. */
  ls = link_specifier_new();
  link_specifier_set_ls_type(ls, LS_LEGACY_ID);
  memcpy(link_specifier_getarray_un_legacy_id(ls), node->identity,
         link_specifier_getlen_un_legacy_id(ls));
  link_specifier_set_ls_len(ls, link_specifier_getlen_un_legacy_id(ls));
  smartlist_add(lspecs, ls);

  /* ed25519 ID is only included if the node has it. */
  if (!ed25519_public_key_is_zero(&node->ed25519_id)) {
    ls = link_specifier_new();
    link_specifier_set_ls_type(ls, LS_ED25519_ID);
    memcpy(link_specifier_getarray_un_ed25519_id(ls), &node->ed25519_id,
           link_specifier_getlen_un_ed25519_id(ls));
    link_specifier_set_ls_len(ls, link_specifier_getlen_un_ed25519_id(ls));
    smartlist_add(lspecs, ls);
  }

  /* Check for IPv6. If so, include it as well. */
  if (node_has_ipv6_orport(node)) {
    ls = link_specifier_new();
    node_get_pref_ipv6_orport(node, &ap);
    link_specifier_set_ls_type(ls, LS_IPV6);
    size_t addr_len = link_specifier_getlen_un_ipv6_addr(ls);
    const uint8_t *in6_addr = tor_addr_to_in6_addr8(&ap.addr);
    uint8_t *ipv6_array = link_specifier_getarray_un_ipv6_addr(ls);
    memcpy(ipv6_array, in6_addr, addr_len);
    link_specifier_set_un_ipv6_port(ls, ap.port);
    /* Sixteen bytes IPv6 and two bytes port. */
    link_specifier_set_ls_len(ls, addr_len + sizeof(ap.port));
    smartlist_add(lspecs, ls);
  }
}
Esempio n. 2
0
hs_desc_intro_point_t *
hs_helper_build_intro_point(const ed25519_keypair_t *signing_kp, time_t now,
                            const char *addr, int legacy)
{
  int ret;
  ed25519_keypair_t auth_kp;
  hs_desc_intro_point_t *intro_point = NULL;
  hs_desc_intro_point_t *ip = hs_desc_intro_point_new();

  /* For a usable intro point we need at least two link specifiers: One legacy
   * keyid and one ipv4 */
  {
    tor_addr_t a;
    tor_addr_make_unspec(&a);
    link_specifier_t *ls_legacy = link_specifier_new();
    link_specifier_t *ls_ip = link_specifier_new();
    link_specifier_set_ls_type(ls_legacy, LS_LEGACY_ID);
    memset(link_specifier_getarray_un_legacy_id(ls_legacy), 'C',
           link_specifier_getlen_un_legacy_id(ls_legacy));
    int family = tor_addr_parse(&a, addr);
    switch (family) {
    case AF_INET:
          link_specifier_set_ls_type(ls_ip, LS_IPV4);
          link_specifier_set_un_ipv4_addr(ls_ip, tor_addr_to_ipv4h(&a));
          link_specifier_set_un_ipv4_port(ls_ip, 9001);
          break;
        case AF_INET6:
          link_specifier_set_ls_type(ls_ip, LS_IPV6);
          memcpy(link_specifier_getarray_un_ipv6_addr(ls_ip),
                 tor_addr_to_in6_addr8(&a),
                 link_specifier_getlen_un_ipv6_addr(ls_ip));
          link_specifier_set_un_ipv6_port(ls_ip, 9001);
          break;
        default:
          /* Stop the test, not supposed to have an error.
           * Compare with -1 to show the actual family.
           */
          tt_int_op(family, OP_EQ, -1);
    }
    smartlist_add(ip->link_specifiers, ls_legacy);
    smartlist_add(ip->link_specifiers, ls_ip);
  }

  ret = ed25519_keypair_generate(&auth_kp, 0);
  tt_int_op(ret, ==, 0);
  ip->auth_key_cert = tor_cert_create(signing_kp, CERT_TYPE_AUTH_HS_IP_KEY,
                                      &auth_kp.pubkey, now,
                                      HS_DESC_CERT_LIFETIME,
                                      CERT_FLAG_INCLUDE_SIGNING_KEY);
  tt_assert(ip->auth_key_cert);

  if (legacy) {
    ip->legacy.key = crypto_pk_new();
    tt_assert(ip->legacy.key);
    ret = crypto_pk_generate_key(ip->legacy.key);
    tt_int_op(ret, ==, 0);
    ssize_t cert_len = tor_make_rsa_ed25519_crosscert(
                                    &signing_kp->pubkey, ip->legacy.key,
                                    now + HS_DESC_CERT_LIFETIME,
                                    &ip->legacy.cert.encoded);
    tt_assert(ip->legacy.cert.encoded);
    tt_u64_op(cert_len, OP_GT, 0);
    ip->legacy.cert.len = cert_len;
  }

  /* Encryption key. */
  {
    int signbit;
    curve25519_keypair_t curve25519_kp;
    ed25519_keypair_t ed25519_kp;
    tor_cert_t *cross_cert;

    ret = curve25519_keypair_generate(&curve25519_kp, 0);
    tt_int_op(ret, ==, 0);
    ed25519_keypair_from_curve25519_keypair(&ed25519_kp, &signbit,
                                            &curve25519_kp);
    cross_cert = tor_cert_create(signing_kp, CERT_TYPE_CROSS_HS_IP_KEYS,
                                 &ed25519_kp.pubkey, time(NULL),
                                 HS_DESC_CERT_LIFETIME,
                                 CERT_FLAG_INCLUDE_SIGNING_KEY);
    tt_assert(cross_cert);
    ip->enc_key_cert = cross_cert;
  }

  intro_point = ip;
 done:
  if (intro_point == NULL)
    tor_free(ip);

  return intro_point;
}