Merge remote-tracking branch 'dgoulet/bug20572_030_01'

This commit is contained in:
Nick Mathewson 2016-12-23 10:03:35 -05:00
commit 0087fe36c1
5 changed files with 146 additions and 103 deletions

View File

@ -86,7 +86,7 @@ cache_dir_desc_new(const char *desc)
} }
/* The blinded pubkey is the indexed key. */ /* 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); dir_desc->created_ts = time(NULL);
return dir_desc; return dir_desc;

View File

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

View File

@ -148,13 +148,13 @@ typedef struct hs_desc_plaintext_data_t {
* replica which is signed by the blinded public key for that replica. */ * replica which is signed by the blinded public key for that replica. */
tor_cert_t *signing_key_cert; 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. */ * 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. */ * 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 /* Revision counter is incremented at each upload, regardless of whether
* the descriptor has changed. This avoids leaking whether the descriptor * 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); void hs_desc_encrypted_data_free(hs_desc_encrypted_data_t *desc);
int hs_desc_encode_descriptor(const hs_descriptor_t *desc, int hs_desc_encode_descriptor(const hs_descriptor_t *desc,
const ed25519_keypair_t *signing_kp,
char **encoded_out); char **encoded_out);
int hs_desc_decode_descriptor(const char *encoded, 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, STATIC int cert_is_valid(tor_cert_t *cert, uint8_t type,
const char *log_obj_type); const char *log_obj_type);
STATIC int desc_sig_is_valid(const char *b64_sig, 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); const char *encoded_desc, size_t encoded_len);
STATIC void desc_intro_point_free(hs_desc_intro_point_t *ip); STATIC void desc_intro_point_free(hs_desc_intro_point_t *ip);
#endif /* HS_DESCRIPTOR_PRIVATE */ #endif /* HS_DESCRIPTOR_PRIVATE */

View File

