Merge remote-tracking branch 'teor/reject-tap-v6'

This commit is contained in:
Nick Mathewson 2016-08-29 15:02:11 -04:00
commit bbaa7d09a0
18 changed files with 325 additions and 93 deletions

15
changes/reject-tap Normal file
View File

@ -0,0 +1,15 @@
o Major bug fixes (circuit building):
- Tor authorities, relays, and clients only use ntor, except for
rare cases in the hidden service protocol.
- Authorities, relays and clients specifically check that each
descriptor has an ntor key.
- Clients avoid downloading a descriptor if the relay version is
too old to support ntor.
- Client code never chooses nodes without ntor keys: they will not
be selected during circuit-building, or as guards, or as directory
mirrors, or as introduction or rendezvous points.
- Circuit-building code assumes that all hops can use ntor,
except for rare hidden service protocol cases.
- Hidden service client to intro point and service to rendezvous point
connections use the TAP key supplied by the protocol.
Fixes bug 19163; bugfix on 0.2.4.18-rc.

View File

@ -1452,16 +1452,6 @@ The following options are useful only for clients (that is, if
"auto" (recommended) then it is on for all clients that do not set
FetchUselessDescriptors. (Default: auto)
[[UseNTorHandshake]] **UseNTorHandshake** **0**|**1**|**auto**::
The "ntor" circuit-creation handshake is faster and (we think) more
secure than the original ("TAP") circuit handshake, but starting to use
it too early might make your client stand out. If this option is 0, your
Tor client won't use the ntor handshake. If it's 1, your Tor client
will use the ntor handshake to extend circuits through servers that
support it. If this option is "auto", then your client
will use the ntor handshake once enough directory authorities recommend
it. (Default: 1)
[[PathBiasCircThreshold]] **PathBiasCircThreshold** __NUM__ +
[[PathBiasNoticeRate]] **PathBiasNoticeRate** __NUM__ +

View File

@ -58,7 +58,6 @@ static crypt_path_t *onion_next_hop_in_cpath(crypt_path_t *cpath);
static int onion_extend_cpath(origin_circuit_t *circ);
static int count_acceptable_nodes(smartlist_t *routers);
static int onion_append_hop(crypt_path_t **head_ptr, extend_info_t *choice);
static int circuits_can_use_ntor(void);
/** This function tries to get a channel to the specified endpoint,
* and then calls command_setup_channel() to give it the right
@ -365,7 +364,7 @@ circuit_rep_hist_note_result(origin_circuit_t *circ)
} while (hop!=circ->cpath);
}
/** Return 1 iff at least one node in circ's cpath supports ntor. */
/** Return 1 iff every node in circ's cpath definitely supports ntor. */
static int
circuit_cpath_supports_ntor(const origin_circuit_t *circ)
{
@ -373,16 +372,19 @@ circuit_cpath_supports_ntor(const origin_circuit_t *circ)
cpath = head = circ->cpath;
do {
if (cpath->extend_info &&
!tor_mem_is_zero(
(const char*)cpath->extend_info->curve25519_onion_key.public_key,
CURVE25519_PUBKEY_LEN))
return 1;
/* if the extend_info is missing, we can't tell if it supports ntor */
if (!cpath->extend_info) {
return 0;
}
/* if the key is blank, it definitely doesn't support ntor */
if (!extend_info_supports_ntor(cpath->extend_info)) {
return 0;
}
cpath = cpath->next;
} while (cpath != head);
return 0;
return 1;
}
/** Pick all the entries in our cpath. Stop and return 0 when we're
@ -390,43 +392,63 @@ circuit_cpath_supports_ntor(const origin_circuit_t *circ)
static int
onion_populate_cpath(origin_circuit_t *circ)
{
int n_tries = 0;
const int using_ntor = circuits_can_use_ntor();
int r = 0;
#define MAX_POPULATE_ATTEMPTS 32
/* onion_extend_cpath assumes these are non-NULL */
tor_assert(circ);
tor_assert(circ->build_state);
while (1) {
int r = onion_extend_cpath(circ);
while (r == 0) {
r = onion_extend_cpath(circ);
if (r < 0) {
log_info(LD_CIRC,"Generating cpath hop failed.");
return -1;
}
if (r == 1) {
/* This circuit doesn't need/shouldn't be forced to have an ntor hop */
if (circ->build_state->desired_path_len <= 1 || ! using_ntor)
}
/* The path is complete */
tor_assert(r == 1);
/* Does every node in this path support ntor? */
int path_supports_ntor = circuit_cpath_supports_ntor(circ);
/* We would like every path to support ntor, but we have to allow for some
* edge cases. */
tor_assert(circuit_get_cpath_len(circ));
if (circuit_can_use_tap(circ)) {
/* Circuits from clients to intro points, and hidden services to
* rend points do not support ntor, because the hidden service protocol
* does not include ntor onion keys. This is also true for Tor2web clients
* and Single Onion Services. */
return 0;
}
/* This circuit has an ntor hop. great! */
if (circuit_cpath_supports_ntor(circ))
if (circuit_get_cpath_len(circ) == 1) {
/* Allow for bootstrapping: when we're fetching directly from a fallback,
* authority, or bridge, we have no way of knowing its ntor onion key
* before we connect to it. So instead, we try connecting, and end up using
* CREATE_FAST. */
tor_assert(circ->cpath);
tor_assert(circ->cpath->extend_info);
const node_t *node = node_get_by_id(
circ->cpath->extend_info->identity_digest);
/* If we don't know the node and its descriptor, we must be bootstrapping.
*/
if (!node || !node_has_descriptor(node)) {
return 0;
/* No node in the circuit supports ntor. Have we already tried too many
* times? */
if (++n_tries >= MAX_POPULATE_ATTEMPTS)
break;
/* Clear the path and retry */
circuit_clear_cpath(circ);
}
}
log_warn(LD_CIRC, "I tried for %d times, but I couldn't build a %d-hop "
"circuit with at least one node that supports ntor.",
MAX_POPULATE_ATTEMPTS,
circ->build_state->desired_path_len);
if (BUG(!path_supports_ntor)) {
/* If we're building a multi-hop path, and it's not one of the HS or
* bootstrapping exceptions, and it doesn't support ntor, something has
* gone wrong. */
return -1;
}
return 0;
}
/** Create and return a new origin circuit. Initialize its purpose and
* build-state based on our arguments. The <b>flags</b> argument is a
* bitfield of CIRCLAUNCH_* flags. */
@ -757,10 +779,13 @@ should_use_create_fast_for_circuit(origin_circuit_t *circ)
tor_assert(circ->cpath);
tor_assert(circ->cpath->extend_info);
if (!circ->cpath->extend_info->onion_key)
return 1; /* our hand is forced: only a create_fast will work. */
if (!circuit_has_usable_onion_key(circ)) {
/* We don't have ntor, and we don't have or can't use TAP,
* so our hand is forced: only a create_fast will work. */
return 1;
}
if (public_server_mode(options)) {
/* We're a server, and we know an onion key. We can choose.
/* We're a server, and we have a usable onion key. We can choose.
* Prefer to blend our circuit into the other circuits we are
* creating on behalf of others. */
return 0;
@ -785,30 +810,20 @@ circuit_timeout_want_to_count_circ(origin_circuit_t *circ)
&& circ->build_state->desired_path_len == DEFAULT_ROUTE_LEN;
}
/** Return true if the ntor handshake is enabled in the configuration, or if
* it's been set to "auto" in the configuration and it's enabled in the
* consensus. */
static int
circuits_can_use_ntor(void)
{
const or_options_t *options = get_options();
if (options->UseNTorHandshake != -1)
return options->UseNTorHandshake;
return networkstatus_get_param(NULL, "UseNTorHandshake", 0, 0, 1);
}
/** Decide whether to use a TAP or ntor handshake for connecting to <b>ei</b>
* directly, and set *<b>cell_type_out</b> and *<b>handshake_type_out</b>
* accordingly. */
* accordingly.
* Note that TAP handshakes are only used for direct connections:
* - from Tor2web to intro points not in the client's consensus, and
* - from Single Onions to rend points not in the service's consensus.
* This is checked in onion_populate_cpath. */
static void
circuit_pick_create_handshake(uint8_t *cell_type_out,
uint16_t *handshake_type_out,
const extend_info_t *ei)
{
/* XXXX029 Remove support for deciding to use TAP. */
if (!tor_mem_is_zero((const char*)ei->curve25519_onion_key.public_key,
CURVE25519_PUBKEY_LEN) &&
circuits_can_use_ntor()) {
/* XXXX030 Remove support for deciding to use TAP. */
if (extend_info_supports_ntor(ei)) {
*cell_type_out = CELL_CREATE2;
*handshake_type_out = ONION_HANDSHAKE_TYPE_NTOR;
return;
@ -822,7 +837,11 @@ circuit_pick_create_handshake(uint8_t *cell_type_out,
* directly, and set *<b>handshake_type_out</b> accordingly. Decide whether,
* in extending through <b>node</b> to do so, we should use an EXTEND2 or an
* EXTEND cell to do so, and set *<b>cell_type_out</b> and
* *<b>create_cell_type_out</b> accordingly. */
* *<b>create_cell_type_out</b> accordingly.
* Note that TAP handshakes are only used for extend handshakes:
* - from clients to intro points, and
* - from hidden services to rend points.
* This is checked in onion_populate_cpath. */
static void
circuit_pick_extend_handshake(uint8_t *cell_type_out,
uint8_t *create_cell_type_out,
@ -833,11 +852,21 @@ circuit_pick_extend_handshake(uint8_t *cell_type_out,
uint8_t t;
circuit_pick_create_handshake(&t, handshake_type_out, ei);
/* XXXX029 Remove support for deciding to use TAP. */
/* XXXX030 Remove support for deciding to use TAP. */
/* It is an error to extend if there is no previous node. */
tor_assert_nonfatal(node_prev);
/* It is an error for a node with a known version to be so old it does not
* support ntor. */
tor_assert_nonfatal(routerstatus_version_supports_ntor(node_prev->rs, 1));
/* Assume relays without tor versions or routerstatuses support ntor.
* The authorities enforce ntor support, and assuming and failing is better
* than allowing a malicious node to perform a protocol downgrade to TAP. */
if (node_prev &&
*handshake_type_out != ONION_HANDSHAKE_TYPE_TAP &&
(node_has_curve25519_onion_key(node_prev) ||
(node_prev->rs && node_prev->rs->version_supports_extend2_cells))) {
(routerstatus_version_supports_ntor(node_prev->rs, 1)))) {
*cell_type_out = RELAY_COMMAND_EXTEND2;
*create_cell_type_out = CELL_CREATE2;
} else {
@ -2058,15 +2087,18 @@ count_acceptable_nodes(smartlist_t *nodes)
if (! node->is_running)
// log_debug(LD_CIRC,"Nope, the directory says %d is not running.",i);
continue;
/* XXX This clause makes us count incorrectly: if AllowInvalidRouters
* allows this node in some places, then we're getting an inaccurate
* count. For now, be conservative and don't count it. But later we
* should try to be smarter. */
if (! node->is_valid)
// log_debug(LD_CIRC,"Nope, the directory says %d is not valid.",i);
continue;
if (! node_has_descriptor(node))
continue;
/* XXX This clause makes us count incorrectly: if AllowInvalidRouters
* allows this node in some places, then we're getting an inaccurate
* count. For now, be conservative and don't count it. But later we
* should try to be smarter. */
/* The node has a descriptor, so we can just check the ntor key directly */
if (!node_has_curve25519_onion_key(node))
continue;
++num;
} SMARTLIST_FOREACH_END(node);
@ -2356,6 +2388,14 @@ extend_info_from_node(const node_t *node, int for_direct_connect)
log_warn(LD_CIRC, "Could not choose valid address for %s",
node->ri ? node->ri->nickname : node->rs->nickname);
/* Every node we connect or extend to must support ntor */
if (!node_has_curve25519_onion_key(node)) {
log_fn(LOG_PROTOCOL_WARN, LD_CIRC,
"Attempted to create extend_info for a node that does not support "
"ntor: %s", node_describe(node));
return NULL;
}
if (valid_addr && node->ri)
return extend_info_new(node->ri->nickname,
node->identity,
@ -2441,3 +2481,65 @@ extend_info_addr_is_allowed(const tor_addr_t *addr)
return 0;
}
/* Does ei have a valid TAP key? */
int
extend_info_supports_tap(const extend_info_t* ei)
{
tor_assert(ei);
/* Valid TAP keys are not NULL */
return ei->onion_key != NULL;
}
/* Does ei have a valid ntor key? */
int
extend_info_supports_ntor(const extend_info_t* ei)
{
tor_assert(ei);
/* Valid ntor keys have at least one non-zero byte */
return !tor_mem_is_zero(
(const char*)ei->curve25519_onion_key.public_key,
CURVE25519_PUBKEY_LEN);
}
/* Is circuit purpose allowed to use the deprecated TAP encryption protocol?
* The hidden service protocol still uses TAP for some connections, because
* ntor onion keys aren't included in HS descriptors or INTRODUCE cells. */
static int
circuit_purpose_can_use_tap_impl(uint8_t purpose)
{
return (purpose == CIRCUIT_PURPOSE_S_CONNECT_REND ||
purpose == CIRCUIT_PURPOSE_C_INTRODUCING);
}
/* Is circ allowed to use the deprecated TAP encryption protocol?
* The hidden service protocol still uses TAP for some connections, because
* ntor onion keys aren't included in HS descriptors or INTRODUCE cells. */
int
circuit_can_use_tap(const origin_circuit_t *circ)
{
tor_assert(circ);
tor_assert(circ->cpath);
tor_assert(circ->cpath->extend_info);
return (circuit_purpose_can_use_tap_impl(circ->base_.purpose) &&
extend_info_supports_tap(circ->cpath->extend_info));
}
/* Does circ have an onion key which it's allowed to use? */
int
circuit_has_usable_onion_key(const origin_circuit_t *circ)
{
tor_assert(circ);
tor_assert(circ->cpath);
tor_assert(circ->cpath->extend_info);
return (extend_info_supports_ntor(circ->cpath->extend_info) ||
circuit_can_use_tap(circ));
}
/* Does ei have an onion key which it would prefer to use?
* Currently, we prefer ntor keys*/
int
extend_info_has_preferred_onion_key(const extend_info_t* ei)
{
tor_assert(ei);
return extend_info_supports_ntor(ei);
}

View File

@ -54,6 +54,11 @@ extend_info_t *extend_info_from_node(const node_t *r, int for_direct_connect);
extend_info_t *extend_info_dup(extend_info_t *info);
void extend_info_free(extend_info_t *info);
int extend_info_addr_is_allowed(const tor_addr_t *addr);
int extend_info_supports_tap(const extend_info_t* ei);
int extend_info_supports_ntor(const extend_info_t* ei);
int circuit_can_use_tap(const origin_circuit_t *circ);
int circuit_has_usable_onion_key(const origin_circuit_t *circ);
int extend_info_has_preferred_onion_key(const extend_info_t* ei);
const node_t *build_state_get_exit_node(cpath_build_state_t *state);
const char *build_state_get_exit_nickname(cpath_build_state_t *state);

View File

@ -1613,7 +1613,8 @@ circuit_find_to_cannibalize(uint8_t purpose, extend_info_t *info,
return best;
}
/** Return the number of hops in circuit's path. */
/** Return the number of hops in circuit's path. If circ has no entries,
* or is NULL, returns 0. */
int
circuit_get_cpath_len(origin_circuit_t *circ)
{
@ -1629,7 +1630,8 @@ circuit_get_cpath_len(origin_circuit_t *circ)
}
/** Return the <b>hopnum</b>th hop in <b>circ</b>->cpath, or NULL if there
* aren't that many hops in the list. */
* aren't that many hops in the list. <b>hopnum</b> starts at 1.
* Returns NULL if <b>hopnum</b> is 0 or negative. */
crypt_path_t *
circuit_get_cpath_hop(origin_circuit_t *circ, int hopnum)
{

View File

@ -438,7 +438,7 @@ static config_var_t option_vars_[] = {
V(UseEntryGuardsAsDirGuards, BOOL, "1"),
V(UseGuardFraction, AUTOBOOL, "auto"),
V(UseMicrodescriptors, AUTOBOOL, "auto"),
V(UseNTorHandshake, AUTOBOOL, "1"),
OBSOLETE("UseNTorHandshake"),
V(User, STRING, NULL),
OBSOLETE("UserspaceIOCPBuffers"),
V(AuthDirSharedRandomness, BOOL, "1"),

View File

@ -255,6 +255,20 @@ dirserv_router_get_status(const routerinfo_t *router, const char **msg,
return FP_REJECT;
}
/* dirserv_get_status_impl already rejects versions older than 0.2.4.18-rc,
* and onion_curve25519_pkey was introduced in 0.2.4.8-alpha.
* But just in case a relay doesn't provide or lies about its version, or
* doesn't include an ntor key in its descriptor, check that it exists,
* and is non-zero (clients check that it's non-zero before using it). */
if (!routerinfo_has_curve25519_onion_key(router)) {
log_fn(severity, LD_DIR,
"Descriptor from router %s is missing an ntor curve25519 onion "
"key.", router_describe(router));
if (msg)
*msg = "Missing ntor curve25519 onion key. Please upgrade!";
return FP_REJECT;
}
if (router->cache_info.signing_key_cert) {
/* This has an ed25519 identity key. */
if (KEYPIN_MISMATCH ==

View File

@ -2275,6 +2275,12 @@ client_would_use_router(const routerstatus_t *rs, time_t now,
/* We'd drop it immediately for being too old. */
return 0;
}
if (!routerstatus_version_supports_ntor(rs, 1)) {
/* We'd ignore it because it doesn't support ntor.
* If we don't know the version, download the descriptor so we can
* check if it supports ntor. */
return 0;
}
return 1;
}

View File

@ -1173,14 +1173,38 @@ node_get_pref_ipv6_dirport(const node_t *node, tor_addr_port_t *ap_out)
}
}
/** Return true iff <b>md</b> has a curve25519 onion key.
* Use node_has_curve25519_onion_key() instead of calling this directly. */
static int
microdesc_has_curve25519_onion_key(const microdesc_t *md)
{
if (!md) {
return 0;
}
if (!md->onion_curve25519_pkey) {
return 0;
}
if (tor_mem_is_zero((const char*)md->onion_curve25519_pkey->public_key,
CURVE25519_PUBKEY_LEN)) {
return 0;
}
return 1;
}
/** Return true iff <b>node</b> has a curve25519 onion key. */
int
node_has_curve25519_onion_key(const node_t *node)
{
if (!node)
return 0;
if (node->ri)
return node->ri->onion_curve25519_pkey != NULL;
return routerinfo_has_curve25519_onion_key(node->ri);
else if (node->md)
return node->md->onion_curve25519_pkey != NULL;
return microdesc_has_curve25519_onion_key(node->md);
else
return 0;
}

View File

@ -11,6 +11,7 @@
**/
#include "or.h"
#include "circuitbuild.h"
#include "circuitlist.h"
#include "config.h"
#include "cpuworker.h"
@ -438,8 +439,7 @@ onion_skin_create(int type,
r = CREATE_FAST_LEN;
break;
case ONION_HANDSHAKE_TYPE_NTOR:
if (tor_mem_is_zero((const char*)node->curve25519_onion_key.public_key,
CURVE25519_PUBKEY_LEN))
if (!extend_info_supports_ntor(node))
return -1;
if (onion_skin_ntor_create((const uint8_t*)node->identity_digest,
&node->curve25519_onion_key,

View File

@ -4384,9 +4384,6 @@ typedef struct {
char *TLSECGroup; /**< One of "P256", "P224", or nil for auto */
/** Autobool: should we use the ntor handshake if we can? */
int UseNTorHandshake;
/** Fraction: */
double PathsNeededToBuildCircuits;

View File

@ -1368,8 +1368,13 @@ rend_client_get_random_intro_impl(const rend_cache_entry_t *entry,
i = crypto_rand_int(smartlist_len(usable_nodes));
intro = smartlist_get(usable_nodes, i);
if (BUG(!intro->extend_info)) {
/* This should never happen, but it isn't fatal, just try another */
smartlist_del(usable_nodes, i);
goto again;
}
/* Do we need to look up the router or is the extend info complete? */
if (!intro->extend_info->onion_key) {
if (!extend_info_supports_tap(intro->extend_info)) {
const node_t *node;
extend_info_t *new_extend_info;
if (tor_digest_is_zero(intro->extend_info->identity_digest))

View File

@ -3896,3 +3896,11 @@ rend_service_set_connection_addr_port(edge_connection_t *conn,
return -2;
}
/* Stub that should be replaced with the #17178 version of the function
* when merging. */
int
rend_service_allow_direct_connection(const or_options_t *options)
{
(void)options;
return 0;
}

View File

@ -131,5 +131,7 @@ void directory_post_to_hs_dir(rend_service_descriptor_t *renddesc,
const char *service_id, int seconds_valid);
void rend_service_desc_has_uploaded(const rend_data_t *rend_data);
int rend_service_allow_direct_connection(const or_options_t *options);
#endif

View File

@ -2836,6 +2836,10 @@ router_dump_router_to_string(routerinfo_t *router,
(const char *)router->onion_curve25519_pkey->public_key,
CURVE25519_PUBKEY_LEN, BASE64_ENCODE_MULTILINE);
smartlist_add_asprintf(chunks, "ntor-onion-key %s", kbuf);
} else {
/* Authorities will start rejecting relays without ntor keys in 0.2.9 */
log_err(LD_BUG, "A relay must have an ntor onion key");
goto err;
}
/* Write the exit policy to the end of 's'. */

View File

@ -2260,10 +2260,16 @@ router_add_running_nodes_to_smartlist(smartlist_t *sl, int allow_invalid,
continue;
if (node_is_unreliable(node, need_uptime, need_capacity, need_guard))
continue;
/* Choose a node with an OR address that matches the firewall rules,
* if we are making a direct connection */
/* Don't choose nodes if we are certain they can't do ntor */
if (node->rs && !routerstatus_version_supports_ntor(node->rs, 1))
continue;
if ((node->ri || node->md) && !node_has_curve25519_onion_key(node))
continue;
/* Choose a node with an OR address that matches the firewall rules */
if (direct_conn && check_reach &&
!fascist_firewall_allows_node(node, FIREWALL_OR_CONNECTION, pref_addr))
!fascist_firewall_allows_node(node,
FIREWALL_OR_CONNECTION,
pref_addr))
continue;
smartlist_add(sl, (void *)node);
@ -5497,6 +5503,45 @@ routerinfo_incompatible_with_extrainfo(const crypto_pk_t *identity_pkey,
return r;
}
/* Does ri have a valid ntor onion key?
* Valid ntor onion keys exist and have at least one non-zero byte. */
int
routerinfo_has_curve25519_onion_key(const routerinfo_t *ri)
{
if (!ri) {
return 0;
}
if (!ri->onion_curve25519_pkey) {
return 0;
}
if (tor_mem_is_zero((const char*)ri->onion_curve25519_pkey->public_key,
CURVE25519_PUBKEY_LEN)) {
return 0;
}
return 1;
}
/* Is rs running a tor version known to support ntor?
* If allow_unknown_versions is true, return true if the version is unknown.
* Otherwise, return false if the version is unknown. */
int
routerstatus_version_supports_ntor(const routerstatus_t *rs,
int allow_unknown_versions)
{
if (!rs) {
return allow_unknown_versions;
}
if (!rs->version_known) {
return allow_unknown_versions;
}
return rs->version_supports_extend2_cells;
}
/** Assert that the internal representation of <b>rl</b> is
* self-consistent. */
void

View File

@ -206,6 +206,9 @@ int routerinfo_incompatible_with_extrainfo(const crypto_pk_t *ri,
extrainfo_t *ei,
signed_descriptor_t *sd,
const char **msg);
int routerinfo_has_curve25519_onion_key(const routerinfo_t *ri);
int routerstatus_version_supports_ntor(const routerstatus_t *rs,
int allow_unknown_versions);
void routerlist_assert_ok(const routerlist_t *rl);
const char *esc_router_info(const routerinfo_t *router);

View File

@ -116,6 +116,7 @@ test_dir_formats(void *arg)
const addr_policy_t *p;
time_t now = time(NULL);
port_cfg_t orport, dirport;
char cert_buf[256];
(void)arg;
pk1 = pk_generate(0);
@ -135,6 +136,11 @@ test_dir_formats(void *arg)
tor_addr_parse(&r1->ipv6_addr, "1:2:3:4::");
r1->ipv6_orport = 9999;
r1->onion_pkey = crypto_pk_dup_key(pk1);
/* Fake just enough of an ntor key to get by */
curve25519_keypair_t r1_onion_keypair;
curve25519_keypair_generate(&r1_onion_keypair, 0);
r1->onion_curve25519_pkey = tor_memdup(&r1_onion_keypair.pubkey,
sizeof(curve25519_public_key_t));
r1->identity_pkey = crypto_pk_dup_key(pk2);
r1->bandwidthrate = 1000;
r1->bandwidthburst = 5000;
@ -167,11 +173,6 @@ test_dir_formats(void *arg)
&kp2.pubkey,
now, 86400,
CERT_FLAG_INCLUDE_SIGNING_KEY);
char cert_buf[256];
base64_encode(cert_buf, sizeof(cert_buf),
(const char*)r2->cache_info.signing_key_cert->encoded,
r2->cache_info.signing_key_cert->encoded_len,
BASE64_ENCODE_MULTILINE);
r2->platform = tor_strdup(platform);
r2->cache_info.published_on = 5;
r2->or_port = 9005;
@ -247,6 +248,11 @@ test_dir_formats(void *arg)
strlcat(buf2, "hidden-service-dir\n", sizeof(buf2));
strlcat(buf2, "contact Magri White <magri@elsewhere.example.com>\n",
sizeof(buf2));
strlcat(buf2, "ntor-onion-key ", sizeof(buf2));
base64_encode(cert_buf, sizeof(cert_buf),
(const char*)r1_onion_keypair.pubkey.public_key, 32,
BASE64_ENCODE_MULTILINE);
strlcat(buf2, cert_buf, sizeof(buf2));
strlcat(buf2, "reject *:*\n", sizeof(buf2));
strlcat(buf2, "tunnelled-dir-server\nrouter-signature\n", sizeof(buf2));
buf[strlen(buf2)] = '\0'; /* Don't compare the sig; it's never the same
@ -276,6 +282,10 @@ test_dir_formats(void *arg)
"router Fred 10.3.2.1 9005 0 0\n"
"identity-ed25519\n"
"-----BEGIN ED25519 CERT-----\n", sizeof(buf2));
base64_encode(cert_buf, sizeof(cert_buf),
(const char*)r2->cache_info.signing_key_cert->encoded,
r2->cache_info.signing_key_cert->encoded_len,
BASE64_ENCODE_MULTILINE);
strlcat(buf2, cert_buf, sizeof(buf2));
strlcat(buf2, "-----END ED25519 CERT-----\n", sizeof(buf2));
strlcat(buf2, "master-key-ed25519 ", sizeof(buf2));