mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-25 15:10:48 +01:00
prop224: Add connection and circuit identifier object
Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit is contained in:
parent
90046a09dd
commit
f8dc1164ba
7 changed files with 242 additions and 7 deletions
|
@ -67,6 +67,7 @@
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "hs_circuitmap.h"
|
#include "hs_circuitmap.h"
|
||||||
#include "hs_common.h"
|
#include "hs_common.h"
|
||||||
|
#include "hs_ident.h"
|
||||||
#include "networkstatus.h"
|
#include "networkstatus.h"
|
||||||
#include "nodelist.h"
|
#include "nodelist.h"
|
||||||
#include "onion.h"
|
#include "onion.h"
|
||||||
|
@ -957,6 +958,7 @@ circuit_free(circuit_t *circ)
|
||||||
|
|
||||||
crypto_pk_free(ocirc->intro_key);
|
crypto_pk_free(ocirc->intro_key);
|
||||||
rend_data_free(ocirc->rend_data);
|
rend_data_free(ocirc->rend_data);
|
||||||
|
hs_ident_circuit_free(ocirc->hs_ident);
|
||||||
|
|
||||||
tor_free(ocirc->dest_address);
|
tor_free(ocirc->dest_address);
|
||||||
if (ocirc->socks_username) {
|
if (ocirc->socks_username) {
|
||||||
|
|
|
@ -84,6 +84,7 @@
|
||||||
#include "geoip.h"
|
#include "geoip.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "hs_common.h"
|
#include "hs_common.h"
|
||||||
|
#include "hs_ident.h"
|
||||||
#include "nodelist.h"
|
#include "nodelist.h"
|
||||||
#include "policies.h"
|
#include "policies.h"
|
||||||
#include "reasons.h"
|
#include "reasons.h"
|
||||||
|
@ -605,6 +606,7 @@ connection_free_(connection_t *conn)
|
||||||
}
|
}
|
||||||
if (CONN_IS_EDGE(conn)) {
|
if (CONN_IS_EDGE(conn)) {
|
||||||
rend_data_free(TO_EDGE_CONN(conn)->rend_data);
|
rend_data_free(TO_EDGE_CONN(conn)->rend_data);
|
||||||
|
hs_ident_edge_conn_free(TO_EDGE_CONN(conn)->hs_ident);
|
||||||
}
|
}
|
||||||
if (conn->type == CONN_TYPE_CONTROL) {
|
if (conn->type == CONN_TYPE_CONTROL) {
|
||||||
control_connection_t *control_conn = TO_CONTROL_CONN(conn);
|
control_connection_t *control_conn = TO_CONTROL_CONN(conn);
|
||||||
|
@ -636,6 +638,7 @@ connection_free_(connection_t *conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
rend_data_free(dir_conn->rend_data);
|
rend_data_free(dir_conn->rend_data);
|
||||||
|
hs_ident_dir_conn_free(dir_conn->hs_ident);
|
||||||
if (dir_conn->guard_state) {
|
if (dir_conn->guard_state) {
|
||||||
/* Cancel before freeing, if it's still there. */
|
/* Cancel before freeing, if it's still there. */
|
||||||
entry_guard_cancel(&dir_conn->guard_state);
|
entry_guard_cancel(&dir_conn->guard_state);
|
||||||
|
|
|
@ -49,6 +49,12 @@
|
||||||
/* The time period rotation offset as seen in prop224 section [TIME-PERIODS] */
|
/* The time period rotation offset as seen in prop224 section [TIME-PERIODS] */
|
||||||
#define HS_TIME_PERIOD_ROTATION_OFFSET (12 * 60) /* minutes */
|
#define HS_TIME_PERIOD_ROTATION_OFFSET (12 * 60) /* minutes */
|
||||||
|
|
||||||
|
/* Type of authentication key used by an introduction point. */
|
||||||
|
typedef enum {
|
||||||
|
HS_AUTH_KEY_TYPE_LEGACY = 1,
|
||||||
|
HS_AUTH_KEY_TYPE_ED25519 = 2,
|
||||||
|
} hs_auth_key_type_t;
|
||||||
|
|
||||||
int hs_check_service_private_dir(const char *username, const char *path,
|
int hs_check_service_private_dir(const char *username, const char *path,
|
||||||
unsigned int dir_group_readable,
|
unsigned int dir_group_readable,
|
||||||
unsigned int create);
|
unsigned int create);
|
||||||
|
|
81
src/or/hs_ident.c
Normal file
81
src/or/hs_ident.c
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/* Copyright (c) 2017, The Tor Project, Inc. */
|
||||||
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file hs_ident.c
|
||||||
|
* \brief Contains circuit and connection identifier code for the whole HS
|
||||||
|
* subsytem.
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "hs_ident.h"
|
||||||
|
|
||||||
|
/* Return a newly allocated circuit identifier. The given public key is copied
|
||||||
|
* identity_pk into the identifier. */
|
||||||
|
hs_ident_circuit_t *
|
||||||
|
hs_ident_circuit_new(const ed25519_public_key_t *identity_pk,
|
||||||
|
hs_ident_circuit_type_t circuit_type)
|
||||||
|
{
|
||||||
|
tor_assert(circuit_type == HS_IDENT_CIRCUIT_INTRO ||
|
||||||
|
circuit_type == HS_IDENT_CIRCUIT_RENDEZVOUS);
|
||||||
|
hs_ident_circuit_t *ident = tor_malloc_zero(sizeof(*ident));
|
||||||
|
ed25519_pubkey_copy(&ident->identity_pk, identity_pk);
|
||||||
|
ident->circuit_type = circuit_type;
|
||||||
|
return ident;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the given circuit identifier. */
|
||||||
|
void
|
||||||
|
hs_ident_circuit_free(hs_ident_circuit_t *ident)
|
||||||
|
{
|
||||||
|
if (ident == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ident->auth_key_type == HS_AUTH_KEY_TYPE_LEGACY) {
|
||||||
|
crypto_pk_free(ident->auth_rsa_pk);
|
||||||
|
}
|
||||||
|
memwipe(ident, 0, sizeof(hs_ident_circuit_t));
|
||||||
|
tor_free(ident);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For a given directory connection identifier src, return a newly allocated
|
||||||
|
* copy of it. This can't fail. */
|
||||||
|
hs_ident_dir_conn_t *
|
||||||
|
hs_ident_dir_conn_dup(const hs_ident_dir_conn_t *src)
|
||||||
|
{
|
||||||
|
hs_ident_dir_conn_t *ident = tor_malloc_zero(sizeof(*ident));
|
||||||
|
memcpy(ident, src, sizeof(*ident));
|
||||||
|
return ident;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the given directory connection identifier. */
|
||||||
|
void
|
||||||
|
hs_ident_dir_conn_free(hs_ident_dir_conn_t *ident)
|
||||||
|
{
|
||||||
|
if (ident == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memwipe(ident, 0, sizeof(hs_ident_dir_conn_t));
|
||||||
|
tor_free(ident);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return a newly allocated edge connection identifier. The given public key
|
||||||
|
* identity_pk is copied into the identifier. */
|
||||||
|
hs_ident_edge_conn_t *
|
||||||
|
hs_ident_edge_conn_new(const ed25519_public_key_t *identity_pk)
|
||||||
|
{
|
||||||
|
hs_ident_edge_conn_t *ident = tor_malloc_zero(sizeof(*ident));
|
||||||
|
ed25519_pubkey_copy(&ident->identity_pk, identity_pk);
|
||||||
|
return ident;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the given edge connection identifier. */
|
||||||
|
void
|
||||||
|
hs_ident_edge_conn_free(hs_ident_edge_conn_t *ident)
|
||||||
|
{
|
||||||
|
if (ident == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memwipe(ident, 0, sizeof(hs_ident_edge_conn_t));
|
||||||
|
tor_free(ident);
|
||||||
|
}
|
||||||
|
|
124
src/or/hs_ident.h
Normal file
124
src/or/hs_ident.h
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
/* Copyright (c) 2017, The Tor Project, Inc. */
|
||||||
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file hs_ident.h
|
||||||
|
* \brief Header file containing circuit and connection identifier data for
|
||||||
|
* the whole HS subsytem.
|
||||||
|
*
|
||||||
|
* \details
|
||||||
|
* This interface is used to uniquely identify a hidden service on a circuit
|
||||||
|
* or connection using the service identity public key. Once the circuit or
|
||||||
|
* connection subsystem calls in the hidden service one, we use those
|
||||||
|
* identifiers to lookup the corresponding objects like service, intro point
|
||||||
|
* and descriptor.
|
||||||
|
*
|
||||||
|
* Furthermore, the circuit identifier holds cryptographic material needed for
|
||||||
|
* the e2e encryption on the rendezvous circuit which is set once the
|
||||||
|
* rendezvous circuit has opened and ready to be used.
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef TOR_HS_IDENT_H
|
||||||
|
#define TOR_HS_IDENT_H
|
||||||
|
|
||||||
|
#include "crypto.h"
|
||||||
|
#include "crypto_ed25519.h"
|
||||||
|
|
||||||
|
#include "hs_common.h"
|
||||||
|
|
||||||
|
/* Length of the rendezvous cookie that is used to connect circuits at the
|
||||||
|
* rendezvous point. */
|
||||||
|
#define HS_REND_COOKIE_LEN DIGEST_LEN
|
||||||
|
|
||||||
|
/* Type of circuit an hs_ident_t object is associated with. */
|
||||||
|
typedef enum {
|
||||||
|
HS_IDENT_CIRCUIT_INTRO = 1,
|
||||||
|
HS_IDENT_CIRCUIT_RENDEZVOUS = 2,
|
||||||
|
} hs_ident_circuit_type_t;
|
||||||
|
|
||||||
|
/* Client and service side circuit identifier that is used for hidden service
|
||||||
|
* circuit establishment. Not all fields contain data, it depends on the
|
||||||
|
* circuit purpose. This is attached to an origin_circuit_t. All fields are
|
||||||
|
* used by both client and service. */
|
||||||
|
typedef struct hs_ident_circuit_t {
|
||||||
|
/* (All circuit) The public key used to uniquely identify the service. It is
|
||||||
|
* the one found in the onion address. */
|
||||||
|
ed25519_public_key_t identity_pk;
|
||||||
|
|
||||||
|
/* (All circuit) The type of circuit this identifier is attached to.
|
||||||
|
* Accessors of the fields in this object assert non fatal on this circuit
|
||||||
|
* type. In other words, if a rendezvous field is being accessed, the
|
||||||
|
* circuit type MUST BE of type HS_IDENT_CIRCUIT_RENDEZVOUS. This value is
|
||||||
|
* set when an object is initialized in its constructor. */
|
||||||
|
hs_ident_circuit_type_t circuit_type;
|
||||||
|
|
||||||
|
/* (Only intro point circuit) Which type of authentication key this
|
||||||
|
* circuit identifier is using. */
|
||||||
|
hs_auth_key_type_t auth_key_type;
|
||||||
|
|
||||||
|
/* (Only intro point circuit) Introduction point authentication key. In
|
||||||
|
* legacy mode, we use an RSA key else an ed25519 public key. */
|
||||||
|
crypto_pk_t *auth_rsa_pk;
|
||||||
|
ed25519_public_key_t auth_ed25519_pk;
|
||||||
|
|
||||||
|
/* (Only rendezvous circuit) Rendezvous cookie sent from the client to the
|
||||||
|
* service with an INTRODUCE1 cell and used by the service in an
|
||||||
|
* RENDEZVOUS1 cell. */
|
||||||
|
uint8_t rendezvous_cookie[HS_REND_COOKIE_LEN];
|
||||||
|
|
||||||
|
/* (Only rendezvous circuit) The HANDSHAKE_INFO needed in the RENDEZVOUS1
|
||||||
|
* cell of the service. The construction is as follows:
|
||||||
|
* SERVER_PK [32 bytes]
|
||||||
|
* AUTH_MAC [32 bytes]
|
||||||
|
*/
|
||||||
|
uint8_t rendezvous_handshake_info[CURVE25519_PUBKEY_LEN + DIGEST256_LEN];
|
||||||
|
|
||||||
|
/* (Only rendezvous circuit) The NTOR_KEY_SEED needed for key derivation for
|
||||||
|
* the e2e encryption with the client on the circuit. */
|
||||||
|
uint8_t rendezvous_ntor_key_seed[DIGEST256_LEN];
|
||||||
|
|
||||||
|
/* (Only rendezvous circuit) Number of streams associated with this
|
||||||
|
* rendezvous circuit. We track this because there is a check on a maximum
|
||||||
|
* value. */
|
||||||
|
uint64_t num_rdv_streams;
|
||||||
|
} hs_ident_circuit_t;
|
||||||
|
|
||||||
|
/* Client and service side directory connection identifier used for a
|
||||||
|
* directory connection to identify which service is being queried. This is
|
||||||
|
* attached to a dir_connection_t. */
|
||||||
|
typedef struct hs_ident_dir_conn_t {
|
||||||
|
/* The public key used to uniquely identify the service. It is the one found
|
||||||
|
* in the onion address. */
|
||||||
|
ed25519_public_key_t identity_pk;
|
||||||
|
|
||||||
|
/* XXX: Client authorization. */
|
||||||
|
} hs_ident_dir_conn_t;
|
||||||
|
|
||||||
|
/* Client and service side edge connection identifier used for an edge
|
||||||
|
* connection to identify which service is being queried. This is attached to
|
||||||
|
* a edge_connection_t. */
|
||||||
|
typedef struct hs_ident_edge_conn_t {
|
||||||
|
/* The public key used to uniquely identify the service. It is the one found
|
||||||
|
* in the onion address. */
|
||||||
|
ed25519_public_key_t identity_pk;
|
||||||
|
|
||||||
|
/* XXX: Client authorization. */
|
||||||
|
} hs_ident_edge_conn_t;
|
||||||
|
|
||||||
|
/* Circuit identifier API. */
|
||||||
|
hs_ident_circuit_t *hs_ident_circuit_new(
|
||||||
|
const ed25519_public_key_t *identity_pk,
|
||||||
|
hs_ident_circuit_type_t circuit_type);
|
||||||
|
void hs_ident_circuit_free(hs_ident_circuit_t *ident);
|
||||||
|
|
||||||
|
/* Directory connection identifier API. */
|
||||||
|
hs_ident_dir_conn_t *hs_ident_dir_conn_dup(const hs_ident_dir_conn_t *src);
|
||||||
|
void hs_ident_dir_conn_free(hs_ident_dir_conn_t *ident);
|
||||||
|
|
||||||
|
/* Edge connection identifier API. */
|
||||||
|
hs_ident_edge_conn_t *hs_ident_edge_conn_new(
|
||||||
|
const ed25519_public_key_t *identity_pk);
|
||||||
|
void hs_ident_edge_conn_free(hs_ident_edge_conn_t *ident);
|
||||||
|
|
||||||
|
#endif /* TOR_HS_IDENT_H */
|
||||||
|
|
|
@ -50,16 +50,17 @@ LIBTOR_A_SOURCES = \
|
||||||
src/or/dnsserv.c \
|
src/or/dnsserv.c \
|
||||||
src/or/fp_pair.c \
|
src/or/fp_pair.c \
|
||||||
src/or/geoip.c \
|
src/or/geoip.c \
|
||||||
src/or/hs_intropoint.c \
|
src/or/hs_cache.c \
|
||||||
src/or/hs_circuitmap.c \
|
src/or/hs_circuitmap.c \
|
||||||
src/or/hs_ntor.c \
|
src/or/hs_common.c \
|
||||||
src/or/hs_service.c \
|
src/or/hs_descriptor.c \
|
||||||
|
src/or/hs_ident.c \
|
||||||
|
src/or/hs_intropoint.c \
|
||||||
|
src/or/hs_ntor.c \
|
||||||
|
src/or/hs_service.c \
|
||||||
src/or/entrynodes.c \
|
src/or/entrynodes.c \
|
||||||
src/or/ext_orport.c \
|
src/or/ext_orport.c \
|
||||||
src/or/hibernate.c \
|
src/or/hibernate.c \
|
||||||
src/or/hs_cache.c \
|
|
||||||
src/or/hs_common.c \
|
|
||||||
src/or/hs_descriptor.c \
|
|
||||||
src/or/keypin.c \
|
src/or/keypin.c \
|
||||||
src/or/main.c \
|
src/or/main.c \
|
||||||
src/or/microdesc.c \
|
src/or/microdesc.c \
|
||||||
|
@ -182,6 +183,7 @@ ORHEADERS = \
|
||||||
src/or/hs_cache.h \
|
src/or/hs_cache.h \
|
||||||
src/or/hs_common.h \
|
src/or/hs_common.h \
|
||||||
src/or/hs_descriptor.h \
|
src/or/hs_descriptor.h \
|
||||||
|
src/or/hs_ident.h \
|
||||||
src/or/hs_intropoint.h \
|
src/or/hs_intropoint.h \
|
||||||
src/or/hs_circuitmap.h \
|
src/or/hs_circuitmap.h \
|
||||||
src/or/hs_ntor.h \
|
src/or/hs_ntor.h \
|
||||||
|
|
17
src/or/or.h
17
src/or/or.h
|
@ -846,6 +846,11 @@ rend_data_v2_t *TO_REND_DATA_V2(const rend_data_t *d)
|
||||||
return DOWNCAST(rend_data_v2_t, d);
|
return DOWNCAST(rend_data_v2_t, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Stub because we can't include hs_ident.h. */
|
||||||
|
typedef struct hs_ident_edge_conn_t hs_ident_edge_conn_t;
|
||||||
|
typedef struct hs_ident_dir_conn_t hs_ident_dir_conn_t;
|
||||||
|
typedef struct hs_ident_circuit_t hs_ident_circuit_t;
|
||||||
|
|
||||||
/** Time interval for tracking replays of DH public keys received in
|
/** Time interval for tracking replays of DH public keys received in
|
||||||
* INTRODUCE2 cells. Used only to avoid launching multiple
|
* INTRODUCE2 cells. Used only to avoid launching multiple
|
||||||
* simultaneous attempts to connect to the same rendezvous point. */
|
* simultaneous attempts to connect to the same rendezvous point. */
|
||||||
|
@ -1633,6 +1638,10 @@ typedef struct edge_connection_t {
|
||||||
* an exit)? */
|
* an exit)? */
|
||||||
rend_data_t *rend_data;
|
rend_data_t *rend_data;
|
||||||
|
|
||||||
|
/* Hidden service connection identifier that is which service is being
|
||||||
|
* queried? */
|
||||||
|
hs_ident_edge_conn_t *hs_ident;
|
||||||
|
|
||||||
uint32_t address_ttl; /**< TTL for address-to-addr mapping on exit
|
uint32_t address_ttl; /**< TTL for address-to-addr mapping on exit
|
||||||
* connection. Exit connections only. */
|
* connection. Exit connections only. */
|
||||||
uint32_t begincell_flags; /** Flags sent or received in the BEGIN cell
|
uint32_t begincell_flags; /** Flags sent or received in the BEGIN cell
|
||||||
|
@ -1783,6 +1792,10 @@ typedef struct dir_connection_t {
|
||||||
/** What rendezvous service are we querying for? */
|
/** What rendezvous service are we querying for? */
|
||||||
rend_data_t *rend_data;
|
rend_data_t *rend_data;
|
||||||
|
|
||||||
|
/* Hidden service connection identifier that is which service is being
|
||||||
|
* queried? */
|
||||||
|
hs_ident_dir_conn_t *hs_ident;
|
||||||
|
|
||||||
/** If this is a one-hop connection, tracks the state of the directory guard
|
/** If this is a one-hop connection, tracks the state of the directory guard
|
||||||
* for this connection (if any). */
|
* for this connection (if any). */
|
||||||
struct circuit_guard_state_t *guard_state;
|
struct circuit_guard_state_t *guard_state;
|
||||||
|
@ -3186,6 +3199,10 @@ typedef struct origin_circuit_t {
|
||||||
/** Holds all rendezvous data on either client or service side. */
|
/** Holds all rendezvous data on either client or service side. */
|
||||||
rend_data_t *rend_data;
|
rend_data_t *rend_data;
|
||||||
|
|
||||||
|
/** Holds hidden service identifier on either client or service side. This
|
||||||
|
* is for both introduction and rendezvous circuit. */
|
||||||
|
hs_ident_circuit_t *hs_ident;
|
||||||
|
|
||||||
/** Holds the data that the entry guard system uses to track the
|
/** Holds the data that the entry guard system uses to track the
|
||||||
* status of the guard this circuit is using, and thereby to determine
|
* status of the guard this circuit is using, and thereby to determine
|
||||||
* whether this circuit can be used. */
|
* whether this circuit can be used. */
|
||||||
|
|
Loading…
Add table
Reference in a new issue