Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up and move to draft09 #443

Merged
merged 3 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,14 @@ Daphne is a Rust implementation of the Distributed Aggregation Protocol
([DAP](https://datatracker.ietf.org/doc/draft-ietf-ppm-dap/)) standard. DAP is
under active development in the PPM working group of the IETF.

Daphne currently implements draft-ietf-ppm-dap-02. The next draft,
draft-ietf-ppm-dap-03, is a work-in-progress.
Daphne currently implements:

* draft-ietf-ppm-dap-02
* VDAF: draft-irtf-cfrg-vdaf-03
* Taskprov extension: draft-wang-ppm-dap-taskprov-02
* draft-ietf-ppm-dap-09
* VDAF: draft-irtf-cfrg-vdaf-08
* Taskprov extension: draft-wang-ppm-dap-taskprov-06

This software is intended to support experimental DAP deployments and is not yet
suitable for use in production. Daphne will evolve along with the DAP draft:
Expand Down
79 changes: 39 additions & 40 deletions daphne/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,31 +68,31 @@ impl DapMediaType {
pub fn from_str_for_version(version: DapVersion, content_type: Option<&str>) -> Self {
match (version, content_type) {
(DapVersion::Draft02, Some(DRAFT02_MEDIA_TYPE_AGG_CONT_REQ))
| (DapVersion::Draft07, Some(MEDIA_TYPE_AGG_JOB_CONT_REQ)) => {
| (DapVersion::Latest, Some(MEDIA_TYPE_AGG_JOB_CONT_REQ)) => {
Self::AggregationJobContinueReq
}
(DapVersion::Draft02, Some(DRAFT02_MEDIA_TYPE_AGG_CONT_RESP)) => {
Self::Draft02AggregateContinueResp
}
(DapVersion::Draft02, Some(DRAFT02_MEDIA_TYPE_AGG_INIT_REQ))
| (DapVersion::Draft07, Some(MEDIA_TYPE_AGG_JOB_INIT_REQ)) => {
| (DapVersion::Latest, Some(MEDIA_TYPE_AGG_JOB_INIT_REQ)) => {
Self::AggregationJobInitReq
}
(DapVersion::Draft02, Some(DRAFT02_MEDIA_TYPE_AGG_INIT_RESP))
| (DapVersion::Draft07, Some(MEDIA_TYPE_AGG_JOB_RESP)) => Self::AggregationJobResp,
| (DapVersion::Latest, Some(MEDIA_TYPE_AGG_JOB_RESP)) => Self::AggregationJobResp,
(DapVersion::Draft02, Some(DRAFT02_MEDIA_TYPE_AGG_SHARE_RESP))
| (DapVersion::Draft07, Some(MEDIA_TYPE_AGG_SHARE)) => Self::AggregateShare,
| (DapVersion::Latest, Some(MEDIA_TYPE_AGG_SHARE)) => Self::AggregateShare,
(DapVersion::Draft02, Some(DRAFT02_MEDIA_TYPE_COLLECT_RESP))
| (DapVersion::Draft07, Some(MEDIA_TYPE_COLLECTION)) => Self::Collection,
| (DapVersion::Latest, Some(MEDIA_TYPE_COLLECTION)) => Self::Collection,
(DapVersion::Draft02, Some(DRAFT02_MEDIA_TYPE_HPKE_CONFIG))
| (DapVersion::Draft07, Some(MEDIA_TYPE_HPKE_CONFIG_LIST)) => Self::HpkeConfigList,
(DapVersion::Draft02 | DapVersion::Draft07, Some(MEDIA_TYPE_AGG_SHARE_REQ)) => {
| (DapVersion::Latest, Some(MEDIA_TYPE_HPKE_CONFIG_LIST)) => Self::HpkeConfigList,
(DapVersion::Draft02 | DapVersion::Latest, Some(MEDIA_TYPE_AGG_SHARE_REQ)) => {
Self::AggregateShareReq
}
(DapVersion::Draft02 | DapVersion::Draft07, Some(MEDIA_TYPE_COLLECT_REQ)) => {
(DapVersion::Draft02 | DapVersion::Latest, Some(MEDIA_TYPE_COLLECT_REQ)) => {
Self::CollectReq
}
(DapVersion::Draft02 | DapVersion::Draft07, Some(MEDIA_TYPE_REPORT)) => Self::Report,
(DapVersion::Draft02 | DapVersion::Latest, Some(MEDIA_TYPE_REPORT)) => Self::Report,
(_, Some(content_type)) => Self::Invalid(content_type.to_string()),
(_, None) => Self::Missing,
}
Expand All @@ -104,33 +104,33 @@ impl DapMediaType {
(DapVersion::Draft02, Self::AggregationJobInitReq) => {
Some(DRAFT02_MEDIA_TYPE_AGG_INIT_REQ)
}
(DapVersion::Draft07, Self::AggregationJobInitReq) => Some(MEDIA_TYPE_AGG_JOB_INIT_REQ),
(DapVersion::Latest, Self::AggregationJobInitReq) => Some(MEDIA_TYPE_AGG_JOB_INIT_REQ),
(DapVersion::Draft02, Self::AggregationJobResp) => {
Some(DRAFT02_MEDIA_TYPE_AGG_INIT_RESP)
}
(DapVersion::Draft07, Self::AggregationJobResp) => Some(MEDIA_TYPE_AGG_JOB_RESP),
(DapVersion::Latest, Self::AggregationJobResp) => Some(MEDIA_TYPE_AGG_JOB_RESP),
(DapVersion::Draft02, Self::AggregationJobContinueReq) => {
Some(DRAFT02_MEDIA_TYPE_AGG_CONT_REQ)
}
(DapVersion::Draft07, Self::AggregationJobContinueReq) => {
(DapVersion::Latest, Self::AggregationJobContinueReq) => {
Some(MEDIA_TYPE_AGG_JOB_CONT_REQ)
}
(DapVersion::Draft02, Self::Draft02AggregateContinueResp) => {
Some(DRAFT02_MEDIA_TYPE_AGG_CONT_RESP)
}
(DapVersion::Draft02 | DapVersion::Draft07, Self::AggregateShareReq) => {
(DapVersion::Draft02 | DapVersion::Latest, Self::AggregateShareReq) => {
Some(MEDIA_TYPE_AGG_SHARE_REQ)
}
(DapVersion::Draft02, Self::AggregateShare) => Some(DRAFT02_MEDIA_TYPE_AGG_SHARE_RESP),
(DapVersion::Draft07, Self::AggregateShare) => Some(MEDIA_TYPE_AGG_SHARE),
(DapVersion::Draft02 | DapVersion::Draft07, Self::CollectReq) => {
(DapVersion::Latest, Self::AggregateShare) => Some(MEDIA_TYPE_AGG_SHARE),
(DapVersion::Draft02 | DapVersion::Latest, Self::CollectReq) => {
Some(MEDIA_TYPE_COLLECT_REQ)
}
(DapVersion::Draft02, Self::Collection) => Some(DRAFT02_MEDIA_TYPE_COLLECT_RESP),
(DapVersion::Draft07, Self::Collection) => Some(MEDIA_TYPE_COLLECTION),
(DapVersion::Latest, Self::Collection) => Some(MEDIA_TYPE_COLLECTION),
(DapVersion::Draft02, Self::HpkeConfigList) => Some(DRAFT02_MEDIA_TYPE_HPKE_CONFIG),
(DapVersion::Draft07, Self::HpkeConfigList) => Some(MEDIA_TYPE_HPKE_CONFIG_LIST),
(DapVersion::Draft02 | DapVersion::Draft07, Self::Report) => Some(MEDIA_TYPE_REPORT),
(DapVersion::Latest, Self::HpkeConfigList) => Some(MEDIA_TYPE_HPKE_CONFIG_LIST),
(DapVersion::Draft02 | DapVersion::Latest, Self::Report) => Some(MEDIA_TYPE_REPORT),
(_, Self::Draft02AggregateContinueResp | Self::Missing) => None,
(_, Self::Invalid(ref content_type)) => Some(content_type),
}
Expand All @@ -141,7 +141,7 @@ impl DapMediaType {
pub(crate) fn agg_job_cont_resp_for_version(version: DapVersion) -> Self {
match version {
DapVersion::Draft02 => Self::Draft02AggregateContinueResp,
DapVersion::Draft07 => Self::AggregationJobResp,
DapVersion::Latest => Self::AggregationJobResp,
}
}
}
Expand Down Expand Up @@ -218,73 +218,72 @@ mod test {
DapMediaType::Collection,
);

// draft07, Section 8.1
assert_eq!(
DapMediaType::from_str_for_version(
DapVersion::Draft07,
DapVersion::Latest,
Some("application/dap-hpke-config-list")
),
DapMediaType::HpkeConfigList
);
assert_eq!(
DapMediaType::from_str_for_version(
DapVersion::Draft07,
DapVersion::Latest,
Some("application/dap-aggregation-job-init-req")
),
DapMediaType::AggregationJobInitReq,
);
assert_eq!(
DapMediaType::from_str_for_version(
DapVersion::Draft07,
DapVersion::Latest,
Some("application/dap-aggregation-job-resp")
),
DapMediaType::AggregationJobResp,
);
assert_eq!(
DapMediaType::from_str_for_version(
DapVersion::Draft07,
DapVersion::Latest,
Some("application/dap-aggregation-job-continue-req")
),
DapMediaType::AggregationJobContinueReq,
);
assert_eq!(
DapMediaType::from_str_for_version(
DapVersion::Draft07,
DapVersion::Latest,
Some("application/dap-aggregate-share-req")
),
DapMediaType::AggregateShareReq,
);
assert_eq!(
DapMediaType::from_str_for_version(
DapVersion::Draft07,
DapVersion::Latest,
Some("application/dap-aggregate-share")
),
DapMediaType::AggregateShare,
);
assert_eq!(
DapMediaType::from_str_for_version(
DapVersion::Draft07,
DapVersion::Latest,
Some("application/dap-collect-req")
),
DapMediaType::CollectReq,
);
assert_eq!(
DapMediaType::from_str_for_version(
DapVersion::Draft07,
DapVersion::Latest,
Some("application/dap-collection")
),
DapMediaType::Collection,
);

// Invalid media type
assert_eq!(
DapMediaType::from_str_for_version(DapVersion::Draft07, Some("blah-blah-blah")),
DapMediaType::from_str_for_version(DapVersion::Latest, Some("blah-blah-blah")),
DapMediaType::Invalid("blah-blah-blah".into()),
);

// Missing media type
assert_eq!(
DapMediaType::from_str_for_version(DapVersion::Draft07, None),
DapMediaType::from_str_for_version(DapVersion::Latest, None),
DapMediaType::Missing,
);
}
Expand All @@ -293,27 +292,27 @@ mod test {
fn round_trip() {
for (version, media_type) in [
(DapVersion::Draft02, DapMediaType::AggregationJobInitReq),
(DapVersion::Draft07, DapMediaType::AggregationJobInitReq),
(DapVersion::Latest, DapMediaType::AggregationJobInitReq),
(DapVersion::Draft02, DapMediaType::AggregationJobResp),
(DapVersion::Draft07, DapMediaType::AggregationJobResp),
(DapVersion::Latest, DapMediaType::AggregationJobResp),
(DapVersion::Draft02, DapMediaType::AggregationJobContinueReq),
(DapVersion::Draft07, DapMediaType::AggregationJobContinueReq),
(DapVersion::Latest, DapMediaType::AggregationJobContinueReq),
(
DapVersion::Draft02,
DapMediaType::Draft02AggregateContinueResp,
),
(DapVersion::Draft02, DapMediaType::AggregateShareReq),
(DapVersion::Draft07, DapMediaType::AggregateShareReq),
(DapVersion::Latest, DapMediaType::AggregateShareReq),
(DapVersion::Draft02, DapMediaType::AggregateShare),
(DapVersion::Draft07, DapMediaType::AggregateShare),
(DapVersion::Latest, DapMediaType::AggregateShare),
(DapVersion::Draft02, DapMediaType::CollectReq),
(DapVersion::Draft07, DapMediaType::CollectReq),
(DapVersion::Latest, DapMediaType::CollectReq),
(DapVersion::Draft02, DapMediaType::Collection),
(DapVersion::Draft07, DapMediaType::Collection),
(DapVersion::Latest, DapMediaType::Collection),
(DapVersion::Draft02, DapMediaType::HpkeConfigList),
(DapVersion::Draft07, DapMediaType::HpkeConfigList),
(DapVersion::Latest, DapMediaType::HpkeConfigList),
(DapVersion::Draft02, DapMediaType::Report),
(DapVersion::Draft07, DapMediaType::Report),
(DapVersion::Latest, DapMediaType::Report),
] {
assert_eq!(
DapMediaType::from_str_for_version(version, media_type.as_str_for_version(version)),
Expand All @@ -334,7 +333,7 @@ mod test {

assert_eq!(
DapMediaType::AggregationJobResp,
DapMediaType::agg_job_cont_resp_for_version(DapVersion::Draft07)
DapMediaType::agg_job_cont_resp_for_version(DapVersion::Latest)
);
}
}
3 changes: 1 addition & 2 deletions daphne/src/error/aborts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ pub enum DapAbort {
#[error("invalidBatchSize")]
InvalidBatchSize { detail: String, task_id: TaskId },

/// draft-wang-ppm-dap-taskprov-02: Invalid DAP task. Sent when a server opts out of a
/// taskprov task configuration.
/// taskprov: Invalid DAP task. Sent when a server opts out of a taskprov task configuration.
#[error("invalidTask")]
InvalidTask { detail: String, task_id: TaskId },

Expand Down
44 changes: 24 additions & 20 deletions daphne/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@
//! PPM working group of the IETF. See [`VdafConfig`] for a listing of supported
//! [VDAFs](https://github.com/cfrg/draft-irtf-cfrg-vdaf).
//!
//! Daphne implements draft-ietf-ppm-dap-02 and draft-ietf-ppm-dap-07.
//!
//! **WARNING:** draft07 is a work-in-progress. We are not yet compatible.
//! Daphne implements:
//! * draft-ietf-ppm-dap-02
//! * VDAF: draft-irtf-cfrg-vdaf-03
//! * Taskprov extension: draft-wang-ppm-dap-taskprov-02
//! * draft-ietf-ppm-dap-09
//! * VDAF: draft-irtf-cfrg-vdaf-08
//! * Taskprov extension: draft-wang-ppm-dap-taskprov-06
//!
//! Daphne does not provide the complete, end-to-end functionality of any party in the protocol.
//! Instead, it defines traits for the functionalities that a concrete instantiation of the
Expand Down Expand Up @@ -102,17 +106,17 @@ pub enum DapVersion {
#[serde(rename = "v02")]
Draft02,

#[serde(rename = "v07")]
#[serde(rename = "v09")]
cjpatton marked this conversation as resolved.
Show resolved Hide resolved
#[default]
Draft07,
Latest,
}

impl FromStr for DapVersion {
type Err = DapAbort;
fn from_str(version: &str) -> Result<Self, Self::Err> {
match version {
"v02" => Ok(DapVersion::Draft02),
"v07" => Ok(DapVersion::Draft07),
"v09" => Ok(DapVersion::Latest),
_ => Err(DapAbort::version_unknown()),
}
}
Expand All @@ -122,7 +126,7 @@ impl AsRef<str> for DapVersion {
fn as_ref(&self) -> &str {
match self {
DapVersion::Draft02 => "v02",
DapVersion::Draft07 => "v07",
DapVersion::Latest => "v09",
}
}
}
Expand Down Expand Up @@ -170,7 +174,7 @@ pub struct DapGlobalConfig {
/// receiver config.
pub supported_hpke_kems: Vec<HpkeKemId>,

/// Indicates if the taskprov extension is enabled.
/// draft-wang-ppm-dap-taskprov: Indicates if the taskprov extension is enabled.
#[serde(default)]
pub allow_taskprov: bool,
}
Expand Down Expand Up @@ -408,7 +412,7 @@ impl Extend<(DapBatchBucket, (ReportId, Time))> for DapAggregateSpan<()> {
#[derive(Clone, Default, Deserialize, Serialize)]
#[cfg_attr(test, derive(PartialEq, Debug))]
pub enum DapTaskConfigMethod {
/// draft-wang-ppm-dap-taskprov-06
/// draft-wang-ppm-dap-taskprov
Taskprov {
/// `TaskConfig.task_info`. If not set, then the task info is unknown.
info: Option<Vec<u8>>,
Expand Down Expand Up @@ -492,7 +496,7 @@ impl DapTaskParameters {
.unwrap();

let (taskprov_advertisement, taskprov_report_extension_payload) = match self.version {
DapVersion::Draft07 => (Some(encode_base64url(&encoded_taskprov_config)), Vec::new()),
DapVersion::Latest => (Some(encode_base64url(&encoded_taskprov_config)), Vec::new()),
// draft02 compatibility: The taskprov config is advertised in an HTTP header in
// the latest draft. In draft02, it is carried by a report extension.
DapVersion::Draft02 => (None, encoded_taskprov_config),
Expand Down Expand Up @@ -1120,7 +1124,7 @@ pub struct DapRequest<S> {
impl<S> Default for DapRequest<S> {
fn default() -> Self {
Self {
version: DapVersion::Draft07,
version: DapVersion::Latest,
media_type: Default::default(),
task_id: Default::default(),
resource: Default::default(),
Expand Down Expand Up @@ -1208,13 +1212,13 @@ pub struct DapLeaderProcessTelemetry {
}

/// draft02 compatibility: A logical aggregation job ID. In the latest draft, this is a 32-byte
/// string included in the HTTP request payload; in draft07, this is a 16-byte string included in
/// the HTTP request path. This type unifies these into one type so that any protocol logic that
/// is agnostic to these details can use the same object.
/// string included in the HTTP request payload; in the latest draft, this is a 16-byte string
/// included in the HTTP request path. This type unifies these into one type so that any protocol
/// logic that is agnostic to these details can use the same object.
#[derive(Clone, Debug)]
pub enum MetaAggregationJobId {
Draft02(Draft02AggregationJobId),
Draft07(AggregationJobId),
Latest(AggregationJobId),
}

impl MetaAggregationJobId {
Expand All @@ -1223,7 +1227,7 @@ impl MetaAggregationJobId {
let mut rng = thread_rng();
match version {
DapVersion::Draft02 => Self::Draft02(Draft02AggregationJobId(rng.gen())),
DapVersion::Draft07 => Self::Draft07(AggregationJobId(rng.gen())),
DapVersion::Latest => Self::Latest(AggregationJobId(rng.gen())),
}
}

Expand All @@ -1232,7 +1236,7 @@ impl MetaAggregationJobId {
pub(crate) fn for_request_payload(&self) -> Option<Draft02AggregationJobId> {
match self {
Self::Draft02(agg_job_id) => Some(*agg_job_id),
Self::Draft07(..) => None,
Self::Latest(..) => None,
}
}

Expand All @@ -1242,23 +1246,23 @@ impl MetaAggregationJobId {
match self {
// In draft02, the aggregation job ID is not determined until the payload is parsed.
Self::Draft02(..) => DapResource::Undefined,
Self::Draft07(agg_job_id) => DapResource::AggregationJob(*agg_job_id),
Self::Latest(agg_job_id) => DapResource::AggregationJob(*agg_job_id),
}
}

/// Convert this aggregation job ID into hex.
pub fn to_hex(&self) -> String {
match self {
Self::Draft02(agg_job_id) => agg_job_id.to_hex(),
Self::Draft07(agg_job_id) => agg_job_id.to_hex(),
Self::Latest(agg_job_id) => agg_job_id.to_hex(),
}
}

/// Convert this aggregation job ID into base64url form.
pub fn to_base64url(&self) -> String {
match self {
Self::Draft02(agg_job_id) => agg_job_id.to_base64url(),
Self::Draft07(agg_job_id) => agg_job_id.to_base64url(),
Self::Latest(agg_job_id) => agg_job_id.to_base64url(),
}
}
}
Loading
Loading