tor  master
Macros | Functions
hs_descriptor.c File Reference

Handle hidden service descriptor encoding/decoding. More...

#include "or.h"
#include "ed25519_cert.h"
#include "hs_descriptor.h"
#include "circuitbuild.h"
#include "crypto_rand.h"
#include "crypto_util.h"
#include "parsecommon.h"
#include "rendcache.h"
#include "hs_cache.h"
#include "hs_config.h"
#include "torcert.h"
Include dependency graph for hs_descriptor.c:

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 FILL_WITH_FAKE_DATA_AND_BASE64(field)
 
#define CLIENT_AUTH_ENTRIES_BLOCK_SIZE   16
 

Functions

STATIC void desc_plaintext_data_free_contents (hs_desc_plaintext_data_t *desc)
 
STATIC char * encode_link_specifiers (const smartlist_t *specs)
 
STATIC size_t build_plaintext_padding (const char *plaintext, size_t plaintext_len, uint8_t **padded_out)
 
STATIC smartlist_tdecode_link_specifiers (const char *encoded)
 
STATIC int cert_is_valid (tor_cert_t *cert, uint8_t type, const char *log_obj_type)
 
STATIC int encrypted_data_length_is_valid (size_t len)
 
 MOCK_IMPL (STATIC size_t, decrypt_desc_layer,(const hs_descriptor_t *desc, const uint8_t *encrypted_blob, size_t encrypted_blob_size, int is_superencrypted_layer, char **decrypted_out))
 
STATIC size_t decode_superencrypted (const char *message, size_t message_len, uint8_t **encrypted_out)
 
STATIC hs_desc_intro_point_tdecode_introduction_point (const hs_descriptor_t *desc, const char *start)
 
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)
 
int hs_desc_decode_encrypted (const hs_descriptor_t *desc, hs_desc_encrypted_data_t *desc_encrypted)
 
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, hs_descriptor_t **desc_out)
 
 MOCK_IMPL (int, hs_desc_encode_descriptor,(const hs_descriptor_t *desc, const ed25519_keypair_t *signing_kp, char **encoded_out))
 
void hs_desc_plaintext_data_free_ (hs_desc_plaintext_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)
 
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)
 
void hs_desc_link_specifier_free_ (hs_desc_link_specifier_t *ls)
 
hs_desc_link_specifier_ths_desc_link_specifier_new (const extend_info_t *info, uint8_t type)
 
void hs_descriptor_clear_intro_points (hs_descriptor_t *desc)
 
link_specifier_ths_desc_lspec_to_trunnel (const hs_desc_link_specifier_t *spec)
 

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.

Macro Definition Documentation

◆ CLIENT_AUTH_ENTRIES_BLOCK_SIZE

#define CLIENT_AUTH_ENTRIES_BLOCK_SIZE   16

How many lines of "client-auth" we want in our descriptors; fake or not.

◆ FILL_WITH_FAKE_DATA_AND_BASE64

#define FILL_WITH_FAKE_DATA_AND_BASE64 (   field)
Value:
STMT_BEGIN \
crypto_rand((char *)field, sizeof(field)); \
retval = base64_encode_nopad(field##_b64, sizeof(field##_b64), \
field, sizeof(field)); \
tor_assert(retval > 0); \
STMT_END
int base64_encode_nopad(char *dest, size_t destlen, const uint8_t *src, size_t srclen)
Definition: util_format.c:296

Function Documentation

◆ 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, int is_superencrypted_layer, char **decrypted_out)   
)

Decrypt an encrypted descriptor layer at encrypted_blob of size encrypted_blob_size. Use the descriptor object desc 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.