tor  0.4.2.0-alpha-dev
Macros | Functions | Variables
hs_descriptor.c File Reference
#include "core/or/or.h"
#include "trunnel/ed25519_cert.h"
#include "feature/hs/hs_descriptor.h"
#include "core/or/circuitbuild.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/crypt_ops/crypto_util.h"
#include "feature/dirparse/parsecommon.h"
#include "feature/rend/rendcache.h"
#include "feature/hs/hs_cache.h"
#include "feature/hs/hs_config.h"
#include "feature/nodelist/torcert.h"
#include "lib/memarea/memarea.h"
#include "lib/crypt_ops/crypto_format.h"
#include "core/or/extend_info_st.h"

Go to the source code of this file.

Macros

#define HS_DESCRIPTOR_PRIVATE
 
#define str_hs_desc   "hs-descriptor"
 
#define str_desc_cert   "descriptor-signing-key-cert"
 
#define str_rev_counter   "revision-counter"
 
#define str_superencrypted   "superencrypted"
 
#define str_encrypted   "encrypted"
 
#define str_signature   "signature"
 
#define str_lifetime   "descriptor-lifetime"
 
#define str_create2_formats   "create2-formats"
 
#define str_intro_auth_required   "intro-auth-required"
 
#define str_single_onion   "single-onion-service"
 
#define str_intro_point   "introduction-point"
 
#define str_ip_onion_key   "onion-key"
 
#define str_ip_auth_key   "auth-key"
 
#define str_ip_enc_key   "enc-key"
 
#define str_ip_enc_key_cert   "enc-key-cert"
 
#define str_ip_legacy_key   "legacy-key"
 
#define str_ip_legacy_key_cert   "legacy-key-cert"
 
#define str_intro_point_start   "\n" str_intro_point " "
 
#define str_enc_const_superencryption   "hsdir-superencrypted-data"
 
#define str_enc_const_encryption   "hsdir-encrypted-data"
 
#define str_desc_sig_prefix   "Tor onion service descriptor sig v3"
 
#define str_desc_auth_type   "desc-auth-type"
 
#define str_desc_auth_key   "desc-auth-ephemeral-key"
 
#define str_desc_auth_client   "auth-client"
 
#define str_encrypted   "encrypted"
 
#define ASSERT_AND_BASE64(field)
 

Functions

static void build_mac (const uint8_t *mac_key, size_t mac_key_len, const uint8_t *salt, size_t salt_len, const uint8_t *encrypted, size_t encrypted_len, uint8_t *mac_out, size_t mac_len)
 
static size_t build_secret_input (const hs_descriptor_t *desc, const uint8_t *secret_data, size_t secret_data_len, uint8_t **secret_input_out)
 
static void build_kdf_key (const hs_descriptor_t *desc, const uint8_t *secret_data, size_t secret_data_len, const uint8_t *salt, size_t salt_len, uint8_t *key_out, size_t key_out_len, int is_superencrypted_layer)
 
static void build_secret_key_iv_mac (const hs_descriptor_t *desc, const uint8_t *secret_data, size_t secret_data_len, const uint8_t *salt, size_t salt_len, uint8_t *key_out, size_t key_len, uint8_t *iv_out, size_t iv_len, uint8_t *mac_out, size_t mac_len, int is_superencrypted_layer)
 
STATIC char * encode_link_specifiers (const smartlist_t *specs)
 
static char * encode_legacy_key (const hs_desc_intro_point_t *ip)
 
static char * encode_enc_key (const hs_desc_intro_point_t *ip)
 
static char * encode_onion_key (const hs_desc_intro_point_t *ip)
 
static char * encode_intro_point (const ed25519_public_key_t *sig_key, const hs_desc_intro_point_t *ip)
 
static size_t compute_padded_plaintext_length (size_t plaintext_len)
 
STATIC size_t build_plaintext_padding (const char *plaintext, size_t plaintext_len, uint8_t **padded_out)
 
static size_t build_encrypted (const uint8_t *key, const uint8_t *iv, const char *plaintext, size_t plaintext_len, uint8_t **encrypted_out, int is_superencrypted_layer)
 
static size_t encrypt_descriptor_data (const hs_descriptor_t *desc, const uint8_t *secret_data, size_t secret_data_len, const char *plaintext, char **encrypted_out, int is_superencrypted_layer)
 
static char * get_auth_client_str (const hs_desc_authorized_client_t *client)
 
