Skip to content

Commit 7db212c

Browse files
committed
feat: support blocking apis
1 parent a13dfb3 commit 7db212c

3 files changed

Lines changed: 280 additions & 1 deletion

File tree

httpsig-hyper/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ rust-version.workspace = true
1212

1313
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1414

15+
[features]
16+
default = ["blocking"]
17+
blocking = ["futures/executor"]
18+
19+
1520
[dependencies]
1621
httpsig = { path = "../httpsig", version = "0.0.20" }
1722

httpsig-hyper/src/hyper_http.rs

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,89 @@ pub trait MessageSignatureRes {
133133
) -> Result<IndexMap<SignatureName, (HttpSignatureBase, HttpSignatureHeaders)>, Self::Error>;
134134
}
135135

136+
/* --------------------------------------- */
137+
#[cfg(feature = "blocking")]
138+
/// A trait about http message signature for request with synchronous signing/verifying key
139+
pub trait MessageSignatureReqSync: MessageSignatureReq {
140+
fn set_message_signature_sync<T>(
141+
&mut self,
142+
signature_params: &HttpSignatureParams,
143+
signing_key: &T,
144+
signature_name: Option<&str>,
145+
) -> Result<(), Self::Error>
146+
where
147+
Self: Sized,
148+
T: SigningKey + Sync;
149+
150+
fn set_message_signatures_sync<T>(
151+
&mut self,
152+
params_key_name: &[(&HttpSignatureParams, &T, Option<&str>)],
153+
) -> Result<(), Self::Error>
154+
where
155+
Self: Sized,
156+
T: SigningKey + Sync;
157+
158+
fn verify_message_signature_sync<T>(&self, verifying_key: &T, key_id: Option<&str>) -> Result<SignatureName, Self::Error>
159+
where
160+
Self: Sized,
161+
T: VerifyingKey + Sync;
162+
163+
fn verify_message_signatures_sync<T>(
164+
&self,
165+
key_and_id: &[(&T, Option<&str>)],
166+
) -> Result<Vec<Result<SignatureName, Self::Error>>, Self::Error>
167+
where
168+
Self: Sized,
169+
T: VerifyingKey + Sync;
170+
}
171+
172+
#[cfg(feature = "blocking")]
173+
/// A trait about http message signature for response with synchronous signing/verifying key
174+
pub trait MessageSignatureResSync: MessageSignatureRes {
175+
fn set_message_signature_sync<T, B>(
176+
&mut self,
177+
signature_params: &HttpSignatureParams,
178+
signing_key: &T,
179+
signature_name: Option<&str>,
180+
req_for_param: Option<&Request<B>>,
181+
) -> Result<(), Self::Error>
182+
where
183+
Self: Sized,
184+
T: SigningKey + Sync,
185+
B: Sync;
186+
187+
fn set_message_signatures_sync<T, B>(
188+
&mut self,
189+
params_key_name: &[(&HttpSignatureParams, &T, Option<&str>)],
190+
req_for_param: Option<&Request<B>>,
191+
) -> Result<(), Self::Error>
192+
where
193+
Self: Sized,
194+
T: SigningKey + Sync,
195+
B: Sync;
196+
197+
fn verify_message_signature_sync<T, B>(
198+
&self,
199+
verifying_key: &T,
200+
key_id: Option<&str>,
201+
req_for_param: Option<&Request<B>>,
202+
) -> Result<SignatureName, Self::Error>
203+
where
204+
Self: Sized,
205+
T: VerifyingKey + Sync,
206+
B: Sync;
207+
208+
fn verify_message_signatures_sync<T, B>(
209+
&self,
210+
key_and_id: &[(&T, Option<&str>)],
211+
req_for_param: Option<&Request<B>>,
212+
) -> Result<Vec<Result<SignatureName, Self::Error>>, Self::Error>
213+
where
214+
Self: Sized,
215+
T: VerifyingKey + Sync,
216+
B: Sync;
217+
}
218+
136219
/* --------------------------------------- */
137220
impl<D> MessageSignature for Request<D>
138221
where
@@ -378,6 +461,117 @@ where
378461
}
379462
}
380463

