cvm-attestation/attest.py (94 lines of code) (raw):

# Copyright (c) Microsoft Corporation. # Licensed under the MIT license. import json import click import hashlib from AttestationClient import AttestationClient, AttestationClientParameters, Verifier from src.Isolation import IsolationType from src.Logger import Logger from urllib.parse import urlparse from src.EndpointSelector import EndpointSelector import os def parse_config_file(filename): with open(filename, 'r') as json_file: return json.load(json_file) IsolationTypeLookup = { 'maa_tdx': IsolationType.TDX, 'maa_snp': IsolationType.SEV_SNP, 'ita': IsolationType.TDX, 'default': IsolationType.UNDEFINED } AttestationProviderLookup = { 'maa_tdx': Verifier.MAA, 'maa_snp': Verifier.MAA, 'ita': Verifier.ITA, 'default': Verifier.UNDEFINED } ATTESTATION_METHODS = { "guest": "attest_guest", "platform": "attest_platform" } class AttestException(Exception): pass def get_endpoint(logger, isolation_type: IsolationType, attestation_type: str): """ Get the base URL for the attestation endpoint based on the region. """ current_dir = os.getcwd() filename = 'attestation_uri_table.json' endpoint_file_path = os.path.join(current_dir, filename) endpoint_selector = EndpointSelector(endpoint_file_path, logger) return endpoint_selector.get_attestation_endpoint(isolation_type, attestation_type) @click.command() @click.option( '--c', type=str, required=True, help = 'Config json file', ) @click.option( '--t', type=click.Choice(['Guest', 'Platform'], case_sensitive=False), default='Platform', help='Attestation type: Guest or Platform (Default)' ) @click.option('--s', is_flag=True, help="Save hardware evidence to files.") def attest(c, t, s): # create a new console logger logger = Logger('logger').get_logger() logger.info("Attestation started...") logger.info(f"Reading config file: {c}") attestation_type = t attestation_type = attestation_type.lower() # creates an attestation parameters based on user's config config_json = parse_config_file(c) provider_tag = config_json.get('attestation_provider', None) endpoint = config_json.get('attestation_url', None) api_key = config_json.get('api_key', None) claims = config_json.get('claims', None) logger.info("Attestation tool configuration:") logger.info(f"provider_tag: {provider_tag}") logger.info(f"api_key: {api_key}") logger.info(f"claims: {claims}") isolation_type = IsolationTypeLookup.get(provider_tag, IsolationTypeLookup['default']) endpoint = get_endpoint(logger, isolation_type, attestation_type) logger.info(f"Attestation endpoint: {endpoint}") # Log SHA512 of user provided claims hash_object = hashlib.sha512(json.dumps(claims).encode('utf-8')) hex_dig = hash_object.hexdigest() logger.info(f"SHA512 of user provided claims: {hex_dig.upper()}") # Build attestation client parameters provider = AttestationProviderLookup.get(provider_tag, AttestationProviderLookup['default']) client_parameters = AttestationClientParameters(endpoint, provider, isolation_type, claims, api_key) # Attest based on user configuration attestation_client = AttestationClient(logger, client_parameters) if attestation_type in ATTESTATION_METHODS: method_name = ATTESTATION_METHODS[attestation_type] token = getattr(attestation_client, method_name)() else: raise AttestException(f"Invalid parameter for attestation type: '{attestation_type}'. \ Supported types: {', '.join(ATTESTATION_METHODS.keys())}") # Store hardware report and runtime data to files if the save flag is specified if s: # get the hardware evidence obtained by the attstation client hardware_evidence = attestation_client.get_hardware_evidence() hardware_report = hardware_evidence.hardware_report runtime_data = hardware_evidence.runtime_data # Store hardware report file_path = 'report.bin' with open(file_path, 'wb') as file: file.write(hardware_report) logger.info(f"Output successfully written to: {file_path}") # Stores the runtime data in a json file json_data = json.loads(runtime_data) with open('runtime_data.json', 'w') as file: json.dump(json_data, file, indent=2) logger.info(f"Output successfully written to: 'runtime_data.json'") if __name__ == "__main__": attest()