@ -66,27 +66,27 @@ helper_build_intro_point(const ed25519_keypair_t *blinded_kp,
/* Return a valid hs_descriptor_t object. */ /* Return a valid hs_descriptor_t object. */
static hs_descriptor_t * static hs_descriptor_t *
helper_build_hs_desc(uint64_t revision_counter, uint32_t lifetime, helper_build_hs_desc(uint64_t revision_counter, uint32_t lifetime,
ed25519_keypair_t *blinded_kp) ed25519_public_key_t *signing_pubkey)
{ {
int ret; int ret;
ed25519_keypair_t blinded_kp;
hs_descriptor_t *descp = NULL, *desc = tor_malloc_zero(sizeof(*desc)); hs_descriptor_t *descp = NULL, *desc = tor_malloc_zero(sizeof(*desc));
desc->plaintext_data.version = HS_DESC_SUPPORTED_FORMAT_VERSION_MAX; 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); tt_int_op(ret, ==, 0);
if (blinded_kp) { /* Copy only the public key into the descriptor. */
memcpy(&desc->plaintext_data.blinded_kp, blinded_kp, memcpy(&desc->plaintext_data.blinded_pubkey, &blinded_kp.pubkey,
sizeof(ed25519_keypair_t)); sizeof(ed25519_public_key_t));
} else {
ret = ed25519_keypair_generate(&desc->plaintext_data.blinded_kp, 0);
tt_int_op(ret, ==, 0);
}
desc->plaintext_data.signing_key_cert = desc->plaintext_data.signing_key_cert =
tor_cert_create(&desc->plaintext_data.blinded_kp, tor_cert_create(&blinded_kp, CERT_TYPE_SIGNING_HS_DESC, signing_pubkey,
CERT_TYPE_SIGNING_HS_DESC, time(NULL), 3600, CERT_FLAG_INCLUDE_SIGNING_KEY);
&desc->plaintext_data.signing_kp.pubkey, time(NULL),
3600, CERT_FLAG_INCLUDE_SIGNING_KEY);
tt_assert(desc->plaintext_data.signing_key_cert); tt_assert(desc->plaintext_data.signing_key_cert);
desc->plaintext_data.revision_counter = revision_counter; desc->plaintext_data.revision_counter = revision_counter;
desc->plaintext_data.lifetime_sec = lifetime; 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(); desc->encrypted_data.intro_points = smartlist_new();
/* Add an intro point. */ /* Add an intro point. */
smartlist_add(desc->encrypted_data.intro_points, smartlist_add(desc->encrypted_data.intro_points,
helper_build_intro_point(&desc->plaintext_data.blinded_kp, helper_build_intro_point(&blinded_kp, "1.2.3.4"));
"1.2.3.4"));
descp = desc; descp = desc;
done: 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 variable used to encoded the HSDir query. */
static char query_b64[256]; 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 * static const char *
helper_get_hsdir_query(const hs_descriptor_t *desc) helper_get_hsdir_query(const hs_descriptor_t *desc)
{ {
ed25519_public_to_base64(query_b64, ed25519_public_to_base64(query_b64, &desc->plaintext_data.blinded_pubkey);
&desc->plaintext_data.blinded_kp.pubkey);
return query_b64; return query_b64;
} }
@ -132,17 +130,20 @@ test_directory(void *arg)
{ {
int ret; int ret;
size_t oom_size; size_t oom_size;
char *desc1_str=NULL; char *desc1_str = NULL;
const char *desc_out; const char *desc_out;
hs_descriptor_t *desc1; ed25519_keypair_t signing_kp1;
hs_descriptor_t *desc1 = NULL;
(void) arg; (void) arg;
init_test(); init_test();
/* Generate a valid descriptor with normal values. */ /* 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); 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); tt_int_op(ret, OP_EQ, 0);
/* Very first basic test, should be able to be stored, survive a /* 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. */ /* 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); tt_assert(desc_zero_lifetime);
char *desc_zero_lifetime_str; 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); &desc_zero_lifetime_str);
tt_int_op(ret, OP_EQ, 0); tt_int_op(ret, OP_EQ, 0);
@ -225,7 +230,7 @@ test_directory(void *arg)
tt_int_op(ret, OP_EQ, 1); tt_int_op(ret, OP_EQ, 1);
/* Bump revision counter. */ /* Bump revision counter. */
desc1->plaintext_data.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); tt_int_op(ret, OP_EQ, 0);
ret = hs_cache_store_as_dir(new_desc_str); ret = hs_cache_store_as_dir(new_desc_str);
tt_int_op(ret, OP_EQ, 0); tt_int_op(ret, OP_EQ, 0);
@ -248,15 +253,18 @@ test_clean_as_dir(void *arg)
char *desc1_str = NULL; char *desc1_str = NULL;
time_t now = time(NULL); time_t now = time(NULL);
hs_descriptor_t *desc1 = NULL; hs_descriptor_t *desc1 = NULL;
ed25519_keypair_t signing_kp1;
(void) arg; (void) arg;
init_test(); init_test();
/* Generate a valid descriptor with values. */ /* 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); 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); tt_int_op(ret, OP_EQ, 0);
ret = hs_cache_store_as_dir(desc1_str); ret = hs_cache_store_as_dir(desc1_str);
tt_int_op(ret, OP_EQ, 0); tt_int_op(ret, OP_EQ, 0);
@ -343,7 +351,7 @@ static void
test_upload_and_download_hs_desc(void *arg) test_upload_and_download_hs_desc(void *arg)
{ {
int retval; int retval;
hs_descriptor_t *published_desc; hs_descriptor_t *published_desc = NULL;
char *published_desc_str = NULL; char *published_desc_str = NULL;
char *received_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. */ /* 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); 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); 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 */ /* Simulate a fetch of the previously published descriptor */
{ {
const ed25519_public_key_t *blinded_key; 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); received_desc_str = helper_fetch_desc_from_hsdir(blinded_key);
} }
@ -391,7 +403,9 @@ test_hsdir_revision_counter_check(void *arg)
{ {
int retval; int retval;
hs_descriptor_t *published_desc; ed25519_keypair_t signing_kp;
hs_descriptor_t *published_desc = NULL;
char *published_desc_str = NULL; char *published_desc_str = NULL;
char *received_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. */ /* 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); 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); 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; 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); received_desc_str = helper_fetch_desc_from_hsdir(blinded_key);
retval = hs_desc_decode_descriptor(received_desc_str,NULL, &received_desc); 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; published_desc->plaintext_data.revision_counter = 1313;
tor_free(published_desc_str); 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); tt_int_op(retval, OP_EQ, 0);
retval = handle_post_hs_descriptor("/tor/hs/3/publish",published_desc_str); 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; 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); received_desc_str = helper_fetch_desc_from_hsdir(blinded_key);
retval = hs_desc_decode_descriptor(received_desc_str,NULL, &received_desc); retval = hs_desc_decode_descriptor(received_desc_str,NULL, &received_desc);

View File

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