464+
/* --------------------------------------- */
465+
#[cfg(feature = "blocking")]
466+
impl<D> MessageSignatureReqSync for Request<D>
467+
where
468+
D: Send + Body + Sync,
469+
{
470+
fn set_message_signature_sync<T>(
471+
&mut self,
472+
signature_params: &HttpSignatureParams,
473+
signing_key: &T,
474+
signature_name: Option<&str>,
475+
) -> Result<(), Self::Error>
476+
where
477+
Self: Sized,
478+
T: SigningKey + Sync,
479+
{
480+
futures::executor::block_on(self.set_message_signature(signature_params, signing_key, signature_name))
481+
}
482+
483+
fn set_message_signatures_sync<T>(
484+
&mut self,
485+
params_key_name: &[(&HttpSignatureParams, &T, Option<&str>)],
486+
) -> Result<(), Self::Error>
487+
where
488+
Self: Sized,
489+
T: SigningKey + Sync,
490+
{
491+
futures::executor::block_on(self.set_message_signatures(params_key_name))
492+
}
493+
494+
fn verify_message_signature_sync<T>(&self, verifying_key: &T, key_id: Option<&str>) -> Result<SignatureName, Self::Error>
495+
where
496+
Self: Sized,
497+
T: VerifyingKey + Sync,
498+
{
499+
futures::executor::block_on(self.verify_message_signature(verifying_key, key_id))
500+
}
501+
502+
fn verify_message_signatures_sync<T>(
503+
&self,
504+
key_and_id: &[(&T, Option<&str>)],
505+
) -> Result<Vec<Result<SignatureName, Self::Error>>, Self::Error>
506+
where
507+
Self: Sized,
508+
T: VerifyingKey + Sync,
509+
{
510+
futures::executor::block_on(self.verify_message_signatures(key_and_id))
511+
}
512+
}
513+
514+
#[cfg(feature = "blocking")]
515+
impl<D> MessageSignatureResSync for Response<D>
516+
where
517+
D: Send + Body + Sync,
518+
{
519+
fn set_message_signature_sync<T, B>(
520+
&mut self,
521+
signature_params: &HttpSignatureParams,
522+
signing_key: &T,
523+
signature_name: Option<&str>,
524+
req_for_param: Option<&Request<B>>,
525+
) -> Result<(), Self::Error>
526+
where
527+
Self: Sized,
528+
T: SigningKey + Sync,
529+
B: Sync,
530+
{
531+
futures::executor::block_on(self.set_message_signature(signature_params, signing_key, signature_name, req_for_param))
532+
}
533+
534+
fn set_message_signatures_sync<T, B>(
535+
&mut self,
536+
params_key_name: &[(&HttpSignatureParams, &T, Option<&str>)],
537+
req_for_param: Option<&Request<B>>,
538+
) -> Result<(), Self::Error>
539+
where
540+
Self: Sized,
541+
T: SigningKey + Sync,
542+
B: Sync,
543+
{
544+
futures::executor::block_on(self.set_message_signatures(params_key_name, req_for_param))
545+
}
546+
547+
fn verify_message_signature_sync<T, B>(
548+
&self,
549+
verifying_key: &T,
550+
key_id: Option<&str>,
551+
req_for_param: Option<&Request<B>>,
552+
) -> Result<SignatureName, Self::Error>
553+
where
554+
Self: Sized,
555+
T: VerifyingKey + Sync,
556+
B: Sync,
557+
{
558+
futures::executor::block_on(self.verify_message_signature(verifying_key, key_id, req_for_param))
559+
}
560+
561+
fn verify_message_signatures_sync<T, B>(
562+
&self,
563+
key_and_id: &[(&T, Option<&str>)],
564+
req_for_param: Option<&Request<B>>,
565+
) -> Result<Vec<Result<SignatureName, Self::Error>>, Self::Error>
566+
where
567+
Self: Sized,
568+
T: VerifyingKey + Sync,
569+
B: Sync,
570+
{
571+
futures::executor::block_on(self.verify_message_signatures(key_and_id, req_for_param))
572+
}
573+
}
574+
381575
/* --------------------------------------- */
382576
// inner functions
383577
/// has message signature inner function
@@ -1026,4 +1220,36 @@ ii+31DW+YulmysZKQKDvuk96TARuWMO/vDbhk777a2QF3bgNoIj8UPMwnw==
10261220
assert!(verification_res[0].as_ref().unwrap() == "eddsa_sig");
10271221
assert!(verification_res[1].as_ref().unwrap() == "p256_sig");
10281222
}
1223+
1224+
#[cfg(feature = "blocking")]
1225+
#[test]
1226+
fn test_blocking_set_verify_message_signature_req() {
1227+
let mut req = futures::executor::block_on(build_request());
1228+
let secret_key = SecretKey::from_pem(EDDSA_SECRET_KEY).unwrap();
1229+
let mut signature_params = HttpSignatureParams::try_new(&build_covered_components_req()).unwrap();
1230+
signature_params.set_key_info(&secret_key);
1231+
1232+
req.set_message_signature_sync(&signature_params, &secret_key, None).unwrap();
1233+
1234+
let public_key = PublicKey::from_pem(EDDSA_PUBLIC_KEY).unwrap();
1235+
let verification_res = req.verify_message_signature_sync(&public_key, None);
1236+
assert!(verification_res.is_ok());
1237+
}
1238+
1239+
#[cfg(feature = "blocking")]
1240+
#[test]
1241+
fn test_blocking_set_verify_message_signature_res() {
1242+
let req = futures::executor::block_on(build_request());
1243+
let mut res = futures::executor::block_on(build_response());
1244+
let secret_key = SecretKey::from_pem(EDDSA_SECRET_KEY).unwrap();
1245+
let mut signature_params = HttpSignatureParams::try_new(&build_covered_components_res()).unwrap();
1246+
signature_params.set_key_info(&secret_key);
1247+
res
1248+
.set_message_signature_sync(&signature_params, &secret_key, None, Some(&req))
1249+
.unwrap();
1250+
1251+
let public_key = PublicKey::from_pem(EDDSA_PUBLIC_KEY).unwrap();
1252+
let verification_res = res.verify_message_signature_sync(&public_key, None, Some(&req));
1253+
assert!(verification_res.is_ok());
1254+
}
10291255
}

