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