static char * get_all_auth_client_lines (const hs_descriptor_t *desc)
 
static char * get_inner_encrypted_layer_plaintext (const hs_descriptor_t *desc)
 
static char * get_outer_encrypted_layer_plaintext (const hs_descriptor_t *desc, const char *layer2_b64_ciphertext)
 
static char * encrypt_desc_data_and_base64 (const hs_descriptor_t *desc, const uint8_t *secret_data, size_t secret_data_len, const char *encoded_str, int is_superencrypted_layer)
 
static size_t build_secret_data (const ed25519_public_key_t *blinded_pubkey, const uint8_t *descriptor_cookie, uint8_t **secret_data_out)
 
static int encode_superencrypted_data (const hs_descriptor_t *desc, const uint8_t *descriptor_cookie, char **encrypted_blob_out)
 
static int desc_encode_v3 (const hs_descriptor_t *desc, const ed25519_keypair_t *signing_kp, const uint8_t *descriptor_cookie, char **encoded_out)
 
static int decode_auth_client (const directory_token_t *tok, hs_desc_authorized_client_t *client)
 
STATIC smartlist_tdecode_link_specifiers (const char *encoded)
 
static int decode_auth_type (hs_desc_encrypted_data_t *desc, const char *list)
 
static void decode_create2_list (hs_desc_encrypted_data_t *desc, const char *list)
 
STATIC int cert_is_valid (tor_cert_t *cert, uint8_t type, const char *log_obj_type)
 
static int cert_parse_and_validate (tor_cert_t **cert_out, const char *data, size_t data_len, unsigned int cert_type_wanted, const char *err_msg)
 
STATIC int encrypted_data_length_is_valid (size_t len)
 
static size_t build_descriptor_cookie_keys (const uint8_t *subcredential, size_t subcredential_len, const curve25519_secret_key_t *sk, const curve25519_public_key_t *pk, uint8_t **keys_out)
 
static int decrypt_descriptor_cookie (const hs_descriptor_t *desc, const hs_desc_authorized_client_t *client, const curve25519_secret_key_t *client_auth_sk, uint8_t **descriptor_cookie_out)
 
 MOCK_IMPL (STATIC size_t, decrypt_desc_layer,(const hs_descriptor_t *desc, const uint8_t *encrypted_blob, size_t encrypted_blob_size, const uint8_t *descriptor_cookie, int is_superencrypted_layer, char **decrypted_out))
 
static size_t desc_decrypt_superencrypted (const hs_descriptor_t *desc, char **decrypted_out)
 
static size_t desc_decrypt_encrypted (const hs_descriptor_t *desc, const curve25519_secret_key_t *client_auth_sk, char **decrypted_out)
 
static int decode_intro_legacy_key (const directory_token_t *tok, smartlist_t *tokens, hs_desc_intro_point_t *ip, const hs_descriptor_t *desc)
 
static int set_intro_point_onion_key (curve25519_public_key_t *onion_key_out, const smartlist_t *tokens)
 
STATIC hs_desc_intro_point_tdecode_introduction_point (const hs_descriptor_t *desc, const char *start)
 
static void decode_intro_points (const hs_descriptor_t *desc, hs_desc_encrypted_data_t *desc_enc, const char *data)
 
STATIC int desc_sig_is_valid (const char *b64_sig, const ed25519_public_key_t *signing_pubkey, const char *encoded_desc, size_t encoded_len)
 
static int desc_decode_plaintext_v3 (smartlist_t *tokens, hs_desc_plaintext_data_t *desc, const char *encoded_desc, size_t encoded_len)
 
static int desc_decode_superencrypted_v3 (const hs_descriptor_t *desc, hs_desc_superencrypted_data_t *desc_superencrypted_out)
 
static int desc_decode_encrypted_v3 (const hs_descriptor_t *desc, const curve25519_secret_key_t *client_auth_sk, hs_desc_encrypted_data_t *desc_encrypted_out)
 
int hs_desc_decode_encrypted (const hs_descriptor_t *desc, const curve25519_secret_key_t *client_auth_sk, hs_desc_encrypted_data_t *desc_encrypted)
 
int hs_desc_decode_superencrypted (const hs_descriptor_t *desc, hs_desc_superencrypted_data_t *desc_superencrypted)
 
int hs_desc_decode_plaintext (const char *encoded, hs_desc_plaintext_data_t *plaintext)
 
