Skip to main content

cratestack_axum/envelope_layer/
cose_impl.rs

1//! [`ServerEnvelope`] for `cratestack_cose::CoseEnvelope`, the default
2//! (maintainer decision D7): the typed `open_request` / `seal_response`, so
3//! no `CratestackContext` is needed. Feature `cose`.
4
5use async_trait::async_trait;
6use bytes::Bytes;
7use cratestack_core::{Binding, CratestackError, VerifiedSigner};
8use cratestack_cose::{CoseEnvelope, Opened};
9
10use super::opened::{OpenedRequest, SealContext, Sealed};
11use super::server_envelope::ServerEnvelope;
12
13#[async_trait]
14impl ServerEnvelope for CoseEnvelope {
15    /// `application/cose; cose-type="cose-sign1"` or `"cose-mac0"`, by mode.
16    fn media_type(&self) -> &'static str {
17        self.mode().media_type()
18    }
19
20    /// The signer is the key that verified: its full RFC 9679 thumbprint
21    /// (not the 8-byte `kid`, which can collide), a copy of its `kid` (so
22    /// the signer does not keep the body alive) and its algorithm. The same
23    /// fields the `CratestackEnvelope::open` path records. One framing, so
24    /// no seal context.
25    async fn open_request(
26        &self,
27        body: Bytes,
28        bind: &Binding<'_>,
29    ) -> Result<OpenedRequest, CratestackError> {
30        let opened = CoseEnvelope::open_request(self, body, bind).await?;
31        Ok(into_request(opened))
32    }
33
34    /// Parse and key resolution happen once; only the signature check runs
35    /// per candidate binding.
36    async fn open_request_any(
37        &self,
38        body: Bytes,
39        binds: &[Binding<'_>],
40    ) -> Result<(OpenedRequest, usize), CratestackError> {
41        let (opened, index) = CoseEnvelope::open_request_any(self, body, binds).await?;
42        Ok((into_request(opened), index))
43    }
44
45    /// One copy of the payload into the message (D1), sent as this
46    /// envelope's mode's media type.
47    async fn seal_response(
48        &self,
49        payload: &[u8],
50        bind: &Binding<'_>,
51        _context: &SealContext,
52    ) -> Result<Sealed, CratestackError> {
53        let body = CoseEnvelope::seal_response(self, payload, bind).await?;
54        Ok(Sealed::new(body, self.mode().media_type()))
55    }
56}
57
58fn into_request(opened: Opened) -> OpenedRequest {
59    let signer = VerifiedSigner::new(
60        Bytes::copy_from_slice(&opened.kid),
61        opened.thumbprint,
62        opened.alg.id(),
63    );
64    OpenedRequest::new(opened.payload, signer)
65}