def generate_cert_request(fqdn): """Create aggregator certificate key pair.""" from openfl.cryptography.participant import generate_csr from openfl.cryptography.io import write_crt, write_key if fqdn is None: fqdn = getfqdn() common_name = f'{fqdn}'.lower() subject_alternative_name = f'DNS:{common_name}' file_name = f'agg_{common_name}' echo(f'Creating AGGREGATOR certificate key pair with following settings: ' f'CN={style(common_name, fg="red")},' f' SAN={style(subject_alternative_name, fg="red")}') server_private_key, server_csr = generate_csr(common_name, server=True) (PKI_DIR / 'server').mkdir(parents=True, exist_ok=True) echo(' Writing AGGREGATOR certificate key pair to: ' + style(f'{PKI_DIR}/server', fg='green')) # Write aggregator csr and key to disk write_crt(server_csr, PKI_DIR / 'server' / f'{file_name}.csr') write_key(server_private_key, PKI_DIR / 'server' / f'{file_name}.key')
def certify(fqdn, silent): """Sign/certify the aggregator certificate key pair.""" from openfl.cryptography.ca import sign_certificate from openfl.cryptography.io import read_key, read_crt, read_csr from openfl.cryptography.io import write_crt from click import confirm common_name = f'{fqdn}'.lower() file_name = f'agg_{common_name}' cert_name = f'server/{file_name}' signing_key_path = 'ca/signing-ca/private/signing-ca.key' signing_crt_path = 'ca/signing-ca.crt' # Load CSR if not Path(PKI_DIR / f'{cert_name}.csr').exists(): echo(style('Aggregator certificate signing request not found.', fg='red') + ' Please run `fx aggregator generate-cert-request`' ' to generate the certificate request.') csr, csr_hash = read_csr(PKI_DIR / f'{cert_name}.csr') # Load private signing key if not Path(PKI_DIR / signing_key_path).exists(): echo(style('Signing key not found.', fg='red') + ' Please run `fx workspace certify`' ' to initialize the local certificate authority.') signing_key = read_key(PKI_DIR / signing_key_path) # Load signing cert if not Path(PKI_DIR / signing_crt_path).exists(): echo(style('Signing certificate not found.', fg='red') + ' Please run `fx workspace certify`' ' to initialize the local certificate authority.') signing_crt = read_crt(PKI_DIR / signing_crt_path) echo('The CSR Hash for file ' + style(f'{cert_name}.csr', fg='green') + ' = ' + style(f'{csr_hash}', fg='red')) if silent: echo(' Signing AGGREGATOR certificate') signed_agg_cert = sign_certificate(csr, signing_key, signing_crt.subject) write_crt(signed_agg_cert, PKI_DIR / f'{cert_name}.crt') else: if confirm("Do you want to sign this certificate?"): echo(' Signing AGGREGATOR certificate') signed_agg_cert = sign_certificate(csr, signing_key, signing_crt.subject) write_crt(signed_agg_cert, PKI_DIR / f'{cert_name}.crt') else: echo(style('Not signing certificate.', fg='red') + ' Please check with this AGGREGATOR to get the correct' ' certificate for this federation.')
def certify(collaborator_name, silent, request_pkg=False, import_=False): """Sign/certify collaborator certificate key pair.""" from click import confirm from shutil import unpack_archive from shutil import make_archive, copy from glob import glob from os.path import basename, join, splitext from os import remove from tempfile import mkdtemp from openfl.cryptography.ca import sign_certificate from openfl.cryptography.io import read_key, read_crt, read_csr from openfl.cryptography.io import write_crt common_name = f'{collaborator_name}'.lower() if not import_: if request_pkg: Path(f'{PKI_DIR}/client').mkdir(parents=True, exist_ok=True) unpack_archive(request_pkg, extract_dir=f'{PKI_DIR}/client') csr = glob(f'{PKI_DIR}/client/*.csr')[0] else: if collaborator_name is None: echo('collaborator_name can only be omitted if signing\n' 'a zipped request package.\n' '\n' 'Example: fx collaborator certify --request-pkg ' 'col_one_to_agg_cert_request.zip') return csr = glob(f'{PKI_DIR}/client/col_{common_name}.csr')[0] copy(csr, PKI_DIR) cert_name = splitext(csr)[0] file_name = basename(cert_name) signing_key_path = 'ca/signing-ca/private/signing-ca.key' signing_crt_path = 'ca/signing-ca.crt' # Load CSR if not Path(f'{cert_name}.csr').exists(): echo( style('Collaborator certificate signing request not found.', fg='red') + ' Please run `fx collaborator generate-cert-request`' ' to generate the certificate request.') csr, csr_hash = read_csr(f'{cert_name}.csr') # Load private signing key if not Path(PKI_DIR / signing_key_path).exists(): echo( style('Signing key not found.', fg='red') + ' Please run `fx workspace certify`' ' to initialize the local certificate authority.') signing_key = read_key(PKI_DIR / signing_key_path) # Load signing cert if not Path(PKI_DIR / signing_crt_path).exists(): echo( style('Signing certificate not found.', fg='red') + ' Please run `fx workspace certify`' ' to initialize the local certificate authority.') signing_crt = read_crt(PKI_DIR / signing_crt_path) echo('The CSR Hash for file ' + style(f'{file_name}.csr', fg='green') + ' = ' + style(f'{csr_hash}', fg='red')) if silent: echo(' Signing COLLABORATOR certificate') signed_col_cert = sign_certificate(csr, signing_key, signing_crt.subject) write_crt(signed_col_cert, f'{cert_name}.crt') RegisterCollaborator(PKI_DIR / 'client' / f'{file_name}.crt') else: if confirm("Do you want to sign this certificate?"): echo(' Signing COLLABORATOR certificate') signed_col_cert = sign_certificate(csr, signing_key, signing_crt.subject) write_crt(signed_col_cert, f'{cert_name}.crt') RegisterCollaborator(PKI_DIR / 'client' / f'{file_name}.crt') else: echo( style('Not signing certificate.', fg='red') + ' Please check with this collaborator to get the' ' correct certificate for this federation.') return if len(common_name) == 0: # If the collaborator name is provided, the collaborator and # certificate does not need to be exported return # Remove unneeded CSR remove(f'{cert_name}.csr') archiveType = 'zip' archiveName = f'agg_to_{file_name}_signed_cert' # archiveFileName = archiveName + '.' + archiveType # Collaborator certificate signing request tmpDir = join(mkdtemp(), 'openfl', archiveName) Path(f'{tmpDir}/client').mkdir(parents=True, exist_ok=True) # Copy the signed cert to the temporary directory copy(f'{PKI_DIR}/client/{file_name}.crt', f'{tmpDir}/client/') # Copy the CA certificate chain to the temporary directory copy(f'{PKI_DIR}/cert_chain.crt', tmpDir) # Create Zip archive of directory make_archive(archiveName, archiveType, tmpDir) else: # Copy the signed certificate and cert chain into PKI_DIR previous_crts = glob(f'{PKI_DIR}/client/*.crt') unpack_archive(import_, extract_dir=PKI_DIR) updated_crts = glob(f'{PKI_DIR}/client/*.crt') cert_difference = list(set(updated_crts) - set(previous_crts)) if len(cert_difference) == 0: crt = basename(cert_difference[0]) echo(f"Certificate {crt} installed to PKI directory") else: crt = basename(updated_crts[0]) echo("Certificate updated in the PKI directory")
def generate_cert_request(collaborator_name, data_path, silent, skip_package): """ Create collaborator certificate key pair. Then create a package with the CSR to send for signing. """ from openfl.cryptography.participant import generate_csr from openfl.cryptography.io import write_crt, write_key common_name = f'{collaborator_name}'.lower() subject_alternative_name = f'DNS:{common_name}' file_name = f'col_{common_name}' echo( f'Creating COLLABORATOR certificate key pair with following settings: ' f'CN={style(common_name, fg="red")},' f' SAN={style(subject_alternative_name, fg="red")}') client_private_key, client_csr = generate_csr(common_name, server=False) (PKI_DIR / 'client').mkdir(parents=True, exist_ok=True) echo(' Moving COLLABORATOR certificate to: ' + style(f'{PKI_DIR}/{file_name}', fg='green')) # Write collaborator csr and key to disk write_crt(client_csr, PKI_DIR / 'client' / f'{file_name}.csr') write_key(client_private_key, PKI_DIR / 'client' / f'{file_name}.key') if not skip_package: from shutil import make_archive, copytree, ignore_patterns from tempfile import mkdtemp from os.path import join, basename from os import remove from glob import glob archiveType = 'zip' archiveName = f'col_{common_name}_to_agg_cert_request' archiveFileName = archiveName + '.' + archiveType # Collaborator certificate signing request tmpDir = join(mkdtemp(), 'openfl', archiveName) ignore = ignore_patterns('__pycache__', '*.key', '*.srl', '*.pem') # Copy the current directory into the temporary directory copytree(f'{PKI_DIR}/client', tmpDir, ignore=ignore) for f in glob(f'{tmpDir}/*'): if common_name not in basename(f): remove(f) # Create Zip archive of directory make_archive(archiveName, archiveType, tmpDir) echo(f'Archive {archiveFileName} with certificate signing' f' request created') echo('This file should be sent to the certificate authority' ' (typically hosted by the aggregator) for signing') # TODO: There should be some association with the plan made here as well RegisterDataPath(common_name, data_path=data_path, silent=silent)