149 lines
7.2 KiB
Python
149 lines
7.2 KiB
Python
#!/usr/bin/python3
|
|
#-------------------------------------------------------------------------------
|
|
# Name: Samba PKI Tools
|
|
# Purpose:
|
|
#
|
|
# Author: kguerineau-adm
|
|
#
|
|
# Created: 10/05/2024
|
|
# Copyright: (c) kguerineau-adm 2024
|
|
# Licence: <your licence>
|
|
#-------------------------------------------------------------------------------
|
|
|
|
# Maange DC Certificates
|
|
|
|
from common import Printing, TisPKI, check_directories, config
|
|
from intermediate_module import generate_intermediate_crl
|
|
|
|
import subprocess
|
|
import jinja2
|
|
import os
|
|
import configparser
|
|
import sys
|
|
from colorama import Fore, Style
|
|
import shutil
|
|
import time
|
|
|
|
|
|
def generate_dc_certificate(dc_name=None, ca_name=None, verbose=False):
|
|
|
|
if ca_name != "Root":
|
|
dc_certfile = os.path.join(TisPKI.intermediate_cert_path(ca_name),f'{dc_name}.crt')
|
|
dc_keyfile = os.path.join(TisPKI.intermediate_keyout_path(ca_name),f'{dc_name}.key')
|
|
dc_csrfile = os.path.join(TisPKI.intermediate_csr_path(ca_name),f'{dc_name}.csr')
|
|
dc_openssl_configfile = os.path.join(TisPKI.intermediate_config_path(ca_name),f'openssl_{dc_name}.ini')
|
|
crl_file = os.path.join(TisPKI.intermediate_crl_path(ca_name),'intermediate_ca.crl')
|
|
dc_ca_keyfile = TisPKI.intermediate_ca_keyfile(ca_name)
|
|
dc_ca_certfile = TisPKI.intermediate_ca_certfile(ca_name)
|
|
crl_uri = config.get('openssl_config','intermediate_crl_uri')
|
|
pki_dir = TisPKI.pki_intermediate_dir(ca_name)
|
|
else:
|
|
dc_certfile = os.path.join(TisPKI.root_cert_path(),f'{dc_name}.crt')
|
|
dc_keyfile = os.path.join(TisPKI.root_keyout_path(),f'{dc_name}.key')
|
|
dc_csrfile = os.path.join(TisPKI.root_csr_path(),f'{dc_name}.csr')
|
|
dc_openssl_configfile = os.path.join(TisPKI.root_config_path(),f'openssl_{dc_name}.ini')
|
|
crl_file = os.path.join(TisPKI.root_crl_path(),'root_ca.crl')
|
|
dc_ca_keyfile = os.path.join(TisPKI.root_keyout_path(),'root_ca.key')
|
|
dc_ca_certfile = os.path.join(TisPKI.root_cert_path(),'root_ca.crt')
|
|
crl_uri = config.get('openssl_config','crl_uri')
|
|
pki_dir = TisPKI.pki_dir()
|
|
|
|
if not os.path.isfile(dc_certfile) and not os.path.isfile(dc_keyfile):
|
|
Printing.information(f'Generate certificate for {dc_name}')
|
|
|
|
dc_name_guid = dc_name.split('.')[0]
|
|
dc_guid = str(subprocess.check_output(f'/bin/bash get_guid.sh {dc_name_guid}',shell=True).decode("utf-8")).strip()
|
|
if str(dc_guid) == '':
|
|
Printing.error('Unable to find dc_guid. Please verify the DC FQDN.')
|
|
sys.exit(1)
|
|
|
|
if verbose:
|
|
Printing.information(f'{dc_name} GUID is : ' + str(dc_guid).strip())
|
|
|
|
template_dir = ('templates')
|
|
jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(template_dir))
|
|
dc_tmpl = jinja_env.get_template('openssl_server_cert.tmpl')
|
|
dc_tmpl_var = {
|
|
'dc_name': dc_name,
|
|
'dc_guid': str(dc_guid),
|
|
'crl_uri': crl_uri,
|
|
'pki_dir': pki_dir,
|
|
'default_cert_duration': config.get('openssl_config','default_cert_duration'),
|
|
'default_crl_duration': config.get('openssl_config','default_crl_duration'),
|
|
'country': config.get('openssl_config','country'),
|
|
'state': config.get('openssl_config','state'),
|
|
'city': config.get('openssl_config','city'),
|
|
'organization_name': config.get('openssl_config','organization_name'),
|
|
'organization_ou': config.get('openssl_config','organization_ou'),
|
|
'dc_ca_keyfile': dc_ca_keyfile,
|
|
'dc_ca_certfile': dc_ca_certfile,
|
|
'commonName': dc_name
|
|
|
|
}
|
|
|
|
config_string = dc_tmpl.render(dc_tmpl_var)
|
|
with open(dc_openssl_configfile,'wt') as file:
|
|
file.write(config_string)
|
|
|
|
if os.path.isfile(dc_openssl_configfile):
|
|
Printing.information(f'{dc_name} OpenSSL configfile is correctly generated !')
|
|
|
|
Printing.information(f'Generate private key and CSR for {dc_name}')
|
|
gen_dc_key = subprocess.run(f"openssl req -new -addext 'subjectAltName = email:copy' -newkey rsa:4096 -nodes -keyout {dc_keyfile} \
|
|
-out {dc_csrfile} -config {dc_openssl_configfile}" , shell=True, check=False, executable='/bin/bash')
|
|
|
|
if gen_dc_key.returncode == 0:
|
|
if os.path.isfile(dc_csrfile):
|
|
Printing.information(f'Sign certificate for {dc_name}')
|
|
sign_dc_cert = subprocess.run(f'openssl ca -config {dc_openssl_configfile} -extensions usr_cert_mskdc \
|
|
-days 3650 -notext -md sha512 -create_serial -in {dc_csrfile} -out {dc_certfile}', shell=True, check=False, executable='/bin/bash')
|
|
|
|
if sign_dc_cert.returncode == 0:
|
|
if os.path.isfile(dc_certfile):
|
|
print('Concatenation of DC and intermediate cert')
|
|
subprocess.run(f'cat {dc_certfile} {dc_ca_certfile} > {dc_certfile}_full',shell=True)
|
|
Printing.success(f'Certificat is stored in : {dc_certfile}')
|
|
Printing.success(f'Key is stored in : {dc_keyfile}')
|
|
else:
|
|
Printing.error('Error on sign Domain Controler certificate')
|
|
retry = input('If you want to retry, press Y : ')
|
|
if retry == "y" or retry == 'Y':
|
|
os.remove(dc_keyfile)
|
|
generate_dc_certificate(dc_name, ca_name, verbose)
|
|
else:
|
|
Printing.error('Error on generating Domain Controler private key')
|
|
retry = input('If you want to retry, press Y : ')
|
|
if retry == "y" or retry == 'Y':
|
|
os.remove(dc_keyfile)
|
|
generate_dc_certificate(dc_name, ca_name, verbose)
|
|
|
|
|
|
def revoke_dc_certificate(dc_name=None, ca_name=None, verbose=False):
|
|
Printing.information(f'Revoke {dc_name} certificate')
|
|
|
|
if ca_name != "Root":
|
|
dc_keyfile = os.path.join(TisPKI.intermediate_keyout_path(ca_name),f'{dc_name}.key')
|
|
dc_certfile = os.path.join(TisPKI.intermediate_cert_path(ca_name),f'{dc_name}.crt')
|
|
dc_openssl_configfile = os.path.join(TisPKI.intermediate_config_path(ca_name),f'openssl_{dc_name}.ini')
|
|
else:
|
|
dc_keyfile = os.path.join(TisPKI.root_keyout_path(),f'{dc_name}.key')
|
|
dc_certfile = os.path.join(TisPKI.root_cert_path(),f'{dc_name}.crt')
|
|
dc_openssl_configfile = os.path.join(TisPKI.root_config_path(),f'openssl_{dc_name}.ini')
|
|
|
|
revoke_dc = input(f'Are you realy sure to revoke {dc_name} certificate ? [y/N]'.strip() or 'y')
|
|
if revoke_dc.lower() == "y":
|
|
Printing.information(f'OK, revoking {dc_name} certificate !')
|
|
revoke_cmd = subprocess.run(f"/usr/bin/openssl ca -config {dc_openssl_configfile} -revoke {dc_certfile}",
|
|
shell=True, check=False, executable='/bin/bash')
|
|
|
|
if revoke_cmd.returncode == 0:
|
|
Printing.information(f'Regenerate {ca_name} CRL')
|
|
generate_intermediate_crl(dc_openssl_configfile, ca_name, verbose)
|
|
else:
|
|
Printing.error('Unable to revoke CA Intermediate certificate')
|
|
|
|
remove_files = input('Would you like to remove private key and certificate ? [Y/n]' or "y")
|
|
if remove_files.lower() == "y":
|
|
os.remove(dc_certfile)
|
|
os.remove(dc_keyfile)
|