def certify(): """Create certificate authority for federation.""" from openfl.cryptography.ca import generate_root_cert, generate_signing_csr, sign_certificate from cryptography.hazmat.primitives import serialization echo('Setting Up Certificate Authority...\n') echo('1. Create Root CA') echo('1.1 Create Directories') (PKI_DIR / 'ca/root-ca/private').mkdir(parents=True, exist_ok=True, mode=0o700) (PKI_DIR / 'ca/root-ca/db').mkdir(parents=True, exist_ok=True) echo('1.2 Create Database') with open(PKI_DIR / 'ca/root-ca/db/root-ca.db', 'w') as f: pass # write empty file with open(PKI_DIR / 'ca/root-ca/db/root-ca.db.attr', 'w') as f: pass # write empty file with open(PKI_DIR / 'ca/root-ca/db/root-ca.crt.srl', 'w') as f: f.write('01') # write file with '01' with open(PKI_DIR / 'ca/root-ca/db/root-ca.crl.srl', 'w') as f: f.write('01') # write file with '01' echo('1.3 Create CA Request and Certificate') root_crt_path = 'ca/root-ca.crt' root_key_path = 'ca/root-ca/private/root-ca.key' root_private_key, root_cert = generate_root_cert() # Write root CA certificate to disk with open(PKI_DIR / root_crt_path, 'wb') as f: f.write(root_cert.public_bytes(encoding=serialization.Encoding.PEM, )) with open(PKI_DIR / root_key_path, "wb") as f: f.write( root_private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.TraditionalOpenSSL, encryption_algorithm=serialization.NoEncryption())) echo('2. Create Signing Certificate') echo('2.1 Create Directories') (PKI_DIR / 'ca/signing-ca/private').mkdir(parents=True, exist_ok=True, mode=0o700) (PKI_DIR / 'ca/signing-ca/db').mkdir(parents=True, exist_ok=True) echo('2.2 Create Database') with open(PKI_DIR / 'ca/signing-ca/db/signing-ca.db', 'w') as f: pass # write empty file with open(PKI_DIR / 'ca/signing-ca/db/signing-ca.db.attr', 'w') as f: pass # write empty file with open(PKI_DIR / 'ca/signing-ca/db/signing-ca.crt.srl', 'w') as f: f.write('01') # write file with '01' with open(PKI_DIR / 'ca/signing-ca/db/signing-ca.crl.srl', 'w') as f: f.write('01') # write file with '01' echo('2.3 Create Signing Certificate CSR') signing_csr_path = 'ca/signing-ca.csr' signing_crt_path = 'ca/signing-ca.crt' signing_key_path = 'ca/signing-ca/private/signing-ca.key' signing_private_key, signing_csr = generate_signing_csr() # Write Signing CA CSR to disk with open(PKI_DIR / signing_csr_path, 'wb') as f: f.write(signing_csr.public_bytes( encoding=serialization.Encoding.PEM, )) with open(PKI_DIR / signing_key_path, "wb") as f: f.write( signing_private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.TraditionalOpenSSL, encryption_algorithm=serialization.NoEncryption())) echo('2.4 Sign Signing Certificate CSR') signing_cert = sign_certificate(signing_csr, root_private_key, root_cert.subject, ca=True) with open(PKI_DIR / signing_crt_path, 'wb') as f: f.write( signing_cert.public_bytes(encoding=serialization.Encoding.PEM, )) echo('3 Create Certificate Chain') # create certificate chain file by combining root-ca and signing-ca with open(PKI_DIR / 'cert_chain.crt', 'w') as d: with open(PKI_DIR / 'ca/root-ca.crt') as s: d.write(s.read()) with open(PKI_DIR / 'ca/signing-ca.crt') as s: d.write(s.read()) echo('\nDone.')
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")