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