Skip to main content

http_msgsign/sign/
response.rs

1use crate::errors::{SignError, VerificationError};
2use crate::sign::signature::Signatures;
3use crate::sign::{SignatureBase, SignatureInput, SignatureParams, SignerKey, VerifierKey};
4use http::{Request, Response};
5
6//noinspection DuplicatedCode
7pub trait ResponseSign {
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
17    fn verify_sign<V: VerifierKey>(
18        self,
19        key: &V,
20        label: &str,
21    ) -> impl Future<Output = Result<Self, VerificationError>> + Send
22    where
23        Self: Sized;
24}
25
26impl<B> ResponseSign for Response<B>
27where
28    B: http_body::Body + Send + Sync,
29    B::Data: Send,
30{
31    async fn sign<S: SignerKey>(
32        self,
33        key: &S,
34        label: &str,
35        params: &SignatureParams,
36    ) -> Result<Self, SignError> {
37        let base = SignatureBase::from_response_with_signer_key(&self, params, key)?
38            .into_header(key, label);
39
40        let (mut parts, body) = self.into_parts();
41        parts.headers.extend(base);
42
43        Ok(Response::from_parts(parts, body))
44    }
45
46    async fn verify_sign<V: VerifierKey>(
47        self,
48        key: &V,
49        label: &str,
50    ) -> Result<Self, VerificationError> {
51        let (parts, body) = self.into_parts();
52        let signatures = Signatures::from_header(&parts.headers)?;
53        let inputs = SignatureInput::from_header(&parts.headers)?;
54        let signature = signatures.get(label)?;
55
56        let Some(params) = inputs.get(label).map(SignatureParams::from) else {
57            return Err(VerificationError::MissingSignatureInput(label.to_string()));
58        };
59
60        let response = Response::from_parts(parts, body);
61        SignatureBase::from_response(&response, &params)?.verify(key, signature)?;
62
63        Ok(response)
64    }
65}
66
67pub trait ExchangeRecordSign<R>: Sync + Send {
68    fn sign<S: SignerKey>(
69        self,
70        key: &S,
71        label: &str,
72        params: &SignatureParams,
73    ) -> impl Future<Output = Result<Self, SignError>> + Send
74    where
75        Self: Sized;
76
77    fn verify_sign<V: VerifierKey>(
78        self,
79        key: &V,
80        label: &str,
81    ) -> impl Future<Output = Result<Self, VerificationError>> + Send
82    where
83        Self: Sized;
84}
85
86#[derive(Debug)]
87pub struct ExchangeRecord<'a, Req, Res> {
88    pub(crate) request: &'a Request<Req>,
89    pub(crate) response: Response<Res>,
90}
91
92impl<Req, Res> From<ExchangeRecord<'_, Req, Res>> for Response<Res> {
93    fn from(value: ExchangeRecord<'_, Req, Res>) -> Self {
94        value.response
95    }
96}
97
98pub trait BindRequest<Req, Res> {
99    fn bind_request(self, request: &Request<Req>) -> ExchangeRecord<Req, Res>;
100}
101
102impl<Req, Res> BindRequest<Req, Res> for Response<Res> {
103    fn bind_request(self, request: &Request<Req>) -> ExchangeRecord<Req, Res> {
104        ExchangeRecord {
105            request,
106            response: self,
107        }
108    }
109}
110
111impl<Req, Res> ExchangeRecordSign<Res> for ExchangeRecord<'_, Req, Res>
112where
113    Req: http_body::Body + Send + Sync,
114    Req::Data: Send,
115    Res: http_body::Body + Send + Sync,
116    Res::Data: Send,
117{
118    async fn sign<S: SignerKey>(
119        mut self,
120        key: &S,
121        label: &str,
122        params: &SignatureParams,
123    ) -> Result<Self, SignError> {
124        let base = SignatureBase::from_exchange_record_with_signer_key(&self, params, key)?
125            .into_header(key, label);
126        let (mut parts, body) = self.response.into_parts();
127        parts.headers.extend(base);
128
129        self.response = Response::from_parts(parts, body);
130        Ok(self)
131    }
132
133    async fn verify_sign<V: VerifierKey>(
134        mut self,
135        key: &V,
136        label: &str,
137    ) -> Result<Self, VerificationError> {
138        let (parts, body) = self.response.into_parts();
139        let signatures = Signatures::from_header(&parts.headers)?;
140        let inputs = SignatureInput::from_header(&parts.headers)?;
141        let signature = signatures.get(label)?;
142        let Some(params) = inputs.get(label).map(SignatureParams::from) else {
143            return Err(VerificationError::MissingSignatureInput(label.to_string()));
144        };
145
146        self.response = Response::from_parts(parts, body);
147        SignatureBase::from_exchange_record(&self, &params)?.verify(key, signature)?;
148
149        Ok(self)
150    }
151}