Tor  0.4.7.0-alpha-dev
Macros | Functions | Variables
hs_descriptor.c File Reference

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

#include <stdbool.h>
#include "core/or/or.h"
#include "app/config/config.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/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 hs_subcredential_t *subcredential, 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)
 
STATIC size_t decrypt_desc_layer (const hs_descriptor_t *desc, const uint8_t *descriptor_cookie, bool 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 hs_desc_decode_status_t desc_decode_plaintext_v3 (smartlist_t *tokens, hs_desc_plaintext_data_t *desc, const char *encoded_desc, size_t encoded_len)
 
static hs_desc_decode_status_t desc_decode_superencrypted_v3 (const hs_descriptor_t *desc, hs_desc_superencrypted_data_t *desc_superencrypted_out)
 
static hs_desc_decode_status_t 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)
 
hs_desc_decode_status_t hs_desc_decode_encrypted (const hs_descriptor_t *desc, const curve25519_secret_key_t *client_auth_sk, hs_desc_encrypted_data_t *desc_encrypted)
 
hs_desc_decode_status_t hs_desc_decode_superencrypted (const hs_descriptor_t *desc, hs_desc_superencrypted_data_t *desc_superencrypted)
 
hs_desc_decode_status_t hs_desc_decode_plaintext (const char *encoded, hs_desc_plaintext_data_t *plaintext)
 
hs_desc_decode_status_t hs_desc_decode_descriptor (const char *encoded, const hs_subcredential_t *subcredential, const curve25519_secret_key_t *client_auth_sk, hs_descriptor_t **desc_out)
 
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 hs_subcredential_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 hs_desc_decode_status_t(* decode_encrypted_handlers [])(const hs_descriptor_t *desc, const curve25519_secret_key_t *client_auth_sk, hs_desc_encrypted_data_t *desc_encrypted)
 
static hs_desc_decode_status_t(* decode_superencrypted_handlers [])(const hs_descriptor_t *desc, hs_desc_superencrypted_data_t *desc_superencrypted)
 
