diff --git a/openfl/cryptography/io.py b/openfl/cryptography/io.py index b9ffce917f..ec7473fa10 100644 --- a/openfl/cryptography/io.py +++ b/openfl/cryptography/io.py @@ -111,3 +111,21 @@ def read_csr(path: Path) -> Tuple[CertificateSigningRequest, str]: # TODO: replace assert with exception / sys.exit assert (isinstance(csr, x509.CertificateSigningRequest)) return csr, hasher.hexdigest() + + +def get_csr_hash(certificate: CertificateSigningRequest) -> str: + """ + Get hash of cryptography certificate. + + Args: + certificate : Cryptography CSR object + + Returns: + Hash of cryptography certificate / csr + """ + hasher = sha384() + encoded_bytes = certificate.public_bytes( + encoding=serialization.Encoding.PEM, + ) + hasher.update(encoded_bytes) + return hasher.hexdigest() diff --git a/openfl/interface/aggregator.py b/openfl/interface/aggregator.py index 8aadaab73a..02f920b229 100644 --- a/openfl/interface/aggregator.py +++ b/openfl/interface/aggregator.py @@ -71,6 +71,7 @@ def generate_cert_request(fqdn): from openfl.cryptography.participant import generate_csr from openfl.cryptography.io import write_crt from openfl.cryptography.io import write_key + from openfl.cryptography.io import get_csr_hash from openfl.interface.cli_helper import CERT_DIR if fqdn is None: @@ -91,6 +92,10 @@ def generate_cert_request(fqdn): echo(' Writing AGGREGATOR certificate key pair to: ' + style( f'{CERT_DIR}/server', fg='green')) + # Print csr hash before writing csr to disk + csr_hash = get_csr_hash(server_csr) + echo('The CSR Hash ' + style(f'{csr_hash}', fg='red')) + # Write aggregator csr and key to disk write_crt(server_csr, CERT_DIR / 'server' / f'{file_name}.csr') write_key(server_private_key, CERT_DIR / 'server' / f'{file_name}.key') @@ -175,6 +180,7 @@ def certify(fqdn, silent): if silent: + echo(' Warning: manual check of certificate hashes is bypassed in silent mode.') echo(' Signing AGGREGATOR certificate') signed_agg_cert = sign_certificate(csr, signing_key, signing_crt.subject) write_crt(signed_agg_cert, crt_path_absolute_path) @@ -183,6 +189,7 @@ def certify(fqdn, silent): if confirm('Do you want to sign this certificate?'): + echo('Make sure the two hashes above are the same.') echo(' Signing AGGREGATOR certificate') signed_agg_cert = sign_certificate(csr, signing_key, signing_crt.subject) write_crt(signed_agg_cert, crt_path_absolute_path) diff --git a/openfl/interface/collaborator.py b/openfl/interface/collaborator.py index a0c25b73d8..bc20ce0d7e 100644 --- a/openfl/interface/collaborator.py +++ b/openfl/interface/collaborator.py @@ -135,6 +135,7 @@ def generate_cert_request(collaborator_name, data_path, silent, skip_package): from openfl.cryptography.participant import generate_csr from openfl.cryptography.io import write_crt from openfl.cryptography.io import write_key + from openfl.cryptography.io import get_csr_hash from openfl.interface.cli_helper import CERT_DIR common_name = f'{collaborator_name}'.lower() @@ -152,6 +153,10 @@ def generate_cert_request(collaborator_name, data_path, silent, skip_package): echo(' Moving COLLABORATOR certificate to: ' + style( f'{CERT_DIR}/{file_name}', fg='green')) + # Print csr hash before writing csr to disk + csr_hash = get_csr_hash(client_csr) + echo('The CSR Hash ' + style(f'{csr_hash}', fg='red')) + # Write collaborator csr and key to disk write_crt(client_csr, CERT_DIR / 'client' / f'{file_name}.csr') write_key(client_private_key, CERT_DIR / 'client' / f'{file_name}.key') @@ -341,12 +346,14 @@ def certify(collaborator_name, silent, request_pkg=None, import_=False): if silent: echo(' Signing COLLABORATOR certificate') + echo(' Warning: manual check of certificate hashes is bypassed in silent mode.') signed_col_cert = sign_certificate(csr, signing_key, signing_crt.subject) write_crt(signed_col_cert, f'{cert_name}.crt') register_collaborator(CERT_DIR / 'client' / f'{file_name}.crt') else: + echo('Make sure the two hashes above are the same.') if confirm('Do you want to sign this certificate?'): echo(' Signing COLLABORATOR certificate')