int hs_desc_decode_descriptor (const char *encoded, const uint8_t *subcredential, const curve25519_secret_key_t *client_auth_sk, hs_descriptor_t **desc_out)
 
 MOCK_IMPL (int, hs_desc_encode_descriptor,(const hs_descriptor_t *desc, const ed25519_keypair_t *signing_kp, const uint8_t *descriptor_cookie, char **encoded_out))
 
void hs_desc_plaintext_data_free_contents (hs_desc_plaintext_data_t *desc)
 
void hs_desc_superencrypted_data_free_contents (hs_desc_superencrypted_data_t *desc)
 
void hs_desc_encrypted_data_free_contents (hs_desc_encrypted_data_t *desc)
 
void hs_desc_plaintext_data_free_ (hs_desc_plaintext_data_t *desc)
 
void hs_desc_superencrypted_data_free_ (hs_desc_superencrypted_data_t *desc)
 
void hs_desc_encrypted_data_free_ (hs_desc_encrypted_data_t *desc)
 
void hs_descriptor_free_ (hs_descriptor_t *desc)
 
size_t hs_desc_plaintext_obj_size (const hs_desc_plaintext_data_t *data)
 
static size_t hs_desc_encrypted_obj_size (const hs_desc_encrypted_data_t *data)
 
size_t hs_desc_obj_size (const hs_descriptor_t *data)
 
hs_desc_intro_point_ths_desc_intro_point_new (void)
 
void hs_desc_intro_point_free_ (hs_desc_intro_point_t *ip)
 
hs_desc_authorized_client_ths_desc_build_fake_authorized_client (void)
 
void hs_desc_build_authorized_client (const uint8_t *subcredential, const curve25519_public_key_t *client_auth_pk, const curve25519_secret_key_t *auth_ephemeral_sk, const uint8_t *descriptor_cookie, hs_desc_authorized_client_t *client_out)
 
void hs_desc_authorized_client_free_ (hs_desc_authorized_client_t *client)
 
void hs_descriptor_clear_intro_points (hs_descriptor_t *desc)
 

Variables

struct {
   hs_desc_auth_type_t   type
 
   const char *   identifier
 
intro_auth_types []
 
static token_rule_t hs_desc_v3_token_table []
 
static token_rule_t hs_desc_superencrypted_v3_token_table []
 
static token_rule_t hs_desc_encrypted_v3_token_table []
 
static token_rule_t hs_desc_intro_point_v3_token_table []
 
static int(* decode_encrypted_handlers [])(const hs_descriptor_t *desc, const curve25519_secret_key_t *client_auth_sk, hs_desc_encrypted_data_t *desc_encrypted)
 
static int(* decode_superencrypted_handlers [])(const hs_descriptor_t *desc, hs_desc_superencrypted_data_t *desc_superencrypted)
 
static int(* decode_plaintext_handlers [])(smartlist_t *tokens, hs_desc_plaintext_data_t *desc, const char *encoded_desc, size_t encoded_len)
 
static int(* encode_handlers [])(const hs_descriptor_t *desc, const ed25519_keypair_t *signing_kp, const uint8_t *descriptor_cookie, char **encoded_out)
 

Detailed Description

Handle hidden service descriptor encoding/decoding.

Here is a graphical depiction of an HS descriptor and its layers:

 +------------------------------------------------------+
 |DESCRIPTOR HEADER:                                    |
 |  hs-descriptor 3                                     |
 |  descriptor-lifetime 180                             |
 |  ...                                                 |
 |  superencrypted                                      |
 |+---------------------------------------------------+ |
 ||SUPERENCRYPTED LAYER (aka OUTER ENCRYPTED LAYER):  | |
 ||  desc-auth-type x25519                            | |
 ||  desc-auth-ephemeral-key                          | |
 ||  auth-client                                      | |
 ||  auth-client                                      | |
 ||  ...                                              | |
 ||  encrypted                                        | |
 ||+-------------------------------------------------+| |
 |||ENCRYPTED LAYER (aka INNER ENCRYPTED LAYER):     || |
 |||  create2-formats                                || |
 |||  intro-auth-required                            || |
 |||  introduction-point                             || |
 |||  introduction-point                             || |
 |||  ...                                            || |
 ||+-------------------------------------------------+| |
 |+---------------------------------------------------+ |
 +------------------------------------------------------+

The DESCRIPTOR HEADER section is completely unencrypted and contains generic descriptor metadata.

The SUPERENCRYPTED LAYER section is the first layer of encryption, and it's encrypted using the blinded public key of the hidden service to protect against entities who don't know its onion address. The clients of the hidden service know its onion address and blinded public key, whereas third-parties (like HSDirs) don't know it (except if it's a public hidden service).

