/* * 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.SimpleKeystore; import com.intel.dcsg.cpg.io.FileResource; 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.dcsg.cpg.x509.X509Util; import com.intel.mtwilson.client.jaxrs.PrivacyCA; import com.intel.mtwilson.configuration.Configurable; import com.intel.mtwilson.privacyca.v2.model.IdentityBlob; import com.intel.mtwilson.privacyca.v2.model.IdentityChallenge; import com.intel.mtwilson.privacyca.v2.model.IdentityChallengeRequest; import com.intel.mtwilson.privacyca.v2.model.IdentityChallengeResponse; import com.intel.mtwilson.trustagent.TrustagentConfiguration; import gov.niarl.his.privacyca.IdentityOS; import gov.niarl.his.privacyca.TpmIdentity; import gov.niarl.his.privacyca.TpmIdentityRequest; import gov.niarl.his.privacyca.TpmModule; import gov.niarl.his.privacyca.TpmPubKey; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.net.URL; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPublicKey; import java.util.HashMap; import java.util.Properties; import org.apache.commons.io.IOUtils; /** * Request AIK Certificate from Mt Wilson Privacy CA * * Pre-requisites: * Owner, SRK, and AIK secrets must already be generated and present in the * configuration; EC must have already been provisioned by ProvisionTPM * * @author jbuhacoff */ public class CreateIdentity implements Configurable, Runnable { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(CreateIdentity.class); private Configuration configuration = null; @Override public void configure(Configuration configuration) { this.configuration = configuration; } @Override public void run() { try { // load the PCA certificate TrustagentConfiguration config = new TrustagentConfiguration(configuration); SimpleKeystore keystore = new SimpleKeystore(new FileResource(config.getTrustagentKeystoreFile()), config.getTrustagentKeystorePassword()); X509Certificate privacy = keystore.getX509Certificate("privacy", SimpleKeystore.CA); // encrypt the EC using the PCA's public key byte[] ekCert = TpmModule.getCredential(config.getTpmOwnerSecret(), "EC"); TpmIdentityRequest encryptedEkCert = new TpmIdentityRequest(ekCert, (RSAPublicKey) privacy.getPublicKey(), false); // create the identity request boolean shortcut = true; String HisIdentityLabel = "HIS Identity Key"; TpmIdentity newId = TpmModule.collateIdentityRequest(config.getTpmOwnerSecret(), config.getAikSecret(), HisIdentityLabel, new TpmPubKey((RSAPublicKey) privacy.getPublicKey(), 3, 1).toByteArray(), config.getAikIndex(), (X509Certificate) null, !shortcut); // TpmKey aik = new TpmKey(newId.getAikBlob()); // HttpsURLConnection.setDefaultHostnameVerifier((new InsecureTlsPolicy()).getHostnameVerifier()); 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()); // send the identity request to the privacy ca to get a challenge PrivacyCA client = new PrivacyCA(clientConfiguration, tlsConnection); IdentityChallengeRequest request = new IdentityChallengeRequest(); request.setEndorsementCertificate(encryptedEkCert.toByteArray()); request.setIdentityRequest(newId.getIdentityRequest()); IdentityChallenge identityChallenge = client.identityChallengeRequest(request); byte[] challenge = identityChallenge.getIdentityChallenge(); // answer the challenge int os = IdentityOS.osType();//return os type. win:0; linux:1; other:-1 byte[] asym1 = new byte[256]; System.arraycopy(challenge, 0, asym1, 0, asym1.length); byte[] sym1 = new byte[challenge.length - 256]; System.arraycopy(challenge, 256, sym1, 0, sym1.length); byte[] decrypted1; if (os == 1) {//linux //decrypted1 = TpmModule.activateIdentity(ownerAuthRaw, keyAuthRaw, asym1, sym1, HisIdentityIndex); HashMap<String, byte[]> results = TpmModule.activateIdentity2(config.getTpmOwnerSecret(), config.getAikSecret(), asym1, sym1, config.getAikIndex()); decrypted1 = results.get("aikcert"); } else //decrypted1 = TpmModuleJava.ActivateIdentity(asym1, sym1, aik, keyAuthRaw, srkAuthRaw, ownerAuthRaw); //Comments temporarily due to TSSCoreService.jar compiling issue { decrypted1 = TpmModule.activateIdentity(config.getTpmOwnerSecret(), config.getAikSecret(), asym1, sym1, config.getAikIndex()); } // send the answer and receive the AIK certificate TpmIdentityRequest encryptedChallenge = new TpmIdentityRequest(decrypted1, (RSAPublicKey) privacy.getPublicKey(), false); System.err.println("Create Identity... Calling into HisPriv second time, size of msg = " + encryptedChallenge.toByteArray().length); IdentityChallengeResponse identityChallengeResponse = new IdentityChallengeResponse(); identityChallengeResponse.setChallengeResponse(encryptedChallenge.toByteArray()); IdentityBlob identityBlob = client.identityChallengeResponse(identityChallengeResponse); byte[] encrypted2 = identityBlob.getIdentityBlob(); // decode and store the aik certificate byte[] asym2 = new byte[256]; System.arraycopy(encrypted2, 0, asym2, 0, asym2.length); byte[] sym2 = new byte[encrypted2.length - 256]; System.arraycopy(encrypted2, 256, sym2, 0, sym2.length); byte[] decrypted2; byte[] aikblob; String aikcertfilepath = config.getAikCertificateFile().getAbsolutePath(); String aikblobfilepath = config.getAikBlobFile().getAbsolutePath(); if (os == 1) {//linux HashMap<String, byte[]> results = TpmModule.activateIdentity2(config.getTpmOwnerSecret(), config.getAikSecret(), asym2, sym2, config.getAikIndex()); System.out.println(results); decrypted2 = results.get("aikcert"); aikblob = results.get("aikblob"); writecert(aikcertfilepath, decrypted2); writeblob(aikblobfilepath, aikblob); Runtime.getRuntime().exec("chmod 600 " + aikblobfilepath); } else { //decrypted1 = TpmModuleJava.ActivateIdentity(asym1, sym1, aik, keyAuthRaw, srkAuthRaw, ownerAuthRaw); //decrypted2 = TpmModuleJava.ActivateIdentity(asym2, sym2, aik, keyAuthRaw, srkAuthRaw, ownerAuthRaw);//Comments temporarily due to TSSCoreService.jar compiling issue decrypted2 = TpmModule.activateIdentity(config.getTpmOwnerSecret(), config.getAikSecret(), asym2, sym2, config.getAikIndex()); writecert(aikcertfilepath, decrypted2); } } catch(Exception e) { throw new RuntimeException(e); } } // issue #878 private static void writecert(String absoluteFilePath, byte[] certificateBytes) throws FileNotFoundException, java.security.cert.CertificateException, IOException { File file = new File(absoluteFilePath); mkdir(file); // ensure the parent directory exists X509Certificate certificate = X509Util.decodeDerCertificate(certificateBytes); // throws CertificateException String certificatePem = X509Util.encodePemCertificate(certificate); try(FileOutputStream out = new FileOutputStream(file)) { // throws FileNotFoundException IOUtils.write(certificatePem, out); // throws IOException } } // issue #878 // given a File, ensures that its parent directory exists, creating it if necessary, and throwing PrivacyCAException // if there is a failure private static void mkdir(File file) throws IOException { if (!file.getParentFile().isDirectory()) { if (!file.getParentFile().mkdirs()) { log.warn("Failed to create client installation path!"); throw new IOException("Failed to create client installation path!"); } } } // issue #878 private static void writeblob(String absoluteFilePath, byte[] encryptedBytes) throws IOException { File file = new File(absoluteFilePath); mkdir(file); // ensure the parent directory exists try(FileOutputStream out = new FileOutputStream(file)) { // throws FileNotFoundException IOUtils.write(encryptedBytes, out); // throws IOException } } }