From 6c8fd2f06cffb85afb007a8a78230c2b8988d00b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodolphe=20Br=C3=A9ard?= Date: Sun, 28 Jan 2024 10:58:01 +0100 Subject: [PATCH] Add the raw_proof variable to the challenge-tls-alpn-01 hook fixes #129 --- CHANGELOG.md | 3 +++ acmed/src/acme_proto.rs | 5 +++-- acmed/src/acme_proto/structs/authorization.rs | 14 +++++++++----- acmed/src/certificate.rs | 2 ++ acmed/src/hooks.rs | 1 + man/en/acmed.toml.5 | 3 +++ 6 files changed, 21 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71ca7e1..b37d34d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added +- The `challenge-tls-alpn-01` hook now exposes the `raw_proof` variable, which contains the SHA-256 digest of the key authorization, encoded using Base64 URL scheme without padding. + ### Changed - The minimum supported Rust version (MSRV) is now 1.71. diff --git a/acmed/src/acme_proto.rs b/acmed/src/acme_proto.rs index e16b28b..9aa0526 100644 --- a/acmed/src/acme_proto.rs +++ b/acmed/src/acme_proto.rs @@ -162,13 +162,14 @@ pub async fn request_certificate( let current_challenge = current_identifier.challenge; for challenge in auth.challenges.iter() { if current_challenge == *challenge { - let proof = challenge.get_proof(&account_s.read().await.current_key.key)?; + let (proof, raw_proof) = + challenge.get_proof(&account_s.read().await.current_key.key)?; let file_name = challenge.get_file_name(); let identifier = auth.identifier.value.to_owned(); // Call the challenge hook in order to complete it let mut data = cert - .call_challenge_hooks(&file_name, &proof, &identifier) + .call_challenge_hooks(&file_name, &proof, raw_proof, &identifier) .await?; data.0.is_clean_hook = true; hook_datas.push(data); diff --git a/acmed/src/acme_proto/structs/authorization.rs b/acmed/src/acme_proto/structs/authorization.rs index fcb4bfb..b08ce1d 100644 --- a/acmed/src/acme_proto/structs/authorization.rs +++ b/acmed/src/acme_proto/structs/authorization.rs @@ -92,19 +92,23 @@ impl Challenge { } } - pub fn get_proof(&self, key_pair: &KeyPair) -> Result { + pub fn get_proof(&self, key_pair: &KeyPair) -> Result<(String, Option), Error> { match self { - Challenge::Http01(tc) => tc.key_authorization(key_pair), + Challenge::Http01(tc) => { + let ka = tc.key_authorization(key_pair)?; + Ok((ka, None)) + } Challenge::Dns01(tc) => { let ka = tc.key_authorization(key_pair)?; let a = HashFunction::Sha256.hash(ka.as_bytes()); let a = b64_encode(&a); - Ok(a) + Ok((a, None)) } Challenge::TlsAlpn01(tc) => { let acme_ext_name = format!("{ACME_OID}.{ID_PE_ACME_ID}"); let ka = tc.key_authorization(key_pair)?; let proof = HashFunction::Sha256.hash(ka.as_bytes()); + let b64_hash = b64_encode(&proof); let proof_str = proof .iter() .map(|e| format!("{e:02x}")) @@ -115,9 +119,9 @@ impl Challenge { proof.len(), ); let acme_ext = format!("{acme_ext_name}={value}"); - Ok(acme_ext) + Ok((acme_ext, Some(b64_hash))) } - Challenge::Unknown => Ok(String::new()), + Challenge::Unknown => Ok((String::new(), None)), } } diff --git a/acmed/src/certificate.rs b/acmed/src/certificate.rs index ed2ca13..c7918cf 100644 --- a/acmed/src/certificate.rs +++ b/acmed/src/certificate.rs @@ -141,6 +141,7 @@ impl Certificate { &self, file_name: &str, proof: &str, + raw_proof: Option, identifier: &str, ) -> Result<(ChallengeHookData, HookType), Error> { let identifier = self.get_identifier_from_str(identifier)?; @@ -150,6 +151,7 @@ impl Certificate { identifier_tls_alpn: identifier.get_tls_alpn_name().unwrap_or_default(), file_name: file_name.to_string(), proof: proof.to_string(), + raw_proof: raw_proof.unwrap_or_default().to_string(), is_clean_hook: false, env: HashMap::new(), }; diff --git a/acmed/src/hooks.rs b/acmed/src/hooks.rs index 8ebcff1..b38c3a1 100644 --- a/acmed/src/hooks.rs +++ b/acmed/src/hooks.rs @@ -62,6 +62,7 @@ pub struct ChallengeHookData { pub challenge: String, pub file_name: String, pub proof: String, + pub raw_proof: String, pub is_clean_hook: bool, pub env: HashMap, } diff --git a/man/en/acmed.toml.5 b/man/en/acmed.toml.5 index 6c713d9..1ebf0dd 100644 --- a/man/en/acmed.toml.5 +++ b/man/en/acmed.toml.5 @@ -522,6 +522,9 @@ ALPN extension value. .Xr acmed 8 will not generate the certificate itself since it can be done using .Xr tacd 8 . +.It Cm raw_proof Ar string +The SHA-256 digest of the key authorization, encoded using Base64 URL scheme without padding. This is intended for the use of ACMEd with a TLS-ALPN responder other than +.Xr tacd 8 . .El .It Ic challenge-tls-alpn-01-clean Invoked once an identifier ownership has been proven using the