+ print("Obtaining certificate '{}' for domains: {}".format(name, ' '.join(domains)))
+ acme(keyfile(name), certfile(name), domains)
+
+def generate_key(name):
+ assert not os.path.exists(certfile(name)), "Don't make create a new key for an old cert"
+ print("Generating new private key '{}'".format(name))
+ openssl_genrsa(keyfile(name))
+
+def check_staging(live, staging):
+ '''Returns 0 if nothing was done, 1 if a stage key is present but has to be kept, 2 is a stage key was unstaged.'''
+ if not os.path.exists(keyfile(staging)):
+ return 0
+
+ staging_time = datetime.timedelta(hours = int(config['timing'].get('staging-hours', 0)))
+ key_age = datetime.datetime.now() - key_mtime(staging)
+ if key_age < staging_time:
+ return 1
+ print("Unstaging '{}' to '{}'".format(staging, live))
+ # unstage the key!
+ make_backup(keyfile(live))
+ os.rename(keyfile(staging), keyfile(live))
+ make_backup(certfile(live))
+ os.rename(certfile(staging), certfile(live))
+ return 2
+
+def auto_renewal(live, staging):
+ '''Returns 0 if nothing was done, 1 if only certs were changed, 2 if certs and keys were changed.'''
+ max_key_age = datetime.timedelta(days = int(config['timing']['max-key-age-days']))
+ renew_cert_time = datetime.timedelta(days = int(config['timing']['renew-cert-before-expiry-days']))
+
+ # determine what to do
+ now = datetime.datetime.now()
+ key_age = now - key_mtime(live)
+ need_new_key = key_age >= max_key_age
+ if os.path.exists(certfile(live)):
+ cert_validity = cert_expiry(live) - now
+ need_new_cert = cert_validity <= renew_cert_time
+ else:
+ need_new_cert = True
+ if need_new_cert and key_age + renew_cert_time >= max_key_age:
+ # We are about to request a new certificate, and within <renew_cert_time>, we need a new key: Get the new key now
+ need_new_key = True
+
+ # Do it
+ if need_new_key:
+ generate_key(staging)
+ request_cert(staging)
+ check_staging(live, staging) # we may want to immediately enable the new key & cert
+ return 2
+ elif need_new_cert:
+ request_cert(live)
+ return 1
+ else:
+ return 0