wire_e2e_identity/
pki_env_hooks.rs

1//! PKI Environment API Hooks
2
3/// An http method
4pub enum HttpMethod {
5    /// GET
6    Get,
7    /// POST
8    Post,
9    /// PUT
10    Put,
11    /// DELETE
12    Delete,
13    /// PATCH
14    Patch,
15    /// HEAD
16    Head,
17}
18
19/// An http header
20pub struct HttpHeader {
21    /// header name
22    pub name: String,
23    /// header value
24    pub value: String,
25}
26
27/// An HTTP Response
28pub struct HttpResponse {
29    /// Response status code
30    pub status: u16,
31    /// Response Header
32    pub headers: Vec<HttpHeader>,
33    /// Response Body
34    pub body: Vec<u8>,
35}
36
37/// Error type for PKI environment hooks
38#[derive(Debug, thiserror::Error)]
39#[error("reason: {reason}")]
40pub struct PkiEnvironmentHooksError {
41    /// the error reason
42    pub reason: String,
43}
44
45/// The PKI Environment Hooks used for external calls during e2e enrollment flow.
46/// When communicating with the Identity Provider (IDP)  and Wire server,
47/// CoreCrypto delegates to the client app by calling the relevant methods.
48///
49/// Client App                 CoreCrypto                     Acme                     IDP
50///    |                           |                          |                        |
51///    | X509CredentialAcquisition().finalize()               |                        |
52///    |-------------------------->|                          |                        |
53///    |                           | GET acme/root.pem        |                        |
54///    |                           |------------------------> |                        |
55///    |                           | 200 OK                   |                        |
56///    |                           |<------------------------ |                        |
57///    | authenticate()            |                          |                        |
58///    |<--------------------------|                          |                        |
59///    |                           | Authentication flow      |                        |
60///    | ----------------------------------------------------------------------------> |
61///    |<----------------------------------------------------------------------------- |
62///    | return Success [PkiEnvironmentHooks.authenticate()]  |                        |
63///    |<--------------------------|                          |                        |
64///    |                           |  (excluded several calls for brevity)             |
65///    | return Success(Credential) [X509CredentialAcquisition().finalize()]           |
66///    |<--------------------------|                          |                        |
67#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
68#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
69pub trait PkiEnvironmentHooks: std::fmt::Debug + Send + Sync {
70    /// Make an HTTP request
71    /// Used for requests to ACME servers, CRL distributors etc.
72    async fn http_request(
73        &self,
74        method: HttpMethod,
75        url: String,
76        headers: Vec<HttpHeader>,
77        body: Vec<u8>,
78    ) -> Result<HttpResponse, PkiEnvironmentHooksError>;
79
80    /// Authenticate with the user's identity provider (IdP)
81    ///
82    /// The implementation should perform an [authentication using the authorization code flow]
83    /// (<https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth>) with the PKCE
84    /// (<https://www.rfc-editor.org/rfc/rfc7636>) extension. As part of the authorization
85    /// request, the implementation should specify `key_auth` and `acme_aud` claims, along with
86    /// their values, in the `claims` parameter. This is to instruct the IdP to add the `key_auth`
87    /// and `acme_aud` claims to the ID token that will be returned as part of the access token.
88    ///
89    /// Once the authentication is completed successfully, the implementation should request
90    /// an access token from the IdP, extract the ID token from it and return it to the caller.
91    async fn authenticate(
92        &self,
93        idp: String,
94        key_auth: String,
95        acme_aud: String,
96    ) -> Result<String, PkiEnvironmentHooksError>;
97
98    /// Get a nonce from the backend
99    async fn get_backend_nonce(&self) -> Result<String, PkiEnvironmentHooksError>;
100
101    /// Fetch an access token to be used for the DPoP challenge (`wire-dpop-01`)
102    ///
103    /// The implementation should take the provided DPoP token (`dpop`) and make a request to the
104    /// backend to obtain an access token, which should be returned to the caller.
105    async fn fetch_backend_access_token(&self, dpop: String) -> Result<String, PkiEnvironmentHooksError>;
106}