diff options
Diffstat (limited to 'src/feature/hs/hs_descriptor.c')
-rw-r--r-- | src/feature/hs/hs_descriptor.c | 239 |
1 files changed, 126 insertions, 113 deletions
diff --git a/src/feature/hs/hs_descriptor.c b/src/feature/hs/hs_descriptor.c index 924ab3115e..d1c81bbff8 100644 --- a/src/feature/hs/hs_descriptor.c +++ b/src/feature/hs/hs_descriptor.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2019, The Tor Project, Inc. */ +/* Copyright (c) 2016-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -56,6 +56,7 @@ #define HS_DESCRIPTOR_PRIVATE #include "core/or/or.h" +#include "app/config/config.h" #include "trunnel/ed25519_cert.h" /* Trunnel interface. */ #include "feature/hs/hs_descriptor.h" #include "core/or/circuitbuild.h" @@ -102,7 +103,7 @@ #define str_desc_auth_client "auth-client" #define str_encrypted "encrypted" -/* Authentication supported types. */ +/** Authentication supported types. */ static const struct { hs_desc_auth_type_t type; const char *identifier; @@ -112,7 +113,7 @@ static const struct { { 0, NULL } }; -/* Descriptor ruleset. */ +/** Descriptor ruleset. */ static token_rule_t hs_desc_v3_token_table[] = { T1_START(str_hs_desc, R_HS_DESCRIPTOR, EQ(1), NO_OBJ), T1(str_lifetime, R3_DESC_LIFETIME, EQ(1), NO_OBJ), @@ -123,7 +124,7 @@ static token_rule_t hs_desc_v3_token_table[] = { END_OF_TABLE }; -/* Descriptor ruleset for the superencrypted section. */ +/** Descriptor ruleset for the superencrypted section. */ static token_rule_t hs_desc_superencrypted_v3_token_table[] = { 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), @@ -132,7 +133,7 @@ static token_rule_t hs_desc_superencrypted_v3_token_table[] = { END_OF_TABLE }; -/* Descriptor ruleset for the encrypted section. */ +/** Descriptor ruleset for the encrypted section. */ static token_rule_t hs_desc_encrypted_v3_token_table[] = { T1_START(str_create2_formats, R3_CREATE2_FORMATS, CONCAT_ARGS, NO_OBJ), T01(str_intro_auth_required, R3_INTRO_AUTH_REQUIRED, ARGS, NO_OBJ), @@ -140,7 +141,7 @@ static token_rule_t hs_desc_encrypted_v3_token_table[] = { END_OF_TABLE }; -/* Descriptor ruleset for the introduction points section. */ +/** Descriptor ruleset for the introduction points section. */ static token_rule_t hs_desc_intro_point_v3_token_table[] = { 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), @@ -152,7 +153,7 @@ static token_rule_t hs_desc_intro_point_v3_token_table[] = { END_OF_TABLE }; -/* Using a key, salt and encrypted payload, build a MAC and put it in mac_out. +/** 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. */ static void @@ -184,7 +185,7 @@ build_mac(const uint8_t *mac_key, size_t mac_key_len, crypto_digest_free(digest); } -/* Using a secret data and a given decriptor object, build the secret +/** Using a secret data and a given decriptor object, build the secret * input needed for the KDF. * * secret_input = SECRET_DATA | subcredential | INT_8(revision_counter) @@ -224,7 +225,7 @@ build_secret_input(const hs_descriptor_t *desc, return secret_input_len; } -/* Do the KDF construction and put the resulting data in key_out which is of +/** 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. */ static void build_kdf_key(const hs_descriptor_t *desc, @@ -269,7 +270,7 @@ build_kdf_key(const hs_descriptor_t *desc, tor_free(secret_input); } -/* Using the given descriptor, secret data, and salt, run it through our +/** 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. */ static void @@ -308,7 +309,7 @@ build_secret_key_iv_mac(const hs_descriptor_t *desc, /* === ENCODING === */ -/* Encode the given link specifier objects into a newly allocated string. +/** 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. */ STATIC char * @@ -355,7 +356,7 @@ encode_link_specifiers(const smartlist_t *specs) return encoded_b64; } -/* Encode an introduction point legacy key and certificate. Return a newly +/** Encode an introduction point legacy key and certificate. Return a newly * allocated string with it. On failure, return NULL. */ static char * encode_legacy_key(const hs_desc_intro_point_t *ip) @@ -392,7 +393,7 @@ encode_legacy_key(const hs_desc_intro_point_t *ip) return encoded; } -/* Encode an introduction point encryption key and certificate. Return a newly +/** Encode an introduction point encryption key and certificate. Return a newly * allocated string with it. On failure, return NULL. */ static char * encode_enc_key(const hs_desc_intro_point_t *ip) @@ -418,7 +419,7 @@ encode_enc_key(const hs_desc_intro_point_t *ip) return encoded; } -/* Encode an introduction point onion key. Return a newly allocated string +/** Encode an introduction point onion key. Return a newly allocated string * with it. Can not fail. */ static char * encode_onion_key(const hs_desc_intro_point_t *ip) @@ -435,7 +436,7 @@ encode_onion_key(const hs_desc_intro_point_t *ip) return encoded; } -/* Encode an introduction point object and return a newly allocated string +/** Encode an introduction point object and return a newly allocated string * with it. On failure, return NULL. */ static char * encode_intro_point(const ed25519_public_key_t *sig_key, @@ -505,7 +506,7 @@ encode_intro_point(const ed25519_public_key_t *sig_key, return encoded_ip; } -/* Given a source length, return the new size including padding for the +/** Given a source length, return the new size including padding for the * plaintext encryption. */ static size_t compute_padded_plaintext_length(size_t plaintext_len) @@ -525,7 +526,7 @@ compute_padded_plaintext_length(size_t plaintext_len) return plaintext_padded_len; } -/* Given a buffer, pad it up to the encrypted section padding requirement. Set +/** 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. */ STATIC size_t @@ -548,7 +549,7 @@ build_plaintext_padding(const char *plaintext, size_t plaintext_len, return padded_len; } -/* Using a key, IV and plaintext data of length plaintext_len, create the +/** 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. */ static size_t @@ -593,7 +594,7 @@ build_encrypted(const uint8_t *key, const uint8_t *iv, const char *plaintext, return encrypted_len; } -/* Encrypt the given <b>plaintext</b> buffer using <b>desc</b> and +/** Encrypt the given <b>plaintext</b> buffer using <b>desc</b> and * <b>secret_data</b> to get the keys. Set encrypted_out with the encrypted * data and return the length of it. <b>is_superencrypted_layer</b> is set * if this is the outer encrypted layer of the descriptor. */ @@ -663,7 +664,7 @@ encrypt_descriptor_data(const hs_descriptor_t *desc, return final_blob_len; } -/* Create and return a string containing a client-auth entry. It's the +/** 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. */ static char * @@ -733,7 +734,7 @@ get_all_auth_client_lines(const hs_descriptor_t *desc) return auth_client_lines_str; } -/* Create the inner layer of the descriptor (which includes the intro points, +/** 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. */ @@ -789,7 +790,7 @@ get_inner_encrypted_layer_plaintext(const hs_descriptor_t *desc) return encoded_str; } -/* Create the middle layer of the descriptor, which includes the client auth +/** Create the middle layer of the descriptor, which includes the client auth * data and the encrypted inner layer (provided as a base64 string at * <b>layer2_b64_ciphertext</b>). Return a newly-allocated string with the * layer plaintext. It's the responsibility of the caller to free the returned @@ -845,7 +846,7 @@ get_outer_encrypted_layer_plaintext(const hs_descriptor_t *desc, return layer1_str; } -/* Encrypt <b>encoded_str</b> into an encrypted blob and then base64 it before +/** Encrypt <b>encoded_str</b> into an encrypted blob and then base64 it before * returning it. <b>desc</b> is provided to derive the encryption * keys. <b>secret_data</b> is also proved to derive the encryption keys. * <b>is_superencrypted_layer</b> is set if <b>encoded_str</b> is the @@ -878,7 +879,7 @@ encrypt_desc_data_and_base64(const hs_descriptor_t *desc, return enc_b64; } -/* Generate the secret data which is used to encrypt/decrypt the descriptor. +/** Generate the secret data which is used to encrypt/decrypt the descriptor. * * SECRET_DATA = blinded-public-key * SECRET_DATA = blinded-public-key | descriptor_cookie @@ -925,7 +926,7 @@ build_secret_data(const ed25519_public_key_t *blinded_pubkey, return secret_data_len; } -/* Generate and encode the superencrypted portion of <b>desc</b>. This also +/** Generate and encode the superencrypted portion of <b>desc</b>. 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 @@ -999,7 +1000,7 @@ encode_superencrypted_data(const hs_descriptor_t *desc, return ret; } -/* Encode a v3 HS descriptor. Return 0 on success and set encoded_out to the +/** 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. */ static int @@ -1111,7 +1112,7 @@ desc_encode_v3(const hs_descriptor_t *desc, /* === DECODING === */ -/* Given the token tok for an auth client, decode it as +/** 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. */ static int @@ -1147,7 +1148,7 @@ decode_auth_client(const directory_token_t *tok, return ret; } -/* Given an encoded string of the link specifiers, return a newly allocated +/** Given an encoded string of the link specifiers, return a newly allocated * list of decoded link specifiers. Return NULL on error. */ STATIC smartlist_t * decode_link_specifiers(const char *encoded) @@ -1201,7 +1202,7 @@ decode_link_specifiers(const char *encoded) return results; } -/* Given a list of authentication types, decode it and put it in the encrypted +/** 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. */ static int @@ -1229,7 +1230,7 @@ decode_auth_type(hs_desc_encrypted_data_t *desc, const char *list) return match; } -/* Parse a space-delimited list of integers representing CREATE2 formats into +/** Parse a space-delimited list of integers representing CREATE2 formats into * the bitfield in hs_desc_encrypted_data_t. Ignore unrecognized values. */ static void decode_create2_list(hs_desc_encrypted_data_t *desc, const char *list) @@ -1263,7 +1264,7 @@ decode_create2_list(hs_desc_encrypted_data_t *desc, const char *list) smartlist_free(tokens); } -/* Given a certificate, validate the certificate for certain conditions which +/** 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. * @@ -1287,11 +1288,20 @@ cert_is_valid(tor_cert_t *cert, uint8_t type, const char *log_obj_type) log_warn(LD_REND, "Signing key is NOT included for %s.", log_obj_type); goto err; } + /* The following will not only check if the signature matches but also the * expiration date and overall validity. */ if (tor_cert_checksig(cert, &cert->signing_key, approx_time()) < 0) { - log_warn(LD_REND, "Invalid signature for %s: %s", log_obj_type, - tor_cert_describe_signature_status(cert)); + if (cert->cert_expired) { + char expiration_str[ISO_TIME_LEN+1]; + format_iso_time(expiration_str, cert->valid_until); + log_fn(LOG_PROTOCOL_WARN, LD_REND, "Invalid signature for %s: %s (%s)", + log_obj_type, tor_cert_describe_signature_status(cert), + expiration_str); + } else { + log_warn(LD_REND, "Invalid signature for %s: %s", + log_obj_type, tor_cert_describe_signature_status(cert)); + } goto err; } @@ -1300,7 +1310,7 @@ cert_is_valid(tor_cert_t *cert, uint8_t type, const char *log_obj_type) return 0; } -/* Given some binary data, try to parse it to get a certificate object. If we +/** 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 @@ -1337,7 +1347,7 @@ cert_parse_and_validate(tor_cert_t **cert_out, const char *data, return -1; } -/* Return true iff the given length of the encrypted data of a descriptor +/** Return true iff the given length of the encrypted data of a descriptor * passes validation. */ STATIC int encrypted_data_length_is_valid(size_t len) @@ -1356,7 +1366,7 @@ encrypted_data_length_is_valid(size_t len) return 0; } -/* Build the KEYS component for the authorized client computation. The format +/** Build the KEYS component for the authorized client computation. The format * of the construction is: * * SECRET_SEED = x25519(sk, pk) @@ -1400,7 +1410,7 @@ build_descriptor_cookie_keys(const uint8_t *subcredential, return keystream_len; } -/* Decrypt the descriptor cookie given the descriptor, the auth client, +/** Decrypt the descriptor cookie given the descriptor, the auth client, * and the client secret key. On sucess, 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 @@ -1424,10 +1434,14 @@ decrypt_descriptor_cookie(const hs_descriptor_t *desc, tor_assert(!fast_mem_is_zero( (char *) &desc->superencrypted_data.auth_ephemeral_pubkey, sizeof(desc->superencrypted_data.auth_ephemeral_pubkey))); - tor_assert(!fast_mem_is_zero((char *) client_auth_sk, - sizeof(*client_auth_sk))); tor_assert(!fast_mem_is_zero((char *) desc->subcredential, DIGEST256_LEN)); + /* Catch potential code-flow cases of an unitialized private key sneaking + * into this function. */ + if (BUG(fast_mem_is_zero((char *)client_auth_sk, sizeof(*client_auth_sk)))) { + goto done; + } + /* Get the KEYS component to derive the CLIENT-ID and COOKIE-KEY. */ keystream_length = build_descriptor_cookie_keys(desc->subcredential, DIGEST256_LEN, @@ -1592,7 +1606,7 @@ decrypt_desc_layer,(const hs_descriptor_t *desc, return result_len; } -/* Decrypt the superencrypted section of the descriptor using the given +/** Decrypt the superencrypted section of the descriptor using the given * descriptor object <b>desc</b>. 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 @@ -1624,7 +1638,7 @@ desc_decrypt_superencrypted(const hs_descriptor_t *desc, char **decrypted_out) return superencrypted_len; } -/* Decrypt the encrypted section of the descriptor using the given descriptor +/** Decrypt the encrypted section of the descriptor using the given descriptor * object <b>desc</b>. 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 @@ -1677,7 +1691,7 @@ desc_decrypt_encrypted(const hs_descriptor_t *desc, return encrypted_len; } -/* Given the token tok for an intro point legacy key, the list of tokens, the +/** 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. */ @@ -1735,7 +1749,7 @@ decode_intro_legacy_key(const directory_token_t *tok, return -1; } -/* Dig into the descriptor <b>tokens</b> to find the onion key we should use +/** Dig into the descriptor <b>tokens</b> to find the onion key we should use * for this intro point, and set it into <b>onion_key_out</b>. Return 0 if it * was found and well-formed, otherwise return -1 in case of errors. */ static int @@ -1779,7 +1793,7 @@ set_intro_point_onion_key(curve25519_public_key_t *onion_key_out, return retval; } -/* Given the start of a section and the end of it, decode a single +/** 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. */ @@ -1908,7 +1922,7 @@ decode_introduction_point(const hs_descriptor_t *desc, const char *start) return ip; } -/* Given a descriptor string at <b>data</b>, decode all possible introduction +/** Given a descriptor string at <b>data</b>, 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. */ @@ -1972,7 +1986,7 @@ decode_intro_points(const hs_descriptor_t *desc, smartlist_free(intro_points); } -/* Return 1 iff the given base64 encoded signature in b64_sig from the encoded +/** Return 1 iff the given base64 encoded signature in b64_sig from the encoded * descriptor in encoded_desc validates the descriptor content. */ STATIC int desc_sig_is_valid(const char *b64_sig, @@ -2031,14 +2045,14 @@ desc_sig_is_valid(const char *b64_sig, return ret; } -/* Decode descriptor plaintext data for version 3. Given a list of tokens, an +/** 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. */ -static int +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) @@ -2128,21 +2142,19 @@ desc_decode_plaintext_v3(smartlist_t *tokens, goto err; } - return 0; - + return HS_DESC_DECODE_OK; err: - return -1; + return HS_DESC_DECODE_PLAINTEXT_ERROR; } -/* Decode the version 3 superencrypted section of the given descriptor desc. - * The desc_superencrypted_out will be populated with the decoded data. - * Return 0 on success else -1. */ -static int +/** Decode the version 3 superencrypted section of the given descriptor desc. + * The desc_superencrypted_out will be populated with the decoded data. */ +static hs_desc_decode_status_t desc_decode_superencrypted_v3(const hs_descriptor_t *desc, hs_desc_superencrypted_data_t * desc_superencrypted_out) { - int ret = -1; + int ret = HS_DESC_DECODE_SUPERENC_ERROR; char *message = NULL; size_t message_len; memarea_t *area = NULL; @@ -2228,11 +2240,11 @@ desc_decode_superencrypted_v3(const hs_descriptor_t *desc, tok->object_size); superencrypted->encrypted_blob_size = tok->object_size; - ret = 0; + ret = HS_DESC_DECODE_OK; goto done; err: - tor_assert(ret < 0); + tor_assert(ret < HS_DESC_DECODE_OK); hs_desc_superencrypted_data_free_contents(desc_superencrypted_out); done: @@ -2249,15 +2261,14 @@ desc_decode_superencrypted_v3(const hs_descriptor_t *desc, return ret; } -/* Decode the version 3 encrypted section of the given descriptor desc. The - * desc_encrypted_out will be populated with the decoded data. Return 0 on - * success else -1. */ -static int +/** Decode the version 3 encrypted section of the given descriptor desc. The + * desc_encrypted_out will be populated with the decoded data. */ +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) { - int ret = -1; + int ret = HS_DESC_DECODE_ENCRYPTED_ERROR; char *message = NULL; size_t message_len; memarea_t *area = NULL; @@ -2280,12 +2291,14 @@ desc_decode_encrypted_v3(const hs_descriptor_t *desc, * authorization is failing. */ log_warn(LD_REND, "Client authorization for requested onion address " "is invalid. Can't decrypt the descriptor."); + ret = HS_DESC_DECODE_BAD_CLIENT_AUTH; } else { /* Inform at notice level that the onion address requested can't be * reached without client authorization most likely. */ log_notice(LD_REND, "Fail to decrypt descriptor for requested onion " "address. It is likely requiring client " "authorization."); + ret = HS_DESC_DECODE_NEED_CLIENT_AUTH; } goto err; } @@ -2343,11 +2356,11 @@ desc_decode_encrypted_v3(const hs_descriptor_t *desc, /* NOTE: Unknown fields are allowed because this function could be used to * decode other descriptor version. */ - ret = 0; + ret = HS_DESC_DECODE_OK; goto done; err: - tor_assert(ret < 0); + tor_assert(ret < HS_DESC_DECODE_OK); hs_desc_encrypted_data_free_contents(desc_encrypted_out); done: @@ -2364,9 +2377,9 @@ desc_decode_encrypted_v3(const hs_descriptor_t *desc, return ret; } -/* Table of encrypted decode function version specific. The function are +/** 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. */ -static int +static hs_desc_decode_status_t (*decode_encrypted_handlers[])( const hs_descriptor_t *desc, const curve25519_secret_key_t *client_auth_sk, @@ -2376,15 +2389,15 @@ static int desc_decode_encrypted_v3, }; -/* Decode the encrypted data section of the given descriptor and store the +/** 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. */ -int +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) { - int ret; + int ret = HS_DESC_DECODE_ENCRYPTED_ERROR; uint32_t version; tor_assert(desc); @@ -2398,7 +2411,6 @@ hs_desc_decode_encrypted(const hs_descriptor_t *desc, /* Let's make sure we have a supported version as well. By correctly parsing * the plaintext, this should not fail. */ if (BUG(!hs_desc_is_supported_version(version))) { - ret = -1; goto err; } /* Extra precaution. Having no handler for the supported version should @@ -2417,9 +2429,9 @@ hs_desc_decode_encrypted(const hs_descriptor_t *desc, return ret; } -/* Table of superencrypted decode function version specific. The function are +/** 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. */ -static int +static hs_desc_decode_status_t (*decode_superencrypted_handlers[])( const hs_descriptor_t *desc, hs_desc_superencrypted_data_t *desc_superencrypted) = @@ -2428,15 +2440,14 @@ static int desc_decode_superencrypted_v3, }; -/* Decode the superencrypted data section of the given descriptor and store the - * data in the given superencrypted data object. Return 0 on success else a - * negative value on error. */ -int +/** Decode the superencrypted data section of the given descriptor and store + * the data in the given superencrypted data object. */ +hs_desc_decode_status_t hs_desc_decode_superencrypted(const hs_descriptor_t *desc, hs_desc_superencrypted_data_t * desc_superencrypted) { - int ret; + int ret = HS_DESC_DECODE_SUPERENC_ERROR; uint32_t version; tor_assert(desc); @@ -2450,7 +2461,6 @@ hs_desc_decode_superencrypted(const hs_descriptor_t *desc, /* Let's make sure we have a supported version as well. By correctly parsing * the plaintext, this should not fail. */ if (BUG(!hs_desc_is_supported_version(version))) { - ret = -1; goto err; } /* Extra precaution. Having no handler for the supported version should @@ -2468,9 +2478,9 @@ hs_desc_decode_superencrypted(const hs_descriptor_t *desc, return ret; } -/* Table of plaintext decode function version specific. The function are +/** 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. */ -static int +static hs_desc_decode_status_t (*decode_plaintext_handlers[])( smartlist_t *tokens, hs_desc_plaintext_data_t *desc, @@ -2481,13 +2491,13 @@ static int desc_decode_plaintext_v3, }; -/* Fully decode the given descriptor plaintext and store the data in the - * plaintext data object. Returns 0 on success else a negative value. */ -int +/** Fully decode the given descriptor plaintext and store the data in the + * plaintext data object. */ +hs_desc_decode_status_t hs_desc_decode_plaintext(const char *encoded, hs_desc_plaintext_data_t *plaintext) { - int ok = 0, ret = -1; + int ok = 0, ret = HS_DESC_DECODE_PLAINTEXT_ERROR; memarea_t *area = NULL; smartlist_t *tokens = NULL; size_t encoded_len; @@ -2537,11 +2547,11 @@ hs_desc_decode_plaintext(const char *encoded, /* Run the version specific plaintext decoder. */ ret = decode_plaintext_handlers[plaintext->version](tokens, plaintext, encoded, encoded_len); - if (ret < 0) { + if (ret != HS_DESC_DECODE_OK) { goto err; } /* Success. Descriptor has been populated with the data. */ - ret = 0; + ret = HS_DESC_DECODE_OK; err: if (tokens) { @@ -2554,19 +2564,19 @@ hs_desc_decode_plaintext(const char *encoded, return ret; } -/* Fully decode an encoded descriptor and set a newly allocated descriptor +/** 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. */ -int +hs_desc_decode_status_t hs_desc_decode_descriptor(const char *encoded, const uint8_t *subcredential, const curve25519_secret_key_t *client_auth_sk, hs_descriptor_t **desc_out) { - int ret = -1; + hs_desc_decode_status_t ret = HS_DESC_DECODE_GENERIC_ERROR; hs_descriptor_t *desc; tor_assert(encoded); @@ -2583,17 +2593,17 @@ hs_desc_decode_descriptor(const char *encoded, memcpy(desc->subcredential, subcredential, sizeof(desc->subcredential)); ret = hs_desc_decode_plaintext(encoded, &desc->plaintext_data); - if (ret < 0) { + if (ret != HS_DESC_DECODE_OK) { goto err; } ret = hs_desc_decode_superencrypted(desc, &desc->superencrypted_data); - if (ret < 0) { + if (ret != HS_DESC_DECODE_OK) { goto err; } ret = hs_desc_decode_encrypted(desc, client_auth_sk, &desc->encrypted_data); - if (ret < 0) { + if (ret != HS_DESC_DECODE_OK) { goto err; } @@ -2614,7 +2624,7 @@ hs_desc_decode_descriptor(const char *encoded, return ret; } -/* Table of encode function version specific. The functions are indexed by the +/** Table of encode function version specific. The functions are indexed by the * version number so v3 callback is at index 3 in the array. */ static int (*encode_handlers[])( @@ -2627,7 +2637,7 @@ static int desc_encode_v3, }; -/* Encode the given descriptor desc including signing with the given key pair +/** 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 @@ -2672,7 +2682,8 @@ hs_desc_encode_descriptor,(const hs_descriptor_t *desc, if (!descriptor_cookie) { ret = hs_desc_decode_descriptor(*encoded_out, desc->subcredential, NULL, NULL); - if (BUG(ret < 0)) { + if (BUG(ret != HS_DESC_DECODE_OK)) { + ret = -1; goto err; } } @@ -2684,7 +2695,7 @@ hs_desc_encode_descriptor,(const hs_descriptor_t *desc, return ret; } -/* Free the content of the plaintext section of a descriptor. */ +/** Free the content of the plaintext section of a descriptor. */ void hs_desc_plaintext_data_free_contents(hs_desc_plaintext_data_t *desc) { @@ -2700,7 +2711,7 @@ hs_desc_plaintext_data_free_contents(hs_desc_plaintext_data_t *desc) memwipe(desc, 0, sizeof(*desc)); } -/* Free the content of the superencrypted section of a descriptor. */ +/** Free the content of the superencrypted section of a descriptor. */ void hs_desc_superencrypted_data_free_contents(hs_desc_superencrypted_data_t *desc) { @@ -2720,7 +2731,7 @@ hs_desc_superencrypted_data_free_contents(hs_desc_superencrypted_data_t *desc) memwipe(desc, 0, sizeof(*desc)); } -/* Free the content of the encrypted section of a descriptor. */ +/** Free the content of the encrypted section of a descriptor. */ void hs_desc_encrypted_data_free_contents(hs_desc_encrypted_data_t *desc) { @@ -2740,7 +2751,7 @@ hs_desc_encrypted_data_free_contents(hs_desc_encrypted_data_t *desc) memwipe(desc, 0, sizeof(*desc)); } -/* Free the descriptor plaintext data object. */ +/** Free the descriptor plaintext data object. */ void hs_desc_plaintext_data_free_(hs_desc_plaintext_data_t *desc) { @@ -2748,7 +2759,7 @@ hs_desc_plaintext_data_free_(hs_desc_plaintext_data_t *desc) tor_free(desc); } -/* Free the descriptor plaintext data object. */ +/** Free the descriptor plaintext data object. */ void hs_desc_superencrypted_data_free_(hs_desc_superencrypted_data_t *desc) { @@ -2756,7 +2767,7 @@ hs_desc_superencrypted_data_free_(hs_desc_superencrypted_data_t *desc) tor_free(desc); } -/* Free the descriptor encrypted data object. */ +/** Free the descriptor encrypted data object. */ void hs_desc_encrypted_data_free_(hs_desc_encrypted_data_t *desc) { @@ -2764,7 +2775,7 @@ hs_desc_encrypted_data_free_(hs_desc_encrypted_data_t *desc) tor_free(desc); } -/* Free the given descriptor object. */ +/** Free the given descriptor object. */ void hs_descriptor_free_(hs_descriptor_t *desc) { @@ -2778,7 +2789,7 @@ hs_descriptor_free_(hs_descriptor_t *desc) tor_free(desc); } -/* Return the size in bytes of the given plaintext data object. A sizeof() is +/** 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. */ @@ -2790,7 +2801,7 @@ hs_desc_plaintext_obj_size(const hs_desc_plaintext_data_t *data) data->superencrypted_blob_size); } -/* Return the size in bytes of the given encrypted data object. Used by OOM +/** Return the size in bytes of the given encrypted data object. Used by OOM * subsystem. */ static size_t hs_desc_encrypted_obj_size(const hs_desc_encrypted_data_t *data) @@ -2810,18 +2821,20 @@ hs_desc_encrypted_obj_size(const hs_desc_encrypted_data_t *data) return sizeof(*data) + intro_size; } -/* Return the size in bytes of the given descriptor object. Used by OOM +/** Return the size in bytes of the given descriptor object. Used by OOM * subsystem. */ size_t hs_desc_obj_size(const hs_descriptor_t *data) { - tor_assert(data); + if (data == NULL) { + return 0; + } return (hs_desc_plaintext_obj_size(&data->plaintext_data) + hs_desc_encrypted_obj_size(&data->encrypted_data) + sizeof(data->subcredential)); } -/* Return a newly allocated descriptor intro point. */ +/** Return a newly allocated descriptor intro point. */ hs_desc_intro_point_t * hs_desc_intro_point_new(void) { @@ -2830,7 +2843,7 @@ hs_desc_intro_point_new(void) return ip; } -/* Free a descriptor intro point object. */ +/** Free a descriptor intro point object. */ void hs_desc_intro_point_free_(hs_desc_intro_point_t *ip) { @@ -2849,7 +2862,7 @@ hs_desc_intro_point_free_(hs_desc_intro_point_t *ip) tor_free(ip); } -/* Allocate and build a new fake client info for the descriptor. Return a +/** Allocate and build a new fake client info for the descriptor. Return a * newly allocated object. This can't fail. */ hs_desc_authorized_client_t * hs_desc_build_fake_authorized_client(void) @@ -2867,7 +2880,7 @@ hs_desc_build_fake_authorized_client(void) return client_auth; } -/* Using the service's subcredential, client public key, auth ephemeral secret +/** 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. */ void @@ -2925,14 +2938,14 @@ hs_desc_build_authorized_client(const uint8_t *subcredential, crypto_cipher_free(cipher); } -/* Free an authoriezd client object. */ +/** Free an authoriezd client object. */ void hs_desc_authorized_client_free_(hs_desc_authorized_client_t *client) { tor_free(client); } -/* From the given descriptor, remove and free every introduction point. */ +/** From the given descriptor, remove and free every introduction point. */ void hs_descriptor_clear_intro_points(hs_descriptor_t *desc) { |