static hs_desc_decode_status_t(* 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 base64_encode_nopad(char *dest, size_t destlen, const uint8_t *src, size_t srclen)
Definition: binascii.c:329
#define tor_assert(expr)
Definition: util_bug.h:102
int fast_mem_is_zero(const char *mem, size_t len)
Definition: util_string.c:74

Function Documentation

◆ build_descriptor_cookie_keys()

static size_t build_descriptor_cookie_keys ( const hs_subcredential_t subcredential,
const curve25519_secret_key_t sk,
const curve25519_public_key_t pk,
uint8_t **  keys_out 
)
static

Build the KEYS component for the authorized client computation. The format of the construction is:

SECRET_SEED = x25519(sk, pk) KEYS = KDF(subcredential | SECRET_SEED, 40)

Set the keys_out argument to point to the buffer containing the KEYS, and return the buffer's length. The caller should wipe and free its content once done with it. This function can't fail.

Definition at line 1375 of file hs_descriptor.c.

◆ build_encrypted()

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

Using a key, IV and plaintext data of length plaintext_len, create the encrypted section by encrypting it and setting encrypted_out with the data. Return size of the encrypted data buffer.

Definition at line 556 of file hs_descriptor.c.

Referenced by encrypt_descriptor_data().

◆ build_kdf_key()

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

Do the KDF construction and put the resulting data in key_out which is of key_out_len length. It uses SHAKE-256 as specified in the spec.

Definition at line 231 of file hs_descriptor.c.

Referenced by build_secret_key_iv_mac().

◆ build_mac()

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

Using a key, salt and encrypted payload, build a MAC and put it in mac_out. We use SHA3-256 for the MAC computation. This function can't fail.

Definition at line 160 of file hs_descriptor.c.

Referenced by decrypt_desc_layer().

◆ build_plaintext_padding()

STATIC size_t build_plaintext_padding ( const char *  plaintext,
size_t  plaintext_len,
uint8_t **  padded_out 
)

Given a buffer, pad it up to the encrypted section padding requirement. Set the newly allocated string in padded_out and return the length of the padded buffer.

Definition at line 533 of file hs_descriptor.c.

Referenced by build_encrypted().

◆ build_secret_data()

static size_t build_secret_data ( const ed25519_public_key_t blinded_pubkey,
const uint8_t *  descriptor_cookie,
uint8_t **  secret_data_out 
)
static

Generate the secret data which is used to encrypt/decrypt the descriptor.

SECRET_DATA = blinded-public-key SECRET_DATA = blinded-public-key | descriptor_cookie

The descriptor_cookie is optional but if it exists, it must be at least HS_DESC_DESCRIPTOR_COOKIE_LEN bytes long.

A newly allocated secret data is put in secret_data_out. Return the length of the secret data. This function cannot fail.

Definition at line 893 of file hs_descriptor.c.

Referenced by decrypt_desc_layer(), and encode_superencrypted_data().

◆ build_secret_input()

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

Using a secret data and a given descriptor object, build the secret input needed for the KDF.

secret_input = SECRET_DATA | subcredential | INT_8(revision_counter)

Then, set the newly allocated buffer in secret_input_out and return the length of the buffer.

Definition at line 196 of file hs_descriptor.c.

Referenced by build_kdf_key().

◆ build_secret_key_iv_mac()

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

Using the given descriptor, secret data, and salt, run it through our KDF function and then extract a secret key in key_out, the IV in iv_out and MAC in mac_out. This function can't fail.

Definition at line 277 of file hs_descriptor.c.

Referenced by decrypt_desc_layer(), and encrypt_descriptor_data().

◆ cert_is_valid()

STATIC int cert_is_valid ( tor_cert_t cert,
uint8_t  type,
const char *  log_obj_type 
)

Given a certificate, validate the certificate for certain conditions which are if the given type matches the cert's one, if the signing key is included and if the that key was actually used to sign the certificate.

Return 1 iff if all conditions pass or 0 if one of them fails.

Definition at line 1269 of file hs_descriptor.c.

◆ cert_parse_and_validate()

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

Given some binary data, try to parse it to get a certificate object. If we have a valid cert, validate it using the given wanted type. On error, print a log using the err_msg has the certificate identifier adding semantic to the log and cert_out is set to NULL. On success, 0 is returned and cert_out points to a newly allocated certificate object.

Definition at line 1315 of file hs_descriptor.c.

◆ compute_padded_plaintext_length()

static size_t compute_padded_plaintext_length ( size_t  plaintext_len)
static

Given a source length, return the new size including padding for the plaintext encryption.

Definition at line 512 of file hs_descriptor.c.

Referenced by build_plaintext_padding().

◆ decode_auth_client()

static int decode_auth_client ( const directory_token_t tok,
hs_desc_authorized_client_t client 
)
static

Given the token tok for an auth client, decode it as hs_desc_authorized_client_t. tok->args MUST contain at least 3 elements Return 0 on success else -1 on failure.

Definition at line 1115 of file hs_descriptor.c.

◆ decode_auth_type()

static int decode_auth_type ( hs_desc_encrypted_data_t desc,
const char *  list 
)
static

Given a list of authentication types, decode it and put it in the encrypted data section. Return 1 if we at least know one of the type or 0 if we know none of them.

Definition at line 1205 of file hs_descriptor.c.

◆ decode_create2_list()

static void decode_create2_list ( hs_desc_encrypted_data_t desc,
const char *  list 
)
static

Parse a space-delimited list of integers representing CREATE2 formats into the bitfield in hs_desc_encrypted_data_t. Ignore unrecognized values.

Definition at line 1232 of file hs_descriptor.c.

◆ decode_intro_legacy_key()

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

Given the token tok for an intro point legacy key, the list of tokens, the introduction point ip being decoded and the descriptor desc from which it comes from, decode the legacy key and set the intro point object. Return 0 on success else -1 on failure.

Definition at line 1695 of file hs_descriptor.c.

◆ decode_intro_points()

static void decode_intro_points ( const hs_descriptor_t desc,
hs_desc_encrypted_data_t desc_enc,
const char *  data 
)
static

Given a descriptor string at data, decode all possible introduction points that we can find. Add the introduction point object to desc_enc as we find them. This function can't fail and it is possible that zero introduction points can be decoded.

Definition at line 1926 of file hs_descriptor.c.

◆ decode_introduction_point()

STATIC hs_desc_intro_point_t* decode_introduction_point ( const hs_descriptor_t desc,
const char *  start 
)

Given the start of a section and the end of it, decode a single introduction point from that section. Return a newly allocated introduction point object containing the decoded data. Return NULL if the section can't be decoded.

Definition at line 1797 of file hs_descriptor.c.

◆ decode_link_specifiers()

STATIC smartlist_t* decode_link_specifiers ( const char *  encoded)

Given an encoded string of the link specifiers, return a newly allocated list of decoded link specifiers. Return NULL on error.

Definition at line 1150 of file hs_descriptor.c.

◆ decrypt_desc_layer()

STATIC size_t decrypt_desc_layer ( const hs_descriptor_t desc,
const uint8_t *  descriptor_cookie,
bool  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 outer encrypted layer of the descriptor.

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

Definition at line 1492 of file hs_descriptor.c.

Referenced by desc_decrypt_superencrypted().

◆ decrypt_descriptor_cookie()

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 
)
static

Decrypt the descriptor cookie given the descriptor, the auth client, and the client secret key. On success, return 0 and a newly allocated descriptor cookie descriptor_cookie_out. On error or if the client id is invalid, return -1 and descriptor_cookie_out is set to NULL.

Definition at line 1414 of file hs_descriptor.c.

Referenced by desc_decrypt_encrypted().

◆ desc_decode_encrypted_v3()

static hs_desc_decode_status_t 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 
)
static

Decode the version 3 encrypted section of the given descriptor desc. The desc_encrypted_out will be populated with the decoded data.

Definition at line 2263 of file hs_descriptor.c.

◆ desc_decode_plaintext_v3()

static hs_desc_decode_status_t desc_decode_plaintext_v3 ( smartlist_t tokens,
hs_desc_plaintext_data_t desc,
const char *  encoded_desc,
size_t  encoded_len 
)
static

Decode descriptor plaintext data for version 3. Given a list of tokens, an allocated plaintext object that will be populated and the encoded descriptor with its length. The last one is needed for signature verification. Unknown tokens are simply ignored so this won't error on unknowns but requires that all v3 token be present and valid.

Return 0 on success else a negative value.

Definition at line 2052 of file hs_descriptor.c.

◆ desc_decode_superencrypted_v3()

static hs_desc_decode_status_t desc_decode_superencrypted_v3 ( const hs_descriptor_t desc,
hs_desc_superencrypted_data_t desc_superencrypted_out 
)
static

Decode the version 3 superencrypted section of the given descriptor desc. The desc_superencrypted_out will be populated with the decoded data.

Definition at line 2149 of file hs_descriptor.c.

◆ desc_decrypt_encrypted()

static size_t desc_decrypt_encrypted ( const hs_descriptor_t desc,
const curve25519_secret_key_t client_auth_sk,
char **  decrypted_out 
)
static

Decrypt the encrypted section of the descriptor using the given descriptor object desc. A newly allocated NUL terminated string is put in decrypted_out which contains the encrypted layer of the descriptor. Return the length of decrypted_out on success else 0 is returned and decrypted_out is set to NULL.

Definition at line 1643 of file hs_descriptor.c.