The ENCRYPTED LAYER section is the second layer of encryption, and it's encrypted using the client authorization key material (if those exist). When client authorization is enabled, this second layer of encryption protects the descriptor content from unauthorized entities. If client authorization is disabled, this second layer of encryption does not provide any extra security but is still present. The plaintext of this layer contains all the information required to connect to the hidden service like its list of introduction points.

Definition in file hs_descriptor.c.

Macro Definition Documentation

◆ ASSERT_AND_BASE64

#define ASSERT_AND_BASE64 (   field)
Value:
tor_assert(!fast_mem_is_zero((char *) client->field, \
sizeof(client->field))); \
ret = base64_encode_nopad(field##_b64, sizeof(field##_b64), \
client->field, sizeof(client->field)); \
tor_assert(ret > 0); \
STMT_END
int fast_mem_is_zero(const char *mem, size_t len)
Definition: util_string.c:74
tor_assert(buffer)
int base64_encode_nopad(char *dest, size_t destlen, const uint8_t *src, size_t srclen)
Definition: binascii.c:329

Function Documentation

◆ get_all_auth_client_lines()

static char* get_all_auth_client_lines ( const hs_descriptor_t desc)
static

Create the "client-auth" part of the descriptor and return a newly-allocated string with it. It's the responsibility of the caller to free the returned string.

Definition at line 705 of file hs_descriptor.c.

References tor_assert().

◆ MOCK_IMPL()

MOCK_IMPL ( STATIC  size_t,
decrypt_desc_layer  ,
(const hs_descriptor_t *desc, const uint8_t *encrypted_blob, size_t encrypted_blob_size, const uint8_t *descriptor_cookie, int is_superencrypted_layer, char **decrypted_out)   
)

Decrypt an encrypted descriptor layer at encrypted_blob of size encrypted_blob_size. The descriptor cookie is optional. Use the descriptor object desc and descriptor_cookie to generate the right decryption keys; set decrypted_out to the plaintext. If is_superencrypted_layer is set, this is the outter encrypted layer of the descriptor.

On any error case, including an empty output, return 0 and set *decrypted_out to NULL.

Definition at line 1478 of file hs_descriptor.c.

Variable Documentation

◆ decode_encrypted_handlers

int(* decode_encrypted_handlers[])(const hs_descriptor_t *desc, const curve25519_secret_key_t *client_auth_sk, hs_desc_encrypted_data_t *desc_encrypted)
static
Initial value:
=
{
NULL, NULL, NULL,
desc_decode_encrypted_v3,
}

Definition at line 2367 of file hs_descriptor.c.

◆ decode_plaintext_handlers

int(* decode_plaintext_handlers[])(smartlist_t *tokens, hs_desc_plaintext_data_t *desc, const char *encoded_desc, size_t encoded_len)
static
Initial value:
=
{
NULL, NULL, NULL,
desc_decode_plaintext_v3,
}

Definition at line 2471 of file hs_descriptor.c.

◆ decode_superencrypted_handlers

int(* decode_superencrypted_handlers[])(const hs_descriptor_t *desc, hs_desc_superencrypted_data_t *desc_superencrypted)
static
Initial value:
=
{
NULL, NULL, NULL,
desc_decode_superencrypted_v3,
}

Definition at line 2420 of file hs_descriptor.c.

◆ encode_handlers

int(* encode_handlers[])(const hs_descriptor_t *desc, const ed25519_keypair_t *signing_kp, const uint8_t *descriptor_cookie, char **encoded_out)
static
Initial value:
=
{
NULL, NULL, NULL,
desc_encode_v3,
}

Definition at line 2617 of file hs_descriptor.c.

◆ hs_desc_encrypted_v3_token_table

token_rule_t hs_desc_encrypted_v3_token_table[]
static
Initial value:
= {
T1_START(str_create2_formats, R3_CREATE2_FORMATS, CONCAT_ARGS, NO_OBJ),
T01(str_intro_auth_required, R3_INTRO_AUTH_REQUIRED, ARGS, NO_OBJ),
T01(str_single_onion, R3_SINGLE_ONION_SERVICE, ARGS, NO_OBJ),
}
#define END_OF_TABLE
Definition: parsecommon.h:244
#define T1_START(s, t, a, o)
Definition: parsecommon.h:252
#define ARGS
Definition: parsecommon.h:263
#define CONCAT_ARGS
Definition: parsecommon.h:267
#define T01(s, t, a, o)
Definition: parsecommon.h:258

