Repository: cloudflare/daphne
Pull request #732 (2024-12-02 11:30:38)

Remove per-task HPKE config
In draft-12 per-task HPKE configs were removed. The aggregator can simply return a list of configs in preference order.


Patch:
diff --git a/crates/daphne-server/src/roles/aggregator.rs b/crates/daphne-server/src/roles/aggregator.rs
index c7774a1..90d5f4f 100644
--- a/crates/daphne-server/src/roles/aggregator.rs
+++ b/crates/daphne-server/src/roles/aggregator.rs
@@ -380,6 +380,7 @@ impl HpkeProvider for crate::App {
         version: DapVersion,
         _task_id: Option<&TaskId>,
     ) -> Result<Self::WrappedHpkeConfig<'static>, DapError> {
+        // TODO(draft-09) Remove `_task_id` parameter, as task id is no longer passed from draft-12.
         self.kv()
             .get_mapped::<kv::prefix::HpkeReceiverConfigSet, _, _>(
                 &version,
diff --git a/crates/daphne/src/roles/aggregator.rs b/crates/daphne/src/roles/aggregator.rs
index 0d1efcf..d9dd4ba 100644
--- a/crates/daphne/src/roles/aggregator.rs
+++ b/crates/daphne/src/roles/aggregator.rs
@@ -145,6 +145,13 @@ where
 {
     let metrics = aggregator.metrics();
 
+    if version == DapVersion::Latest && task_id.is_some() {
+        return Err(DapAbort::BadRequest(
+            "Task ID may not be specified in draft 12 or later".to_string(),
+        )
+        .into());
+    }
+
     let hpke_config = aggregator
         .get_hpke_config_for(version, task_id.as_ref())
         .await?;
diff --git a/crates/daphne/src/roles/mod.rs b/crates/daphne/src/roles/mod.rs
index 989b079..d24ea9b 100644
--- a/crates/daphne/src/roles/mod.rs
+++ b/crates/daphne/src/roles/mod.rs
@@ -629,21 +629,35 @@ mod test {
     //    }
     //
     //    async_test_versions! { handle_agg_job_req_init_expired_task }
-
-    async fn handle_hpke_config_req_unrecognized_task(version: DapVersion) {
-        let t = Test::new(version);
+    #[tokio::test]
+    async fn handle_hpke_config_req_unrecognized_task_draft09() {
+        let t = Test::new(DapVersion::Draft09);
         let mut rng = thread_rng();
         let task_id = TaskId(rng.gen());
 
         assert_eq!(
-            aggregator::handle_hpke_config_req(&*t.leader, version, Some(task_id))
+            aggregator::handle_hpke_config_req(&*t.leader, DapVersion::Draft09, Some(task_id))
                 .await
                 .unwrap_err(),
             DapError::Abort(DapAbort::UnrecognizedTask { task_id })
         );
     }
 
-    async_test_versions! { handle_hpke_config_req_unrecognized_task }
+    #[tokio::test]
+    async fn handle_hpke_config_req_task_latest() {
+        let t = Test::new(DapVersion::Latest);
+        let mut rng = thread_rng();
+        let task_id = TaskId(rng.gen());
+
+        assert_eq!(
+            aggregator::handle_hpke_config_req(&*t.leader, DapVersion::Latest, Some(task_id))
+                .await
+                .unwrap_err(),
+            DapError::Abort(DapAbort::BadRequest(
+                "Task ID may not be specified in draft 12 or later".to_string()
+            ))
+        );
+    }
 
     async fn handle_hpke_config_req_missing_task_id(version: DapVersion) {
         let t = Test::new(version);


Test patch:
diff --git a/crates/daphne-server/tests/e2e/test_runner.rs b/crates/daphne-server/tests/e2e/test_runner.rs
index 3ceb07c..1fd77bb 100644
--- a/crates/daphne-server/tests/e2e/test_runner.rs
+++ b/crates/daphne-server/tests/e2e/test_runner.rs
@@ -352,14 +352,28 @@ impl TestRunner {
         &self,
         client: &reqwest::Client,
     ) -> anyhow::Result<Vec<u8>> {
-        get_raw_hpke_config(client, self.task_id.as_ref(), &self.leader_url, "leader").await
+        get_raw_hpke_config(
+            client,
+            self.task_id.as_ref(),
+            &self.leader_url,
+            "leader",
+            &self.version,
+        )
+        .await
     }
 
     pub async fn helper_get_raw_hpke_config(
         &self,
         client: &reqwest::Client,
     ) -> anyhow::Result<Vec<u8>> {
-        get_raw_hpke_config(client, self.task_id.as_ref(), &self.helper_url, "helper").await
+        get_raw_hpke_config(
+            client,
+            self.task_id.as_ref(),
+            &self.helper_url,
+            "helper",
+            &self.version,
+        )
+        .await
     }
 
     pub async fn leader_request_expect_ok(
@@ -692,6 +706,7 @@ async fn get_raw_hpke_config(
     task_id: &[u8],
     base_url: &Url,
     svc: &str,
+    version: &DapVersion,
 ) -> anyhow::Result<Vec<u8>> {
     let time_to_wait = std::time::Duration::from_secs(15);
     let max_time_to_wait = std::time::Duration::from_secs(60 * 3);
@@ -699,7 +714,10 @@ async fn get_raw_hpke_config(
     let url = base_url.join("hpke_config")?;
     let query = [("task_id", encode_base64url(task_id))];
     while elapsed_time < max_time_to_wait {
-        let req = client.get(url.as_str()).query(&query);
+        let req = match version {
+            DapVersion::Draft09 => client.get(url.as_str()).query(&query),
+            DapVersion::Latest => client.get(url.as_str()),
+        };
         match req.send().await {
             Ok(resp) => {
                 if resp.status() == 200 {