◆ desc_decrypt_superencrypted()

static size_t desc_decrypt_superencrypted ( const hs_descriptor_t desc,
char **  decrypted_out 
)
static

Decrypt the superencrypted section of the descriptor using the given descriptor object desc. A newly allocated NUL terminated string is put in decrypted_out which contains the superencrypted layer of the descriptor. Return the length of decrypted_out on success else 0 is returned and decrypted_out is set to NULL.

Definition at line 1611 of file hs_descriptor.c.

◆ desc_encode_v3()

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

Encode a v3 HS descriptor. Return 0 on success and set encoded_out to the newly allocated string of the encoded descriptor. On error, -1 is returned and encoded_out is untouched.

Definition at line 1007 of file hs_descriptor.c.

◆ desc_sig_is_valid()

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 
)

Return 1 iff the given base64 encoded signature in b64_sig from the encoded descriptor in encoded_desc validates the descriptor content.

Definition at line 1988 of file hs_descriptor.c.

◆ encode_enc_key()

static char* encode_enc_key ( const hs_desc_intro_point_t ip)
static

Encode an introduction point encryption key and certificate. Return a newly allocated string with it. On failure, return NULL.

Definition at line 399 of file hs_descriptor.c.

◆ encode_intro_point()

static char* encode_intro_point ( const ed25519_public_key_t sig_key,
const hs_desc_intro_point_t ip 
)
static

Encode an introduction point object and return a newly allocated string with it. On failure, return NULL.

Definition at line 442 of file hs_descriptor.c.

◆ encode_legacy_key()

static char* encode_legacy_key ( const hs_desc_intro_point_t ip)
static

Encode an introduction point legacy key and certificate. Return a newly allocated string with it. On failure, return NULL.

Definition at line 362 of file hs_descriptor.c.

◆ encode_link_specifiers()

STATIC char* encode_link_specifiers ( const smartlist_t specs)

Encode the given link specifier objects into a newly allocated string. This can't fail so caller can always assume a valid string being returned.

Definition at line 316 of file hs_descriptor.c.

Referenced by encode_intro_point().

◆ encode_onion_key()

static char* encode_onion_key ( const hs_desc_intro_point_t ip)
static

Encode an introduction point onion key. Return a newly allocated string with it. Can not fail.

Definition at line 425 of file hs_descriptor.c.

◆ encode_superencrypted_data()

static int encode_superencrypted_data ( const hs_descriptor_t desc,
const uint8_t *  descriptor_cookie,
char **  encrypted_blob_out 
)
static

Generate and encode the superencrypted portion of desc. This also involves generating the encrypted portion of the descriptor, and performing the superencryption. A newly allocated NUL-terminated string pointer containing the encrypted encoded blob is put in encrypted_blob_out. Return 0 on success else a negative value.

Definition at line 935 of file hs_descriptor.c.

◆ encrypt_desc_data_and_base64()

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

Encrypt encoded_str into an encrypted blob and then base64 it before returning it. desc is provided to derive the encryption keys. secret_data is also proved to derive the encryption keys. is_superencrypted_layer is set if encoded_str is the middle (superencrypted) layer of the descriptor. It's the responsibility of the caller to free the returned string.

Definition at line 856 of file hs_descriptor.c.

Referenced by encode_superencrypted_data().

◆ encrypt_descriptor_data()

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

Encrypt the given plaintext buffer using desc and secret_data to get the keys. Set encrypted_out with the encrypted data and return the length of it. is_superencrypted_layer is set if this is the outer encrypted layer of the descriptor.

Definition at line 602 of file hs_descriptor.c.

Referenced by encrypt_desc_data_and_base64().

◆ encrypted_data_length_is_valid()

STATIC int encrypted_data_length_is_valid ( size_t  len)

Return true iff the given length of the encrypted data of a descriptor passes validation.

Definition at line 1349 of file hs_descriptor.c.

