wire_e2e_identity/acquisition/
oidc_challenge.rs1use obfuscate::Obfuscated;
2use rusty_jwt_tools::{
3 jwk_thumbprint::JwkThumbprint,
4 prelude::{HashAlgorithm, Pem},
5};
6use x509_cert::Certificate;
7
8use super::{Result, X509CredentialAcquisition, states};
9use crate::{
10 acme,
11 pki_env::hooks::{HttpHeader, HttpMethod},
12};
13
14impl X509CredentialAcquisition<states::DpopChallengeCompleted> {
15 pub async fn complete_oidc_challenge(self) -> Result<(Pem, Vec<Certificate>)> {
21 let hooks = self.pki_env.hooks();
22
23 let oidc_challenge_token = &self.data.oidc_challenge.token;
25 let thumbprint = JwkThumbprint::generate(&self.acme_jwk, HashAlgorithm::SHA256)?.kid;
27 let key_auth = format!("{oidc_challenge_token}.{thumbprint}");
28 let snapshot = serde_json::to_vec(&self)?;
29
30 let url = &self.data.oidc_challenge.url;
31 let target = self.data.oidc_challenge.target.to_string();
32 let id_token = hooks.authenticate(target, key_auth, url.to_string(), snapshot).await?;
33 log::debug!(
34 "acquisition({:?}): got the ID token from the OIDC server",
35 Obfuscated::from(&self.sign_kp),
36 );
37
38 let oidc_challenge_request = acme::oidc_chall_request(
39 id_token,
40 &self.data.oidc_challenge,
41 &self.data.acme_account,
42 self.sign_alg,
43 &self.acme_kp,
44 self.data.nonce.clone(),
45 )?;
46 let (nonce, response) = self.acme_request(url, &oidc_challenge_request).await?;
47 let _ = acme::new_chall_response(response)?;
48 log::info!(
49 "acquisition({:?}): OIDC challenge completed",
50 Obfuscated::from(&self.sign_kp),
51 );
52
53 let finalize_request = acme::finalize_req(
56 &self.data.order,
57 &self.data.acme_account,
58 self.sign_alg,
59 &self.acme_kp,
60 &self.sign_kp,
61 nonce,
62 )?;
63 let (nonce, response) = self.acme_request(&self.data.order.finalize, &finalize_request).await?;
64 let finalize = acme::finalize_response(response)?;
65 log::debug!(
66 "acquisition({:?}): ACME order finalized",
67 Obfuscated::from(&self.sign_kp),
68 );
69
70 let certificate_request =
74 acme::certificate_req(&finalize, &self.data.acme_account, self.sign_alg, &self.acme_kp, nonce)?;
75 let headers = vec![HttpHeader {
76 name: "content-type".into(),
77 value: "application/jose+json".into(),
78 }];
79 let body = serde_json::to_string(&certificate_request)?.into();
80 let response = hooks
81 .http_request(HttpMethod::Post, finalize.certificate.to_string(), headers, body)
82 .await?;
83 let response = String::from_utf8(response.body).map_err(|e| acme::Error::from(e.utf8_error()))?;
84 let certificates = acme::certificate_response(response, &self.data.order)?;
85 log::debug!(
86 "acquisition({:?}): got the certificate",
87 Obfuscated::from(&self.sign_kp),
88 );
89
90 self.verify_cert_chain(&certificates).await?;
91 log::info!(
92 "acquisition({:?}): certificate verified successfully",
93 Obfuscated::from(&self.sign_kp),
94 );
95
96 Ok((self.sign_kp, certificates))
97 }
98}