def test_signature_verification(self): """ Test the signature verification """ curdir = os.path.dirname(os.path.abspath(__file__)) keydir = os.path.join(curdir, "data", "ima_keys") lines = SIGNATURES.split('\n') # empty keyring keyring = ima_file_signatures.ImaKeyring() self.assertTrue( ima.process_measurement_list(lines, ima_keyring=keyring) is None) # add key for 1st entry; 1st entry must be verifiable rsakeyfile = os.path.join(keydir, "rsa2048pub.pem") pubkey = ima_file_signatures.get_pubkey_from_file(rsakeyfile) keyring.add_pubkey(pubkey) self.assertTrue( ima.process_measurement_list(lines[0:1], ima_keyring=keyring) is not None) self.assertTrue( ima.process_measurement_list(lines[1:2], ima_keyring=keyring) is None) # add key for 2nd entry; 1st & 2nd entries must be verifiable eckeyfile = os.path.join(keydir, "secp256k1.pem") pubkey = ima_file_signatures.get_pubkey_from_file(eckeyfile) keyring.add_pubkey(pubkey) self.assertTrue( ima.process_measurement_list(lines[0:2], ima_keyring=keyring) is not None)
def test_mixed_verfication(self): """ Test verification using allowlist and keys """ lists_map = ima.process_allowlists(ALLOWLIST.splitlines(), '') # every entry is covered by the allowlist and there's no keyring -> this should pass self.assertTrue( ima.process_measurement_list(COMBINED.splitlines(), str(lists_map)) is not None) curdir = os.path.dirname(os.path.abspath(__file__)) keydir = os.path.join(curdir, "data", "ima_keys") keyring = ima_file_signatures.ImaKeyring() rsakeyfile = os.path.join(keydir, "rsa2048pub.pem") pubkey = ima_file_signatures.get_pubkey_from_file(rsakeyfile) keyring.add_pubkey(pubkey) eckeyfile = os.path.join(keydir, "secp256k1.pem") pubkey = ima_file_signatures.get_pubkey_from_file(eckeyfile) keyring.add_pubkey(pubkey) # entries are not covered by a exclude list -> this should fail self.assertTrue( ima.process_measurement_list(COMBINED.splitlines(), ima_keyring=keyring) is None) # all entries are either covered by exclude list or by signature verification -> this should pass self.assertTrue( ima.process_measurement_list(COMBINED.splitlines(), str(lists_map), ima_keyring=keyring) is not None)
def test_measurment_verification(self): """ Test IMA measurement list verification """ lines = MEASUREMENTS.splitlines() lists_map = ima.process_allowlists(ALLOWLIST, '') self.assertTrue( ima.process_measurement_list(lines, lists_map) is not None) # test with list as a string self.assertTrue( ima.process_measurement_list(lines, str(lists_map)) is not None)
def test_ima_buf_verification(self): """ The verification of ima-buf entries supporting keys loaded onto keyrings """ list_map = ima.process_allowlists(ALLOWLIST, '') self.assertTrue( ima.process_measurement_list(AgentAttestState( '1'), KEYRINGS.splitlines(), str(list_map)) is not None)
def __check_ima(self, agent_id, pcrval, ima_measurement_list, allowlist, ima_keyring): logger.info(f"Checking IMA measurement list on agent: {agent_id}") if config.STUB_IMA: pcrval = None ex_value = ima.process_measurement_list(ima_measurement_list.split('\n'), allowlist, pcrval=pcrval, ima_keyring=ima_keyring) if ex_value is None: return False logger.debug(f"IMA measurement list of agent {agent_id} validated") return True
def __check_ima(self, agent_id, pcrval, ima_measurement_list, ima_whitelist): logger.info(f"Checking IMA measurement list on agent: {agent_id}") ex_value = ima.process_measurement_list(ima_measurement_list.split('\n'), ima_whitelist) if ex_value is None: return False if pcrval != ex_value and not common.STUB_IMA: logger.error("IMA measurement list expected pcr value %s does not match TPM PCR %s"%(ex_value, pcrval)) return False logger.debug(f"IMA measurement list of agent {agent_id} validated") return True
def test_ima_buf_verification(self): """ The verification of ima-buf entries supporting keys loaded onto keyrings """ list_map = ima.process_allowlists(ALLOWLIST, '') ima_keyrings = ima_file_signatures.ImaKeyrings() self.assertTrue( ima.process_measurement_list(AgentAttestState('1'), KEYRINGS.splitlines(), json.dumps(list_map), ima_keyrings=ima_keyrings) is not None)
def test_iterative_attestation(self): """ Test that the resulting pcr value is as expected by subsequently feeding a measurement list. The AgentAtestState() will maintain the state of PCR 10. """ lines = MEASUREMENTS.splitlines() agentAttestState = AgentAttestState('1') running_hash = agentAttestState.get_pcr_state(10) for line in lines: parts = line.split(' ') template_hash = codecs.decode(parts[1].encode("utf-8"), "hex") running_hash = hashlib.sha1(running_hash + template_hash).digest() pcrval = codecs.encode(running_hash, "hex").decode("utf-8") self.assertTrue( ima.process_measurement_list(agentAttestState, [line], pcrval=pcrval) == pcrval) # Feed empty iterative measurement list simulating 'no new measurement list entries' on attested system self.assertTrue( ima.process_measurement_list(agentAttestState, [''], pcrval=pcrval) == pcrval)
def test_signature_verification(self): """ Test the signature verification """ curdir = os.path.dirname(os.path.abspath(__file__)) keydir = os.path.join(curdir, "data", "ima_keys") lines = SIGNATURES.split('\n') # empty keyring keyrings = ima_file_signatures.ImaKeyrings() _, failure = ima.process_measurement_list(AgentAttestState('1'), lines, ima_keyrings=keyrings) self.assertTrue(failure) tenant_keyring = ima_file_signatures.ImaKeyring() keyrings.set_tenant_keyring(tenant_keyring) # add key for 1st entry; 1st entry must be verifiable rsakeyfile = os.path.join(keydir, "rsa2048pub.pem") pubkey, keyidv2 = ima_file_signatures.get_pubkey_from_file(rsakeyfile) tenant_keyring.add_pubkey(pubkey, keyidv2) _, failure = ima.process_measurement_list(AgentAttestState('1'), lines[0:1], ima_keyrings=keyrings) self.assertTrue(not failure) _, failure = ima.process_measurement_list(AgentAttestState('1'), lines[1:2], ima_keyrings=keyrings) self.assertTrue(failure) # add key for 2nd entry; 1st & 2nd entries must be verifiable eckeyfile = os.path.join(keydir, "secp256k1.pem") pubkey, keyidv2 = ima_file_signatures.get_pubkey_from_file(eckeyfile) tenant_keyring.add_pubkey(pubkey, keyidv2) _, failure = ima.process_measurement_list(AgentAttestState('1'), lines[0:2], ima_keyrings=keyrings) self.assertTrue(not failure)
def test_measurment_verification(self): """ Test IMA measurement list verification """ lines = MEASUREMENTS.splitlines() lists_map = ima.process_allowlists(ALLOWLIST, '') lists_map_empty = ima.process_allowlists(ALLOWLIST_EMPTY, '') _, failure = ima.process_measurement_list(AgentAttestState('1'), lines) self.assertTrue( not failure, "Validation should always work when no allowlist and no keyring is specified" ) _, failure = ima.process_measurement_list(AgentAttestState('1'), lines, lists_map) self.assertTrue(not failure) # test with list with JSON _, failure = ima.process_measurement_list(AgentAttestState('1'), lines, json.dumps(lists_map)) self.assertTrue(not failure) # No files are in the allowlist -> this should fail _, failure = ima.process_measurement_list(AgentAttestState('1'), lines, lists_map_empty) self.assertTrue(failure)
def test_measurment_verification(self): """ Test IMA measurement list verification """ lines = MEASUREMENTS.splitlines() lists_map = ima.process_allowlists(ALLOWLIST, '') lists_map_empty = ima.process_allowlists(ALLOWLIST_EMPTY, '') self.assertTrue( ima.process_measurement_list(AgentAttestState('1'), lines) is not None, "Validation should always work when no allowlist and no keyring is specified" ) self.assertTrue( ima.process_measurement_list(AgentAttestState('1'), lines, lists_map) is not None) # test with list as a string self.assertTrue( ima.process_measurement_list(AgentAttestState('1'), lines, str(lists_map)) is not None) # No files are in the allowlist -> this should fail self.assertTrue( ima.process_measurement_list(AgentAttestState('1'), lines, lists_map_empty) is None)
def __check_ima(self, agentAttestState, pcrval, ima_measurement_list, allowlist, ima_keyring, boot_aggregates): logger.info("Checking IMA measurement list on agent: %s", agentAttestState.get_agent_id()) if config.STUB_IMA: pcrval = None ex_value = ima.process_measurement_list( agentAttestState, ima_measurement_list.split('\n'), allowlist, pcrval=pcrval, ima_keyring=ima_keyring, boot_aggregates=boot_aggregates) if ex_value is None: return False logger.debug("IMA measurement list of agent %s validated", agentAttestState.get_agent_id()) return True
def __check_ima(agentAttestState, pcrval, ima_measurement_list, allowlist, ima_keyrings, boot_aggregates, hash_alg): failure = Failure(Component.IMA) logger.info("Checking IMA measurement list on agent: %s", agentAttestState.get_agent_id()) if config.STUB_IMA: pcrval = None _, ima_failure = ima.process_measurement_list( agentAttestState, ima_measurement_list.split('\n'), allowlist, pcrval=pcrval, ima_keyrings=ima_keyrings, boot_aggregates=boot_aggregates, hash_alg=hash_alg) failure.merge(ima_failure) if not failure: logger.debug("IMA measurement list of agent %s validated", agentAttestState.get_agent_id()) return failure
def test_mixed_verfication(self): """ Test verification using allowlist and keys """ lists_map = ima.process_allowlists(ALLOWLIST, '') lists_map_wrong = ima.process_allowlists(ALLOWLIST_WRONG, '') lists_map_empty = ima.process_allowlists(ALLOWLIST_EMPTY, '') lists_map_exclude = ima.process_allowlists(ALLOWLIST, EXCLUDELIST) lists_map_exclude_wrong = ima.process_allowlists( ALLOWLIST_WRONG, EXCLUDELIST) ima_keyrings = ima_file_signatures.ImaKeyrings() empty_keyring = ima_file_signatures.ImaKeyring() # every entry is covered by the allowlist and there's no keyring -> this should pass _, failure = ima.process_measurement_list(AgentAttestState('1'), COMBINED.splitlines(), json.dumps(lists_map)) self.assertTrue(not failure) curdir = os.path.dirname(os.path.abspath(__file__)) keydir = os.path.join(curdir, "data", "ima_keys") tenant_keyring = ima_file_signatures.ImaKeyring() rsakeyfile = os.path.join(keydir, "rsa2048pub.pem") pubkey, keyidv2 = ima_file_signatures.get_pubkey_from_file(rsakeyfile) tenant_keyring.add_pubkey(pubkey, keyidv2) eckeyfile = os.path.join(keydir, "secp256k1.pem") pubkey, keyidv2 = ima_file_signatures.get_pubkey_from_file(eckeyfile) tenant_keyring.add_pubkey(pubkey, keyidv2) ima_keyrings.set_tenant_keyring(tenant_keyring) # entries are not covered by a exclude list -> this should fail _, failure = ima.process_measurement_list(AgentAttestState('1'), COMBINED.splitlines(), ima_keyrings=ima_keyrings) self.assertTrue(failure) # all entries are either covered by allow list or by signature verification -> this should pass _, failure = ima.process_measurement_list(AgentAttestState('1'), COMBINED.splitlines(), json.dumps(lists_map), ima_keyrings=ima_keyrings) self.assertTrue(not failure) # the signature is valid but the hash in the allowlist is wrong -> this should fail _, failure = ima.process_measurement_list(AgentAttestState('1'), SIGNATURES.splitlines(), json.dumps(lists_map_wrong), ima_keyrings=ima_keyrings) self.assertTrue(failure) # the signature is valid and the file is not in the allowlist -> this should pass _, failure = ima.process_measurement_list(AgentAttestState('1'), SIGNATURES.splitlines(), json.dumps(lists_map_empty), ima_keyrings=ima_keyrings) self.assertTrue(not failure) # the signature is invalid but the correct hash is in the allowlist -> this should fail ima_keyrings.set_tenant_keyring(empty_keyring) _, failure = ima.process_measurement_list(AgentAttestState('1'), SIGNATURES.splitlines(), json.dumps(lists_map), ima_keyrings=ima_keyrings) self.assertTrue(failure) # the file has no signature but the hash is correct -> this should pass _, failure = ima.process_measurement_list(AgentAttestState('1'), MEASUREMENTS.splitlines(), json.dumps(lists_map)) self.assertTrue(not failure) # All files are in the exclude list but hashes are invalid -> this should pass _, failure = ima.process_measurement_list( AgentAttestState('1'), MEASUREMENTS.splitlines(), json.dumps(lists_map_exclude_wrong)) self.assertTrue(not failure) # All files are in the exclude list and their signatures are invalid -> this should pass ima_keyrings.set_tenant_keyring(tenant_keyring) _, failure = ima.process_measurement_list( AgentAttestState('1'), SIGNATURES.splitlines(), json.dumps(lists_map_exclude), ima_keyrings=ima_keyrings) self.assertTrue(not failure) # All files are in the exclude list but hashes or signatures are invalid -> this should pass _, failure = ima.process_measurement_list( AgentAttestState('1'), MEASUREMENTS.splitlines(), json.dumps(lists_map_exclude_wrong), ima_keyrings=ima_keyrings) self.assertTrue(not failure)