Referenced by decrypt_desc_layer().

◆ 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 706 of file hs_descriptor.c.

◆ get_auth_client_str()

static char* get_auth_client_str ( const hs_desc_authorized_client_t client)
static

Create and return a string containing a client-auth entry. It's the responsibility of the caller to free the returned string. This function will never fail.

Definition at line 671 of file hs_descriptor.c.

◆ get_inner_encrypted_layer_plaintext()

static char* get_inner_encrypted_layer_plaintext ( const hs_descriptor_t desc)
static

Create the inner layer of the descriptor (which includes the intro points, etc.). Return a newly-allocated string with the layer plaintext, or NULL if an error occurred. It's the responsibility of the caller to free the returned string.

Definition at line 742 of file hs_descriptor.c.

Referenced by encode_superencrypted_data().

◆ get_outer_encrypted_layer_plaintext()

static char* get_outer_encrypted_layer_plaintext ( const hs_descriptor_t desc,
const char *  layer2_b64_ciphertext 
)
static

Create the middle layer of the descriptor, which includes the client auth data and the encrypted inner layer (provided as a base64 string at layer2_b64_ciphertext). Return a newly-allocated string with the layer plaintext. It's the responsibility of the caller to free the returned string. Can not fail.

Definition at line 799 of file hs_descriptor.c.

Referenced by encode_superencrypted_data().

◆ hs_desc_authorized_client_free_()

void hs_desc_authorized_client_free_ ( hs_desc_authorized_client_t client)

Free an authoriezd client object.

Definition at line 2939 of file hs_descriptor.c.

◆ hs_desc_build_authorized_client()

void hs_desc_build_authorized_client ( const hs_subcredential_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 
)

Using the service's subcredential, client public key, auth ephemeral secret key, and descriptor cookie, build the auth client so we can then encode the descriptor for publication. client_out must be already allocated.

Definition at line 2883 of file hs_descriptor.c.

◆ hs_desc_build_fake_authorized_client()

hs_desc_authorized_client_t* hs_desc_build_fake_authorized_client ( void  )

Allocate and build a new fake client info for the descriptor. Return a newly allocated object. This can't fail.

Definition at line 2864 of file hs_descriptor.c.

◆ hs_desc_decode_descriptor()

hs_desc_decode_status_t hs_desc_decode_descriptor ( const char *  encoded,
const hs_subcredential_t subcredential,
const curve25519_secret_key_t client_auth_sk,
hs_descriptor_t **  desc_out 
)

Fully decode an encoded descriptor and set a newly allocated descriptor object in desc_out. Client secret key is used to decrypt the "encrypted" section if not NULL else it's ignored.

Return 0 on success. A negative value is returned on error and desc_out is set to NULL.

Definition at line 2570 of file hs_descriptor.c.

Referenced by hs_client_decode_descriptor(), and hs_desc_encode_descriptor().

◆ hs_desc_decode_encrypted()

hs_desc_decode_status_t hs_desc_decode_encrypted ( const hs_descriptor_t desc,
const curve25519_secret_key_t client_auth_sk,
hs_desc_encrypted_data_t desc_encrypted 
)

Decode the encrypted data section of the given descriptor and store the data in the given encrypted data object. Return 0 on success else a negative value on error.

Definition at line 2392 of file hs_descriptor.c.

◆ hs_desc_decode_plaintext()

hs_desc_decode_status_t hs_desc_decode_plaintext ( const char *  encoded,
hs_desc_plaintext_data_t plaintext 
)

Fully decode the given descriptor plaintext and store the data in the plaintext data object.

Definition at line 2493 of file hs_descriptor.c.

◆ hs_desc_decode_superencrypted()

hs_desc_decode_status_t hs_desc_decode_superencrypted ( const hs_descriptor_t desc,
hs_desc_superencrypted_data_t desc_superencrypted 
)

Decode the superencrypted data section of the given descriptor and store the data in the given superencrypted data object.

