From 9ad15140b15371a737d0ffea3a3645354cd5e52c Mon Sep 17 00:00:00 2001 From: Grant Baker Date: Thu, 27 Apr 2023 12:52:34 -0700 Subject: [PATCH] This prints out the hash of the CSR to disk for both the aggregator and collaborator. The user then compares and approves this hash with the hash printed out of the file to validate the CSR. In addition, a warning message is pritned if certify is run in silent mode. Fixes securefederatedai#692 Signed-off-by: Grant Baker --- openfl/cryptography/io.py | 18 ++++++++++++++++++ openfl/interface/aggregator.py | 7 +++++++ openfl/interface/collaborator.py | 7 +++++++ 3 files changed, 32 insertions(+) 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')