Browse Source

Add the raw_proof variable to the challenge-tls-alpn-01 hook

fixes #129
pull/130/head
Rodolphe Bréard 11 months ago
parent
commit
6c8fd2f06c
  1. 3
      CHANGELOG.md
  2. 5
      acmed/src/acme_proto.rs
  3. 14
      acmed/src/acme_proto/structs/authorization.rs
  4. 2
      acmed/src/certificate.rs
  5. 1
      acmed/src/hooks.rs
  6. 3
      man/en/acmed.toml.5

3
CHANGELOG.md

@ -14,6 +14,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [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 ### Changed
- The minimum supported Rust version (MSRV) is now 1.71. - The minimum supported Rust version (MSRV) is now 1.71.

5
acmed/src/acme_proto.rs

@ -162,13 +162,14 @@ pub async fn request_certificate(
let current_challenge = current_identifier.challenge; let current_challenge = current_identifier.challenge;
for challenge in auth.challenges.iter() { for challenge in auth.challenges.iter() {
if current_challenge == *challenge { 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 file_name = challenge.get_file_name();
let identifier = auth.identifier.value.to_owned(); let identifier = auth.identifier.value.to_owned();
// Call the challenge hook in order to complete it // Call the challenge hook in order to complete it
let mut data = cert let mut data = cert
.call_challenge_hooks(&file_name, &proof, &identifier)
.call_challenge_hooks(&file_name, &proof, raw_proof, &identifier)
.await?; .await?;
data.0.is_clean_hook = true; data.0.is_clean_hook = true;
hook_datas.push(data); hook_datas.push(data);

14
acmed/src/acme_proto/structs/authorization.rs

@ -92,19 +92,23 @@ impl Challenge {
} }
} }
pub fn get_proof(&self, key_pair: &KeyPair) -> Result<String, Error> {
pub fn get_proof(&self, key_pair: &KeyPair) -> Result<(String, Option<String>), Error> {
match self { 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) => { Challenge::Dns01(tc) => {
let ka = tc.key_authorization(key_pair)?; let ka = tc.key_authorization(key_pair)?;
let a = HashFunction::Sha256.hash(ka.as_bytes()); let a = HashFunction::Sha256.hash(ka.as_bytes());
let a = b64_encode(&a); let a = b64_encode(&a);
Ok(a)
Ok((a, None))
} }
Challenge::TlsAlpn01(tc) => { Challenge::TlsAlpn01(tc) => {
let acme_ext_name = format!("{ACME_OID}.{ID_PE_ACME_ID}"); let acme_ext_name = format!("{ACME_OID}.{ID_PE_ACME_ID}");
let ka = tc.key_authorization(key_pair)?; let ka = tc.key_authorization(key_pair)?;
let proof = HashFunction::Sha256.hash(ka.as_bytes()); let proof = HashFunction::Sha256.hash(ka.as_bytes());
let b64_hash = b64_encode(&proof);
let proof_str = proof let proof_str = proof
.iter() .iter()
.map(|e| format!("{e:02x}")) .map(|e| format!("{e:02x}"))
@ -115,9 +119,9 @@ impl Challenge {
proof.len(), proof.len(),
); );
let acme_ext = format!("{acme_ext_name}={value}"); 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)),
} }
} }

2
acmed/src/certificate.rs

@ -141,6 +141,7 @@ impl Certificate {
&self, &self,
file_name: &str, file_name: &str,
proof: &str, proof: &str,
raw_proof: Option<String>,
identifier: &str, identifier: &str,
) -> Result<(ChallengeHookData, HookType), Error> { ) -> Result<(ChallengeHookData, HookType), Error> {
let identifier = self.get_identifier_from_str(identifier)?; 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(), identifier_tls_alpn: identifier.get_tls_alpn_name().unwrap_or_default(),
file_name: file_name.to_string(), file_name: file_name.to_string(),
proof: proof.to_string(), proof: proof.to_string(),
raw_proof: raw_proof.unwrap_or_default().to_string(),
is_clean_hook: false, is_clean_hook: false,
env: HashMap::new(), env: HashMap::new(),
}; };

1
acmed/src/hooks.rs

@ -62,6 +62,7 @@ pub struct ChallengeHookData {
pub challenge: String, pub challenge: String,
pub file_name: String, pub file_name: String,
pub proof: String, pub proof: String,
pub raw_proof: String,
pub is_clean_hook: bool, pub is_clean_hook: bool,
pub env: HashMap<String, String>, pub env: HashMap<String, String>,
} }

3
man/en/acmed.toml.5

@ -522,6 +522,9 @@ ALPN extension value.
.Xr acmed 8 .Xr acmed 8
will not generate the certificate itself since it can be done using will not generate the certificate itself since it can be done using
.Xr tacd 8 . .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 .El
.It Ic challenge-tls-alpn-01-clean .It Ic challenge-tls-alpn-01-clean
Invoked once an identifier ownership has been proven using the Invoked once an identifier ownership has been proven using the

Loading…
Cancel
Save