acertmgr: try using a fallback configuration for revoke

If no configuration matching the domains in the given certificate exist
use the globalconfig/default settings for an authority to revoke the
certificate (which might still fail if things do not match up, but the
authority will decide on that)

Configuration parsing for the authority settings is therefore split into
a seperate function which will be called for the 'fallback_authority'
element in runtimeconfig.
This commit is contained in:
Kishi85 2019-04-03 12:34:25 +02:00
parent 762037c42d
commit 79b625619a
2 changed files with 42 additions and 25 deletions

View File

@ -118,14 +118,20 @@ def cert_put(settings):
return crt_action
def cert_revoke(cert, configs, reason=None):
def cert_revoke(cert, configs, fallback_authority, reason=None):
domains = set(tools.get_cert_domains(cert))
acmeconfig = None
for config in configs:
if domains == set(config['domainlist']):
acme = authority(config['authority'])
acme.register_account()
acme.revoke_crt(cert, reason)
return
acmeconfig = config['authority']
break
if not acmeconfig:
acmeconfig = fallback_authority
log("No matching authority found to revoke {}: {}, using globalconfig/defaults".format(tools.get_cert_cn(cert),
tools.get_cert_domains(cert)), warning=True)
acme = authority(acmeconfig)
acme.register_account()
acme.revoke_crt(cert, reason)
def main():
@ -134,7 +140,10 @@ def main():
if runtimeconfig.get('mode') == 'revoke':
# Mode: revoke certificate
log("Revoking {}".format(runtimeconfig['revoke']))
cert_revoke(tools.read_pem_file(runtimeconfig['revoke']), domainconfigs, runtimeconfig['revoke_reason'])
cert_revoke(tools.read_pem_file(runtimeconfig['revoke']),
domainconfigs,
runtimeconfig['fallback_authority'],
runtimeconfig['revoke_reason'])
else:
# Mode: issue certificates (implicit)
# post-update actions (run only once)
@ -190,7 +199,7 @@ def main():
log("Revoking '{}' valid until {} as superseded".format(
tools.get_cert_cn(superseded_cert),
tools.get_cert_valid_until(superseded_cert)))
cert_revoke(superseded_cert, domainconfigs, reason=4) # reason=4 is superseded
cert_revoke(superseded_cert, domainconfigs, runtimeconfig['fallback_authority'], reason=4)
except Exception as e:
log("Certificate supersede revoke failed", e, error=True)
exceptions.append(e)

View File

@ -86,6 +86,28 @@ def idna_convert(domainlist):
return list()
# @brief parse authority from config
def parse_authority(localconfig, globalconfig, runtimeconfig):
authority = {}
# - API version
update_config_value(authority, 'api', localconfig, globalconfig, DEFAULT_API)
# - Certificate authority
update_config_value(authority, 'authority', localconfig, globalconfig, DEFAULT_AUTHORITY)
# - Certificate authority ToS agreement
update_config_value(authority, 'authority_tos_agreement', localconfig, globalconfig,
runtimeconfig['authority_tos_agreement'])
# - Certificate authority contact email addresses
update_config_value(authority, 'authority_contact_email', localconfig, globalconfig, None)
# - Account key path
update_config_value(authority, 'account_key', localconfig, globalconfig,
os.path.join(runtimeconfig['work_dir'], "account.key"))
return authority
# @brief load the configuration from a file
def parse_config_entry(entry, globalconfig, runtimeconfig):
config = dict()
@ -104,24 +126,7 @@ def parse_config_entry(entry, globalconfig, runtimeconfig):
config['defaults'] = globalconfig.get('defaults', {})
# Authority related config options
config['authority'] = {}
# - API version
update_config_value(config['authority'], 'api', localconfig, globalconfig, DEFAULT_API)
# - Certificate authority
update_config_value(config['authority'], 'authority', localconfig, globalconfig, DEFAULT_AUTHORITY)
# - Certificate authority ToS agreement
update_config_value(config['authority'], 'authority_tos_agreement', localconfig, globalconfig,
runtimeconfig['authority_tos_agreement'])
# - Certificate authority contact email addresses
update_config_value(config['authority'], 'authority_contact_email', localconfig, globalconfig, None)
# - Account key path
update_config_value(config['authority'], 'account_key', localconfig, globalconfig,
os.path.join(runtimeconfig['work_dir'], "account.key"))
config['authority'] = parse_authority(localconfig, globalconfig, runtimeconfig)
# Certificate directory
update_config_value(config, 'cert_dir', localconfig, globalconfig, runtimeconfig['work_dir'])
@ -310,4 +315,7 @@ def load():
for entry in yaml.safe_load(config_fd).items():
domainconfigs.append(parse_config_entry(entry, globalconfig, runtimeconfig))
# Define a fallback authority from global configuration / defaults
runtimeconfig['fallback_authority'] = parse_authority([], globalconfig, runtimeconfig)
return runtimeconfig, domainconfigs