/* * Copyright (C) 2014 Intel Corporation * All rights reserved. */ package com.intel.mtwilson.trustagent.niarl; import com.intel.dcsg.cpg.configuration.Configuration; import com.intel.dcsg.cpg.crypto.Sha1Digest; import com.intel.dcsg.cpg.tls.policy.TlsConnection; import com.intel.dcsg.cpg.tls.policy.TlsPolicy; import com.intel.dcsg.cpg.tls.policy.TlsPolicyBuilder; import com.intel.mtwilson.client.jaxrs.PrivacyCA; import com.intel.mtwilson.configuration.Configurable; import com.intel.mtwilson.trustagent.TrustagentConfiguration; import gov.niarl.his.privacyca.TpmModule; import gov.niarl.his.privacyca.TpmUtils; import java.net.URL; import java.security.cert.X509Certificate; import java.util.Properties; /** * Take ownership * Request EC from Mt Wilson Privacy CA * * Pre-requisites: * TPM Owner Secret and TPM SRK Secret must already be configured * (whether newly generated for taking ownership or previously generated for * existing TPM owner) * * NOTE: * TSS_TPMSTATUS_CEKP_USED can be used to determine if the EK is the original * manufacturer EK or a locally generated one using Tspi_TPM_CreateEndorsementKey * * * @author jbuhacoff */ public class ProvisionTPM implements Configurable, Runnable { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ProvisionTPM.class); private Configuration configuration = null; @Override public void configure(Configuration configuration) { this.configuration = configuration; } @Override public void run() { try { TrustagentConfiguration config = new TrustagentConfiguration(configuration); /* * The following actions must be performed during the TPM Provisioning process: * 1. Take ownership of the TPM * - owner auth * 2. Create an Endorsement Certificate (EC) * - public EK * - owner auth (should already have from above) * - private key and cert for CA to create new cert * - validity period of EC cert * 3. Store the newly created EC in the TPM's NV-RAM */ // Take Ownership - we expect either the tpm to be cleared so we can // take ownership usng the configured tpm owner secret, or for // the tpm to already be owned (we'll get error code #4) with the // secret we know so we can continue byte [] nonce1 = TpmUtils.createRandomBytes(20); try { TpmModule.takeOwnership(config.getTpmOwnerSecret(), nonce1); } catch (TpmModule.TpmModuleException e){ if( e.getErrorCode() != null && e.getErrorCode() == 4 ) { log.debug("Ownership is already taken"); /* if( !System.getProperty("forceCreateEk", "false").equals("true") ) { // feature to help with bug #554 and allow admin to force creating an ek (in case it failed the first time due to a non-tpm error such as java missing classes exception return; } */ } else { throw e; } } // Create Endorsement Certificate byte[] nonce2 = TpmUtils.createRandomBytes(20); log.debug("Nonce: {}", TpmUtils.byteArrayToHexString(nonce2)); try { byte [] pubEkMod = TpmModule.getEndorsementKeyModulus(config.getTpmOwnerSecret(), nonce2); log.debug("Public EK Modulus: {}", TpmUtils.byteArrayToHexString(pubEkMod)); log.debug("Requesting TPM endorsement from Privacy CA"); // send the public endorsement key modulus to the privacy ca and receive the endorsement certificate TlsPolicy tlsPolicy = TlsPolicyBuilder.factory().strictWithKeystore(config.getTrustagentKeystoreFile(), config.getTrustagentKeystorePassword()).build(); TlsConnection tlsConnection = new TlsConnection(new URL(config.getMtWilsonApiUrl()), tlsPolicy); Properties clientConfiguration = new Properties(); clientConfiguration.setProperty(TrustagentConfiguration.MTWILSON_API_USERNAME, config.getMtWilsonApiUsername()); clientConfiguration.setProperty(TrustagentConfiguration.MTWILSON_API_PASSWORD, config.getMtWilsonApiPassword()); PrivacyCA pcaClient = new PrivacyCA(clientConfiguration, tlsConnection); X509Certificate ekCert = pcaClient.endorseTpm(pubEkMod); log.debug("Received EC {}", Sha1Digest.digestOf(ekCert.getEncoded()).toHexString()); // write the EC to the TPM NVRAM TpmModule.setCredential(config.getTpmOwnerSecret(), "EC", ekCert.getEncoded()); } catch (TpmModule.TpmModuleException e){ log.error("Error getting EC: {}", e.getMessage()); throw e; } } catch(Exception e) { log.error("Error provisioning TPM: {}", e.getMessage()); throw new RuntimeException(e); } } }