Skip to content
Snippets Groups Projects
Commit a57cda11 authored by gabi-250's avatar gabi-250 :face_with_spiral_eyes:
Browse files

tor-hsservice: Do not store the subcredentials in RendRequestContext.

Previously, the subcredentials were computed in `IptEstablisher::launch`
and stored in `RendRequestContext`. This caused long-running services to
report errors like:

```
WARN tor_hsservice::helpers: Problem while accepting rendezvous request: error: Could not process INTRODUCE request: Introduction handshake was invalid: Circuit-extension handshake authentication failed
```

for clients using newer subcredentials than the ones the service had at
the time the IPT was established.

Fixes #1242
parent d8565206
No related branches found
No related tags found
1 merge request!1901tor-hsservice: Do not store the subcredentials in RendRequestContext.
......@@ -7,10 +7,8 @@ use educe::Educe;
use futures::{Stream, StreamExt};
use std::sync::Arc;
use tor_cell::relaycell::msg::{Connected, End, Introduce2};
use tor_hscrypto::{
pk::{HsIntroPtSessionIdKey, HsSvcNtorKeypair},
Subcredential,
};
use tor_hscrypto::pk::{HsIntroPtSessionIdKey, HsSvcNtorKeypair};
use tor_keymgr::KeyMgr;
use tor_error::Bug;
use tor_proto::{
......@@ -20,7 +18,7 @@ use tor_proto::{
use crate::{
svc::rend_handshake::{self, RendCircConnector},
ClientError, IptLocalId,
ClientError, HsNickname, IptLocalId,
};
/// Request to complete an introduction/rendezvous handshake.
......@@ -75,6 +73,12 @@ pub struct StreamRequest {
/// Keys and objects needed to answer a RendRequest.
pub(crate) struct RendRequestContext {
/// The nickname of the service receiving the request.
pub(crate) nickname: HsNickname,
/// The key manager, used for looking up subcredentials.
pub(crate) keymgr: Arc<KeyMgr>,
/// Key we'll use to decrypt the rendezvous request.
pub(crate) kp_hss_ntor: Arc<HsSvcNtorKeypair>,
......@@ -82,10 +86,6 @@ pub(crate) struct RendRequestContext {
/// and prevent replays across sessions.
pub(crate) kp_hs_ipt_sid: HsIntroPtSessionIdKey,
/// A set of subcredentials that we accept as identifying ourself on this
/// introduction point.
pub(crate) subcredentials: Vec<Subcredential>,
/// Provider we'll use to find a directory so that we can build a rendezvous
/// circuit.
pub(crate) netdir_provider: Arc<dyn tor_netdir::NetDirProvider>,
......
......@@ -327,18 +327,11 @@ impl IptEstablisher {
let state = Arc::new(Mutex::new(EstablisherState { accepting_requests }));
// We need the subcredential for the *current time period* in order to do the hs_ntor
// handshake. But that can change over time. We will instead use KeyMgr::get_matching to
// find all current subcredentials.
//
// TODO HSS: perhaps the subcredentials should be retrieved in
// server_receive_intro_no_keygen instead? See also the TODO in HsNtorServiceInput
let subcredentials = compute_subcredentials(&nickname, keymgr)?;
let request_context = Arc::new(RendRequestContext {
nickname: nickname.clone(),
keymgr: Arc::clone(keymgr),
kp_hss_ntor: Arc::clone(&k_ntor),
kp_hs_ipt_sid: k_sid.as_ref().as_ref().verifying_key().into(),
subcredentials,
netdir_provider: netdir_provider.clone(),
circ_pool: pool.clone(),
});
......@@ -403,7 +396,9 @@ impl IptEstablisher {
/// Obtain the all current `Subcredential`s of `nickname`
/// from the `K_hs_blind_id` read from the keystore.
fn compute_subcredentials(
///
// TODO: make this a method of RendRequestContext
pub(crate) fn compute_subcredentials(
nickname: &HsNickname,
keymgr: &Arc<KeyMgr>,
) -> Result<Vec<Subcredential>, FatalError> {
......
......@@ -29,7 +29,7 @@ use tor_proto::{
};
use tor_rtcompat::Runtime;
use crate::req::RendRequestContext;
use crate::{req::RendRequestContext, svc::ipt_establish::compute_subcredentials};
/// An error produced while trying to process an introduction request we have
/// received from a client via an introduction point.
......@@ -205,11 +205,17 @@ impl IntroRequest {
use IntroRequestError as E;
let mut rng = rand::thread_rng();
// We need the subcredential for the *current time period* in order to do the hs_ntor
// handshake. But that can change over time. We will instead use KeyMgr::get_matching to
// find all current subcredentials.
let subcredentials = compute_subcredentials(&context.nickname, &context.keymgr)
.map_err(IntroRequestError::Subcredentials)?;
let (key_gen, rend1_body, msg_body) = hs_ntor::server_receive_intro(
&mut rng,
&context.kp_hss_ntor,
&context.kp_hs_ipt_sid,
&context.subcredentials[..],
&subcredentials[..],
req.encoded_header(),
req.encrypted_body(),
)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment