Browse Source

Merge remote-tracking branch 'dgoulet/bug20572_030_01'

Nick Mathewson 6 years ago
parent
commit
0087fe36c1
5 changed files with 146 additions and 103 deletions
  1. 1 1
      src/or/hs_cache.c
  2. 35 29
      src/or/hs_descriptor.c
  3. 6 5
      src/or/hs_descriptor.h
  4. 56 37
      src/test/test_hs_cache.c
  5. 48 31
      src/test/test_hs_descriptor.c

+ 1 - 1
src/or/hs_cache.c

@@ -86,7 +86,7 @@ cache_dir_desc_new(const char *desc)
   }
 
   /* The blinded pubkey is the indexed key. */
-  dir_desc->key = dir_desc->plaintext_data->blinded_kp.pubkey.pubkey;
+  dir_desc->key = dir_desc->plaintext_data->blinded_pubkey.pubkey;
   dir_desc->created_ts = time(NULL);
   return dir_desc;
 

+ 35 - 29
src/or/hs_descriptor.c

@@ -219,7 +219,7 @@ encode_link_specifiers(const smartlist_t *specs)
 /* Encode an introduction point encryption key and return a newly allocated
  * string with it. On failure, return NULL. */
 static char *
-encode_enc_key(const ed25519_keypair_t *sig_key,
+encode_enc_key(const ed25519_public_key_t *sig_key,
                const hs_desc_intro_point_t *ip)
 {
   char *encoded = NULL;
@@ -237,8 +237,7 @@ encode_enc_key(const ed25519_keypair_t *sig_key,
     uint8_t *cert_data = NULL;
 
     /* Create cross certification cert. */
-    cert_len = tor_make_rsa_ed25519_crosscert(&sig_key->pubkey,
-                                              ip->enc_key.legacy,
+    cert_len = tor_make_rsa_ed25519_crosscert(sig_key, ip->enc_key.legacy,
                                               now + HS_DESC_CERT_LIFETIME,
                                               &cert_data);
     if (cert_len < 0) {
@@ -282,7 +281,7 @@ encode_enc_key(const ed25519_keypair_t *sig_key,
     }
     tor_cert_t *cross_cert = tor_cert_create(&curve_kp,
                                              CERT_TYPE_CROSS_HS_IP_KEYS,
-                                             &sig_key->pubkey, now,
+                                             sig_key, now,
                                              HS_DESC_CERT_LIFETIME,
                                              CERT_FLAG_INCLUDE_SIGNING_KEY);
     memwipe(&curve_kp, 0, sizeof(curve_kp));
@@ -318,7 +317,7 @@ encode_enc_key(const ed25519_keypair_t *sig_key,
 /* Encode an introduction point object and return a newly allocated string
  * with it. On failure, return NULL. */
 static char *
-encode_intro_point(const ed25519_keypair_t *sig_key,
+encode_intro_point(const ed25519_public_key_t *sig_key,
                    const hs_desc_intro_point_t *ip)
 {
   char *encoded_ip = NULL;
@@ -377,9 +376,9 @@ build_secret_input(const hs_descriptor_t *desc, uint8_t *dst, size_t dstlen)
 
   /* XXX use the destination length as the memcpy length */
   /* Copy blinded public key. */
-  memcpy(dst, desc->plaintext_data.blinded_kp.pubkey.pubkey,
-         sizeof(desc->plaintext_data.blinded_kp.pubkey.pubkey));
-  offset += sizeof(desc->plaintext_data.blinded_kp.pubkey.pubkey);
+  memcpy(dst, desc->plaintext_data.blinded_pubkey.pubkey,
+         sizeof(desc->plaintext_data.blinded_pubkey.pubkey));
+  offset += sizeof(desc->plaintext_data.blinded_pubkey.pubkey);
   /* Copy subcredential. */
   memcpy(dst + offset, desc->subcredential, sizeof(desc->subcredential));
   offset += sizeof(desc->subcredential);
@@ -665,7 +664,7 @@ encode_encrypted_data(const hs_descriptor_t *desc,
   /* Build the introduction point(s) section. */
   SMARTLIST_FOREACH_BEGIN(desc->encrypted_data.intro_points,
                           const hs_desc_intro_point_t *, ip) {
-    char *encoded_ip = encode_intro_point(&desc->plaintext_data.signing_kp,
+    char *encoded_ip = encode_intro_point(&desc->plaintext_data.signing_pubkey,
                                           ip);
     if (encoded_ip == NULL) {
       log_err(LD_BUG, "HS desc intro point is malformed.");
@@ -710,7 +709,8 @@ encode_encrypted_data(const hs_descriptor_t *desc,
  * newly allocated string of the encoded descriptor. On error, -1 is returned
  * and encoded_out is untouched. */
 static int
-desc_encode_v3(const hs_descriptor_t *desc, char **encoded_out)
+desc_encode_v3(const hs_descriptor_t *desc,
+               const ed25519_keypair_t *signing_kp, char **encoded_out)
 {
   int ret = -1;
   char *encoded_str = NULL;
@@ -718,6 +718,7 @@ desc_encode_v3(const hs_descriptor_t *desc, char **encoded_out)
   smartlist_t *lines = smartlist_new();
 
   tor_assert(desc);
+  tor_assert(signing_kp);
   tor_assert(encoded_out);
   tor_assert(desc->plaintext_data.version == 3);
 
@@ -732,7 +733,7 @@ desc_encode_v3(const hs_descriptor_t *desc, char **encoded_out)
       goto err;
     }
     if (tor_cert_encode_ed22519(desc->plaintext_data.signing_key_cert,
-                    &encoded_cert) < 0) {
+                                &encoded_cert) < 0) {
       /* The function will print error logs. */
       goto err;
     }
@@ -775,8 +776,7 @@ desc_encode_v3(const hs_descriptor_t *desc, char **encoded_out)
     char ed_sig_b64[ED25519_SIG_BASE64_LEN + 1];
     if (ed25519_sign_prefixed(&sig,
                               (const uint8_t *) encoded_str, encoded_len,
-                              str_desc_sig_prefix,
-                              &desc->plaintext_data.signing_kp) < 0) {
+                              str_desc_sig_prefix, signing_kp) < 0) {
       log_warn(LD_BUG, "Can't sign encoded HS descriptor!");
       tor_free(encoded_str);
       goto err;
@@ -1365,7 +1365,8 @@ decode_intro_points(const hs_descriptor_t *desc,
 /* 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, const ed25519_keypair_t *signing_kp,
+desc_sig_is_valid(const char *b64_sig,
+                  const ed25519_public_key_t *signing_pubkey,
                   const char *encoded_desc, size_t encoded_len)
 {
   int ret = 0;
@@ -1373,7 +1374,7 @@ desc_sig_is_valid(const char *b64_sig, const ed25519_keypair_t *signing_kp,
   const char *sig_start;
 
   tor_assert(b64_sig);
-  tor_assert(signing_kp);
+  tor_assert(signing_pubkey);
   tor_assert(encoded_desc);
   /* Verifying nothing won't end well :). */
   tor_assert(encoded_len > 0);
@@ -1408,7 +1409,7 @@ desc_sig_is_valid(const char *b64_sig, const ed25519_keypair_t *signing_kp,
                                 (const uint8_t *) encoded_desc,
                                 sig_start - encoded_desc,
                                 str_desc_sig_prefix,
-                                &signing_kp->pubkey) != 0) {
+                                signing_pubkey) != 0) {
     log_warn(LD_REND, "Invalid signature on service descriptor");
     goto err;
   }
@@ -1474,10 +1475,10 @@ desc_decode_plaintext_v3(smartlist_t *tokens,
     goto err;
   }
 
-  /* Copy the public keys into signing_kp and blinded_kp */
-  memcpy(&desc->signing_kp.pubkey, &desc->signing_key_cert->signed_key,
+  /* Copy the public keys into signing_pubkey and blinded_pubkey */
+  memcpy(&desc->signing_pubkey, &desc->signing_key_cert->signed_key,
          sizeof(ed25519_public_key_t));
-  memcpy(&desc->blinded_kp.pubkey, &desc->signing_key_cert->signing_key,
+  memcpy(&desc->blinded_pubkey, &desc->signing_key_cert->signing_key,
          sizeof(ed25519_public_key_t));
 
   /* Extract revision counter value. */
@@ -1511,7 +1512,7 @@ desc_decode_plaintext_v3(smartlist_t *tokens,
   tok = find_by_keyword(tokens, R3_SIGNATURE);
   tor_assert(tok->n_args == 1);
   /* First arg here is the actual encoded signature. */
-  if (!desc_sig_is_valid(tok->args[0], &desc->signing_kp,
+  if (!desc_sig_is_valid(tok->args[0], &desc->signing_pubkey,
                          encoded_desc, encoded_len)) {
     goto err;
   }
@@ -1806,41 +1807,46 @@ hs_desc_decode_descriptor(const char *encoded,
   return ret;
 }
 
-/* Table of encode function version specific. The function 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[])(
       const hs_descriptor_t *desc,
+      const ed25519_keypair_t *signing_kp,
       char **encoded_out) =
 {
   /* v0 */ NULL, /* v1 */ NULL, /* v2 */ NULL,
   desc_encode_v3,
 };
 
-/* Encode the given descriptor desc. On success, encoded_out points to a newly
- * allocated NUL terminated string that contains the encoded descriptor as a
- * string.
+/* Encode the given descriptor desc including signing with the given key pair
+ * signing_kp. 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. */
 int
-hs_desc_encode_descriptor(const hs_descriptor_t *desc, char **encoded_out)
+hs_desc_encode_descriptor(const hs_descriptor_t *desc,
+                          const ed25519_keypair_t *signing_kp,
+                          char **encoded_out)
 {
   int ret = -1;
+  uint32_t version;
 
   tor_assert(desc);
   tor_assert(encoded_out);
 
   /* Make sure we support the version of the descriptor format. */
-  if (!hs_desc_is_supported_version(desc->plaintext_data.version)) {
+  version = desc->plaintext_data.version;
+  if (!hs_desc_is_supported_version(version)) {
     goto err;
   }
   /* Extra precaution. Having no handler for the supported version should
    * never happened else we forgot to add it but we bumped the version. */
-  tor_assert(ARRAY_LENGTH(encode_handlers) >= desc->plaintext_data.version);
-  tor_assert(encode_handlers[desc->plaintext_data.version]);
+  tor_assert(ARRAY_LENGTH(encode_handlers) >= version);
+  tor_assert(encode_handlers[version]);
 
-  ret = encode_handlers[desc->plaintext_data.version](desc, encoded_out);
+  ret = encode_handlers[version](desc, signing_kp, encoded_out);
   if (ret < 0) {
     goto err;
   }

+ 6 - 5
src/or/hs_descriptor.h

@@ -148,13 +148,13 @@ typedef struct hs_desc_plaintext_data_t {
    * replica which is signed by the blinded public key for that replica. */
   tor_cert_t *signing_key_cert;
 
-  /* Signing keypair which is used to sign the descriptor. Same public key
+  /* Signing public key which is used to sign the descriptor. Same public key
    * as in the signing key certificate. */
-  ed25519_keypair_t signing_kp;
+  ed25519_public_key_t signing_pubkey;
 
-  /* Blinded keypair used for this descriptor derived from the master
+  /* Blinded public key used for this descriptor derived from the master
    * identity key and generated for a specific replica number. */
-  ed25519_keypair_t blinded_kp;
+  ed25519_public_key_t blinded_pubkey;
 
   /* Revision counter is incremented at each upload, regardless of whether
    * the descriptor has changed. This avoids leaking whether the descriptor
@@ -201,6 +201,7 @@ void hs_desc_plaintext_data_free(hs_desc_plaintext_data_t *desc);
 void hs_desc_encrypted_data_free(hs_desc_encrypted_data_t *desc);
 
 int hs_desc_encode_descriptor(const hs_descriptor_t *desc,
+                              const ed25519_keypair_t *signing_kp,
                               char **encoded_out);
 
 int hs_desc_decode_descriptor(const char *encoded,
@@ -232,7 +233,7 @@ STATIC int encrypted_data_length_is_valid(size_t len);
 STATIC int cert_is_valid(tor_cert_t *cert, uint8_t type,
                          const char *log_obj_type);
 STATIC int desc_sig_is_valid(const char *b64_sig,
-                             const ed25519_keypair_t *signing_kp,
+                             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);
 #endif /* HS_DESCRIPTOR_PRIVATE */

+ 56 - 37
src/test/test_hs_cache.c

@@ -66,27 +66,27 @@ helper_build_intro_point(const ed25519_keypair_t *blinded_kp,
 /* Return a valid hs_descriptor_t object. */
 static hs_descriptor_t *
 helper_build_hs_desc(uint64_t revision_counter, uint32_t lifetime,
-                     ed25519_keypair_t *blinded_kp)
+                     ed25519_public_key_t *signing_pubkey)
 {
   int ret;
+  ed25519_keypair_t blinded_kp;
   hs_descriptor_t *descp = NULL, *desc = tor_malloc_zero(sizeof(*desc));
 
   desc->plaintext_data.version = HS_DESC_SUPPORTED_FORMAT_VERSION_MAX;
-  ret = ed25519_keypair_generate(&desc->plaintext_data.signing_kp, 0);
+
+  /* Copy only the public key into the descriptor. */
+  memcpy(&desc->plaintext_data.signing_pubkey, signing_pubkey,
+         sizeof(ed25519_public_key_t));
+
+  ret = ed25519_keypair_generate(&blinded_kp, 0);
   tt_int_op(ret, ==, 0);
-  if (blinded_kp) {
-    memcpy(&desc->plaintext_data.blinded_kp, blinded_kp,
-           sizeof(ed25519_keypair_t));
-  } else {
-    ret = ed25519_keypair_generate(&desc->plaintext_data.blinded_kp, 0);
-    tt_int_op(ret, ==, 0);
-  }
+  /* Copy only the public key into the descriptor. */
+  memcpy(&desc->plaintext_data.blinded_pubkey, &blinded_kp.pubkey,
+         sizeof(ed25519_public_key_t));
 
   desc->plaintext_data.signing_key_cert =
-    tor_cert_create(&desc->plaintext_data.blinded_kp,
-                    CERT_TYPE_SIGNING_HS_DESC,
-                    &desc->plaintext_data.signing_kp.pubkey, time(NULL),
-                    3600, CERT_FLAG_INCLUDE_SIGNING_KEY);
+    tor_cert_create(&blinded_kp, CERT_TYPE_SIGNING_HS_DESC, signing_pubkey,
+                    time(NULL), 3600, CERT_FLAG_INCLUDE_SIGNING_KEY);
   tt_assert(desc->plaintext_data.signing_key_cert);
   desc->plaintext_data.revision_counter = revision_counter;
   desc->plaintext_data.lifetime_sec = lifetime;
@@ -98,8 +98,7 @@ helper_build_hs_desc(uint64_t revision_counter, uint32_t lifetime,
   desc->encrypted_data.intro_points = smartlist_new();
   /* Add an intro point. */
   smartlist_add(desc->encrypted_data.intro_points,
-                helper_build_intro_point(&desc->plaintext_data.blinded_kp,
-                                         "1.2.3.4"));
+                helper_build_intro_point(&blinded_kp, "1.2.3.4"));
 
   descp = desc;
  done:
@@ -109,12 +108,11 @@ helper_build_hs_desc(uint64_t revision_counter, uint32_t lifetime,
 /* Static variable used to encoded the HSDir query. */
 static char query_b64[256];
 
-/* Build an HSDir query using a ed25519 keypair. */
+/* Build an HSDir query using a ed25519 public key. */
 static const char *
 helper_get_hsdir_query(const hs_descriptor_t *desc)
 {
-  ed25519_public_to_base64(query_b64,
-                           &desc->plaintext_data.blinded_kp.pubkey);
+  ed25519_public_to_base64(query_b64, &desc->plaintext_data.blinded_pubkey);
   return query_b64;
 }
 
@@ -132,17 +130,20 @@ test_directory(void *arg)
 {
   int ret;
   size_t oom_size;
-  char *desc1_str=NULL;
+  char *desc1_str = NULL;
   const char *desc_out;
-  hs_descriptor_t *desc1;
+  ed25519_keypair_t signing_kp1;
+  hs_descriptor_t *desc1 = NULL;
 
   (void) arg;
 
   init_test();
   /* Generate a valid descriptor with normal values. */
-  desc1 = helper_build_hs_desc(42, 3 * 60 * 60, NULL);
+  ret = ed25519_keypair_generate(&signing_kp1, 0);
+  tt_int_op(ret, ==, 0);
+  desc1 = helper_build_hs_desc(42, 3 * 60 * 60, &signing_kp1.pubkey);
   tt_assert(desc1);
-  ret = hs_desc_encode_descriptor(desc1, &desc1_str);
+  ret = hs_desc_encode_descriptor(desc1, &signing_kp1, &desc1_str);
   tt_int_op(ret, OP_EQ, 0);
 
   /* Very first basic test, should be able to be stored, survive a
@@ -170,10 +171,14 @@ test_directory(void *arg)
 
   /* Store two descriptors and remove the expiring one only. */
   {
-    hs_descriptor_t *desc_zero_lifetime = helper_build_hs_desc(1, 0, NULL);
+    ed25519_keypair_t signing_kp_zero;
+    ret = ed25519_keypair_generate(&signing_kp_zero, 0);
+    tt_int_op(ret, ==, 0);
+    hs_descriptor_t *desc_zero_lifetime;
+    desc_zero_lifetime = helper_build_hs_desc(1, 0, &signing_kp_zero.pubkey);
     tt_assert(desc_zero_lifetime);
     char *desc_zero_lifetime_str;
-    ret = hs_desc_encode_descriptor(desc_zero_lifetime,
+    ret = hs_desc_encode_descriptor(desc_zero_lifetime, &signing_kp_zero,
                                     &desc_zero_lifetime_str);
     tt_int_op(ret, OP_EQ, 0);
 
@@ -225,7 +230,7 @@ test_directory(void *arg)
     tt_int_op(ret, OP_EQ, 1);
     /* Bump revision counter. */
     desc1->plaintext_data.revision_counter++;
-    ret = hs_desc_encode_descriptor(desc1, &new_desc_str);
+    ret = hs_desc_encode_descriptor(desc1, &signing_kp1, &new_desc_str);
     tt_int_op(ret, OP_EQ, 0);
     ret = hs_cache_store_as_dir(new_desc_str);
     tt_int_op(ret, OP_EQ, 0);
@@ -248,15 +253,18 @@ test_clean_as_dir(void *arg)
   char *desc1_str = NULL;
   time_t now = time(NULL);
   hs_descriptor_t *desc1 = NULL;
+  ed25519_keypair_t signing_kp1;
 
   (void) arg;
 
   init_test();
 
   /* Generate a valid descriptor with values. */
-  desc1 = helper_build_hs_desc(42, 3 * 60 * 60, NULL);
+  ret = ed25519_keypair_generate(&signing_kp1, 0);
+  tt_int_op(ret, ==, 0);
+  desc1 = helper_build_hs_desc(42, 3 * 60 * 60, &signing_kp1.pubkey);
   tt_assert(desc1);
-  ret = hs_desc_encode_descriptor(desc1, &desc1_str);
+  ret = hs_desc_encode_descriptor(desc1, &signing_kp1, &desc1_str);
   tt_int_op(ret, OP_EQ, 0);
   ret = hs_cache_store_as_dir(desc1_str);
   tt_int_op(ret, OP_EQ, 0);
@@ -343,7 +351,7 @@ static void
 test_upload_and_download_hs_desc(void *arg)
 {
   int retval;
-  hs_descriptor_t *published_desc;
+  hs_descriptor_t *published_desc = NULL;
 
   char *published_desc_str = NULL;
   char *received_desc_str = NULL;
@@ -355,9 +363,13 @@ test_upload_and_download_hs_desc(void *arg)
 
   /* Generate a valid descriptor with normal values. */
   {
-    published_desc = helper_build_hs_desc(42, 3 * 60 * 60, NULL);
+    ed25519_keypair_t signing_kp;
+    retval = ed25519_keypair_generate(&signing_kp, 0);
+    tt_int_op(retval, ==, 0);
+    published_desc = helper_build_hs_desc(42, 3 * 60 * 60, &signing_kp.pubkey);
     tt_assert(published_desc);
-    retval = hs_desc_encode_descriptor(published_desc, &published_desc_str);
+    retval = hs_desc_encode_descriptor(published_desc, &signing_kp,
+                                       &published_desc_str);
     tt_int_op(retval, OP_EQ, 0);
   }
 
@@ -370,7 +382,7 @@ test_upload_and_download_hs_desc(void *arg)
   /* Simulate a fetch of the previously published descriptor */
   {
     const ed25519_public_key_t *blinded_key;
-    blinded_key = &published_desc->plaintext_data.blinded_kp.pubkey;
+    blinded_key = &published_desc->plaintext_data.blinded_pubkey;
     received_desc_str = helper_fetch_desc_from_hsdir(blinded_key);
   }
 
@@ -391,7 +403,9 @@ test_hsdir_revision_counter_check(void *arg)
 {
   int retval;
 
-  hs_descriptor_t *published_desc;
+  ed25519_keypair_t signing_kp;
+
+  hs_descriptor_t *published_desc = NULL;
   char *published_desc_str = NULL;
 
   char *received_desc_str = NULL;
@@ -404,9 +418,13 @@ test_hsdir_revision_counter_check(void *arg)
 
   /* Generate a valid descriptor with normal values. */
   {
-    published_desc = helper_build_hs_desc(1312, 3 * 60 * 60, NULL);
+    retval = ed25519_keypair_generate(&signing_kp, 0);
+    tt_int_op(retval, ==, 0);
+    published_desc = helper_build_hs_desc(1312, 3 * 60 * 60,
+                                          &signing_kp.pubkey);
     tt_assert(published_desc);
-    retval = hs_desc_encode_descriptor(published_desc, &published_desc_str);
+    retval = hs_desc_encode_descriptor(published_desc, &signing_kp,
+                                       &published_desc_str);
     tt_int_op(retval, OP_EQ, 0);
   }
 
@@ -426,7 +444,7 @@ test_hsdir_revision_counter_check(void *arg)
   {
     const ed25519_public_key_t *blinded_key;
 
-    blinded_key = &published_desc->plaintext_data.blinded_kp.pubkey;
+    blinded_key = &published_desc->plaintext_data.blinded_pubkey;
     received_desc_str = helper_fetch_desc_from_hsdir(blinded_key);
 
     retval = hs_desc_decode_descriptor(received_desc_str,NULL, &received_desc);
@@ -445,7 +463,8 @@ test_hsdir_revision_counter_check(void *arg)
   {
     published_desc->plaintext_data.revision_counter = 1313;
     tor_free(published_desc_str);
-    retval = hs_desc_encode_descriptor(published_desc, &published_desc_str);
+    retval = hs_desc_encode_descriptor(published_desc, &signing_kp,
+                                       &published_desc_str);
     tt_int_op(retval, OP_EQ, 0);
 
     retval = handle_post_hs_descriptor("/tor/hs/3/publish",published_desc_str);
@@ -457,7 +476,7 @@ test_hsdir_revision_counter_check(void *arg)
   {
     const ed25519_public_key_t *blinded_key;
 
-    blinded_key = &published_desc->plaintext_data.blinded_kp.pubkey;
+    blinded_key = &published_desc->plaintext_data.blinded_pubkey;
     received_desc_str = helper_fetch_desc_from_hsdir(blinded_key);
 
     retval = hs_desc_decode_descriptor(received_desc_str,NULL, &received_desc);

+ 48 - 31
src/test/test_hs_descriptor.c

@@ -77,24 +77,28 @@ helper_build_intro_point(const ed25519_keypair_t *blinded_kp, time_t now,
 /* Return a valid hs_descriptor_t object. If no_ip is set, no introduction
  * points are added. */
 static hs_descriptor_t *
-helper_build_hs_desc(unsigned int no_ip)
+helper_build_hs_desc(unsigned int no_ip, ed25519_public_key_t *signing_pubkey)
 {
   int ret;
   time_t now = time(NULL);
+  ed25519_keypair_t blinded_kp;
   hs_descriptor_t *descp = NULL, *desc = tor_malloc_zero(sizeof(*desc));
 
   desc->plaintext_data.version = HS_DESC_SUPPORTED_FORMAT_VERSION_MAX;
-  ret = ed25519_keypair_generate(&desc->plaintext_data.signing_kp, 0);
-  tt_int_op(ret, ==, 0);
-  ret = ed25519_keypair_generate(&desc->plaintext_data.blinded_kp, 0);
+
+  /* Copy only the public key into the descriptor. */
+  memcpy(&desc->plaintext_data.signing_pubkey, signing_pubkey,
+         sizeof(ed25519_public_key_t));
+
+  ret = ed25519_keypair_generate(&blinded_kp, 0);
   tt_int_op(ret, ==, 0);
+  /* Copy only the public key into the descriptor. */
+  memcpy(&desc->plaintext_data.blinded_pubkey, &blinded_kp.pubkey,
+         sizeof(ed25519_public_key_t));
 
   desc->plaintext_data.signing_key_cert =
-    tor_cert_create(&desc->plaintext_data.blinded_kp,
-                    CERT_TYPE_SIGNING_HS_DESC,
-                    &desc->plaintext_data.signing_kp.pubkey, now,
-                    3600,
-                    CERT_FLAG_INCLUDE_SIGNING_KEY);
+    tor_cert_create(&blinded_kp, CERT_TYPE_SIGNING_HS_DESC, signing_pubkey,
+                    now, 3600, CERT_FLAG_INCLUDE_SIGNING_KEY);
   tt_assert(desc->plaintext_data.signing_key_cert);
   desc->plaintext_data.revision_counter = 42;
   desc->plaintext_data.lifetime_sec = 3 * 60 * 60;
@@ -108,17 +112,13 @@ helper_build_hs_desc(unsigned int no_ip)
   if (!no_ip) {
     /* Add four intro points. */
     smartlist_add(desc->encrypted_data.intro_points,
-                helper_build_intro_point(&desc->plaintext_data.blinded_kp, now,
-                                           "1.2.3.4", 0));
+                helper_build_intro_point(&blinded_kp, now, "1.2.3.4", 0));
     smartlist_add(desc->encrypted_data.intro_points,
-                helper_build_intro_point(&desc->plaintext_data.blinded_kp, now,
-                                           "[2600::1]", 0));
+                helper_build_intro_point(&blinded_kp, now, "[2600::1]", 0));
     smartlist_add(desc->encrypted_data.intro_points,
-                helper_build_intro_point(&desc->plaintext_data.blinded_kp, now,
-                                           "3.2.1.4", 1));
+                helper_build_intro_point(&blinded_kp, now, "3.2.1.4", 1));
     smartlist_add(desc->encrypted_data.intro_points,
-                helper_build_intro_point(&desc->plaintext_data.blinded_kp, now,
-                                           "", 1));
+                helper_build_intro_point(&blinded_kp, now, "", 1));
   }
 
   descp = desc;
@@ -138,11 +138,11 @@ helper_compare_hs_desc(const hs_descriptor_t *desc1,
              desc2->plaintext_data.lifetime_sec);
   tt_assert(tor_cert_eq(desc1->plaintext_data.signing_key_cert,
                         desc2->plaintext_data.signing_key_cert));
-  tt_mem_op(desc1->plaintext_data.signing_kp.pubkey.pubkey, OP_EQ,
-            desc2->plaintext_data.signing_kp.pubkey.pubkey,
+  tt_mem_op(desc1->plaintext_data.signing_pubkey.pubkey, OP_EQ,
+            desc2->plaintext_data.signing_pubkey.pubkey,
             ED25519_PUBKEY_LEN);
-  tt_mem_op(desc1->plaintext_data.blinded_kp.pubkey.pubkey, OP_EQ,
-            desc2->plaintext_data.blinded_kp.pubkey.pubkey,
+  tt_mem_op(desc1->plaintext_data.blinded_pubkey.pubkey, OP_EQ,
+            desc2->plaintext_data.blinded_pubkey.pubkey,
             ED25519_PUBKEY_LEN);
   tt_u64_op(desc1->plaintext_data.revision_counter, ==,
              desc2->plaintext_data.revision_counter);
@@ -481,11 +481,15 @@ test_encode_descriptor(void *arg)
 {
   int ret;
   char *encoded = NULL;
-  hs_descriptor_t *desc = helper_build_hs_desc(0);
+  ed25519_keypair_t signing_kp;
+  hs_descriptor_t *desc = NULL;
 
   (void) arg;
 
-  ret = hs_desc_encode_descriptor(desc, &encoded);
+  ret = ed25519_keypair_generate(&signing_kp, 0);
+  tt_int_op(ret, ==, 0);
+  desc = helper_build_hs_desc(0, &signing_kp.pubkey);
+  ret = hs_desc_encode_descriptor(desc, &signing_kp, &encoded);
   tt_int_op(ret, ==, 0);
   tt_assert(encoded);
 
@@ -499,17 +503,22 @@ test_decode_descriptor(void *arg)
 {
   int ret;
   char *encoded = NULL;
-  hs_descriptor_t *desc = helper_build_hs_desc(0);
+  ed25519_keypair_t signing_kp;
+  hs_descriptor_t *desc = NULL;
   hs_descriptor_t *decoded = NULL;
   hs_descriptor_t *desc_no_ip = NULL;
 
   (void) arg;
 
+  ret = ed25519_keypair_generate(&signing_kp, 0);
+  tt_int_op(ret, ==, 0);
+  desc = helper_build_hs_desc(0, &signing_kp.pubkey);
+
   /* Give some bad stuff to the decoding function. */
   ret = hs_desc_decode_descriptor("hladfjlkjadf", NULL, &decoded);
   tt_int_op(ret, OP_EQ, -1);
 
-  ret = hs_desc_encode_descriptor(desc, &encoded);
+  ret = hs_desc_encode_descriptor(desc, &signing_kp, &encoded);
   tt_int_op(ret, ==, 0);
   tt_assert(encoded);
 
@@ -521,10 +530,13 @@ test_decode_descriptor(void *arg)
 
   /* Decode a descriptor with _no_ introduction points. */
   {
-    desc_no_ip = helper_build_hs_desc(1);
+    ed25519_keypair_t signing_kp_no_ip;
+    ret = ed25519_keypair_generate(&signing_kp_no_ip, 0);
+    tt_int_op(ret, ==, 0);
+    desc_no_ip = helper_build_hs_desc(1, &signing_kp_no_ip.pubkey);
     tt_assert(desc_no_ip);
     tor_free(encoded);
-    ret = hs_desc_encode_descriptor(desc_no_ip, &encoded);
+    ret = hs_desc_encode_descriptor(desc_no_ip, &signing_kp_no_ip, &encoded);
     tt_int_op(ret, ==, 0);
     tt_assert(encoded);
     hs_descriptor_free(decoded);
@@ -599,6 +611,7 @@ test_decode_intro_point(void *arg)
   char *encoded_ip = NULL;
   size_t len_out;
   hs_desc_intro_point_t *ip = NULL;
+  ed25519_keypair_t signing_kp;
   hs_descriptor_t *desc = NULL;
 
   (void) arg;
@@ -647,7 +660,9 @@ test_decode_intro_point(void *arg)
   /* Start by testing the "decode all intro points" function. */
   {
     char *line;
-    desc = helper_build_hs_desc(0);
+    ret = ed25519_keypair_generate(&signing_kp, 0);
+    tt_int_op(ret, ==, 0);
+    desc = helper_build_hs_desc(0, &signing_kp.pubkey);
     tt_assert(desc);
     /* Only try to decode an incomplete introduction point section. */
     tor_asprintf(&line, "\n%s", intro_point);
@@ -674,7 +689,9 @@ test_decode_intro_point(void *arg)
   /* Try to decode a junk string. */
   {
     hs_descriptor_free(desc);
-    desc = helper_build_hs_desc(0);
+    ret = ed25519_keypair_generate(&signing_kp, 0);
+    tt_int_op(ret, ==, 0);
+    desc = helper_build_hs_desc(0, &signing_kp.pubkey);
     const char *junk = "this is not a descriptor";
     ip = decode_introduction_point(desc, junk);
     tt_assert(!ip);
@@ -977,10 +994,10 @@ test_desc_signature(void *arg)
   tt_int_op(ret, ==, 0);
   /* Build the descriptor that should be valid. */
   tor_asprintf(&desc, "%ssignature %s\n", data, sig_b64);
-  ret = desc_sig_is_valid(sig_b64, &kp, desc, strlen(desc));
+  ret = desc_sig_is_valid(sig_b64, &kp.pubkey, desc, strlen(desc));
   tt_int_op(ret, ==, 1);
   /* Junk signature. */
-  ret = desc_sig_is_valid("JUNK", &kp, desc, strlen(desc));
+  ret = desc_sig_is_valid("JUNK", &kp.pubkey, desc, strlen(desc));
   tt_int_op(ret, ==, 0);
 
  done: