mirror of
https://github.com/moepman/acertmgr.git
synced 2024-11-13 06:45:24 +01:00
tools/configuration: Add support for EC/Ed25519/Ed448 generation
This commit is contained in:
parent
4f0fe2c74a
commit
6a07ab1188
@ -69,9 +69,12 @@ By default the directory (work_dir) containing the working data (csr,certificate
|
||||
| authority_tos_agreement | d,**g**,c | Indicates agreement to the ToS of the certificate authority (--authority-tos-agreement on command line) | |
|
||||
| authority_contact_email | d,**g** | (v2 API only) Contact e-mail to be registered with your account key | |
|
||||
| account_key | d,**g** | Path to the account key | {work_dir}/account.key |
|
||||
| account_key_algorithm | d,**g** | Key-algorithm for newly generated account keys (RSA, EC, ED25519, ED448) | RSA |
|
||||
| account_key_length | d,**g** | Key-length for newly generated RSA account keys (in bits) or EC curve (256=P-256, 384=P-384, 521=P-521) | depends on account_key_algorithm |
|
||||
| ttl_days | d,**g** | Renew certificate if it has less than this value validity left | 30 |
|
||||
| cert_dir | d,**g** | Directory containing all certificate related data (crt,key,csr) | {work_dir} |
|
||||
| key_length | d,**g** | Key-length for newly generated private keys | 4096 |
|
||||
| key_algorithm | d,**g** | Key-algorithm for newly generated private keys (RSA, EC, ED25519, ED448) | RSA |
|
||||
| key_length | d,**g** | Key-length for newly generated RSA private keys (in bits) or EC curve (256=P-256, 384=P-384, 521=P-521) | depends on key_algorithm |
|
||||
| csr_static | **d**,g | Whether to re-use a static CSR or generate a new dynamic CSR | false |
|
||||
| csr_file | **d**,g | Path to store (and load) the certificate CSR file | {cert_dir}/{cert_id}.csr |
|
||||
| ca_static | **d**,g | Whether to re-use a static CA or download a CA file | false |
|
||||
|
@ -35,12 +35,11 @@ def cert_get(settings):
|
||||
|
||||
# create ssl key
|
||||
key_file = settings['key_file']
|
||||
key_length = settings['key_length']
|
||||
if os.path.isfile(key_file):
|
||||
key = tools.read_pem_file(key_file, key=True)
|
||||
else:
|
||||
log("SSL key not found at '{0}'. Creating {1} bit key.".format(key_file, key_length))
|
||||
key = tools.new_ssl_key(key_file, key_length)
|
||||
log("SSL key not found at '{0}'. Creating key.".format(key_file))
|
||||
key = tools.new_ssl_key(key_file, settings['key_algorithm'], settings['key_length'])
|
||||
|
||||
# create ssl csr
|
||||
csr_file = settings['csr_file']
|
||||
|
@ -28,7 +28,7 @@ def authority(settings):
|
||||
acc_key = tools.read_pem_file(acc_file, key=True)
|
||||
else:
|
||||
log("Account key not found at '{0}'. Creating key.".format(acc_file))
|
||||
acc_key = tools.new_account_key(acc_file)
|
||||
acc_key = tools.new_account_key(acc_file, settings['account_key_algorithm'], settings['account_key_size'])
|
||||
|
||||
authority_module = importlib.import_module("acertmgr.authority.{0}".format(settings["api"]))
|
||||
authority_class = getattr(authority_module, "ACMEAuthority")
|
||||
|
@ -32,7 +32,6 @@ LEGACY_AUTHORITY_TOS_AGREEMENT = "true"
|
||||
# Configuration defaults to use if not specified otherwise
|
||||
DEFAULT_CONF_FILE = "/etc/acertmgr/acertmgr.conf"
|
||||
DEFAULT_CONF_DIR = "/etc/acertmgr"
|
||||
DEFAULT_KEY_LENGTH = 4096 # bits
|
||||
DEFAULT_TTL = 30 # days
|
||||
DEFAULT_API = "v2"
|
||||
DEFAULT_AUTHORITY = "https://acme-v02.api.letsencrypt.org"
|
||||
@ -105,6 +104,14 @@ def parse_authority(localconfig, globalconfig, runtimeconfig):
|
||||
# - Account key path
|
||||
update_config_value(authority, 'account_key', localconfig, globalconfig,
|
||||
os.path.join(runtimeconfig['work_dir'], "account.key"))
|
||||
|
||||
# - Account key algorithm (if key has to be (re-)generated)
|
||||
update_config_value(authority, 'account_key_algorithm', localconfig, globalconfig, None)
|
||||
|
||||
# - Account key length (if key has to be (re-)generated, converted to int)
|
||||
update_config_value(authority, 'account_key_length', localconfig, globalconfig, None)
|
||||
authority['account_key_length'] = int(authority['account_key_length']) if authority['account_key_length'] else None
|
||||
|
||||
return authority
|
||||
|
||||
|
||||
@ -162,9 +169,12 @@ def parse_config_entry(entry, globalconfig, runtimeconfig):
|
||||
globalconfig.get('server_key',
|
||||
os.path.join(config['cert_dir'], "{}.key".format(config['id']))))
|
||||
|
||||
# SSL key algorithm (if key has to be (re-)generated)
|
||||
update_config_value(config, 'key_algorithm', localconfig, globalconfig, None)
|
||||
|
||||
# SSL key length (if key has to be (re-)generated, converted to int)
|
||||
update_config_value(config, 'key_length', localconfig, globalconfig, DEFAULT_KEY_LENGTH)
|
||||
config['key_length'] = int(config['key_length'])
|
||||
update_config_value(config, 'key_length', localconfig, globalconfig, None)
|
||||
config['key_length'] = int(config['key_length']) if config['key_length'] else None
|
||||
|
||||
# SSL CA location / use static
|
||||
update_config_value(config, 'ca_file', localconfig, globalconfig,
|
||||
|
@ -116,24 +116,47 @@ def new_cert_request(names, key, must_staple=False):
|
||||
|
||||
# @brief generate a new account key
|
||||
# @param path path where the new key file should be written in PEM format (optional)
|
||||
def new_account_key(path=None, key_size=4096):
|
||||
return new_ssl_key(path, key_size)
|
||||
def new_account_key(path=None, key_algo=None, key_size=None):
|
||||
return new_ssl_key(path, key_algo, key_size)
|
||||
|
||||
|
||||
# @brief generate a new ssl key
|
||||
# @param path path where the new key file should be written in PEM format (optional)
|
||||
def new_ssl_key(path=None, key_size=4096):
|
||||
private_key = rsa.generate_private_key(
|
||||
public_exponent=65537,
|
||||
key_size=key_size,
|
||||
backend=default_backend()
|
||||
)
|
||||
pem = private_key.private_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
||||
encryption_algorithm=serialization.NoEncryption()
|
||||
)
|
||||
def new_ssl_key(path=None, key_algo=None, key_size=None):
|
||||
if not key_algo or key_algo.lower() == 'rsa':
|
||||
if not key_size:
|
||||
key_size = 4096
|
||||
key_format = serialization.PrivateFormat.TraditionalOpenSSL
|
||||
private_key = rsa.generate_private_key(
|
||||
public_exponent=65537,
|
||||
key_size=key_size,
|
||||
backend=default_backend()
|
||||
)
|
||||
elif key_algo.lower() == 'ec':
|
||||
if not key_size or key_size == 256:
|
||||
key_curve = ec.SECP256R1
|
||||
elif key_size == 384:
|
||||
key_curve = ec.SECP384R1
|
||||
elif key_size == 521:
|
||||
key_curve = ec.SECP521R1
|
||||
else:
|
||||
raise ValueError("Unsupported EC curve size parameter: {}".format(key_size))
|
||||
key_format = serialization.PrivateFormat.PKCS8
|
||||
private_key = ec.generate_private_key(curve=key_curve, backend=default_backend())
|
||||
elif key_algo.lower() == 'ed25519' and "cryptography.hazmat.primitives.asymmetric.ed25519":
|
||||
key_format = serialization.PrivateFormat.PKCS8
|
||||
private_key = ed25519.Ed25519PrivateKey.generate()
|
||||
elif key_algo.lower() == 'ed448' and "cryptography.hazmat.primitives.asymmetric.ed448":
|
||||
key_format = serialization.PrivateFormat.PKCS8
|
||||
private_key = ed448.Ed448PrivateKey.generate()
|
||||
else:
|
||||
raise ValueError("Unsupported key algorithm: {}".format(key_algo))
|
||||
if path is not None:
|
||||
pem = private_key.private_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=key_format,
|
||||
encryption_algorithm=serialization.NoEncryption(),
|
||||
)
|
||||
with io.open(path, 'wb') as pem_out:
|
||||
pem_out.write(pem)
|
||||
try:
|
||||
|
Loading…
Reference in New Issue
Block a user