int respondToClientBySendingAGeneratedDirectoryList(struct AmmServer_Instance * instance,struct HTTPTransaction * transaction,char * servefile) { // We need to generate and serve a directory listing..! strncpy(servefile,instance->webserver_root,MAX_FILE_PATH); strncat(servefile,transaction->incomingHeader.resource,MAX_FILE_PATH); ReducePathSlashes_Inplace(servefile); unsigned long sendSize = 0; char * replyBody = GenerateDirectoryPage(servefile,transaction->incomingHeader.resource,&sendSize); if (replyBody !=0) { //If Directory_listing enabled and directory is ok , send the generated site SendMemoryBlockAsFile(instance,"dir.html",transaction,replyBody ,sendSize); if (replyBody !=0) { safeFree(replyBody,sendSize /*It just cleans the populated part of the buffer*/); } logSuccess(instance,transaction,200,servefile); } else { //If Directory listing disabled or directory is not ok send a 404 SendErrorFile(instance,transaction,404); logError(instance,transaction,404,servefile); return 0; } return 1; }
void startTimer(){ #if !(PI_DEBUG_LEVEL & PI_DEBUG_TIMER) disableLog(); #endif logLevel("Starting timer"); logChild("Unblocking signal"); if(sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1) logError("Unblocking failed"); logSuccess("Signal Unblocked"); logChild("Setting timer time"); if(timer_settime(timer_ID, 0, &its, NULL) == -1) logError("Timer interval set failed"); logSuccess("Timer interval set"); #if !(PI_DEBUG_LEVEL & PI_DEBUG_TIMER) enableLog(); #endif }
void createTimer(int interval_ms, timer_call call) { #if !(PI_DEBUG_LEVEL & PI_DEBUG_TIMER) disableLog(); #endif timerCall = call; logLevel("Creating timer"); logChild("Creating sigaction"); struct sigaction sa; sa.sa_flags = SA_SIGINFO; sa.sa_sigaction = handler; sigemptyset(&sa.sa_mask); if(sigaction(SIG, &sa, NULL) == -1) logError("sigaction failed"); logSuccess("Sigaction created for %d", SIG); logChild("Blocking signal"); sigemptyset(&mask); sigaddset(&mask, SIG); if(sigprocmask(SIG_SETMASK, &mask, NULL) == -1) logError("Blocking failed"); logSuccess("Signal blocked"); logChild("Creating system timer"); struct sigevent se; se.sigev_notify = SIGEV_SIGNAL; se.sigev_signo = SIG; se.sigev_value.sival_ptr = &timer_ID; if(timer_create(CLOCK_REALTIME, &se, &timer_ID) == -1) logError("System clock creation failed"); logSuccess("System timer created"); its.it_value.tv_sec = interval_ms / 1000; its.it_value.tv_nsec = (interval_ms % 1000) * 1000000; its.it_interval.tv_sec = its.it_value.tv_sec; its.it_interval.tv_nsec = its.it_value.tv_nsec; #if !(PI_DEBUG_LEVEL & PI_DEBUG_TIMER) enableLog(); #endif }
int main(int argc, char **argv) { TSS_RESULT tResult; TSS_HTPM hTpm; int iRc = -1; struct option opts[] = { {"infile", required_argument, NULL, 'i'}, }; BYTE revokeData[TPM_SHA1BASED_NONCE_LEN]; BYTE *revData = revokeData; initIntlSys(); if (genericOptHandler(argc, argv, "i:", opts, sizeof(opts) / sizeof(struct option), parse, help) != 0) goto out; if (isInputSet) { if (readData(sizeof(revokeData), &revData)) goto out; } else { logError(_("Please specify which file contains the secret to revoke the Ek (use option -i, --infile).\n")); goto out; } logDebug("Input file name: %s\n", in_filename); if (contextCreate(&hContext) != TSS_SUCCESS) goto out; if (contextConnect(hContext) != TSS_SUCCESS) goto out_close; if (contextGetTpm(hContext, &hTpm) != TSS_SUCCESS) goto out_close; tResult = tpmRevokeEk(hTpm, sizeof(revokeData), revData); if (tResult != TSS_SUCCESS) goto out_close; iRc = 0; logSuccess(argv[0]); out_close: contextClose(hContext); out: return iRc; }
int main(int argc, char **argv) { char *szTpmPasswd = NULL; int pswd_len; TSS_HTPM hTpm; TSS_HPOLICY hTpmPolicy; int iRc = -1; struct option opts[] = { {"force", no_argument, NULL, 'f'}, {"well-known", no_argument, NULL, 'z'}, }; BYTE well_known[] = TSS_WELL_KNOWN_SECRET; initIntlSys(); if (genericOptHandler (argc, argv, "fz", opts, sizeof(opts) / sizeof(struct option), parse, help) != 0) goto out; if (contextCreate(&hContext) != TSS_SUCCESS) goto out; if (contextConnect(hContext) != TSS_SUCCESS) goto out_close; if (contextGetTpm(hContext, &hTpm) != TSS_SUCCESS) goto out_close; if (!bValue) { if (isWellKnown){ szTpmPasswd = (char *)well_known; pswd_len = sizeof(well_known); }else{ szTpmPasswd = GETPASSWD(_("Enter owner password: "******"Failed to get password\n")); goto out_close; } } if (policyGet(hTpm, &hTpmPolicy) != TSS_SUCCESS) goto out_close; if (policySetSecret(hTpmPolicy, pswd_len, (BYTE *)szTpmPasswd) != TSS_SUCCESS) goto out_close; } //Setup complete attempt command if (tpmClearOwner(hTpm, bValue) != TSS_SUCCESS) goto out_close; //Command successful iRc = 0; logSuccess(argv[0]); logMsg( _("TPM Successfuly Cleared. You need to reboot to complete this operation. After reboot the TPM will be in the default state: unowned, disabled and inactive.\n") ); //Cleanup out_close: if (szTpmPasswd && !isWellKnown) shredPasswd(szTpmPasswd); contextClose(hContext); out: return iRc; }
int main(int argc, char **argv) { char *szTpmPasswd = NULL; int pswd_len; TSS_HPOLICY hTpmPolicy; TSS_HTPM hTpm; int iRc = -1; struct option opts[] = { {"allow", no_argument, NULL, 'a'}, {"status", no_argument, NULL, 's'}, {"restrict", no_argument, NULL, 'r'}, {"well-known", no_argument, NULL, 'z'}, }; BYTE well_known[TCPA_SHA1_160_HASH_LEN] = TSS_WELL_KNOWN_SECRET; initIntlSys(); if (genericOptHandler (argc, argv, "asrz", opts, sizeof(opts) / sizeof(struct option), parse, help) != 0) goto out; /* If no args are given, the default should be to give status */ if (argc == 1) bCheck = TRUE; //Connect to TSS and TPM if (contextCreate(&hContext) != TSS_SUCCESS) goto out; if (contextConnect(hContext) != TSS_SUCCESS) goto out_close; if (contextGetTpm(hContext, &hTpm) != TSS_SUCCESS) goto out_close; if (isWellKnown) { szTpmPasswd = (char *)well_known; pswd_len = sizeof(well_known); } else { // Prompt for owner password szTpmPasswd = GETPASSWD(_("Enter owner password: "******"Failed to get password\n")); goto out_close; } } if (policyGet(hTpm, &hTpmPolicy) != TSS_SUCCESS) goto out_close; if (policySetSecret (hTpmPolicy, pswd_len, (BYTE *)szTpmPasswd) != TSS_SUCCESS) goto out_close; if (bCheck) { TSS_BOOL bValue; if (tpmGetStatus (hTpm, TSS_TPMSTATUS_DISABLEPUBSRKREAD, &bValue) != TSS_SUCCESS) goto out; logMsg(_("Storage Root Key readable with: %s\n"), bValue ? _("owner auth") : _("SRK auth")); } else { if (tpmSetStatus(hTpm, TSS_TPMSTATUS_DISABLEPUBSRKREAD, bRestrict) != TSS_SUCCESS) goto out_close; } iRc = 0; logSuccess(argv[0]); out_close: contextClose(hContext); out: if (szTpmPasswd && !isWellKnown) shredPasswd(szTpmPasswd); return iRc; }
int main(int argc, char **argv) { TSS_RESULT tResult; TSS_HTPM hTpm; TSS_HKEY hEk; TSS_FLAG fEkAttrs; int iRc = -1; #ifdef TSS_LIB_IS_12 struct option opts[] = {{"revocable", no_argument, NULL, 'r'}, {"generate-secret", no_argument, NULL, 'g'}, {"infile", required_argument, NULL, 'i'}, {"outfile", required_argument, NULL, 'o'}, }; UINT32 revDataSz; BYTE revokeData[TPM_SHA1BASED_NONCE_LEN]; BYTE *pRevData; #endif initIntlSys(); #ifdef TSS_LIB_IS_12 if (genericOptHandler(argc, argv, "rgi:o:", opts, sizeof(opts) / sizeof(struct option), parse, help) != 0) goto out; //Check commands for command hierarchy if (isRevocable) { if (needGenerateSecret) { if (!outFileSet) { logError(_("Please specify an output file\n")); goto out; } if (inFileSet) { logError(_("The option -i, --infile is not valid with -g\n")); goto out; } } else if (!inFileSet) { logError(_("Please specify -i, --infile or -g, --generate-secret\n")); goto out; } else if (outFileSet) { logError(_("The option -o, --outfile is not valid with -i, --infile")); goto out; } } logDebug("Input file name: %s\n", in_filename); logDebug("Output file name: %s\n", out_filename); if (inFileSet) { pRevData = revokeData; revDataSz = sizeof(revokeData); if (readData(revDataSz, &pRevData)) goto out; } else if (outFileSet) { FILE *outfile = fopen(out_filename, "w"); if (!outfile) { iRc = -1; logError(_("Unable to open output file: %s\n"), out_filename); goto out; } fclose(outfile); //TPM should generate the revoke data revDataSz = 0; pRevData = NULL; } #else if (genericOptHandler(argc, argv, NULL, NULL, 0, NULL, NULL) != 0){ logError(_("See man pages for details.\n")); goto out; } #endif if (contextCreate(&hContext) != TSS_SUCCESS) goto out; if (contextConnect(hContext) != TSS_SUCCESS) goto out_close; if (contextGetTpm(hContext, &hTpm) != TSS_SUCCESS) goto out_close; //Initialize EK attributes here fEkAttrs = TSS_KEY_SIZE_2048 | TSS_KEY_TYPE_LEGACY; if (contextCreateObject(hContext, TSS_OBJECT_TYPE_RSAKEY, fEkAttrs, &hEk) != TSS_SUCCESS) goto out_close; #ifdef TSS_LIB_IS_12 if (isRevocable){ tResult = tpmCreateRevEk(hTpm, hEk, NULL, &revDataSz, &pRevData); if (tResult != TSS_SUCCESS) goto out_close; //Writes the generated secret into the output file if (outFileSet) { if (writeData(revDataSz, pRevData)) { logError(_("Creating revocable EK succeeded, but writing the EK " "revoke authorization to disk failed.\nPrinting the " "revoke authorization instead:\n")); logHex(revDataSz, pRevData); logError(_("You should record this data, as its the authorization " "you'll need to revoke your EK!\n")); goto out_close; } } } else #endif tResult = tpmCreateEk(hTpm, hEk, NULL); if (tResult != TSS_SUCCESS) goto out_close; iRc = 0; logSuccess(argv[0]); out_close: contextClose(hContext); out: return iRc; }
int main( int argc, char **argv ) { char *szTpmPasswd = NULL; int tpm_len; TSS_HTPM hTpm; TSS_HPOLICY hTpmPolicy; TSS_BOOL bValue = TRUE; int iRc = -1; struct option opts[] = { {"use-hex", no_argument, NULL, 'x'}, {"well-known", no_argument, NULL, 'z'}, }; BYTE wellKnown[TCPA_SHA1_160_HASH_LEN] = TSS_WELL_KNOWN_SECRET; BYTE* pTpmPasswd = NULL; int iTpmPasswdLen; initIntlSys(); if (genericOptHandler(argc, argv, "xz", opts, sizeof(opts) / sizeof(struct option), parse, help) != 0) goto out; if (contextCreate(&hContext) != TSS_SUCCESS) goto out; if (!isWellKnown) { // Prompt for owner password szTpmPasswd = GETPASSWD(_("Enter owner password: "******"Failed to get Owner password\n")); goto out; } if( decodeHexPassword ) { if( hex2bytea(szTpmPasswd, &pTpmPasswd, &iTpmPasswdLen) != 0 ) { logError(_("Invalid hex owner secret\n")); goto out_close; } } } else { szTpmPasswd = (char *)wellKnown; tpm_len = sizeof(wellKnown); } if (contextConnect(hContext) != TSS_SUCCESS) goto out_close; if (contextGetTpm(hContext, &hTpm) != TSS_SUCCESS) goto out_close; if (policyGet(hTpm, &hTpmPolicy) != TSS_SUCCESS) goto out_close; if( decodeHexPassword ) { if( Tspi_Policy_SetSecret(hTpmPolicy, TSS_SECRET_MODE_PLAIN, iTpmPasswdLen, pTpmPasswd) != TSS_SUCCESS) goto out_close; } else { if (policySetSecret(hTpmPolicy, tpm_len, (BYTE *)szTpmPasswd) != TSS_SUCCESS) goto out_close; } if (tpmSetStatus(hTpm, TSS_TPMSTATUS_RESETLOCK, bValue) != TSS_SUCCESS) goto out_close; iRc = 0; logSuccess(argv[0]); out_close: contextClose(hContext); out: if (!isWellKnown && szTpmPasswd) shredPasswd(szTpmPasswd); if( pTpmPasswd ) shredByteArray(pTpmPasswd, iTpmPasswdLen); return iRc; }
int ServeClientKeepAliveLoop(struct AmmServer_Instance * instance,struct HTTPTransaction * transaction) { //Remember the IP of this client.. getSocketIPAddress(instance,transaction->clientSock,transaction->ipStr,MAX_IP_STRING_SIZE,&transaction->port); //We have our connection / instancing /etc covered if we are here //In order to serve our client we must first receive the request header , so we do it now..! int httpHeaderReceivedWithNoProblems = receiveAndHandleHTTPHeaderSentByClient(instance,transaction); if (!httpHeaderReceivedWithNoProblems) { if (transaction->clientDisconnected) { warningID(ASV_WARNING_CONNECTION_CLOSED_WHILE_KEEPALIVE); } else { /*We got a bad http request so we will rig it to make server emmit the 400 message*/ errorID(ASV_ERROR_FAILED_TO_RECEIVE_HEADER); SendErrorFile(instance,transaction,400); logError(instance,transaction,400,"400.html"); } return 0; } else if (!clientList_isClientAllowedToUseResource(instance->clientList,transaction->clientListID,transaction->incomingHeader.resource)) { //Client is forbidden but he is not IP banned to use resource ( already opened too many connections or w/e other reason ) //Doesnt have access to the specific file , etc..! warningID(ASV_WARNING_CLIENT_DENIED_ACCESS); SendErrorCodeHeader(instance,transaction,403 ,"403.html",instance->templates_root); logError(instance,transaction,403,"403.html"); return 0; } else if ((instance->settings.PASSWORD_PROTECTION)&&(!transaction->incomingHeader.authorized)) { errorID(ASV_ERROR_UNAUTHORIZED_REQUEST); respondToClientRequestingAuthorization(instance,transaction); return 0; } else { // Not a Bad request Start //This is a hack and should be probably be changed..! if ( ( transaction->incomingHeader.requestType==POST ) && (instance->settings.ENABLE_POST) && (MASTER_ENABLE_POST) ) { fprintf(stderr,GREEN "POST HEADER : %lu length \n %s \n" NORMAL,transaction->incomingHeader.ContentLength,transaction->incomingHeader.headerRAW); //TODO ADD Here a possibly rfc1867 , HTTP POST FILE compatible (multipart/form-data) recv handler.. //TODO TODO TODO fprintf(stderr,"Found a POST query %lu bytes long , %s \n",transaction->incomingHeader.POSTrequestSize, transaction->incomingHeader.POSTrequest); warningID(ASV_WARNING_PRETENDING_IT_IS_A_GET_REQUEST); //Will now pretend that we are a GET request for the rest of the page to be served nicely transaction->incomingHeader.requestType=GET; } if ( (transaction->incomingHeader.requestType==GET) || (transaction->incomingHeader.requestType==HEAD) || (transaction->incomingHeader.requestType==POST) ) { char servefile[(MAX_FILE_PATH*2)+1]={0}; // Since we are strcat-ing the file on top of the webserver_root it is only logical to // reserve space for two MAX_FILE_PATHS they are a software security limitation ( system max_path is much larger ) so its not a problem anywhere..! int resource_is_a_directory=0,resource_is_a_file=0,resource_is_a_template=0,generate_directory_list=0; /*! PART 1 : Sense what we want to serve , and set the flags resource_is_a_directory , resource_is_a_file , generate_directory_list accordingly..! */ decideAboutHowToHandleRequestedResource ( instance, transaction, servefile, &resource_is_a_directory, &resource_is_a_file , &resource_is_a_template , &generate_directory_list ); /*! PART 2 : The flags resource_is_a_directory , resource_is_a_file , generate_directory_list have been set to the correct ( :P ) value so all we have to do now is serve the correct repsonse..! */ if (resource_is_a_template) { //We have a specific request for a file ( transaction->incomingHeader.resource ) fprintf(stderr,"It is a template request for %s ..!\n",servefile); // ------------------------------------------------------ // ------------------------------------------------------ // ------------------------------------------------------ if ( SendEmbeddedFile ( instance, transaction, servefile // -- Log What was asked to be served ) ) { logSuccess(instance,transaction,200,servefile); } else { //We where unable to serve request , closing connections..\n errorID(ASV_ERROR_UNABLE_TO_SERVE_TEMPLATE); return 0; } // ------------------------------------------------------ // ------------------------------------------------------ // ------------------------------------------------------ } else if (generate_directory_list) { respondToClientBySendingAGeneratedDirectoryList(instance,transaction,servefile); return 0; } else if (resource_is_a_file) { //We have a specific request for a file ( transaction->incomingHeader.resource ) //fprintf(stderr,"It is a file request for %s ..!\n",servefile); // ------------------------------------------------------ // ------------------------------------------------------ // ------------------------------------------------------ if ( SendFile ( instance, transaction, servefile, // -- Log What was asked to be served 0 // <- We dont want to force an error code! ) ) { logSuccess(instance,transaction,200,servefile); } else { //We where unable to serve request , closing connections..\n errorID(ASV_ERROR_UNABLE_TO_SERVE_REQUEST); return 0; } // ------------------------------------------------------ // ------------------------------------------------------ // ------------------------------------------------------ } else { fprintf(stderr,"404 not found..!!\n"); SendErrorFile(instance,transaction,404); logError(instance,transaction,404,servefile); return 0; } } else if (transaction->incomingHeader.requestType==BAD) { //In case some of the security features of the server sensed a BAD! request we should log it.. warningID(ASV_WARNING_PREDATORY_REQUST); //TODO : call -> int ErrorLogAppend(char * IP,char * DateStr,char * Request,unsigned int ResponseCode,unsigned long ResponseLength,char * Location,char * Useragent) SendErrorFile(instance,transaction,400); logError(instance,transaction,400,"400.html"); return 0; } else if (transaction->incomingHeader.requestType==NONE) { //We couldnt find a request type so it is a weird input that doesn't seem to be HTTP based warningID(ASV_WARNING_UNRECOGNIZED_REQUEST); SendErrorFile(instance,transaction,400); logError(instance,transaction,400,"400.html"); return 0; } else { //The request we got requires not implemented functionality , so we will admit not implementing it..! :P warningID(ASV_WARNING_NOTIMPLEMENTED_REQUEST); SendErrorFile(instance,transaction,501); logError(instance,transaction,501,"501.html"); return 0; } } // Not a Bad request END clientList_signalClientStoppedUsingResource(instance->clientList,transaction->clientListID,transaction->incomingHeader.resource); // This in order for client_list to correctly track client behaviour..! if ( transaction->incomingHeader.headerRAW!=0 ) { safeFree(transaction->incomingHeader.headerRAW,transaction->incomingHeader.headerRAWSize); transaction->incomingHeader.headerRAW=0; } //We are done with request! if (!transaction->incomingHeader.keepalive) { return 0; } // Close_connection controls the receive "keep-alive" loop //If we are on a keepalive streak , then go on ! return 1; }
int cmdVersion(const char *a_szCmd) { TSS_HTPM hTpm; UINT32 uiSubCap; BYTE *pSubCap; UINT32 uiResultLen; BYTE *pResult; int iRc = -1; if (contextCreate(&hContext) != TSS_SUCCESS) goto out; if (contextConnect(hContext) != TSS_SUCCESS) goto out_close; if (contextGetTpm(hContext, &hTpm) != TSS_SUCCESS) goto out_close; #ifdef TSS_LIB_IS_12 { UINT64 offset; TSS_RESULT uiResult; TPM_CAP_VERSION_INFO versionInfo; int tmpLogLevel = iLogLevel; /* disable logging during this call. If we're on a 1.1 TPM, it'd throw an error */ iLogLevel = LOG_LEVEL_NONE; if ((uiResult = getCapability(hTpm, TSS_TPMCAP_VERSION_VAL, 0, NULL, &uiResultLen, &pResult)) != TSS_SUCCESS) { iLogLevel = tmpLogLevel; if (uiResult == TPM_E_BAD_MODE) goto print_cap_version; else goto out_close; } iLogLevel = tmpLogLevel; offset = 0; if ((uiResult = unloadVersionInfo(&offset, pResult, &versionInfo))) { goto out_close; } logMsg(_(" TPM 1.2 Version Info:\n")); logMsg(_(" Chip Version: %hhu.%hhu.%hhu.%hhu\n"), versionInfo.version.major, versionInfo.version.minor, versionInfo.version.revMajor, versionInfo.version.revMinor); logMsg(_(" Spec Level: %hu\n"), versionInfo.specLevel); logMsg(_(" Errata Revision: %hhu\n"), versionInfo.errataRev); logMsg(_(" TPM Vendor ID: %c%c%c%c\n"), versionInfo.tpmVendorID[0], versionInfo.tpmVendorID[1], versionInfo.tpmVendorID[2], versionInfo.tpmVendorID[3]); if (versionInfo.vendorSpecificSize) { logMsg(_(" Vendor Specific data: ")); logHex(versionInfo.vendorSpecificSize, versionInfo.vendorSpecific); free(versionInfo.vendorSpecific); } } print_cap_version: #endif if (getCapability(hTpm, TSS_TPMCAP_VERSION, 0, NULL, &uiResultLen, &pResult) != TSS_SUCCESS) goto out_close; logMsg(_(" TPM Version: ")); logHex(uiResultLen, pResult); uiSubCap = TSS_TPMCAP_PROP_MANUFACTURER; pSubCap = (BYTE *) & uiSubCap; if (getCapability(hTpm, TSS_TPMCAP_PROPERTY, sizeof(uiSubCap), pSubCap, &uiResultLen, &pResult) != TSS_SUCCESS) goto out_close; logMsg(_(" Manufacturer Info: ")); logHex(uiResultLen, pResult); iRc = 0; logSuccess(a_szCmd); out_close: contextClose(hContext); out: return iRc; }
int main(int argc, char **argv) { TSS_HKEY hSrk, hKey; TSS_HENCDATA hEncdata; TSS_HPOLICY hPolicy; int iRc = -1; struct option opts[] = { {"infile", required_argument, NULL, 'i'}, {"outfile", required_argument, NULL, 'o'}, {"pcr", required_argument, NULL, 'p'}, {"unicode", no_argument, NULL, 'u'}, {"well-known", no_argument, NULL, 'z'} }; unsigned char line[EVP_CIPHER_block_size(EVP_aes_256_cbc()) * 16]; int lineLen; unsigned char encData[sizeof(line) + EVP_CIPHER_block_size(EVP_aes_256_cbc())]; int encDataLen; UINT32 encLen, i; BYTE *encKey; BYTE *randKey = NULL; UINT32 sealKeyLen; BYTE *sealKey; TSS_FLAG keyFlags = TSS_KEY_TYPE_STORAGE | TSS_KEY_SIZE_2048 | TSS_KEY_VOLATILE | TSS_KEY_AUTHORIZATION | TSS_KEY_NOT_MIGRATABLE; TSS_HPOLICY hSrkPolicy; char *passwd = NULL; int pswd_len; BYTE wellKnown[TCPA_SHA1_160_HASH_LEN] = TSS_WELL_KNOWN_SECRET; BIO *bin = NULL, *bdata=NULL, *b64=NULL; initIntlSys(); if (genericOptHandler(argc, argv, "i:o:p:uz", opts, sizeof(opts) / sizeof(struct option), parse, help) != 0) goto out; if (contextCreate(&hContext) != TSS_SUCCESS) goto out; if (contextConnect(hContext) != TSS_SUCCESS) goto out_close; if (contextGetTpm(hContext, &hTpm) != TSS_SUCCESS) goto out_close; /* Create a BIO for the input file */ if ((bin = BIO_new(BIO_s_file())) == NULL) { logError(_("Unable to open input BIO\n")); goto out_close; } /* Assign the input file to the BIO */ if (strlen(in_filename) == 0) BIO_set_fp(bin, stdin, BIO_NOCLOSE); else if (!BIO_read_filename(bin, in_filename)) { logError(_("Unable to open input file: %s\n"), in_filename); goto out_close; } /* Create the PCRs object. If any PCRs above 15 are selected, this will need to be * a 1.2 TSS/TPM */ if (selectedPcrsLen) { TSS_FLAG initFlag = 0; UINT32 pcrSize; BYTE *pcrValue; for (i = 0; i < selectedPcrsLen; i++) { if (selectedPcrs[i] > 15) { #ifdef TSS_LIB_IS_12 initFlag |= TSS_PCRS_STRUCT_INFO_LONG; #else logError(_("This version of %s was compiled for a v1.1 TSS, which " "can only seal\n data to PCRs 0-15. PCR %u is out of range" "\n"), argv[0], selectedPcrs[i]); goto out_close; #endif } } if (contextCreateObject(hContext, TSS_OBJECT_TYPE_PCRS, initFlag, &hPcrs) != TSS_SUCCESS) goto out_close; for (i = 0; i < selectedPcrsLen; i++) { if (tpmPcrRead(hTpm, selectedPcrs[i], &pcrSize, &pcrValue) != TSS_SUCCESS) goto out_close; if (pcrcompositeSetPcrValue(hPcrs, selectedPcrs[i], pcrSize, pcrValue) != TSS_SUCCESS) goto out_close; } #ifdef TSS_LIB_IS_12 if (initFlag) { UINT32 localityValue = TPM_LOC_ZERO | TPM_LOC_ONE | TPM_LOC_TWO | TPM_LOC_THREE | TPM_LOC_FOUR; if (pcrcompositeSetPcrLocality(hPcrs, localityValue) != TSS_SUCCESS) goto out_close; } #endif } /* Retrieve random data to be used as the symmetric key (this key will encrypt the input file contents) */ if (tpmGetRandom(hTpm, EVP_CIPHER_key_length(EVP_aes_256_cbc()), &randKey) != TSS_SUCCESS) goto out_close; /* Load the SRK and set the SRK policy (no password) */ if (keyLoadKeyByUUID(hContext, TSS_PS_TYPE_SYSTEM, SRK_UUID, &hSrk) != TSS_SUCCESS) goto out_close; /* Use the context's default policy for the SRK secret */ if (policyGet(hSrk, &hSrkPolicy) != TSS_SUCCESS) goto out_close; /* Prompt for SRK password */ if (!isWellKnown) { passwd = _GETPASSWD(_("Enter SRK password: "******"Failed to get SRK password\n")); goto out_close; } } else { passwd = (char *)wellKnown; pswd_len = sizeof(wellKnown); } if (policySetSecret(hSrkPolicy, (UINT32)pswd_len, (BYTE *)passwd) != TSS_SUCCESS) goto out_close; if (!isWellKnown) shredPasswd(passwd); passwd = NULL; /* Build an RSA key object that will be created by the TPM (this will encrypt and protect the symmetric key) */ if (contextCreateObject (hContext, TSS_OBJECT_TYPE_RSAKEY, keyFlags, &hKey) != TSS_SUCCESS) goto out_close; if (contextCreateObject (hContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hPolicy) != TSS_SUCCESS) goto out_close; if (policySetSecret(hPolicy, strlen(TPMSEAL_SECRET), (BYTE *)TPMSEAL_SECRET) != TSS_SUCCESS) goto out_close; if (policyAssign(hPolicy, hKey) != TSS_SUCCESS) goto out_close; /* Create the RSA key (under the SRK) */ if (keyCreateKey(hKey, hSrk, NULL_HPCRS) != TSS_SUCCESS) goto out_close; /* Load the newly created RSA key */ if (keyLoadKey(hKey, hSrk) != TSS_SUCCESS) goto out_close; /* Build an encrypted data object that will hold the encrypted version of the symmetric key */ if (contextCreateObject (hContext, TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_SEAL, &hEncdata) != TSS_SUCCESS) goto out_close; if (contextCreateObject (hContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hPolicy) != TSS_SUCCESS) goto out_close; if (policySetSecret(hPolicy, strlen(TPMSEAL_SECRET), (BYTE *)TPMSEAL_SECRET) != TSS_SUCCESS) goto out_close; if (policyAssign(hPolicy, hEncdata) != TSS_SUCCESS) goto out_close; /* Encrypt and seal the symmetric key */ if (dataSeal (hEncdata, hKey, EVP_CIPHER_key_length(EVP_aes_256_cbc()), randKey, hPcrs) != TSS_SUCCESS) goto out_close; if (getAttribData(hEncdata, TSS_TSPATTRIB_ENCDATA_BLOB, TSS_TSPATTRIB_ENCDATABLOB_BLOB, &encLen, &encKey) != TSS_SUCCESS) goto out_close; if (getAttribData (hKey, TSS_TSPATTRIB_KEY_BLOB, TSS_TSPATTRIB_KEYBLOB_BLOB, &sealKeyLen, &sealKey) != TSS_SUCCESS) goto out_close; /* Create a BIO to perform base64 encoding */ if ((b64 = BIO_new(BIO_f_base64())) == NULL) { logError(_("Unable to open base64 BIO\n")); goto out_close; } /* Create a BIO for the output file */ if ((bdata = BIO_new(BIO_s_file())) == NULL) { logError(_("Unable to open output BIO\n")); goto out_close; } /* Assign the output file to the BIO */ if (strlen(out_filename) == 0) BIO_set_fp(bdata, stdout, BIO_NOCLOSE); else if (BIO_write_filename(bdata, out_filename) <= 0) { logError(_("Unable to open output file: %s\n"), out_filename); goto out_close; } /* Output the sealed data header string */ BIO_puts(bdata, TPMSEAL_HDR_STRING); /* Sealing key used on the TPM */ BIO_puts(bdata, TPMSEAL_TSS_STRING); bdata = BIO_push(b64, bdata); BIO_write(bdata, sealKey, sealKeyLen); if (BIO_flush(bdata) != 1) { logError(_("Unable to flush output\n")); goto out_close; } bdata = BIO_pop(b64); /* Sealed EVP Symmetric Key */ BIO_puts(bdata, TPMSEAL_EVP_STRING); BIO_puts(bdata, TPMSEAL_KEYTYPE_SYM); BIO_puts(bdata, TPMSEAL_CIPHER_AES256CBC); bdata = BIO_push(b64, bdata); BIO_write(bdata, encKey, encLen); if (BIO_flush(bdata) != 1) { logError(_("Unable to flush output\n")); goto out_close; } bdata = BIO_pop(b64); /* Encrypted Data */ BIO_puts(bdata, TPMSEAL_ENC_STRING); bdata = BIO_push(b64, bdata); EVP_CIPHER_CTX ctx; EVP_EncryptInit(&ctx, EVP_aes_256_cbc(), randKey, (unsigned char *)TPMSEAL_IV); while ((lineLen = BIO_read(bin, line, sizeof(line))) > 0) { EVP_EncryptUpdate(&ctx, encData, &encDataLen, line, lineLen); BIO_write(bdata, encData, encDataLen); } EVP_EncryptFinal(&ctx, encData, &encDataLen); BIO_write(bdata, encData, encDataLen); if (BIO_flush(bdata) != 1) { logError(_("Unable to flush output\n")); goto out_close; } bdata = BIO_pop(b64); BIO_puts( bdata, TPMSEAL_FTR_STRING); iRc = 0; logSuccess(argv[0]); out_close: contextClose(hContext); out: if (bin) BIO_free(bin); if (bdata) BIO_free(bdata); if (b64) BIO_free(b64); return iRc; }