Definition at line 2442 of file hs_descriptor.c.

◆ hs_desc_encode_descriptor()

int hs_desc_encode_descriptor ( const hs_descriptor_t desc,
const ed25519_keypair_t signing_kp,
const uint8_t *  descriptor_cookie,
char **  encoded_out 
)

Encode the given descriptor desc including signing with the given key pair signing_kp and encrypting with the given descriptor cookie.

If the client authorization is enabled, descriptor_cookie must be the same as the one used to build hs_desc_authorized_client_t in the descriptor. Otherwise, it must be NULL. On success, encoded_out points to a newly allocated NUL terminated string that contains the encoded descriptor as a string.

Return 0 on success and encoded_out is a valid pointer. On error, -1 is returned and encoded_out is set to NULL.

Definition at line 2651 of file hs_descriptor.c.

Referenced by service_encode_descriptor().

◆ hs_desc_encrypted_data_free_()

void hs_desc_encrypted_data_free_ ( hs_desc_encrypted_data_t desc)

Free the descriptor encrypted data object.

Definition at line 2768 of file hs_descriptor.c.

◆ hs_desc_encrypted_data_free_contents()

void hs_desc_encrypted_data_free_contents ( hs_desc_encrypted_data_t desc)

Free the content of the encrypted section of a descriptor.

Definition at line 2732 of file hs_descriptor.c.

Referenced by hs_desc_encrypted_data_free_(), and hs_descriptor_free_().

◆ hs_desc_encrypted_obj_size()

static size_t hs_desc_encrypted_obj_size ( const hs_desc_encrypted_data_t data)
static

Return the size in bytes of the given encrypted data object. Used by OOM subsystem.

Definition at line 2803 of file hs_descriptor.c.

Referenced by hs_desc_obj_size().

◆ hs_desc_intro_point_free_()

void hs_desc_intro_point_free_ ( hs_desc_intro_point_t ip)

Free a descriptor intro point object.

Definition at line 2844 of file hs_descriptor.c.

◆ hs_desc_intro_point_new()

hs_desc_intro_point_t* hs_desc_intro_point_new ( void  )

Return a newly allocated descriptor intro point.

Definition at line 2835 of file hs_descriptor.c.

◆ hs_desc_obj_size()

size_t hs_desc_obj_size ( const hs_descriptor_t data)

Return the size in bytes of the given descriptor object. Used by OOM subsystem.

Definition at line 2823 of file hs_descriptor.c.

Referenced by cache_get_client_entry_size().

◆ hs_desc_plaintext_data_free_()

void hs_desc_plaintext_data_free_ ( hs_desc_plaintext_data_t desc)

Free the descriptor plaintext data object.

Definition at line 2752 of file hs_descriptor.c.

◆ hs_desc_plaintext_data_free_contents()

void hs_desc_plaintext_data_free_contents ( hs_desc_plaintext_data_t desc)

Free the content of the plaintext section of a descriptor.

Definition at line 2696 of file hs_descriptor.c.

Referenced by hs_desc_plaintext_data_free_(), and hs_descriptor_free_().

◆ hs_desc_plaintext_obj_size()

size_t hs_desc_plaintext_obj_size ( const hs_desc_plaintext_data_t data)

Return the size in bytes of the given plaintext data object. A sizeof() is not enough because the object contains pointers and the encrypted blob. This is particularly useful for our OOM subsystem that tracks the HSDir cache size for instance.

Definition at line 2793 of file hs_descriptor.c.

Referenced by cache_get_dir_entry_size(), and hs_desc_obj_size().

◆ hs_desc_superencrypted_data_free_()

void hs_desc_superencrypted_data_free_ ( hs_desc_superencrypted_data_t desc)

Free the descriptor plaintext data object.

Definition at line 2760 of file hs_descriptor.c.

◆ hs_desc_superencrypted_data_free_contents()

