http_msgsign/sign/
request.rs1use crate::errors::{SignError, VerificationError};
2use crate::sign::signature::Signatures;
3use crate::sign::{SignatureBase, SignatureInput, SignatureParams, SignerKey, VerifierKey};
4use http::Request;
5
6pub trait RequestSign {
8 fn sign<S: SignerKey>(
9 self,
10 key: &S,
11 label: &str,
12 params: &SignatureParams,
13 ) -> impl Future<Output = Result<Self, SignError>> + Send
14 where
15 Self: Sized;
16 fn verify_sign<V: VerifierKey>(
17 self,
18 key: &V,
19 label: &str,
20 ) -> impl Future<Output = Result<Self, VerificationError>> + Send
21 where
22 Self: Sized;
23}
24
25impl<B> RequestSign for Request<B>
26where
27 B: http_body::Body + Send,
28 B::Data: Send,
29{
30 async fn sign<S: SignerKey>(
31 self,
32 key: &S,
33 label: &str,
34 params: &SignatureParams,
35 ) -> Result<Self, SignError> {
36 let base = SignatureBase::from_request_with_signer_key(&self, params, key)?
37 .into_header(key, label);
38 let (mut parts, body) = self.into_parts();
39 parts.headers.extend(base);
40
41 Ok(Request::from_parts(parts, body))
42 }
43
44 async fn verify_sign<V: VerifierKey>(
45 self,
46 key: &V,
47 label: &str,
48 ) -> Result<Self, VerificationError> {
49 let (parts, body) = self.into_parts();
50 let signatures = Signatures::from_header(&parts.headers)?;
51 let inputs = SignatureInput::from_header(&parts.headers)?;
52 let signature = signatures.get(label)?;
53 let Some(params) = inputs.get(label).map(SignatureParams::from) else {
54 return Err(VerificationError::MissingSignatureInput(label.to_string()));
55 };
56
57 let request = Request::from_parts(parts, body);
58 SignatureBase::from_request(&request, ¶ms)?.verify(key, signature)?;
59
60 Ok(request)
61 }
62}