Skip to main content

http_msgsign/sign/
request.rs

1use crate::errors::{SignError, VerificationError};
2use crate::sign::signature::Signatures;
3use crate::sign::{SignatureBase, SignatureInput, SignatureParams, SignerKey, VerifierKey};
4use http::Request;
5
6//noinspection DuplicatedCode
7pub 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, &params)?.verify(key, signature)?;
59
60        Ok(request)
61    }
62}