void hs_desc_superencrypted_data_free_contents ( hs_desc_superencrypted_data_t desc)

Free the content of the superencrypted section of a descriptor.

Definition at line 2712 of file hs_descriptor.c.

Referenced by hs_desc_superencrypted_data_free_(), and hs_descriptor_free_().

◆ hs_descriptor_clear_intro_points()

void hs_descriptor_clear_intro_points ( hs_descriptor_t desc)

From the given descriptor, remove and free every introduction point.

Definition at line 2946 of file hs_descriptor.c.

Referenced by build_desc_intro_points().

◆ hs_descriptor_free_()

void hs_descriptor_free_ ( hs_descriptor_t desc)

Free the given descriptor object.

Definition at line 2776 of file hs_descriptor.c.

◆ set_intro_point_onion_key()

static int set_intro_point_onion_key ( curve25519_public_key_t onion_key_out,
const smartlist_t tokens 
)
static

Dig into the descriptor tokens to find the onion key we should use for this intro point, and set it into onion_key_out. Return 0 if it was found and well-formed, otherwise return -1 in case of errors.

Definition at line 1752 of file hs_descriptor.c.

Variable Documentation

◆ decode_encrypted_handlers

hs_desc_decode_status_t(* decode_encrypted_handlers[])(const hs_descriptor_t *desc, const curve25519_secret_key_t *client_auth_sk, hs_desc_encrypted_data_t *desc_encrypted) ( 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,
}
static hs_desc_decode_status_t 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)

Table of encrypted decode function version specific. The function are indexed by the version number so v3 callback is at index 3 in the array.

Definition at line 2378 of file hs_descriptor.c.

◆ decode_plaintext_handlers

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

Table of plaintext decode function version specific. The function are indexed by the version number so v3 callback is at index 3 in the array.

Definition at line 2479 of file hs_descriptor.c.

◆ decode_superencrypted_handlers

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

Table of superencrypted decode function version specific. The function are indexed by the version number so v3 callback is at index 3 in the array.

Definition at line 2430 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) ( 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,
}
static int desc_encode_v3(const hs_descriptor_t *desc, const ed25519_keypair_t *signing_kp, const uint8_t *descriptor_cookie, char **encoded_out)

Table of encode function version specific. The functions are indexed by the version number so v3 callback is at index 3 in the array.

Definition at line 2625 of file hs_descriptor.c.

Referenced by hs_desc_encode_descriptor().

◆ 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 T01(s, t, a, o)
Definition: parsecommon.h:257
@ NO_OBJ
Definition: parsecommon.h:219
#define T1_START(s, t, a, o)
Definition: parsecommon.h:251
#define CONCAT_ARGS
Definition: parsecommon.h:266
#define END_OF_TABLE
Definition: parsecommon.h:243
#define ARGS
Definition: parsecommon.h:262

Descriptor ruleset for the encrypted section.

Definition at line 137 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 NO_ARGS
Definition: parsecommon.h:264
@ OBJ_OK
Definition: parsecommon.h:223
@ NEED_OBJ
Definition: parsecommon.h:220
@ NEED_KEY_1024
Definition: parsecommon.h:221
#define T1N(s, t, a, o)
Definition: parsecommon.h:255
#define GE(n)
Definition: parsecommon.h:268
#define T1(s, t, a, o)
Definition: parsecommon.h:249
#define EQ(n)
Definition: parsecommon.h:270

Descriptor ruleset for the introduction points section.

Definition at line 145 of file hs_descriptor.c.

Referenced by decode_introduction_point().

◆ 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),
}

Descriptor ruleset for the superencrypted section.

Definition at line 128 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 T1_END(s, t, a, o)
Definition: parsecommon.h:253

Descriptor ruleset.

Definition at line 117 of file hs_descriptor.c.

◆ 

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

Authentication supported types.

Referenced by decode_auth_type().