Definition at line 136 of file hs_descriptor.c.

◆ hs_desc_intro_point_v3_token_table

token_rule_t hs_desc_intro_point_v3_token_table[]
static
Initial value:
= {
T1_START(str_intro_point, R3_INTRODUCTION_POINT, EQ(1), NO_OBJ),
T1N(str_ip_onion_key, R3_INTRO_ONION_KEY, GE(2), OBJ_OK),
T1(str_ip_auth_key, R3_INTRO_AUTH_KEY, NO_ARGS, NEED_OBJ),
T1(str_ip_enc_key, R3_INTRO_ENC_KEY, GE(2), OBJ_OK),
T1(str_ip_enc_key_cert, R3_INTRO_ENC_KEY_CERT, ARGS, OBJ_OK),
T01(str_ip_legacy_key, R3_INTRO_LEGACY_KEY, ARGS, NEED_KEY_1024),
T01(str_ip_legacy_key_cert, R3_INTRO_LEGACY_KEY_CERT, ARGS, OBJ_OK),
}
#define END_OF_TABLE
Definition: parsecommon.h:244
#define T1_START(s, t, a, o)
Definition: parsecommon.h:252
#define T1N(s, t, a, o)
Definition: parsecommon.h:256
#define NO_ARGS
Definition: parsecommon.h:265
#define GE(n)
Definition: parsecommon.h:269
#define ARGS
Definition: parsecommon.h:263
#define EQ(n)
Definition: parsecommon.h:271
#define T1(s, t, a, o)
Definition: parsecommon.h:250
#define T01(s, t, a, o)
Definition: parsecommon.h:258

Definition at line 144 of file hs_descriptor.c.

◆ hs_desc_superencrypted_v3_token_table

token_rule_t hs_desc_superencrypted_v3_token_table[]
static
Initial value:
= {
T1_START(str_desc_auth_type, R3_DESC_AUTH_TYPE, GE(1), NO_OBJ),
T1(str_desc_auth_key, R3_DESC_AUTH_KEY, GE(1), NO_OBJ),
T1N(str_desc_auth_client, R3_DESC_AUTH_CLIENT, GE(3), NO_OBJ),
T1(str_encrypted, R3_ENCRYPTED, NO_ARGS, NEED_OBJ),
}
#define END_OF_TABLE
Definition: parsecommon.h:244
#define T1_START(s, t, a, o)
Definition: parsecommon.h:252
#define T1N(s, t, a, o)
Definition: parsecommon.h:256
#define NO_ARGS
Definition: parsecommon.h:265
#define GE(n)
Definition: parsecommon.h:269
#define T1(s, t, a, o)
Definition: parsecommon.h:250

Definition at line 127 of file hs_descriptor.c.

◆ hs_desc_v3_token_table

token_rule_t hs_desc_v3_token_table[]
static
Initial value:
= {
T1_START(str_hs_desc, R_HS_DESCRIPTOR, EQ(1), NO_OBJ),
T1(str_lifetime, R3_DESC_LIFETIME, EQ(1), NO_OBJ),
T1(str_desc_cert, R3_DESC_SIGNING_CERT, NO_ARGS, NEED_OBJ),
T1(str_rev_counter, R3_REVISION_COUNTER, EQ(1), NO_OBJ),
T1(str_superencrypted, R3_SUPERENCRYPTED, NO_ARGS, NEED_OBJ),
T1_END(str_signature, R3_SIGNATURE, EQ(1), NO_OBJ),
}
#define END_OF_TABLE
Definition: parsecommon.h:244
#define T1_START(s, t, a, o)
Definition: parsecommon.h:252
#define NO_ARGS
Definition: parsecommon.h:265
#define EQ(n)
Definition: parsecommon.h:271
#define T1_END(s, t, a, o)
Definition: parsecommon.h:254
#define T1(s, t, a, o)
Definition: parsecommon.h:250

Definition at line 116 of file hs_descriptor.c.

◆ intro_auth_types

const { ... } intro_auth_types[]
Initial value:
= {
{ HS_DESC_AUTH_ED25519, "ed25519" },
{ 0, NULL }
}