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}