From 5ee0572f54262482d02e323fc100c5667ced483e Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Wed, 8 Jun 2022 17:10:11 -0400 Subject: [PATCH] Change to using 'full' openssl ca OpenSSL does not allow access to custom start date without the full 'ca' facility, do the work to set up the full CA and then backdate certificates. This does open the way for managed CA if required. --- confluent_server/confluent/certutil.py | 143 +++++++++++++++++++------ 1 file changed, 111 insertions(+), 32 deletions(-) diff --git a/confluent_server/confluent/certutil.py b/confluent_server/confluent/certutil.py index f1df0c6a..7c1d2868 100644 --- a/confluent_server/confluent/certutil.py +++ b/confluent_server/confluent/certutil.py @@ -7,6 +7,13 @@ import socket import eventlet.green.subprocess as subprocess import tempfile +def mkdirp(targ): + try: + return os.makedirs(targ) + except OSError as e: + if e.errno != 17: + raise + def get_openssl_conf_location(): if exists('/etc/pki/tls/openssl.cnf'): return '/etc/pki/tls/openssl.cnf' @@ -79,31 +86,8 @@ def get_certificate_paths(): def assure_tls_ca(): keyout, certout = ('/etc/confluent/tls/cakey.pem', '/etc/confluent/tls/cacert.pem') if not os.path.exists(certout): - try: - os.makedirs('/etc/confluent/tls') - except OSError as e: - if e.errno != 17: - raise - sslcfg = get_openssl_conf_location() - tmphdl, tmpconfig = tempfile.mkstemp() - os.close(tmphdl) - shutil.copy2(sslcfg, tmpconfig) - subprocess.check_call( - ['openssl', 'ecparam', '-name', 'secp384r1', '-genkey', '-out', - keyout]) - try: - subj = '/CN=Confluent TLS Certificate authority ({0})'.format(socket.gethostname()) - if len(subj) > 68: - subj = subj[:68] - with open(tmpconfig, 'a') as cfgfile: - cfgfile.write('\n[CACert]\nbasicConstraints = CA:true\n') - subprocess.check_call([ - 'openssl', 'req', '-new', '-x509', '-key', keyout, '-days', - '27300', '-out', certout, '-subj', subj, - '-extensions', 'CACert', '-config', tmpconfig - ]) - finally: - os.remove(tmpconfig) + #create_simple_ca(keyout, certout) + create_full_ca(certout) fname = '/var/lib/confluent/public/site/tls/{0}.pem'.format( collective.get_myname()) ouid = normalize_uid() @@ -133,6 +117,93 @@ def assure_tls_ca(): pass os.symlink(certname, hashname) +def substitute_cfg(setting, key, val, newval, cfgfile, line): + if key.strip() == setting: + cfgfile.write(line.replace(val, newval) + '\n') + return True + return False + +def create_full_ca(certout): + mkdirp('/etc/confluent/tls/ca/private') + keyout = '/etc/confluent/tls/ca/private/cakey.pem' + csrout = '/etc/confluent/tls/ca/ca.csr' + mkdirp('/etc/confluent/tls/ca/newcerts') + with open('/etc/confluent/tls/ca/index.txt', 'w') as idx: + pass + with open('/etc/confluent/tls/ca/index.txt.attr', 'w') as idx: + idx.write('unique_subject = no') + with open('/etc/confluent/tls/ca/serial', 'w') as srl: + srl.write('01') + sslcfg = get_openssl_conf_location() + newcfg = '/etc/confluent/tls/ca/openssl.cfg' + settings = { + 'dir': '/etc/confluent/tls/ca', + 'certificate': '$dir/cacert.pem', + 'private_key': '$dir/private/cakey.pem', + 'countryName': 'optional', + 'stateOrProvinceName': 'optional', + 'organizationName': 'optional', + } + subj = '/CN=Confluent TLS Certificate authority ({0})'.format(socket.gethostname()) + if len(subj) > 68: + subj = subj[:68] + with open(sslcfg, 'r') as cfgin: + with open(newcfg, 'w') as cfgfile: + for line in cfgin.readlines(): + cfg = line.split('#')[0] + if '=' in cfg: + key, val = cfg.split('=', 1) + for stg in settings: + if substitute_cfg(stg, key, val, settings[stg], cfgfile, line): + break + else: + cfgfile.write(line.strip() + '\n') + continue + cfgfile.write(line.strip() + '\n') + cfgfile.write('\n[CACert]\nbasicConstraints = CA:true\n\n[ca_confluent]\n') + subprocess.check_call( + ['openssl', 'ecparam', '-name', 'secp384r1', '-genkey', '-out', + keyout]) + subprocess.check_call( + ['openssl', 'req', '-new', '-key', keyout, '-out', csrout, '-subj', subj]) + subprocess.check_call( + ['openssl', 'ca', '-config', newcfg, '-batch', '-selfsign', + '-extensions', 'CACert', '-extfile', newcfg, + '-startdate', + '19700101010101Z', '-enddate', '21000101010101Z', '-keyfile', + keyout, '-out', '/etc/confluent/tls/ca/cacert.pem', '-in', csrout] + ) + shutil.copy2('/etc/confluent/tls/ca/cacert.pem', certout) +#openssl ca -config openssl.cnf -selfsign -keyfile cakey.pem -startdate 20150214120000Z -enddate 20160214120000Z +#20160107071311Z -enddate 20170106071311Z + +def create_simple_ca(keyout, certout): + try: + os.makedirs('/etc/confluent/tls') + except OSError as e: + if e.errno != 17: + raise + sslcfg = get_openssl_conf_location() + tmphdl, tmpconfig = tempfile.mkstemp() + os.close(tmphdl) + shutil.copy2(sslcfg, tmpconfig) + subprocess.check_call( + ['openssl', 'ecparam', '-name', 'secp384r1', '-genkey', '-out', + keyout]) + try: + subj = '/CN=Confluent TLS Certificate authority ({0})'.format(socket.gethostname()) + if len(subj) > 68: + subj = subj[:68] + with open(tmpconfig, 'a') as cfgfile: + cfgfile.write('\n[CACert]\nbasicConstraints = CA:true\n') + subprocess.check_call([ + 'openssl', 'req', '-new', '-x509', '-key', keyout, '-days', + '27300', '-out', certout, '-subj', subj, + '-extensions', 'CACert', '-config', tmpconfig + ]) + finally: + os.remove(tmpconfig) + def create_certificate(keyout=None, certout=None): if not keyout: keyout, certout = get_certificate_paths() @@ -170,13 +241,21 @@ def create_certificate(keyout=None, certout=None): '/CN={0}'.format(longname), '-extensions', 'SAN', '-config', tmpconfig ]) - subprocess.check_call([ - 'openssl', 'x509', '-req', '-in', csrout, - '-CA', '/etc/confluent/tls/cacert.pem', - '-CAkey', '/etc/confluent/tls/cakey.pem', - '-set_serial', serialnum, '-out', certout, '-days', '27300', - '-extfile', extconfig - ]) + if os.path.exists('/etc/confluent/tls/cakey.pem'): + subprocess.check_call([ + 'openssl', 'x509', '-req', '-in', csrout, + '-CA', '/etc/confluent/tls/cacert.pem', + '-CAkey', '/etc/confluent/tls/cakey.pem', + '-set_serial', serialnum, '-out', certout, '-days', '27300', + '-extfile', extconfig + ]) + else: + subprocess.check_call([ + 'openssl', 'ca', '-config', '/etc/confluent/tls/ca/openssl.cfg', + '-in', csrout, '-out', certout, '-batch', '-notext', + '-startdate', '19700101010101Z', '-enddate', '21000101010101Z', + '-extfile', extconfig + ]) finally: os.remove(tmpconfig) os.remove(csrout)