tor
master
|
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"
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_t * | decode_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_t * | decode_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_t * | hs_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_t * | hs_desc_link_specifier_new (const extend_info_t *info, uint8_t type) |
void | hs_descriptor_clear_intro_points (hs_descriptor_t *desc) |
link_specifier_t * | hs_desc_lspec_to_trunnel (const hs_desc_link_specifier_t *spec) |
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.
#define CLIENT_AUTH_ENTRIES_BLOCK_SIZE 16 |
How many lines of "client-auth" we want in our descriptors; fake or not.
#define FILL_WITH_FAKE_DATA_AND_BASE64 | ( | field | ) |
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.