From fb4bf51e25a999d3626ec8fea2282efc96b4063e Mon Sep 17 00:00:00 2001 From: Jun Kurihara Date: Sat, 27 Jan 2024 04:20:30 +0900 Subject: [PATCH] reimplement http message component mod --- src/ext/hyper_http.rs | 20 +- src/lib.rs | 14 +- src/message_component.rs | 460 +++++++++++++++++++++------------------ src/signature_base.rs | 2 +- src/signature_params.rs | 13 +- 5 files changed, 272 insertions(+), 237 deletions(-) diff --git a/src/ext/hyper_http.rs b/src/ext/hyper_http.rs index 6f2a1e2..3bb22e8 100644 --- a/src/ext/hyper_http.rs +++ b/src/ext/hyper_http.rs @@ -1,7 +1,7 @@ use super::{ContentDigestType, CONTENT_DIGEST_HEADER}; use crate::{ message_component::{ - DerivedComponentName, HttpMessageComponent, HttpMessageComponentIdentifier, HttpMessageComponentParam, + DerivedComponentName, HttpMessageComponent, HttpMessageComponentName, HttpMessageComponentParam, HttpMessageComponentValue, }, signature_base::SignatureBase, @@ -178,7 +178,7 @@ where .covered_components .iter() .map(|component_id_str| { - let component_id = HttpMessageComponentIdentifier::from(component_id_str.as_str()); + let component_id = HttpMessageComponentName::from(component_id_str.as_str()); extract_component_from_request(self, &component_id) }) @@ -199,11 +199,11 @@ where /// Extract http message component from hyper http request fn extract_component_from_request( req: &Request, - target_component_id: &HttpMessageComponentIdentifier, + target_component_id: &HttpMessageComponentName, ) -> Result { let params = match &target_component_id { - HttpMessageComponentIdentifier::HttpField(field_id) => &field_id.params, - HttpMessageComponentIdentifier::Derived(derived_id) => &derived_id.params, + HttpMessageComponentName::HttpField(field_id) => &field_id.params, + HttpMessageComponentName::Derived(derived_id) => &derived_id.params, }; anyhow::ensure!( !params.0.contains(&HttpMessageComponentParam::Req), @@ -211,7 +211,7 @@ fn extract_component_from_request( ); let field_values = match &target_component_id { - HttpMessageComponentIdentifier::HttpField(field_id) => { + HttpMessageComponentName::HttpField(field_id) => { let field_values = req .headers() .get_all(&field_id.filed_name) @@ -220,7 +220,7 @@ fn extract_component_from_request( .collect::>(); field_values } - HttpMessageComponentIdentifier::Derived(derived_id) => { + HttpMessageComponentName::Derived(derived_id) => { let url = url::Url::parse(&req.uri().to_string())?; let field_value = match derived_id.component_name { DerivedComponentName::Method => req.method().to_string(), @@ -253,7 +253,7 @@ fn extract_component_from_request( }; let component = HttpMessageComponent { - id: target_component_id.clone(), + name: target_component_id.clone(), value: HttpMessageComponentValue::from(""), }; Ok(component) @@ -274,11 +274,11 @@ mod tests { .body(()) .unwrap(); - let component_id_method = HttpMessageComponentIdentifier::from("\"@method\""); + let component_id_method = HttpMessageComponentName::from("\"@method\""); let component = extract_component_from_request(&req, &component_id_method).unwrap(); println!("{:?}", component); - let component_id_query_param = HttpMessageComponentIdentifier::from("\"@query-param\""); + let component_id_query_param = HttpMessageComponentName::from("\"@query-param\""); let component = extract_component_from_request(&req, &component_id_query_param).unwrap(); println!("{:?}", component); // let component = extract_component_from_request(&req, &component_id).unwrap(); diff --git a/src/lib.rs b/src/lib.rs index fe0f86b..7bf28b8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,14 +1,14 @@ mod crypto; -mod ext; +// mod ext; mod message_component; -mod signature_base; -mod signature_params; +// mod signature_base; +// mod signature_params; mod trace; -mod util; +// mod util; use crate::{ crypto::{PublicKey, SecretKey, SigningKey, VerifyingKey}, - signature_params::{HttpSignatureParams, HttpSignatureParamsBuilder}, + // signature_params::{HttpSignatureParams, HttpSignatureParamsBuilder}, }; #[cfg(test)] @@ -65,7 +65,7 @@ Signature: sig-b26=:wqcAqbmYJ2ji2glfAMaRy4gruYYnx2nEFN2HN6jrnDnQCK1\ #[test] fn test_http_signature_params() { let signature_params_str = r##"("date" "@method" "@path" "@authority" "content-type" "content-length");created=1618884473;keyid="test-key-ed25519""##; - let signature_params = HttpSignatureParams::try_from(signature_params_str).unwrap(); - assert_eq!(signature_params.to_string(), signature_params_str); + // let signature_params = HttpSignatureParams::try_from(signature_params_str).unwrap(); + // assert_eq!(signature_params.to_string(), signature_params_str); } } diff --git a/src/message_component.rs b/src/message_component.rs index 1a1e217..bd69236 100644 --- a/src/message_component.rs +++ b/src/message_component.rs @@ -4,41 +4,55 @@ use rustc_hash::FxHashSet as HashSet; #[derive(Debug, Clone)] /// Http message component pub(crate) struct HttpMessageComponent { - /// Http message component identifier - pub(crate) id: HttpMessageComponentIdentifier, + /// Http message component id + pub(crate) id: HttpMessageComponentId, /// Http message component value pub(crate) value: HttpMessageComponentValue, } -impl TryFrom<&str> for HttpMessageComponent { - type Error = anyhow::Error; - fn try_from(val: &str) -> std::result::Result { - let Some((id, value)) = val.split_once(':') else { - return Err(anyhow::anyhow!("Invalid http message component: {}", val)); +impl HttpMessageComponent { + /// Create HttpMessageComponent from serialized string, i.e., `"": ` in the signature input + pub(crate) fn from_serialized_str(serialized_str: &str) -> std::result::Result { + let Some((id, value)) = serialized_str.split_once(':') else { + return Err(anyhow::anyhow!("Invalid http message component: {}", serialized_str)); }; let id = id.trim(); if ensure_component_id(id).is_err() { return Err(anyhow::anyhow!("Invalid http message component id: {}", id)); } + let (name, params) = if id.contains(';') { + id.split_once(';').unwrap() + } else { + (id, "") + }; Ok(Self { - id: HttpMessageComponentIdentifier::from(id), + id: HttpMessageComponentId::try_from((name, params))?, value: HttpMessageComponentValue::from(value.trim()), }) } -} -impl TryFrom<(&str, &str)> for HttpMessageComponent { - type Error = anyhow::Error; - fn try_from((k, v): (&str, &str)) -> std::result::Result { - let id = k.trim(); - if ensure_component_id(id).is_err() { - return Err(anyhow::anyhow!("Invalid http message component id: {}", id)); - } - Ok(Self { - id: HttpMessageComponentIdentifier::from(id), - value: HttpMessageComponentValue::from(v.trim()), - }) - } + // /// Create an iterator of HttpMessageComponent from name and values + // pub(crate) fn from_name_and_values(name: &str, values: impl Iterator) -> Vec { + // let name = HttpMessageComponentName::from(name); + // let iter = values + // .map(move |v| { + // // let params = match name { + // // HttpMessageComponentName::HttpField(_) => HttpMessageComponentParams::from(""), + // // HttpMessageComponentName::Derived(DerivedComponentName::QueryParam) => { + // // HttpMessageComponentParams::from(format!("name=\"{}\"", v)) + // // } + // // _ => HttpMessageComponentParams::from(""), + // // }; + // let res = Self { + // name: name.clone(), + // params: HttpMessageComponentParams(HashSet::default()), + // value: HttpMessageComponentValue::from(v.as_ref()), + // }; + // res + // }) + // .collect::>(); + // iter + // } } fn ensure_component_id(id: &str) -> anyhow::Result<()> { @@ -56,6 +70,73 @@ impl std::fmt::Display for HttpMessageComponent { } } +/* ---------------------------------------------------------------- */ +#[derive(Debug, Clone)] +/// Http message component id +pub(crate) struct HttpMessageComponentId { + /// Http message component name + pub(crate) name: HttpMessageComponentName, + /// Http message component params + pub(crate) params: HttpMessageComponentParams, +} + +impl HttpMessageComponentId { + /// Add `req` field param to the component, which is used to generate signature input for response from its corresponding request. + pub(crate) fn add_req_param(&mut self) { + self.params.0.insert(HttpMessageComponentParam::Req); + } +} + +impl std::fmt::Display for HttpMessageComponentId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}{}", self.name, self.params) + } +} + +impl TryFrom<(&str, &str)> for HttpMessageComponentId { + type Error = anyhow::Error; + fn try_from((name, params): (&str, &str)) -> std::result::Result { + let res = Self { + name: HttpMessageComponentName::from(name), + params: HttpMessageComponentParams::from(params), + }; + + // assert for query param + if res + .params + .0 + .iter() + .any(|v| matches!(v, &HttpMessageComponentParam::Name(_))) + { + anyhow::ensure!( + matches!( + res.name, + HttpMessageComponentName::Derived(DerivedComponentName::QueryParam) + ), + "Invalid http message component id: {}", + res + ); + } + + // assert for http field components + if res.params.0.iter().any(|v| { + matches!(v, &HttpMessageComponentParam::Bs) + || matches!(v, &HttpMessageComponentParam::Sf) + || matches!(v, &HttpMessageComponentParam::Req) + || matches!(v, &HttpMessageComponentParam::Tr) + || matches!(v, &HttpMessageComponentParam::Key(_)) + }) { + anyhow::ensure!( + matches!(res.name, HttpMessageComponentName::HttpField(_)), + "Invalid http message component id: {}", + res + ); + } + + Ok(res) + } +} + /* ---------------------------------------------------------------- */ #[derive(Debug, Clone)] /// Http message component value @@ -79,24 +160,24 @@ impl std::fmt::Display for HttpMessageComponentValue { /* ---------------------------------------------------------------- */ #[derive(PartialEq, Eq, Hash, Debug, Clone)] /// Http message component identifier -pub(crate) enum HttpMessageComponentIdentifier { +pub(crate) enum HttpMessageComponentName { /// Http field component - HttpField(HttpFieldComponentId), - /// Derived commponent - Derived(DerivedComponentId), + HttpField(String), + /// Derived component + Derived(DerivedComponentName), } -impl From<&str> for HttpMessageComponentIdentifier { +impl From<&str> for HttpMessageComponentName { fn from(val: &str) -> Self { if val.starts_with("\"@") { - Self::Derived(DerivedComponentId::from(val)) + Self::Derived(DerivedComponentName::from(val)) } else { - Self::HttpField(HttpFieldComponentId::from(val)) + Self::HttpField(val.to_string()) } } } -impl std::fmt::Display for HttpMessageComponentIdentifier { +impl std::fmt::Display for HttpMessageComponentName { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::HttpField(val) => write!(f, "{}", val), @@ -122,6 +203,7 @@ pub(crate) enum HttpMessageComponentParam { // req: https://www.ietf.org/archive/id/draft-ietf-httpbis-message-signatures-19.html#section-2.4 Req, // name: https://www.ietf.org/archive/id/draft-ietf-httpbis-message-signatures-19.html#name-query-parameters + /// This will be encoded to `;name="..."` in the signature input Name(String), } @@ -129,7 +211,7 @@ impl From for String { fn from(val: HttpMessageComponentParam) -> Self { match val { HttpMessageComponentParam::Sf => "sf".to_string(), - HttpMessageComponentParam::Key(val) => format!("key=\"{}\"", val), + HttpMessageComponentParam::Key(val) => format!("key=\"{val}\""), HttpMessageComponentParam::Bs => "bs".to_string(), HttpMessageComponentParam::Tr => "tr".to_string(), HttpMessageComponentParam::Req => "req".to_string(), @@ -166,6 +248,36 @@ impl std::hash::Hash for HttpMessageComponentParams { params.hash(state); } } +impl From<&str> for HttpMessageComponentParams { + fn from(val: &str) -> Self { + let mut hs = HashSet::default(); + val.split(';').for_each(|v| { + if !v.is_empty() { + let param = HttpMessageComponentParam::from(v); + hs.insert(param); + } + }); + Self(hs) + } +} +impl std::fmt::Display for HttpMessageComponentParams { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if !self.0.is_empty() { + write!( + f, + ";{}", + self + .0 + .iter() + .map(|v| v.clone().into()) + .collect::>() + .join(";") + ) + } else { + Ok(()) + } + } +} /* ---------------------------------------------------------------- */ #[derive(PartialEq, Eq, Clone, Hash, Debug)] @@ -219,215 +331,141 @@ impl From<&str> for DerivedComponentName { } } -#[derive(PartialEq, Eq, Hash, Debug, Clone)] -/// Http derived component setting with optional parameters -pub(crate) struct DerivedComponentId { - /// derived component - pub(crate) component_name: DerivedComponentName, - /// parameters - pub(crate) params: HttpMessageComponentParams, -} - -impl From<&str> for DerivedComponentId { - /// this feeds `"";` format, e.g., `"@method";req` - fn from(val: &str) -> Self { - let mut iter = val.split(';'); - let component = iter.next().unwrap(); - // only `req` field param for any or `name="xx"` for @query-params are allowed for derived components unlike general http fields - let params = iter - .map(HttpMessageComponentParam::from) - .filter(|v| { - matches!(v, HttpMessageComponentParam::Req) - || (matches!(v, HttpMessageComponentParam::Name(_)) && matches!(component, "\"@query-param\"")) - }) - .collect::>(); - Self { - component_name: DerivedComponentName::from(component), - params: HttpMessageComponentParams(params), - } - } -} -impl std::fmt::Display for DerivedComponentId { +impl std::fmt::Display for DerivedComponentName { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let mut s: String = self.component_name.clone().into(); - if !self.params.0.is_empty() { - s.push(';'); - s.push_str( - &self - .params - .0 - .iter() - .map(|v| v.clone().into()) - .collect::>() - .join(";"), - ); - } - write!(f, "{}", s) + write!(f, "{}", AsRef::::as_ref(self)) } } /* ---------------------------------------------------------------- */ -#[derive(PartialEq, Eq, Hash, Debug, Clone)] -/// Http field component setting with optional parameters -/// https://www.ietf.org/archive/id/draft-ietf-httpbis-message-signatures-19.html#name-http-fields -pub(crate) struct HttpFieldComponentId { - /// field name - pub(crate) filed_name: String, - /// parameters - pub(crate) params: HttpMessageComponentParams, -} - -impl From<&str> for HttpFieldComponentId { - /// this feeds `"";` format, e.g., `"example-header";bs` - fn from(val: &str) -> Self { - let mut iter = val.split(';'); - let field_name = iter.next().unwrap(); - let params = iter.map(HttpMessageComponentParam::from).collect::>(); - Self { - filed_name: field_name.to_string(), - params: HttpMessageComponentParams(params), - } - } -} - -impl std::fmt::Display for HttpFieldComponentId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let mut s: String = self.filed_name.clone(); - if !self.params.0.is_empty() { - s.push(';'); - s.push_str( - &self - .params - .0 - .iter() - .map(|v| v.clone().into()) - .collect::>() - .join(";"), - ); - } - write!(f, "{}", s) - } -} - #[cfg(test)] mod tests { use super::*; #[test] - fn test_http_message_component() { - let comp = HttpMessageComponent::try_from("\"example-header\";bs: example-value").unwrap(); + fn test_http_message_component_from_string() { + let comp = HttpMessageComponent::from_serialized_str("\"@method\": POST").unwrap(); assert_eq!( - comp.id, - HttpMessageComponentIdentifier::HttpField(HttpFieldComponentId { - filed_name: "\"example-header\"".to_string(), - params: HttpMessageComponentParams(vec![HttpMessageComponentParam::Bs].into_iter().collect::>()) - }) - ); - assert_eq!(comp.value.inner, "example-value"); - assert_eq!(comp.to_string(), "\"example-header\";bs: example-value"); - - let comp = HttpMessageComponent::try_from("\"@method\";req: POST").unwrap(); - assert_eq!( - comp.id, - HttpMessageComponentIdentifier::Derived(DerivedComponentId { - component_name: DerivedComponentName::Method, - params: HttpMessageComponentParams(vec![HttpMessageComponentParam::Req].into_iter().collect::>()) - }) + comp.id.name, + HttpMessageComponentName::Derived(DerivedComponentName::Method) ); + assert_eq!(comp.id.params.0, HashSet::default()); assert_eq!(comp.value.inner, "POST"); - assert_eq!(comp.to_string(), "\"@method\";req: POST"); + assert_eq!(comp.to_string(), "\"@method\": POST"); - let comp = HttpMessageComponent::try_from("\"x-empty-header\": ").unwrap(); + let comp = HttpMessageComponent::from_serialized_str("\"example-header\";bs;tr: example-value").unwrap(); assert_eq!( - comp.id, - HttpMessageComponentIdentifier::HttpField(HttpFieldComponentId { - filed_name: "\"x-empty-header\"".to_string(), - params: HttpMessageComponentParams(HashSet::default()) - }) + comp.id.name, + HttpMessageComponentName::HttpField("\"example-header\"".to_string()) ); - assert_eq!(comp.value.inner, ""); - assert_eq!(comp.to_string(), "\"x-empty-header\": "); - } - #[test] - fn test_http_message_component_value() { - let val = HttpMessageComponentValue::from("example-value"); - assert_eq!(val.inner, "example-value"); - assert_eq!(val.to_string(), "example-value"); - - let val = HttpMessageComponentValue::from(""); - assert_eq!(val.inner, ""); - assert_eq!(val.to_string(), ""); - } - #[test] - fn test_http_message_component_id_enum() { - let params = HttpMessageComponentIdentifier::from("\"example-header\";bs"); assert_eq!( - params, - HttpMessageComponentIdentifier::HttpField(HttpFieldComponentId { - filed_name: "\"example-header\"".to_string(), - params: HttpMessageComponentParams(vec![HttpMessageComponentParam::Bs].into_iter().collect::>()) - }) + comp.id.params.0, + vec![HttpMessageComponentParam::Bs, HttpMessageComponentParam::Tr] + .into_iter() + .collect::>() ); - let params = HttpMessageComponentIdentifier::from("\"@method\";req"); + let comp = HttpMessageComponent::from_serialized_str("\"@method\";req: POST").unwrap(); assert_eq!( - params, - HttpMessageComponentIdentifier::Derived(DerivedComponentId { - component_name: DerivedComponentName::Method, - params: HttpMessageComponentParams(vec![HttpMessageComponentParam::Req].into_iter().collect::>()) - }) + comp.id.name, + HttpMessageComponentName::Derived(DerivedComponentName::Method) ); - } - #[test] - fn test_derived_components() { - let params = DerivedComponentId::from("\"@method\";req"); - assert_eq!(params.component_name, DerivedComponentName::Method); assert_eq!( - params.params.0, + comp.id.params.0, vec![HttpMessageComponentParam::Req].into_iter().collect::>() ); + assert_eq!(comp.value.inner, "POST"); + assert_eq!(comp.to_string(), "\"@method\";req: POST"); - // drops invalid field params - let params = DerivedComponentId::from("\"@path\";req;key=\"test\""); - assert_eq!(params.component_name, DerivedComponentName::Path); + let comp = HttpMessageComponent::from_serialized_str("\"x-empty-header\": ").unwrap(); assert_eq!( - params.params.0, - vec![HttpMessageComponentParam::Req].into_iter().collect::>() + comp.id.name, + HttpMessageComponentName::HttpField("\"x-empty-header\"".to_string()) ); + assert_eq!(comp.id.params.0, HashSet::default()); + assert_eq!(comp.value.inner, ""); } - #[test] - fn test_query_params() { - let params = DerivedComponentId::from("\"@query-param\";name=\"test\""); - assert_eq!(params.component_name, DerivedComponentName::QueryParam); - assert_eq!( - params.params.0, - vec![HttpMessageComponentParam::Name("test".to_string())] - .into_iter() - .collect::>() - ); - assert_eq!(params.to_string(), "\"@query-param\";name=\"test\""); - } + // #[test] + // fn test_http_message_component_value() { + // let val = HttpMessageComponentValue::from("example-value"); + // assert_eq!(val.inner, "example-value"); + // assert_eq!(val.to_string(), "example-value"); - #[test] - fn test_http_general_field() { - let params = HttpFieldComponentId::from("\"example-header\";bs"); - assert_eq!(params.filed_name, "\"example-header\""); - assert_eq!( - params.params.0, - vec![HttpMessageComponentParam::Bs].into_iter().collect::>() - ); + // let val = HttpMessageComponentValue::from(""); + // assert_eq!(val.inner, ""); + // assert_eq!(val.to_string(), ""); + // } + // #[test] + // fn test_http_message_component_id_enum() { + // let params = HttpMessageComponentName::from("\"example-header\";bs"); + // assert_eq!( + // params, + // HttpMessageComponentName::HttpField(HttpFieldComponentId { + // filed_name: "\"example-header\"".to_string(), + // params: HttpMessageComponentParams(vec![HttpMessageComponentParam::Bs].into_iter().collect::>()) + // }) + // ); - // keeps field params - let params = HttpFieldComponentId::from("\"example-header\";bs;key=\"test\""); - assert_eq!(params.filed_name, "\"example-header\""); - assert_eq!( - params.params.0, - vec![ - HttpMessageComponentParam::Bs, - HttpMessageComponentParam::Key("test".to_string()) - ] - .into_iter() - .collect::>() - ); - } + // let params = HttpMessageComponentName::from("\"@method\";req"); + // assert_eq!( + // params, + // HttpMessageComponentName::Derived(DerivedComponentId { + // component_name: DerivedComponentName::Method, + // params: HttpMessageComponentParams(vec![HttpMessageComponentParam::Req].into_iter().collect::>()) + // }) + // ); + // } + // #[test] + // fn test_derived_components() { + // let params = DerivedComponentId::from("\"@method\";req"); + // assert_eq!(params.component_name, DerivedComponentName::Method); + // assert_eq!( + // params.params.0, + // vec![HttpMessageComponentParam::Req].into_iter().collect::>() + // ); + + // // drops invalid field params + // let params = DerivedComponentId::from("\"@path\";req;key=\"test\""); + // assert_eq!(params.component_name, DerivedComponentName::Path); + // assert_eq!( + // params.params.0, + // vec![HttpMessageComponentParam::Req].into_iter().collect::>() + // ); + // } + + // #[test] + // fn test_query_params() { + // let params = DerivedComponentId::from("\"@query-param\";name=\"test\""); + // assert_eq!(params.component_name, DerivedComponentName::QueryParam); + // assert_eq!( + // params.params.0, + // vec![HttpMessageComponentParam::Name("test".to_string())] + // .into_iter() + // .collect::>() + // ); + // assert_eq!(params.to_string(), "\"@query-param\";name=\"test\""); + // } + + // #[test] + // fn test_http_general_field() { + // let params = HttpFieldComponentId::from("\"example-header\";bs"); + // assert_eq!(params.filed_name, "\"example-header\""); + // assert_eq!( + // params.params.0, + // vec![HttpMessageComponentParam::Bs].into_iter().collect::>() + // ); + + // // keeps field params + // let params = HttpFieldComponentId::from("\"example-header\";bs;key=\"test\""); + // assert_eq!(params.filed_name, "\"example-header\""); + // assert_eq!( + // params.params.0, + // vec![ + // HttpMessageComponentParam::Bs, + // HttpMessageComponentParam::Key("test".to_string()) + // ] + // .into_iter() + // .collect::>() + // ); + // } } diff --git a/src/signature_base.rs b/src/signature_base.rs index 904eee5..a9f00da 100644 --- a/src/signature_base.rs +++ b/src/signature_base.rs @@ -27,7 +27,7 @@ impl SignatureBase { .iter() .zip(signature_params.covered_components.iter()) .all(|(component_line, covered_component_id)| { - let component_line_id_string = &component_line.id.to_string(); + let component_line_id_string = &component_line.name.to_string(); component_line_id_string == covered_component_id }); if !assertion { diff --git a/src/signature_params.rs b/src/signature_params.rs index 3c8070a..fe22753 100644 --- a/src/signature_params.rs +++ b/src/signature_params.rs @@ -1,4 +1,4 @@ -use crate::{crypto::VerifyingKey, message_component::HttpMessageComponentIdentifier, util::has_unique_elements}; +use crate::{crypto::VerifyingKey, message_component::HttpMessageComponentName, util::has_unique_elements}; use base64::{engine::general_purpose, Engine as _}; use rand::Rng; use std::time::{SystemTime, UNIX_EPOCH}; @@ -124,7 +124,7 @@ pub struct HttpSignatureParamsBuilder { tag: Option, /// derived components and http field component ike `date`, `content-type`, `content-length`, etc. /// https://www.ietf.org/archive/id/draft-ietf-httpbis-message-signatures-19.html#section-2 - covered_components: Vec, + covered_components: Vec, } impl Default for HttpSignatureParamsBuilder { @@ -168,17 +168,14 @@ impl HttpSignatureParamsBuilder { } /// Set covered components pub fn covered_message_component_ids(&mut self, components: &[&str]) { - self.covered_components = components - .iter() - .map(|&c| HttpMessageComponentIdentifier::from(c)) - .collect(); + self.covered_components = components.iter().map(|&c| HttpMessageComponentName::from(c)).collect(); assert!(has_unique_elements(self.covered_components.iter())) } /// Extend covered conmpoents pub fn extend_covered_message_component_ids(&mut self, components: &[&str]) { self .covered_components - .extend(components.iter().map(|&c| HttpMessageComponentIdentifier::from(c))); + .extend(components.iter().map(|&c| HttpMessageComponentName::from(c))); // check duplicates assert!(has_unique_elements(self.covered_components.iter())) } @@ -253,7 +250,7 @@ MCowBQYDK2VwAyEA1ixMQcxO46PLlgQfYS46ivFd+n0CcDHSKUnuhm3i1O0= params.covered_message_component_ids(&["\"@method\"", "\"@path\";bs", "\"@authority\""]); let x = vec!["\"@method\"", "\"@path\";bs", "\"@authority\""] .into_iter() - .map(HttpMessageComponentIdentifier::from) + .map(HttpMessageComponentName::from) .collect::>(); assert_eq!(params.covered_components, x); params.key_info(&PublicKey::from_pem(EDDSA_PUBLIC_KEY).unwrap());