diff --git a/src/feature/hs/hs_descriptor.c b/src/feature/hs/hs_descriptor.c index 9c3d4fc96b..f34685e232 100644 --- a/src/feature/hs/hs_descriptor.c +++ b/src/feature/hs/hs_descriptor.c @@ -2851,11 +2851,12 @@ hs_desc_build_fake_authorized_client(void) return client_auth; } -/* Using the client public key, auth ephemeral secret key, and descriptor - * cookie, build the auth client so we can then encode the descriptor for - * publication. client_out must be already allocated. */ +/* Using the service's subcredential, client public key, auth ephemeral secret + * key, and descriptor cookie, build the auth client so we can then encode the + * descriptor for publication. client_out must be already allocated. */ void -hs_desc_build_authorized_client(const curve25519_public_key_t *client_auth_pk, +hs_desc_build_authorized_client(const uint8_t *subcredential, + const curve25519_public_key_t *client_auth_pk, const curve25519_secret_key_t * auth_ephemeral_sk, const uint8_t *descriptor_cookie, @@ -2871,20 +2872,24 @@ hs_desc_build_authorized_client(const curve25519_public_key_t *client_auth_pk, tor_assert(auth_ephemeral_sk); tor_assert(descriptor_cookie); tor_assert(client_out); + tor_assert(subcredential); tor_assert(!tor_mem_is_zero((char *) auth_ephemeral_sk, sizeof(*auth_ephemeral_sk))); tor_assert(!tor_mem_is_zero((char *) client_auth_pk, sizeof(*client_auth_pk))); tor_assert(!tor_mem_is_zero((char *) descriptor_cookie, HS_DESC_DESCRIPTOR_COOKIE_LEN)); + tor_assert(!tor_mem_is_zero((char *) subcredential, + DIGEST256_LEN)); /* Calculate x25519(hs_y, client_X) */ curve25519_handshake(secret_seed, auth_ephemeral_sk, client_auth_pk); - /* Calculate KEYS = KDF(SECRET_SEED, 40) */ + /* Calculate KEYS = KDF(subcredential | SECRET_SEED, 40) */ xof = crypto_xof_new(); + crypto_xof_add_bytes(xof, subcredential, DIGEST256_LEN); crypto_xof_add_bytes(xof, secret_seed, sizeof(secret_seed)); crypto_xof_squeeze_bytes(xof, keystream, sizeof(keystream)); crypto_xof_free(xof); diff --git a/src/feature/hs/hs_service.c b/src/feature/hs/hs_service.c index 79ef0a35e9..43e5626a57 100644 --- a/src/feature/hs/hs_service.c +++ b/src/feature/hs/hs_service.c @@ -1744,10 +1744,18 @@ build_service_desc_superencrypted(const hs_service_t *service, /* The ephemeral key pair is already generated, so this should not give * an error. */ + if (BUG(!curve25519_public_key_is_ok(&desc->auth_ephemeral_kp.pubkey))) { + return -1; + } memcpy(&superencrypted->auth_ephemeral_pubkey, &desc->auth_ephemeral_kp.pubkey, sizeof(curve25519_public_key_t)); + /* Test that subcred is not zero because we might use it below */ + if (BUG(tor_mem_is_zero((char*)desc->desc->subcredential, DIGEST256_LEN))) { + return -1; + } + /* Create a smartlist to store clients */ superencrypted->clients = smartlist_new(); @@ -1761,7 +1769,8 @@ build_service_desc_superencrypted(const hs_service_t *service, /* Prepare the client for descriptor and then add to the list in the * superencrypted part of the descriptor */ - hs_desc_build_authorized_client(&client->client_pk, + hs_desc_build_authorized_client(desc->desc->subcredential, + &client->client_pk, &desc->auth_ephemeral_kp.seckey, desc->descriptor_cookie, desc_client); smartlist_add(superencrypted->clients, desc_client); diff --git a/src/test/test_hs_descriptor.c b/src/test/test_hs_descriptor.c index be7932cd2c..4889281cb1 100644 --- a/src/test/test_hs_descriptor.c +++ b/src/test/test_hs_descriptor.c @@ -400,12 +400,16 @@ test_decode_descriptor(void *arg) memcpy(&desc->superencrypted_data.auth_ephemeral_pubkey, &auth_ephemeral_kp.pubkey, CURVE25519_PUBKEY_LEN); + hs_helper_get_subcred_from_identity_keypair(&signing_kp, + subcredential); + /* Build and add the auth client to the descriptor. */ clients = desc->superencrypted_data.clients; if (!clients) { clients = smartlist_new(); } - hs_desc_build_authorized_client(&client_kp.pubkey, + hs_desc_build_authorized_client(subcredential, + &client_kp.pubkey, &auth_ephemeral_kp.seckey, descriptor_cookie, client); smartlist_add(clients, client); @@ -418,8 +422,6 @@ test_decode_descriptor(void *arg) desc->superencrypted_data.clients = clients; /* Test the encoding/decoding in the following lines. */ - hs_helper_get_subcred_from_identity_keypair(&signing_kp, - subcredential); tor_free(encoded); ret = hs_desc_encode_descriptor(desc, &signing_kp, descriptor_cookie, &encoded); @@ -874,6 +876,7 @@ test_build_authorized_client(void *arg) "07d087f1d8c68393721f6e70316d3b29"; const char client_pubkey_b16[] = "8c1298fa6050e372f8598f6deca32e27b0ad457741422c2629ebb132cf7fae37"; + uint8_t subcredential[DIGEST256_LEN]; char *mem_op_hex_tmp=NULL; (void) arg; @@ -885,6 +888,8 @@ test_build_authorized_client(void *arg) tt_int_op(ret, OP_EQ, 0); curve25519_public_key_generate(&client_auth_pk, &client_auth_sk); + memset(subcredential, 42, sizeof(subcredential)); + desc_client = tor_malloc_zero(sizeof(hs_desc_authorized_client_t)); base16_decode((char *) &auth_ephemeral_sk, @@ -904,15 +909,16 @@ test_build_authorized_client(void *arg) MOCK(crypto_strongest_rand, mock_crypto_strongest_rand); - hs_desc_build_authorized_client(&client_auth_pk, &auth_ephemeral_sk, + hs_desc_build_authorized_client(subcredential, + &client_auth_pk, &auth_ephemeral_sk, descriptor_cookie, desc_client); test_memeq_hex((char *) desc_client->client_id, - "b514ef67192cad5f"); + "EC19B7FF4D2DDA13"); test_memeq_hex((char *) desc_client->iv, "01010101010101010101010101010101"); test_memeq_hex((char *) desc_client->encrypted_cookie, - "46860a9df37b9f6d708E0D7E730C10C1"); + "B21222BE13F385F355BD07B2381F9F29"); done: tor_free(desc_client);