Coverage for admin/verify_sgx_attestation.py: 96%

51 statements  

« prev     ^ index     » next       coverage.py v7.5.3, created at 2025-07-10 13:43 +0000

1# The MIT License (MIT) 

2# 

3# Copyright (c) 2021 RSK Labs Ltd 

4# 

5# Permission is hereby granted, free of charge, to any person obtaining a copy of 

6# this software and associated documentation files (the "Software"), to deal in 

7# the Software without restriction, including without limitation the rights to 

8# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 

9# of the Software, and to permit persons to whom the Software is furnished to do 

10# so, subject to the following conditions: 

11# 

12# The above copyright notice and this permission notice shall be included in all 

13# copies or substantial portions of the Software. 

14# 

15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 

16# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 

17# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 

18# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 

19# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 

20# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 

21# SOFTWARE. 

22 

23from .misc import info, head, AdminError 

24from .attestation_utils import PowHsmAttestationMessage, load_pubkeys, \ 

25 compute_pubkeys_hash, compute_pubkeys_output, \ 

26 get_root_of_trust 

27from .certificate import HSMCertificate 

28 

29 

30# ################################################################################### 

31# As default root authority, we use the Provisioning Certification Root CA from Intel 

32# The Provisioning Certification Root CA is available for download 

33# from Intel, as described here: 

34# https://api.portal.trustedservices.intel.com/content/documentation.html 

35 

36DEFAULT_ROOT_AUTHORITY = "https://certificates.trustedservices.intel.com/"\ 

37 "Intel_SGX_Provisioning_Certification_RootCA.pem" 

38 

39# ################################################################################### 

40 

41 

42def do_verify_attestation(options): 

43 head("### -> Verify powHSM attestation", fill="#") 

44 

45 if options.attestation_certificate_file_path is None: 

46 raise AdminError("No attestation certificate file given") 

47 

48 if options.pubkeys_file_path is None: 

49 raise AdminError("No public keys file given") 

50 

51 # Load root authority 

52 root_authority = options.root_authority or DEFAULT_ROOT_AUTHORITY 

53 info(f"Attempting to gather root authority from {root_authority}...") 

54 try: 

55 root_of_trust = get_root_of_trust(root_authority) 

56 info("Attempting to validate self-signed root authority...") 

57 if not root_of_trust.is_valid(root_of_trust): 

58 raise ValueError("Failed to validate self-signed root of trust") 

59 except Exception as e: 

60 raise AdminError(f"Invalid root authority {root_authority}: {e}") 

61 info(f"Using {root_authority} as root authority") 

62 

63 # Load public keys, compute their hash and format them for output 

64 try: 

65 pubkeys_map = load_pubkeys(options.pubkeys_file_path) 

66 pubkeys_hash = compute_pubkeys_hash(pubkeys_map) 

67 pubkeys_output = compute_pubkeys_output(pubkeys_map) 

68 except Exception as e: 

69 raise AdminError(str(e)) 

70 

71 # Load the given attestation key certificate 

72 try: 

73 att_cert = HSMCertificate.from_jsonfile(options.attestation_certificate_file_path) 

74 except Exception as e: 

75 raise AdminError(f"While loading the attestation certificate file: {str(e)}") 

76 

77 # Validate the certificate using the given root authority 

78 # (this should be *one of* Ledger's public keys) 

79 result = att_cert.validate_and_get_values(root_of_trust) 

80 

81 # powHSM specific validations 

82 if "quote" not in result: 

83 raise AdminError("Certificate does not contain a powHSM attestation") 

84 

85 powhsm_result = result["quote"] 

86 if not powhsm_result[0]: 

87 raise AdminError( 

88 f"Invalid powHSM attestation: error validating '{powhsm_result[1]}'") 

89 powhsm_result = powhsm_result[1] 

90 

91 sgx_quote = powhsm_result["sgx_quote"] 

92 powhsm_message = bytes.fromhex(powhsm_result["message"]) 

93 if not PowHsmAttestationMessage.is_header(powhsm_message): 

94 raise AdminError( 

95 f"Invalid powHSM attestation message header: {powhsm_message.hex()}") 

96 

97 try: 

98 powhsm_message = PowHsmAttestationMessage(powhsm_message) 

99 except Exception as e: 

100 raise AdminError(f"Error parsing powHSM attestation message: {str(e)}") 

101 reported_pubkeys_hash = powhsm_message.public_keys_hash 

102 

103 if reported_pubkeys_hash != pubkeys_hash: 

104 raise AdminError( 

105 f"powHSM attestation public keys hash mismatch: expected {pubkeys_hash.hex()}" 

106 f" but attestation reports {reported_pubkeys_hash.hex()}" 

107 ) 

108 

109 signer_info = [ 

110 f"Hash: {pubkeys_hash.hex()}", 

111 "", 

112 f"Installed powHSM MRENCLAVE: {sgx_quote.report_body.mrenclave.hex()}", 

113 f"Installed powHSM MRSIGNER: {sgx_quote.report_body.mrsigner.hex()}", 

114 f"Installed powHSM version: {powhsm_message.version}", 

115 ] 

116 

117 signer_info += [ 

118 f"Platform: {powhsm_message.platform}", 

119 f"UD value: {powhsm_message.ud_value.hex()}", 

120 f"Best block: {powhsm_message.best_block.hex()}", 

121 f"Last transaction signed: {powhsm_message.last_signed_tx.hex()}", 

122 f"Timestamp: {powhsm_message.timestamp}", 

123 ] 

124 

125 head( 

126 ["powHSM verified with public keys:"] + pubkeys_output + signer_info, 

127 fill="-", 

128 )