package adt.mainnode.service; //FUNCTIONALITY import lombok.*; import lombok.extern.slf4j.Slf4j; import java.io.*; import org.springframework.stereotype.Service; import org.springframework.beans.factory.annotation.Autowired; import org.apache.commons.codec.digest.DigestUtils; import java.util.List; //ENTITIES import adt.mainnode.entity.TPMHash; import adt.mainnode.entity.Credentials; //REPOSITORIES import adt.mainnode.repository.TPMHashRepository; import adt.mainnode.repository.CredentialsRepository; //SERVICES import adt.mainnode.service.InitializeService; import adt.mainnode.service.FileHashingService; @Service @Slf4j public class TPMValidationService { private final InitializeService initializeService; private final FileHashingService fileHashingService; private final TPMHashRepository tpmHashRepository; private final CredentialsRepository credentialsRepository; @Getter @Setter String tpm_executableHash; @Getter @Setter String tpm_pcrHash; @Autowired public TPMValidationService(InitializeService initializeService, FileHashingService fileHashingService, TPMHashRepository tpmHashRepository, CredentialsRepository credentialsRepository) { this.initializeService = initializeService; this.fileHashingService = fileHashingService; this.tpmHashRepository = tpmHashRepository; this.credentialsRepository = credentialsRepository; } public boolean verify_executableHash() { String tpm_executableHash = null; try { tpm_executableHash = fileHashingService.getMD5Checksum("./usr/local/sbin/tpm2_listpcrs"); TPMHash tpmHash = TPMHash.createTPMHash(tpm_executableHash); List stored = tpmHashRepository.findAll(); if (stored.size() == 0) { //(this.tpm_executableHash == null) { log.info("FIRST ADT MAIN NODE execution. Storing tpm's executable hash..."); this.tpm_executableHash = tpm_executableHash; tpmHashRepository.save(tpmHash); return true; } else { this.tpm_executableHash = stored.get(0).getHash(); log.info("Validating TPM's executable hash against {}...", this.tpm_executableHash); if (this.tpm_executableHash.equals(tpm_executableHash)) { log.info("Successful TPM validation."); return true; } else { log.warn("[POTENTIAL VULNERABILITY] Failed TPM validation. Available tokens will now be disabled."); List allCreds = credentialsRepository.findAll(); for(int i= 0; i < allCreds.size(); i++){ String currentHash = allCreds.get(i).getPcrToken(); log.warn("[POTENTIAL VULNERABILITY] PCR matching failed. Available tokens will now be disabled."); allCreds.get(i).setStatus("INVALID"); credentialsRepository.saveAll(allCreds); } return false; } } } catch (Throwable t) { t.printStackTrace(); } return false; } public boolean verify_pcrHash() { try { String target = new String("tpm2_listpcrs --algorithm 0x0004"); log.info("Accessing and storing PCRs..."); Runtime rt = Runtime.getRuntime(); Process proc = rt.exec(target); int exitCode = proc.waitFor(); BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream())); String line = ""; String pcr_concat = ""; int pcr_ctr = 0; while (line != null && pcr_ctr <= 7) { // RE-DO if(line.contains("PCR_")) { String[] sep = line.split(":"); if(sep.length == 2){ pcr_concat += sep[1]; } pcr_ctr++; } line = reader.readLine(); } String pcr_hash = DigestUtils.sha256Hex(pcr_concat); this.tpm_pcrHash = pcr_hash; List allCreds = credentialsRepository.findAll(); boolean flag = true; for(int i= 0; i < allCreds.size(); i++){ String currentHash = allCreds.get(i).getPcrToken(); if( DigestUtils.sha256Hex( allCreds.get(i).getToken() + this.tpm_pcrHash ).equals(currentHash) ){ log.info("PCR matching successfully validated"); flag = true; }else{ log.warn("[POTENTIAL VULNERABILITY] PCR matching failed. Available tokens will now be disabled."); allCreds.get(i).setStatus("INVALID"); credentialsRepository.saveAll(allCreds); flag = false; } } // AT THIS POINT, NO CREDENTIALS WOULD BE REGISTERED AND NO MATCHING COULD BE PERFORMED return flag; } catch (Throwable t) { t.printStackTrace(); } return false; } }