acme: api: add eab options to api

Optionally allow for setting external account binding credentials at the
account registration endpoint.

Signed-off-by: Folke Gleumes <f.gleumes@proxmox.com>
This commit is contained in:
Folke Gleumes 2023-11-14 15:14:03 +01:00 committed by Wolfgang Bumiller
parent 92fcc4c3cd
commit 6aeb96e708
3 changed files with 47 additions and 7 deletions

View File

@ -116,6 +116,7 @@ impl AcmeClient {
tos_agreed: bool,
contact: Vec<String>,
rsa_bits: Option<u32>,
eab_creds: Option<(String, String)>,
) -> Result<&'a Account, anyhow::Error> {
self.tos = if tos_agreed {
self.terms_of_service_url().await?.map(str::to_owned)
@ -123,10 +124,14 @@ impl AcmeClient {
None
};
let account = Account::creator()
let mut account = Account::creator()
.set_contacts(contact)
.agree_to_tos(tos_agreed);
if let Some((eab_kid, eab_hmac_key)) = eab_creds {
account = account.set_eab_credentials(eab_kid, eab_hmac_key)?;
}
let account = if let Some(bits) = rsa_bits {
account.generate_rsa_key(bits)?
} else {

View File

@ -182,6 +182,16 @@ fn account_contact_from_string(s: &str) -> Vec<String> {
description: "The ACME Directory.",
optional: true,
},
eab_kid: {
type: String,
description: "Key Identifier for External Account Binding.",
optional: true,
},
eab_hmac_key: {
type: String,
description: "HMAC Key for External Account Binding.",
optional: true,
}
},
},
access: {
@ -196,6 +206,8 @@ fn register_account(
contact: String,
tos_url: Option<String>,
directory: Option<String>,
eab_kid: Option<String>,
eab_hmac_key: Option<String>,
rpcenv: &mut dyn RpcEnvironment,
) -> Result<String, Error> {
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
@ -204,6 +216,15 @@ fn register_account(
AcmeAccountName::from_string_unchecked("default".to_string())
});
// TODO: this should be done via the api definition, but
// the api macro currently lacks this ability (2023-11-06)
if eab_kid.is_some() ^ eab_hmac_key.is_some() {
http_bail!(
BAD_REQUEST,
"either both or none of 'eab_kid' and 'eab_hmac_key' have to be set."
);
}
if Path::new(&crate::config::acme::account_path(&name)).exists() {
http_bail!(BAD_REQUEST, "account {} already exists", name);
}
@ -224,8 +245,15 @@ fn register_account(
task_log!(worker, "Registering ACME account '{}'...", &name);
let account =
do_register_account(&mut client, &name, tos_url.is_some(), contact, None).await?;
let account = do_register_account(
&mut client,
&name,
tos_url.is_some(),
contact,
None,
eab_kid.zip(eab_hmac_key),
)
.await?;
task_log!(
worker,
@ -244,10 +272,11 @@ pub async fn do_register_account<'a>(
agree_to_tos: bool,
contact: String,
rsa_bits: Option<u32>,
eab_creds: Option<(String, String)>,
) -> Result<&'a Account, Error> {
let contact = account_contact_from_string(&contact);
client
.new_account(name, agree_to_tos, contact, rsa_bits)
.new_account(name, agree_to_tos, contact, rsa_bits, eab_creds)
.await
}

View File

@ -156,9 +156,15 @@ async fn register_account(
println!("Attempting to register account with {:?}...", directory);
let account =
api2::config::acme::do_register_account(&mut client, &name, tos_agreed, contact, None)
.await?;
let account = api2::config::acme::do_register_account(
&mut client,
&name,
tos_agreed,
contact,
None,
None,
)
.await?;
println!("Registration successful, account URL: {}", account.location);