Loading src/or/hs_descriptor.c +671 −247 File changed.Preview size limit exceeded, changes collapsed. Show changes src/or/hs_descriptor.h +11 −23 Original line number Diff line number Diff line Loading @@ -41,24 +41,11 @@ * the secret IV and MAC key length which is the length of H() output. */ #define HS_DESC_ENCRYPTED_KDF_OUTPUT_LEN \ CIPHER256_KEY_LEN + CIPHER_IV_LEN + DIGEST256_LEN /* We need to pad the plaintext version of the encrypted data section before * encryption and it has to be a multiple of this value. */ #define HS_DESC_PLAINTEXT_PADDING_MULTIPLE 128 /* XXX: Let's make sure this makes sense as an upper limit for the padded * plaintext section. Then we should enforce it as now only an assert will be * triggered if we are above it. */ /* Once padded, this is the maximum length in bytes for the plaintext. */ #define HS_DESC_PADDED_PLAINTEXT_MAX_LEN 8192 /* Minimum length in bytes of the encrypted portion of the descriptor. */ #define HS_DESC_ENCRYPTED_MIN_LEN \ HS_DESC_ENCRYPTED_SALT_LEN + \ HS_DESC_PLAINTEXT_PADDING_MULTIPLE + DIGEST256_LEN /* Pad plaintext of superencrypted data section before encryption so that its * length is a multiple of this value. */ #define HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE 10000 /* Maximum length in bytes of a full hidden service descriptor. */ #define HS_DESC_MAX_LEN 50000 /* 50kb max size */ /* The minimum amount of fields a descriptor should contain. The parsing of * the fields are version specific so the only required field, as a generic * view of a descriptor, is 1 that is the version field. */ #define HS_DESC_PLAINTEXT_MIN_FIELDS 1 /* Key length for the descriptor symmetric encryption. As specified in the * protocol, we use AES-256 for the encrypted section of the descriptor. The Loading @@ -68,8 +55,7 @@ /* Type of authentication in the descriptor. */ typedef enum { HS_DESC_AUTH_PASSWORD = 1, HS_DESC_AUTH_ED25519 = 2, HS_DESC_AUTH_ED25519 = 1 } hs_desc_auth_type_t; /* Type of encryption key in the descriptor. */ Loading Loading @@ -132,7 +118,7 @@ typedef struct hs_desc_encrypted_data_t { /* A list of authentication types that a client must at least support one * in order to contact the service. Contains NULL terminated strings. */ smartlist_t *auth_types; smartlist_t *intro_auth_types; /* Is this descriptor a single onion service? */ unsigned int single_onion_service : 1; Loading Loading @@ -167,11 +153,11 @@ typedef struct hs_desc_plaintext_data_t { * has changed. Spec specifies this as a 8 bytes positive integer. */ uint64_t revision_counter; /* Decoding only: The base64-decoded encrypted blob from the descriptor */ uint8_t *encrypted_blob; /* Decoding only: The b64-decoded superencrypted blob from the descriptor */ uint8_t *superencrypted_blob; /* Decoding only: Size of the encrypted_blob */ size_t encrypted_blob_size; /* Decoding only: Size of the superencrypted_blob */ size_t superencrypted_blob_size; } hs_desc_plaintext_data_t; /* Service descriptor in its decoded form. */ Loading Loading @@ -242,6 +228,8 @@ 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 void desc_intro_point_free(hs_desc_intro_point_t *ip); STATIC size_t decode_superencrypted(const char *message, size_t message_len, uint8_t **encrypted_out); #endif /* HS_DESCRIPTOR_PRIVATE */ #endif /* TOR_HS_DESCRIPTOR_H */ Loading src/or/parsecommon.h +5 −1 Original line number Diff line number Diff line Loading @@ -157,12 +157,16 @@ typedef enum { R3_SUPERENCRYPTED, R3_SIGNATURE, R3_CREATE2_FORMATS, R3_AUTHENTICATION_REQUIRED, R3_INTRO_AUTH_REQUIRED, R3_SINGLE_ONION_SERVICE, R3_INTRODUCTION_POINT, R3_INTRO_AUTH_KEY, R3_INTRO_ENC_KEY, R3_INTRO_ENC_KEY_CERTIFICATION, R3_DESC_AUTH_TYPE, R3_DESC_AUTH_KEY, R3_DESC_AUTH_CLIENT, R3_ENCRYPTED, R_IPO_IDENTIFIER, R_IPO_IP_ADDRESS, Loading src/test/test_hs_cache.c +3 −3 Original line number Diff line number Diff line Loading @@ -93,8 +93,8 @@ helper_build_hs_desc(uint64_t revision_counter, uint32_t lifetime, /* Setup encrypted data section. */ desc->encrypted_data.create2_ntor = 1; desc->encrypted_data.auth_types = smartlist_new(); smartlist_add(desc->encrypted_data.auth_types, tor_strdup("ed25519")); desc->encrypted_data.intro_auth_types = smartlist_new(); smartlist_add(desc->encrypted_data.intro_auth_types, tor_strdup("ed25519")); desc->encrypted_data.intro_points = smartlist_new(); /* Add an intro point. */ smartlist_add(desc->encrypted_data.intro_points, Loading Loading @@ -333,7 +333,7 @@ helper_fetch_desc_from_hsdir(const ed25519_public_key_t *blinded_key) size_t body_used = 0; fetch_from_buf_http(TO_CONN(conn)->outbuf, &headers, MAX_HEADERS_SIZE, &received_desc, &body_used, 10000, 0); &received_desc, &body_used, HS_DESC_MAX_LEN, 0); tor_free(headers); } Loading src/test/test_hs_descriptor.c +122 −24 Original line number Diff line number Diff line Loading @@ -15,6 +15,9 @@ #include "test.h" #include "torcert.h" #include "test_helpers.h" #include "log_test_helpers.h" static hs_desc_intro_point_t * helper_build_intro_point(const ed25519_keypair_t *blinded_kp, time_t now, const char *addr, int legacy) Loading Loading @@ -105,9 +108,9 @@ helper_build_hs_desc(unsigned int no_ip, ed25519_public_key_t *signing_pubkey) /* Setup encrypted data section. */ desc->encrypted_data.create2_ntor = 1; desc->encrypted_data.auth_types = smartlist_new(); desc->encrypted_data.intro_auth_types = smartlist_new(); desc->encrypted_data.single_onion_service = 1; smartlist_add(desc->encrypted_data.auth_types, tor_strdup("ed25519")); smartlist_add(desc->encrypted_data.intro_auth_types, tor_strdup("ed25519")); desc->encrypted_data.intro_points = smartlist_new(); if (!no_ip) { /* Add four intro points. */ Loading Loading @@ -157,14 +160,17 @@ helper_compare_hs_desc(const hs_descriptor_t *desc1, desc2->encrypted_data.create2_ntor); /* Authentication type. */ tt_int_op(!!desc1->encrypted_data.auth_types, ==, !!desc2->encrypted_data.auth_types); if (desc1->encrypted_data.auth_types && desc2->encrypted_data.auth_types) { tt_int_op(smartlist_len(desc1->encrypted_data.auth_types), ==, smartlist_len(desc2->encrypted_data.auth_types)); for (int i = 0; i < smartlist_len(desc1->encrypted_data.auth_types); i++) { tt_str_op(smartlist_get(desc1->encrypted_data.auth_types, i), OP_EQ, smartlist_get(desc2->encrypted_data.auth_types, i)); tt_int_op(!!desc1->encrypted_data.intro_auth_types, ==, !!desc2->encrypted_data.intro_auth_types); if (desc1->encrypted_data.intro_auth_types && desc2->encrypted_data.intro_auth_types) { tt_int_op(smartlist_len(desc1->encrypted_data.intro_auth_types), ==, smartlist_len(desc2->encrypted_data.intro_auth_types)); for (int i = 0; i < smartlist_len(desc1->encrypted_data.intro_auth_types); i++) { tt_str_op(smartlist_get(desc1->encrypted_data.intro_auth_types, i),OP_EQ, smartlist_get(desc2->encrypted_data.intro_auth_types, i)); } } Loading Loading @@ -311,13 +317,13 @@ test_descriptor_padding(void *arg) /* Example: if l = 129, the ceiled division gives 2 and then multiplied by 128 * to give 256. With l = 127, ceiled division gives 1 then times 128. */ #define PADDING_EXPECTED_LEN(l) \ CEIL_DIV(l, HS_DESC_PLAINTEXT_PADDING_MULTIPLE) * \ HS_DESC_PLAINTEXT_PADDING_MULTIPLE CEIL_DIV(l, HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE) * \ HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE (void) arg; { /* test #1: no padding */ plaintext_len = HS_DESC_PLAINTEXT_PADDING_MULTIPLE; plaintext_len = HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE; plaintext = tor_malloc(plaintext_len); padded_len = build_plaintext_padding(plaintext, plaintext_len, &padded_plaintext); Loading @@ -333,7 +339,7 @@ test_descriptor_padding(void *arg) } { /* test #2: one byte padding? */ plaintext_len = HS_DESC_PLAINTEXT_PADDING_MULTIPLE - 1; plaintext_len = HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE - 1; plaintext = tor_malloc(plaintext_len); padded_plaintext = NULL; padded_len = build_plaintext_padding(plaintext, plaintext_len, Loading @@ -350,7 +356,7 @@ test_descriptor_padding(void *arg) } { /* test #3: Lots more bytes of padding? */ plaintext_len = HS_DESC_PLAINTEXT_PADDING_MULTIPLE + 1; plaintext_len = HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE + 1; plaintext = tor_malloc(plaintext_len); padded_plaintext = NULL; padded_len = build_plaintext_padding(plaintext, plaintext_len, Loading Loading @@ -587,19 +593,11 @@ test_encrypted_data_len(void *arg) /* No length, error. */ ret = encrypted_data_length_is_valid(0); tt_int_op(ret, OP_EQ, 0); /* Not a multiple of our encryption algorithm (thus no padding). It's * suppose to be aligned on HS_DESC_PLAINTEXT_PADDING_MULTIPLE. */ value = HS_DESC_PLAINTEXT_PADDING_MULTIPLE * 10 - 1; ret = encrypted_data_length_is_valid(value); tt_int_op(ret, OP_EQ, 0); /* Valid value. */ value = HS_DESC_PADDED_PLAINTEXT_MAX_LEN + HS_DESC_ENCRYPTED_SALT_LEN + DIGEST256_LEN; value = HS_DESC_ENCRYPTED_SALT_LEN + DIGEST256_LEN + 1; ret = encrypted_data_length_is_valid(value); tt_int_op(ret, OP_EQ, 1); /* XXX: Test maximum possible size. */ done: ; } Loading Loading @@ -1006,6 +1004,103 @@ test_desc_signature(void *arg) tor_free(data); } /* bad desc auth type */ const char bad_superencrypted_text1[] = "desc-auth-type scoobysnack\n" "desc-auth-ephemeral-key A/O8DVtnUheb3r1JqoB8uJB7wxXL1XJX3eny4yB+eFA=\n" "auth-client oiNrQB8WwKo S5D02W7vKgiWIMygrBl8RQ FB//SfOBmLEx1kViEWWL1g\n" "encrypted\n" "-----BEGIN MESSAGE-----\n" "YmVpbmcgb24gbW91bnRhaW5zLCB0aGlua2luZyBhYm91dCBjb21wdXRlcnMsIGlzIG5vdC" "BiYWQgYXQgYWxs\n" "-----END MESSAGE-----\n"; /* bad ephemeral key */ const char bad_superencrypted_text2[] = "desc-auth-type x25519\n" "desc-auth-ephemeral-key differentalphabet\n" "auth-client oiNrQB8WwKo S5D02W7vKgiWIMygrBl8RQ FB//SfOBmLEx1kViEWWL1g\n" "encrypted\n" "-----BEGIN MESSAGE-----\n" "YmVpbmcgb24gbW91bnRhaW5zLCB0aGlua2luZyBhYm91dCBjb21wdXRlcnMsIGlzIG5vdC" "BiYWQgYXQgYWxs\n" "-----END MESSAGE-----\n"; /* bad encrypted msg */ const char bad_superencrypted_text3[] = "desc-auth-type x25519\n" "desc-auth-ephemeral-key A/O8DVtnUheb3r1JqoB8uJB7wxXL1XJX3eny4yB+eFA=\n" "auth-client oiNrQB8WwKo S5D02W7vKgiWIMygrBl8RQ FB//SfOBmLEx1kViEWWL1g\n" "encrypted\n" "-----BEGIN MESSAGE-----\n" "SO SMALL NOT GOOD\n" "-----END MESSAGE-----\n"; const char correct_superencrypted_text[] = "desc-auth-type x25519\n" "desc-auth-ephemeral-key A/O8DVtnUheb3r1JqoB8uJB7wxXL1XJX3eny4yB+eFA=\n" "auth-client oiNrQB8WwKo S5D02W7vKgiWIMygrBl8RQ FB//SfOBmLEx1kViEWWL1g\n" "auth-client Od09Qu636Qo /PKLzqewAdS/+0+vZC+MvQ dpw4NFo13zDnuPz45rxrOg\n" "auth-client JRr840iGYN0 8s8cxYqF7Lx23+NducC4Qg zAafl4wPLURkuEjJreZq1g\n" "encrypted\n" "-----BEGIN MESSAGE-----\n" "YmVpbmcgb24gbW91bnRhaW5zLCB0aGlua2luZyBhYm91dCBjb21wdXRlcnMsIGlzIG5vdC" "BiYWQgYXQgYWxs\n" "-----END MESSAGE-----\n"; const char correct_encrypted_plaintext[] = "being on mountains, " "thinking about computers, is not bad at all"; static void test_parse_hs_desc_superencrypted(void *arg) { (void) arg; int retval; uint8_t *encrypted_out = NULL; { setup_full_capture_of_logs(LOG_WARN); retval = decode_superencrypted(bad_superencrypted_text1, strlen(bad_superencrypted_text1), &encrypted_out); tt_int_op(retval, ==, 0); tt_assert(!encrypted_out); expect_log_msg_containing("Unrecognized desc auth type"); teardown_capture_of_logs(); } { setup_full_capture_of_logs(LOG_WARN); retval = decode_superencrypted(bad_superencrypted_text2, strlen(bad_superencrypted_text2), &encrypted_out); tt_int_op(retval, ==, 0); tt_assert(!encrypted_out); expect_log_msg_containing("Bogus desc auth key in HS desc"); teardown_capture_of_logs(); } { setup_full_capture_of_logs(LOG_WARN); retval = decode_superencrypted(bad_superencrypted_text3, strlen(bad_superencrypted_text3), &encrypted_out); tt_int_op(retval, ==, 0); tt_assert(!encrypted_out); expect_log_msg_containing("Length of descriptor\'s encrypted data " "is too small."); teardown_capture_of_logs(); } /* Now finally the good one */ retval = decode_superencrypted(correct_superencrypted_text, strlen(correct_superencrypted_text), &encrypted_out); tt_int_op(retval, ==, strlen(correct_encrypted_plaintext)); tt_mem_op(encrypted_out, OP_EQ, correct_encrypted_plaintext, strlen(correct_encrypted_plaintext)); done: tor_free(encrypted_out); } struct testcase_t hs_descriptor[] = { /* Encoding tests. */ { "cert_encoding", test_cert_encoding, TT_FORK, Loading Loading @@ -1035,6 +1130,9 @@ struct testcase_t hs_descriptor[] = { { "desc_signature", test_desc_signature, TT_FORK, NULL, NULL }, { "parse_hs_desc_superencrypted", test_parse_hs_desc_superencrypted, TT_FORK, NULL, NULL }, END_OF_TESTCASES }; Loading
src/or/hs_descriptor.c +671 −247 File changed.Preview size limit exceeded, changes collapsed. Show changes
src/or/hs_descriptor.h +11 −23 Original line number Diff line number Diff line Loading @@ -41,24 +41,11 @@ * the secret IV and MAC key length which is the length of H() output. */ #define HS_DESC_ENCRYPTED_KDF_OUTPUT_LEN \ CIPHER256_KEY_LEN + CIPHER_IV_LEN + DIGEST256_LEN /* We need to pad the plaintext version of the encrypted data section before * encryption and it has to be a multiple of this value. */ #define HS_DESC_PLAINTEXT_PADDING_MULTIPLE 128 /* XXX: Let's make sure this makes sense as an upper limit for the padded * plaintext section. Then we should enforce it as now only an assert will be * triggered if we are above it. */ /* Once padded, this is the maximum length in bytes for the plaintext. */ #define HS_DESC_PADDED_PLAINTEXT_MAX_LEN 8192 /* Minimum length in bytes of the encrypted portion of the descriptor. */ #define HS_DESC_ENCRYPTED_MIN_LEN \ HS_DESC_ENCRYPTED_SALT_LEN + \ HS_DESC_PLAINTEXT_PADDING_MULTIPLE + DIGEST256_LEN /* Pad plaintext of superencrypted data section before encryption so that its * length is a multiple of this value. */ #define HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE 10000 /* Maximum length in bytes of a full hidden service descriptor. */ #define HS_DESC_MAX_LEN 50000 /* 50kb max size */ /* The minimum amount of fields a descriptor should contain. The parsing of * the fields are version specific so the only required field, as a generic * view of a descriptor, is 1 that is the version field. */ #define HS_DESC_PLAINTEXT_MIN_FIELDS 1 /* Key length for the descriptor symmetric encryption. As specified in the * protocol, we use AES-256 for the encrypted section of the descriptor. The Loading @@ -68,8 +55,7 @@ /* Type of authentication in the descriptor. */ typedef enum { HS_DESC_AUTH_PASSWORD = 1, HS_DESC_AUTH_ED25519 = 2, HS_DESC_AUTH_ED25519 = 1 } hs_desc_auth_type_t; /* Type of encryption key in the descriptor. */ Loading Loading @@ -132,7 +118,7 @@ typedef struct hs_desc_encrypted_data_t { /* A list of authentication types that a client must at least support one * in order to contact the service. Contains NULL terminated strings. */ smartlist_t *auth_types; smartlist_t *intro_auth_types; /* Is this descriptor a single onion service? */ unsigned int single_onion_service : 1; Loading Loading @@ -167,11 +153,11 @@ typedef struct hs_desc_plaintext_data_t { * has changed. Spec specifies this as a 8 bytes positive integer. */ uint64_t revision_counter; /* Decoding only: The base64-decoded encrypted blob from the descriptor */ uint8_t *encrypted_blob; /* Decoding only: The b64-decoded superencrypted blob from the descriptor */ uint8_t *superencrypted_blob; /* Decoding only: Size of the encrypted_blob */ size_t encrypted_blob_size; /* Decoding only: Size of the superencrypted_blob */ size_t superencrypted_blob_size; } hs_desc_plaintext_data_t; /* Service descriptor in its decoded form. */ Loading Loading @@ -242,6 +228,8 @@ 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 void desc_intro_point_free(hs_desc_intro_point_t *ip); STATIC size_t decode_superencrypted(const char *message, size_t message_len, uint8_t **encrypted_out); #endif /* HS_DESCRIPTOR_PRIVATE */ #endif /* TOR_HS_DESCRIPTOR_H */ Loading
src/or/parsecommon.h +5 −1 Original line number Diff line number Diff line Loading @@ -157,12 +157,16 @@ typedef enum { R3_SUPERENCRYPTED, R3_SIGNATURE, R3_CREATE2_FORMATS, R3_AUTHENTICATION_REQUIRED, R3_INTRO_AUTH_REQUIRED, R3_SINGLE_ONION_SERVICE, R3_INTRODUCTION_POINT, R3_INTRO_AUTH_KEY, R3_INTRO_ENC_KEY, R3_INTRO_ENC_KEY_CERTIFICATION, R3_DESC_AUTH_TYPE, R3_DESC_AUTH_KEY, R3_DESC_AUTH_CLIENT, R3_ENCRYPTED, R_IPO_IDENTIFIER, R_IPO_IP_ADDRESS, Loading
src/test/test_hs_cache.c +3 −3 Original line number Diff line number Diff line Loading @@ -93,8 +93,8 @@ helper_build_hs_desc(uint64_t revision_counter, uint32_t lifetime, /* Setup encrypted data section. */ desc->encrypted_data.create2_ntor = 1; desc->encrypted_data.auth_types = smartlist_new(); smartlist_add(desc->encrypted_data.auth_types, tor_strdup("ed25519")); desc->encrypted_data.intro_auth_types = smartlist_new(); smartlist_add(desc->encrypted_data.intro_auth_types, tor_strdup("ed25519")); desc->encrypted_data.intro_points = smartlist_new(); /* Add an intro point. */ smartlist_add(desc->encrypted_data.intro_points, Loading Loading @@ -333,7 +333,7 @@ helper_fetch_desc_from_hsdir(const ed25519_public_key_t *blinded_key) size_t body_used = 0; fetch_from_buf_http(TO_CONN(conn)->outbuf, &headers, MAX_HEADERS_SIZE, &received_desc, &body_used, 10000, 0); &received_desc, &body_used, HS_DESC_MAX_LEN, 0); tor_free(headers); } Loading
src/test/test_hs_descriptor.c +122 −24 Original line number Diff line number Diff line Loading @@ -15,6 +15,9 @@ #include "test.h" #include "torcert.h" #include "test_helpers.h" #include "log_test_helpers.h" static hs_desc_intro_point_t * helper_build_intro_point(const ed25519_keypair_t *blinded_kp, time_t now, const char *addr, int legacy) Loading Loading @@ -105,9 +108,9 @@ helper_build_hs_desc(unsigned int no_ip, ed25519_public_key_t *signing_pubkey) /* Setup encrypted data section. */ desc->encrypted_data.create2_ntor = 1; desc->encrypted_data.auth_types = smartlist_new(); desc->encrypted_data.intro_auth_types = smartlist_new(); desc->encrypted_data.single_onion_service = 1; smartlist_add(desc->encrypted_data.auth_types, tor_strdup("ed25519")); smartlist_add(desc->encrypted_data.intro_auth_types, tor_strdup("ed25519")); desc->encrypted_data.intro_points = smartlist_new(); if (!no_ip) { /* Add four intro points. */ Loading Loading @@ -157,14 +160,17 @@ helper_compare_hs_desc(const hs_descriptor_t *desc1, desc2->encrypted_data.create2_ntor); /* Authentication type. */ tt_int_op(!!desc1->encrypted_data.auth_types, ==, !!desc2->encrypted_data.auth_types); if (desc1->encrypted_data.auth_types && desc2->encrypted_data.auth_types) { tt_int_op(smartlist_len(desc1->encrypted_data.auth_types), ==, smartlist_len(desc2->encrypted_data.auth_types)); for (int i = 0; i < smartlist_len(desc1->encrypted_data.auth_types); i++) { tt_str_op(smartlist_get(desc1->encrypted_data.auth_types, i), OP_EQ, smartlist_get(desc2->encrypted_data.auth_types, i)); tt_int_op(!!desc1->encrypted_data.intro_auth_types, ==, !!desc2->encrypted_data.intro_auth_types); if (desc1->encrypted_data.intro_auth_types && desc2->encrypted_data.intro_auth_types) { tt_int_op(smartlist_len(desc1->encrypted_data.intro_auth_types), ==, smartlist_len(desc2->encrypted_data.intro_auth_types)); for (int i = 0; i < smartlist_len(desc1->encrypted_data.intro_auth_types); i++) { tt_str_op(smartlist_get(desc1->encrypted_data.intro_auth_types, i),OP_EQ, smartlist_get(desc2->encrypted_data.intro_auth_types, i)); } } Loading Loading @@ -311,13 +317,13 @@ test_descriptor_padding(void *arg) /* Example: if l = 129, the ceiled division gives 2 and then multiplied by 128 * to give 256. With l = 127, ceiled division gives 1 then times 128. */ #define PADDING_EXPECTED_LEN(l) \ CEIL_DIV(l, HS_DESC_PLAINTEXT_PADDING_MULTIPLE) * \ HS_DESC_PLAINTEXT_PADDING_MULTIPLE CEIL_DIV(l, HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE) * \ HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE (void) arg; { /* test #1: no padding */ plaintext_len = HS_DESC_PLAINTEXT_PADDING_MULTIPLE; plaintext_len = HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE; plaintext = tor_malloc(plaintext_len); padded_len = build_plaintext_padding(plaintext, plaintext_len, &padded_plaintext); Loading @@ -333,7 +339,7 @@ test_descriptor_padding(void *arg) } { /* test #2: one byte padding? */ plaintext_len = HS_DESC_PLAINTEXT_PADDING_MULTIPLE - 1; plaintext_len = HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE - 1; plaintext = tor_malloc(plaintext_len); padded_plaintext = NULL; padded_len = build_plaintext_padding(plaintext, plaintext_len, Loading @@ -350,7 +356,7 @@ test_descriptor_padding(void *arg) } { /* test #3: Lots more bytes of padding? */ plaintext_len = HS_DESC_PLAINTEXT_PADDING_MULTIPLE + 1; plaintext_len = HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE + 1; plaintext = tor_malloc(plaintext_len); padded_plaintext = NULL; padded_len = build_plaintext_padding(plaintext, plaintext_len, Loading Loading @@ -587,19 +593,11 @@ test_encrypted_data_len(void *arg) /* No length, error. */ ret = encrypted_data_length_is_valid(0); tt_int_op(ret, OP_EQ, 0); /* Not a multiple of our encryption algorithm (thus no padding). It's * suppose to be aligned on HS_DESC_PLAINTEXT_PADDING_MULTIPLE. */ value = HS_DESC_PLAINTEXT_PADDING_MULTIPLE * 10 - 1; ret = encrypted_data_length_is_valid(value); tt_int_op(ret, OP_EQ, 0); /* Valid value. */ value = HS_DESC_PADDED_PLAINTEXT_MAX_LEN + HS_DESC_ENCRYPTED_SALT_LEN + DIGEST256_LEN; value = HS_DESC_ENCRYPTED_SALT_LEN + DIGEST256_LEN + 1; ret = encrypted_data_length_is_valid(value); tt_int_op(ret, OP_EQ, 1); /* XXX: Test maximum possible size. */ done: ; } Loading Loading @@ -1006,6 +1004,103 @@ test_desc_signature(void *arg) tor_free(data); } /* bad desc auth type */ const char bad_superencrypted_text1[] = "desc-auth-type scoobysnack\n" "desc-auth-ephemeral-key A/O8DVtnUheb3r1JqoB8uJB7wxXL1XJX3eny4yB+eFA=\n" "auth-client oiNrQB8WwKo S5D02W7vKgiWIMygrBl8RQ FB//SfOBmLEx1kViEWWL1g\n" "encrypted\n" "-----BEGIN MESSAGE-----\n" "YmVpbmcgb24gbW91bnRhaW5zLCB0aGlua2luZyBhYm91dCBjb21wdXRlcnMsIGlzIG5vdC" "BiYWQgYXQgYWxs\n" "-----END MESSAGE-----\n"; /* bad ephemeral key */ const char bad_superencrypted_text2[] = "desc-auth-type x25519\n" "desc-auth-ephemeral-key differentalphabet\n" "auth-client oiNrQB8WwKo S5D02W7vKgiWIMygrBl8RQ FB//SfOBmLEx1kViEWWL1g\n" "encrypted\n" "-----BEGIN MESSAGE-----\n" "YmVpbmcgb24gbW91bnRhaW5zLCB0aGlua2luZyBhYm91dCBjb21wdXRlcnMsIGlzIG5vdC" "BiYWQgYXQgYWxs\n" "-----END MESSAGE-----\n"; /* bad encrypted msg */ const char bad_superencrypted_text3[] = "desc-auth-type x25519\n" "desc-auth-ephemeral-key A/O8DVtnUheb3r1JqoB8uJB7wxXL1XJX3eny4yB+eFA=\n" "auth-client oiNrQB8WwKo S5D02W7vKgiWIMygrBl8RQ FB//SfOBmLEx1kViEWWL1g\n" "encrypted\n" "-----BEGIN MESSAGE-----\n" "SO SMALL NOT GOOD\n" "-----END MESSAGE-----\n"; const char correct_superencrypted_text[] = "desc-auth-type x25519\n" "desc-auth-ephemeral-key A/O8DVtnUheb3r1JqoB8uJB7wxXL1XJX3eny4yB+eFA=\n" "auth-client oiNrQB8WwKo S5D02W7vKgiWIMygrBl8RQ FB//SfOBmLEx1kViEWWL1g\n" "auth-client Od09Qu636Qo /PKLzqewAdS/+0+vZC+MvQ dpw4NFo13zDnuPz45rxrOg\n" "auth-client JRr840iGYN0 8s8cxYqF7Lx23+NducC4Qg zAafl4wPLURkuEjJreZq1g\n" "encrypted\n" "-----BEGIN MESSAGE-----\n" "YmVpbmcgb24gbW91bnRhaW5zLCB0aGlua2luZyBhYm91dCBjb21wdXRlcnMsIGlzIG5vdC" "BiYWQgYXQgYWxs\n" "-----END MESSAGE-----\n"; const char correct_encrypted_plaintext[] = "being on mountains, " "thinking about computers, is not bad at all"; static void test_parse_hs_desc_superencrypted(void *arg) { (void) arg; int retval; uint8_t *encrypted_out = NULL; { setup_full_capture_of_logs(LOG_WARN); retval = decode_superencrypted(bad_superencrypted_text1, strlen(bad_superencrypted_text1), &encrypted_out); tt_int_op(retval, ==, 0); tt_assert(!encrypted_out); expect_log_msg_containing("Unrecognized desc auth type"); teardown_capture_of_logs(); } { setup_full_capture_of_logs(LOG_WARN); retval = decode_superencrypted(bad_superencrypted_text2, strlen(bad_superencrypted_text2), &encrypted_out); tt_int_op(retval, ==, 0); tt_assert(!encrypted_out); expect_log_msg_containing("Bogus desc auth key in HS desc"); teardown_capture_of_logs(); } { setup_full_capture_of_logs(LOG_WARN); retval = decode_superencrypted(bad_superencrypted_text3, strlen(bad_superencrypted_text3), &encrypted_out); tt_int_op(retval, ==, 0); tt_assert(!encrypted_out); expect_log_msg_containing("Length of descriptor\'s encrypted data " "is too small."); teardown_capture_of_logs(); } /* Now finally the good one */ retval = decode_superencrypted(correct_superencrypted_text, strlen(correct_superencrypted_text), &encrypted_out); tt_int_op(retval, ==, strlen(correct_encrypted_plaintext)); tt_mem_op(encrypted_out, OP_EQ, correct_encrypted_plaintext, strlen(correct_encrypted_plaintext)); done: tor_free(encrypted_out); } struct testcase_t hs_descriptor[] = { /* Encoding tests. */ { "cert_encoding", test_cert_encoding, TT_FORK, Loading Loading @@ -1035,6 +1130,9 @@ struct testcase_t hs_descriptor[] = { { "desc_signature", test_desc_signature, TT_FORK, NULL, NULL }, { "parse_hs_desc_superencrypted", test_parse_hs_desc_superencrypted, TT_FORK, NULL, NULL }, END_OF_TESTCASES };