httpsig-hyper/src/lib.rs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ impl std::str::FromStr for ContentDigestType {
4242
pub use error::{HyperDigestError, HyperDigestResult, HyperSigError, HyperSigResult};
4343
pub use httpsig::prelude;
4444
pub use hyper_content_digest::{ContentDigest, RequestContentDigest, ResponseContentDigest};
45-
pub use hyper_http::{MessageSignature, MessageSignatureReq, MessageSignatureRes};
45+
pub use hyper_http::{
46+
MessageSignature, MessageSignatureReq, MessageSignatureReqSync, MessageSignatureRes, MessageSignatureResSync,
47+
};
4648

4749
/* ----------------------------------------------------------------- */
4850
#[cfg(test)]
@@ -188,4 +190,50 @@ MCowBQYDK2VwAyEA1ixMQcxO46PLlgQfYS46ivFd+n0CcDHSKUnuhm3i1O0=
188190
.await;
189191
assert!(verification_res.is_err());
190192
}
193+
194+
#[cfg(feature = "blocking")]
195+
#[test]
196+
fn test_set_verify_request_sync() {
197+
// show usage of set_message_signature_sync and verify_message_signature_sync
198+
199+
let mut req = futures::executor::block_on(build_request());
200+
let secret_key = SecretKey::from_pem(EDDSA_SECRET_KEY).unwrap();
201+
let covered_components = COVERED_COMPONENTS_REQ
202+
.iter()
203+
.map(|v| message_component::HttpMessageComponentId::try_from(*v))
204+
.collect::<Result<Vec<_>, _>>()
205+
.unwrap();
206+
let mut signature_params = HttpSignatureParams::try_new(&covered_components).unwrap();
207+
// set key information, alg and keyid
208+
signature_params.set_key_info(&secret_key);
209+
// set signature
210+
req.set_message_signature_sync(&signature_params, &secret_key, None).unwrap();
211+
let public_key = PublicKey::from_pem(EDDSA_PUBLIC_KEY).unwrap();
212+
let verification_res = req.verify_message_signature_sync(&public_key, None);
213+
assert!(verification_res.is_ok());
214+
}
215+
216+
#[cfg(feature = "blocking")]
217+
#[test]
218+
fn test_set_verify_response_sync() {
219+
// show usage of set_message_signature_sync and verify_message_signature_sync
220+
let req = futures::executor::block_on(build_request());
221+
let mut res = futures::executor::block_on(build_response());
222+
let secret_key = SecretKey::from_pem(EDDSA_SECRET_KEY).unwrap();
223+
let covered_components = COVERED_COMPONENTS_RES
224+
.iter()
225+
.map(|v| message_component::HttpMessageComponentId::try_from(*v))
226+
.collect::<Result<Vec<_>, _>>()
227+
.unwrap();
228+
let mut signature_params = HttpSignatureParams::try_new(&covered_components).unwrap();
229+
// set key information, alg and keyid
230+
signature_params.set_key_info(&secret_key);
231+
// set signature
232+
res
233+
.set_message_signature_sync(&signature_params, &secret_key, None, Some(&req))
234+
.unwrap();
235+
let public_key = PublicKey::from_pem(EDDSA_PUBLIC_KEY).unwrap();
236+
let verification_res = res.verify_message_signature_sync(&public_key, None, Some(&req));
237+
assert!(verification_res.is_ok());
238+
}
191239
}

0 commit comments

Comments
 (0)