Sfoglia il codice sorgente

Merge remote-tracking branch 'asn/bug21334_v3'

Nick Mathewson 7 anni fa
parent
commit
43dd9bf0fc
5 ha cambiato i file con 801 aggiunte e 288 eliminazioni
  1. 660 237
      src/or/hs_descriptor.c
  2. 11 23
      src/or/hs_descriptor.h
  3. 5 1
      src/or/parsecommon.h
  4. 3 3
      src/test/test_hs_cache.c
  5. 122 24
      src/test/test_hs_descriptor.c

File diff suppressed because it is too large
+ 660 - 237
src/or/hs_descriptor.c


+ 11 - 23
src/or/hs_descriptor.h

@@ -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
@@ -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. */
@@ -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;
@@ -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. */
@@ -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 */

+ 5 - 1
src/or/parsecommon.h

@@ -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,

+ 3 - 3
src/test/test_hs_cache.c

@@ -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,
@@ -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);
   }
 

+ 122 - 24
src/test/test_hs_descriptor.c

@@ -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)
@@ -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. */
@@ -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));
     }
   }
 
@@ -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);
@@ -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,
@@ -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,
@@ -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:
   ;
 }
@@ -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,
@@ -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
 };
 

Some files were not shown because too many files changed in this diff