tpm遷移密鑰

說明:代碼分爲源tpm(服務端)和目的TPM(客戶端),傳輸數據時使用socket編程實現通訊。算法

源tpm端key.c源碼編程

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>服務器

#include <tss/tss_error.h>
#include <tss/platform.h>
#include <tss/tss_defines.h>
#include <tss/tss_typedef.h>
#include <tss/tss_structs.h>
#include <tss/tspi.h>
#include <trousers/trousers.h>socket

#include <openssl/rsa.h>
#include <openssl/err.h>
#include <openssl/ssl.h>函數

#include<netinet/in.h> // sockaddr_in
#include<sys/types.h>  // socket
#include<sys/socket.h> // socket
#include<stdio.h>    // printf
#include<stdlib.h>   // exit
#include<string.h>   // bzero工具

#define SOFTWARE_KEY_FILE_PATH "/home/sm/opensslkey/key.pem"
#define MIMRATION_KEY_FILE_PATH "/home/sm/opensslkey/migkey.pem"
#define Debug(message, tResult) printf("%s : %s\n", message, (char *)Trspi_Error_String(result))ui

#define SERVER_PORT 8000
#define LENGTH_OF_LISTEN_QUEUE 20
#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512加密

TSS_HCONTEXT    hContext;
TSS_HTPM        hTPM;
TSS_HKEY        hSRK;
//獲取錯誤信息,工具函數
const char *get_error(TSS_RESULT res)
{
    switch(ERROR_CODE(res))
    {
        case 0x0001L:
            return "Authentication failed";
        case TSS_SUCCESS:
            return "success";
        case TSS_E_INVALID_HANDLE:
            return "hContext or phObject is an invalid handle";
        case TSS_E_BAD_PARAMETER:
            return "persistent storage type is not valid/One or more parameters is incorrect";
        case TSS_E_INTERNAL_ERROR:
            return "an error occurred internal to the TSS";
        case TSS_E_PS_KEY_NOTFOUND:
            return "NOT FOUND SRK";
        case TSS_E_INVALID_ATTRIB_FLAG:
            return "attrib flag is incorrect";
        case TSS_E_INVALID_ATTRIB_SUBFLAG:
            return "subflag is incorrect";
        case TSS_E_INVALID_ATTRIB_DATA:
            return "ulAttrib is incorrect";
        case TSS_E_KEY_ALREADY_REGISTERED:
            return "UUID used";
        case TSS_E_KEY_NOT_LOADED:
            return "the addressed key is currently not loaded";
        default:
            return "unknown error";
    }
}code

void
openssl_print_errors()
{
    ERR_load_ERR_strings();
    ERR_load_crypto_strings();
    ERR_print_errors_fp(stderr);
}orm

RSA *
openssl_read_key(char *filename)
{
        BIO *b = NULL;
        RSA *rsa = NULL;

        b = BIO_new_file(filename, "r");
        if (b == NULL) {
                fprintf(stderr, "Error opening file for read: %s\n", filename);
                return NULL;
        }

        if ((rsa = PEM_read_bio_RSAPrivateKey(b, NULL, 0, NULL)) == NULL) {
                fprintf(stderr, "Reading key %s from disk failed.\n", filename);
                openssl_print_errors();
        }
        BIO_free(b);

        return rsa;
}
//計算size,返回密鑰大小
TSS_FLAG
get_tss_key_size(UINT32 size)
{
    if(size <= 512){
        return TSS_KEY_SIZE_512;
    }else if(size <= 1024){
        return TSS_KEY_SIZE_1024;
    }else if(size <= 2048){
        return TSS_KEY_SIZE_2048;
    }else if(size <= 4096){
        return TSS_KEY_SIZE_4096;
    }else if(size <= 8192){
        return TSS_KEY_SIZE_8192;
    }else if(size <= 16384){
        return TSS_KEY_SIZE_16384;
    }

    return TSS_KEY_SIZE_2048;
}
int
openssl_get_modulus_and_prime(RSA *rsa, unsigned int *size_n, unsigned char *n,
                  unsigned int *size_p, unsigned char *p)
{
    /* 從RSA對象獲取modulus */
    if ((*size_n = BN_bn2bin(rsa->n, n)) <= 0) {
        openssl_print_errors();
        return -1;
    }
    /* 從RSA對象獲取 primes */
    if ((*size_p = BN_bn2bin(rsa->p, p)) <= 0) {
        openssl_print_errors();
        return -1;
    }

    return 0;
}
TSS_RESULT
MyFunc_WrapKey(char *path,
                TSS_HKEY hParentKey,
                TSS_FLAG initFlags,
                TSS_HPCRS hPcrs,
                TSS_HKEY *hKey)
{

    RSA             *rsa;
    UINT32          pubKeyLen;
    BYTE            *pubKey;
    TSS_RESULT      result;
    unsigned char   n[2048], p[2048];
    int             sizeN, sizeP;
    UINT32          keySize;
    TSS_HPOLICY     keyMigPolicy;
    BYTE            wellKnownSecret[] = TSS_WELL_KNOWN_SECRET;
    /*從磁盤讀取openssl 密鑰. */
    if ((rsa = openssl_read_key(path)) == NULL) {
        printf("Failed opening OpenSSL key file!\n");
        return TSS_E_FAIL;
    }

    /*獲取SRK的公鑰*/
    //result = Tspi_Key_GetPubKey(hSRK, &pubKeyLen, &pubKey);
    result = Tspi_TPM_OwnerGetSRKPubKey(hTPM, &pubKeyLen, &pubKey);
    if (result != TSS_SUCCESS) {
        printf("Tspi_Key_GetPubKey failed: %s\n", get_error(result));
        RSA_free(rsa);
        printf("Error code:%d!\n", result);
        return result;
    }
    /* 將openSSL密鑰轉換爲適合包含於initFlags的TSS密鑰大小標記. */
    if ((keySize = get_tss_key_size(RSA_size(rsa) * 8)) == 0){
        return TSS_E_BAD_PARAMETER;
    }
    /*建立TSS 密鑰對象 */
    result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_RSAKEY,keySize|initFlags, hKey);
    Debug("create tss key object :", result);
    if (result != TSS_SUCCESS) {
        printf("Tspi_Context_CreateObject failed: %s\n",get_error(result));
        return result;
    }
    /*使用openSSL調用提取RSA軟件密鑰中心公開的N和私有的P */
    if(openssl_get_modulus_and_prime(rsa, &sizeN, n, &sizeP, p) != 0) {
        Tspi_Context_CloseObject(hContext, *hKey);
        *hKey = 0;
        return result;
    }
    /* 設置密鑰對象的公鑰數據 */
    result = Tspi_SetAttribData(*hKey, TSS_TSPATTRIB_RSAKEY_INFO,
                                TSS_TSPATTRIB_KEYINFO_RSA_MODULUS,
                                sizeN, n);
    Debug("set key object public:", result);
    if (result != TSS_SUCCESS) {
        printf("Tspi_SetAttribData failed: %s; Error number:%.2x\n", get_error(result),result);
        Tspi_Context_CloseObject(hContext, *hKey);
        *hKey = 0;
        return result;
    }
    /* 設置密鑰對象的私鑰數據*/
    result = Tspi_SetAttribData(*hKey, TSS_TSPATTRIB_KEY_BLOB,
                                TSS_TSPATTRIB_KEYBLOB_PRIVATE_KEY,
                                sizeP, p);
    Debug("set key object private:", result);
    if (result != TSS_SUCCESS) {
        printf("Tspi_SetAttribData failed: %s\n", get_error(result));
        Tspi_Context_CloseObject(hContext, *hKey);
        *hKey = 0;
        return result;
    }
    /* 設置密鑰策略對象*/
    result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_MIGRATION, &keyMigPolicy);
    Debug("set key policy object :", result);
    /* 設置策略對象祕密細節*/
    result = Tspi_Policy_SetSecret(keyMigPolicy,TSS_SECRET_MODE_SHA1,20, wellKnownSecret);
    Debug("set key policy object secret:", result);
    /*爲密鑰分配策略 */
    result = Tspi_Policy_AssignToObject(keyMigPolicy, *hKey);
    Debug("assign policy object ro key  secret:", result);

    /*調用TSS接口封裝密鑰*/
    result = Tspi_Key_WrapKey(*hKey, hParentKey, hPcrs);
    Debug("Wrap Key:", result);
    if (result != TSS_SUCCESS) {
        printf("Tspi_Key_WrapKey failed: %s; Error number:%.2x\n", get_error(result), result);
        Tspi_Context_CloseObject(hContext, *hKey);
        *hKey = 0;
    }
    RSA_free(rsa);
    if(result ==TSS_SUCCESS)
    {
        printf("Wrap key succeed!\n");
    }

    return result;
}
TSS_RESULT
MyFunc_CreatePubKey(RSA *rsa,int padding,TSS_HKEY *hKey)
{
    TSS_RESULT      result;
    UINT32          encScheme,sizeN,keySize;
    BYTE            n[2048];

    switch (padding) {
        case RSA_PKCS1_PADDING:
        encScheme=TSS_ES_RSAESPKCSV15;
           break;
        case RSA_PKCS1_OAEP_PADDING:
                encScheme=TSS_ES_RSAESOAEP_SHA1_MGF1;
                break;
        case RSA_NO_PADDING:
                encScheme=TSS_ES_NONE;
                break;
        default:
                return  TSS_E_INTERNAL_ERROR;
                break;
    }
    keySize=get_tss_key_size(RSA_size(rsa)*8);
    if(keySize==0){
       return TSS_E_BAD_PARAMETER;
    }
    /*建立TSS密鑰對象*/
    result=Tspi_Context_CreateObject(hContext,TSS_OBJECT_TYPE_RSAKEY,TSS_KEY_TYPE_LEGACY|keySize,hKey);
    Debug("create tss key object:",result);
    if(result!=TSS_SUCCESS){
        return result;
    }
    printf("111111111\n");
    /*從openSSL密鑰獲取公用'n'值*/
    if((sizeN=BN_bn2bin(rsa->n,n))<=0){
       printf("BN_bn2bin failed\n");
       ERR_print_errors_fp(stdout);
       Tspi_Context_CloseObject(hContext,*hKey);
       Debug("close context object:",result);
       return result;
    }
    printf("222222\n");
    /*在TSS對象中設置公鑰數據*/
    //result=Tspi_SetAttribData(*hKey,TSS_TSPATTRIB_KEY_BLOB,TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY,sizeN,n);
 result = Tspi_SetAttribData(*hKey, TSS_TSPATTRIB_RSAKEY_INFO,TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, sizeN, n);
    printf("333333\n");
    Debug("setAttrib public data:",result);
    if(result!=TSS_SUCCESS){
       printf("tspi_setattribdata faild\n");
       Tspi_Context_CloseObject(hContext,*hKey);
       Debug("close context object:",result);
       return result;

    }
    /*設置密鑰算法*/
    result=Tspi_SetAttribUint32(*hKey,TSS_TSPATTRIB_KEY_INFO,TSS_TSPATTRIB_KEYINFO_ALGORITHM,TSS_ALG_RSA);
    Debug("set key algorithm:",result);
    if(result!=TSS_SUCCESS){
       printf("tspi_setattribunit32 faild\n");
       Tspi_Context_CloseObject(hContext,*hKey);
       Debug("close context object:",result);
       return result;
    }
    /*設置密鑰的素數個數*/
    result=Tspi_SetAttribUint32(*hKey,TSS_TSPATTRIB_RSAKEY_INFO,TSS_TSPATTRIB_KEYINFO_RSA_PRIMES,2);
    Debug("set sushu geshu:",result);
    if(result!=TSS_SUCCESS){
       printf("tspi_setattribunit32 faild\n");
       Tspi_Context_CloseObject(hContext,*hKey);
       Debug("close context object:",result);
       return result;
    }
    /*設置密鑰加密機制
    result=Tspi_SetAttribUint32(*hKey,TSS_TSPATTRIB_KEY_INFO,TSS_TSPATTRIB_KEYINFO_ENCSCHEME,encScheme);
    Debug("ser key enc :",result);
    if(result!=TSS_SUCCESS){
       printf("tspi_setattribunit32 faild\n");
       Tspi_Context_CloseObject(hContext,*hKey);
       Debug("close context object:",result);
       return result;
    }*/
    return TSS_SUCCESS;


}

int main(int argc, char **argv)
{
    
    TSS_HPCRS       hPcrs;
    TSS_HENCDATA    hEncData;
    TSS_HENCDATA    hRetrieveData;
    TSS_RESULT      result;
    TSS_HKEY        hUserSWMigKey,hMAKey;
    TSS_HPOLICY     hSRKPolicy,hPolicy,hownerpolicy;
    TSS_UUID        SRK_UUID = TSS_UUID_SRK,MigKeyUuid,swMigKeyUuid;
    BYTE            secretData[]=TSS_WELL_KNOWN_SECRET;
    TSS_FLAG        initFlags;
    BYTE            *ticket;
    BYTE            *migBlob;
    UINT32          ticketLen;
    UINT32          migBlobLen;
    char            file_name[512]="./tpm.c";
    RSA         *ca_rsa, *migration_pub_rsa, *maintenance_pub_rsa;/* OpenSSL objects */

    /* 完成OpenSSL的全部設置調用 */
    //init_external_libraries();
    /* SSL init*/
   //書中使用的init_external_libraries找不到函數,用別的方式代替
    SSL_library_init();
    /* load all SSL */
    OpenSSL_add_all_algorithms();
    /* load all SSL error message */
    SSL_load_error_strings();
    /*建立上下文句柄*/
    result=Tspi_Context_Create(&hContext);
    Debug("Create Context", result);
    /*獲取上下文句柄,鏈接到本地TCS提供者*/
    result = Tspi_Context_Connect(hContext, NULL);
    Debug("Context Connect", result);
    /*獲取TPM對象句柄*/
    result = Tspi_Context_GetTpmObject(hContext, &hTPM);
    Debug("Get TPM Handle", result);
    /*獲取TPM策略對象,保存TPM全部者受權數據*/
    result=Tspi_GetPolicyObject(hTPM,TSS_POLICY_USAGE,&hownerpolicy);
    Debug("get ownerpolicy", result);
    result=Tspi_Policy_SetSecret(hownerpolicy,TSS_SECRET_MODE_POPUP,0,NULL);
    Debug("set owmerpolicy sercet", result);
    /*加載SRK*/
    result = Tspi_Context_LoadKeyByUUID(hContext, TSS_PS_TYPE_SYSTEM, SRK_UUID, &hSRK);
    Debug("LOAD SRK", result);
    /*獲取SRK策略*/  
    result = Tspi_GetPolicyObject(hSRK, TSS_POLICY_USAGE, &hSRKPolicy);
    Debug("Get the SRK policy", result);
    /*設置SRK策略祕密細節*/  
    result=Tspi_Policy_SetSecret(hSRKPolicy,TSS_SECRET_MODE_POPUP,0,NULL);
    Debug("setSRK SECRET", result);
    /*使用SRK公鑰封裝軟件生成的密鑰,並將這個祕鑰設置爲一個須要口令的可遷移存儲密鑰*/
    initFlags = TSS_KEY_TYPE_STORAGE | TSS_KEY_MIGRATABLE | TSS_KEY_AUTHORIZATION;
    MyFunc_WrapKey(SOFTWARE_KEY_FILE_PATH, hSRK, initFlags, 0,&hUserSWMigKey);
    /*在用戶永久存儲區註冊封裝後的密鑰*/
    result = Tspi_Context_RegisterKey(hContext, hUserSWMigKey,TSS_PS_TYPE_USER, swMigKeyUuid,TSS_PS_TYPE_SYSTEM, SRK_UUID);
    Debug("registerkey uermigkey :",result);
    /*使用遷移受權遷移一個密鑰*/
    /*從一個文件中讀取遷移受權的公鑰*/
    migration_pub_rsa=openssl_read_key(MIMRATION_KEY_FILE_PATH);
    MyFunc_CreatePubKey(migration_pub_rsa,RSA_PKCS1_PADDING,&hMAKey);
    RSA_free(migration_pub_rsa);
    /*使用hMAKey建立一個遷移通行證*/
    result=Tspi_TPM_AuthorizeMigrationTicket(hTPM,hMAKey,TSS_MS_REWRAP,&ticketLen,&ticket);
    Debug("creat migrate ticket", result);
    /*使用遷移通行證把 hUserSWMigKey遷移到數據塊中*/
    result=Tspi_Key_CreateMigrationBlob(hUserSWMigKey,hSRK,ticketLen,ticket,0,NULL,&migBlobLen,&migBlob);
    Debug("create migrateblob", result);
    printf("migBlobLen :%d\n",migBlobLen);
    //printf("migBlob:%s\n",migBlob);
    FILE *fp = fopen(file_name, "w");
    if(NULL == fp)
    {
      printf("File:\t%s Can Not Open To Write\n", file_name);
      exit(1);
    }
    printf("打開文件成功\n");
    if(fwrite(migBlob,sizeof(UINT32),migBlobLen, fp) < 0)
    {
      printf("File:\t%s Write Failed\n", file_name);
    }

    printf("寫入數據\n");
    //Clean up  
    Tspi_Context_FreeMemory(hContext, NULL);
    Tspi_Context_Close(hContext);
    /*傳輸遷移數據*/
    // 聲明並初始化一個服務器端的socket地址結構
  struct sockaddr_in server_addr;
  bzero(&server_addr, sizeof(server_addr));
  server_addr.sin_family = AF_INET;
  server_addr.sin_addr.s_addr = htons(INADDR_ANY);
  server_addr.sin_port = htons(SERVER_PORT);

  // 建立socket,若成功,返回socket描述符
  int server_socket_fd = socket(PF_INET, SOCK_STREAM, 0);
  if(server_socket_fd < 0)
  {
    perror("Create Socket Failed:");
    exit(1);
  }
  int opt = 1;
  setsockopt(server_socket_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

  // 綁定socket和socket地址結構
  if(-1 == (bind(server_socket_fd, (struct sockaddr*)&server_addr, sizeof(server_addr))))
  {
    perror("Server Bind Failed:");
    exit(1);
  }

  // socket監聽
  if(-1 == (listen(server_socket_fd, LENGTH_OF_LISTEN_QUEUE)))
  {
    perror("Server Listen Failed:");
    exit(1);
  }

  while(1)
  {
     // 定義客戶端的socket地址結構
    struct sockaddr_in client_addr;
    socklen_t client_addr_length = sizeof(client_addr);
    // 接受鏈接請求,返回一個新的socket(描述符),這個新socket用於同鏈接的客戶端通訊
    // accept函數會把鏈接到的客戶端信息寫到client_addr中
    int new_server_socket_fd = accept(server_socket_fd, (struct sockaddr*)&client_addr, &client_addr_length);
    if(new_server_socket_fd < 0)
    {
      perror("Server Accept Failed:");
      break;
    }

    // recv函數接收數據到緩衝區buffer中
    char buffer[BUFFER_SIZE];
    bzero(buffer, BUFFER_SIZE);
    if(recv(new_server_socket_fd, buffer, BUFFER_SIZE, 0) < 0)
    {
      perror("Server Recieve Data Failed:");
      break;
    }

    // 而後從buffer(緩衝區)拷貝到file_name中
    char file_name[FILE_NAME_MAX_SIZE+1];
    bzero(file_name, FILE_NAME_MAX_SIZE+1);
    strncpy(file_name, buffer, strlen(buffer)>FILE_NAME_MAX_SIZE?FILE_NAME_MAX_SIZE:strlen(buffer));
    printf("%s\n", file_name);

    // 打開文件並讀取文件數據
    FILE *fp = fopen(file_name, "r");
    if(NULL == fp)
    {
      printf("File:%s Not Found\n", file_name);
    }
    else
    {
      bzero(buffer, BUFFER_SIZE);
      int length = 0;
      // 每讀取一段數據,便將其發送給客戶端,循環直到文件讀完爲止
      while((length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
      {
        if(send(new_server_socket_fd, buffer, length, 0) < 0)
        {
          printf("Send File:%s Failed./n", file_name);
          break;
        }
        bzero(buffer, BUFFER_SIZE);
      }
       // 關閉文件
      fclose(fp);
      printf("File:%s Transfer Successful!\n", file_name);
     }
     // 關閉與客戶端的鏈接
     close(new_server_socket_fd);
    }
    // 關閉監聽用的socket
    close(server_socket_fd);
    return 0;
}

目的tpm端file_client.c源代碼:

#include<netinet/in.h>  // sockaddr_in
#include<sys/types.h>  // socket
#include<sys/socket.h>  // socket
#include<stdio.h>    // printf
#include<stdlib.h>    // exit
#include<string.h>    // bzero

#include<tss/tss_error.h>
#include<tss/platform.h>
#include<tss/tss_defines.h>
#include<tss/tss_typedef.h>
#include<tss/tss_structs.h>
#include<tss/tspi.h>
#include<trousers/trousers.h>

#define SERVER_PORT 8000
#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512
   
#define Debug(message,tResult) printf("%s: %s\n",message,(char *)Trspi_Error_String(result))
int main()
{
 
  BYTE               *migBlob;
  TSS_RESULT         result;
  TSS_HKEY           hSRK,hKeyToMigrate;
  UINT32             migBlobLen=32667;
  TSS_HCONTEXT       hContext;
  TSS_HTPM           hTPM;
  TSS_HPOLICY        hSRKPolicy,hownerpolicy;
  TSS_UUID           SRK_UUID=TSS_UUID_SRK,MigKeyUuid;
  // 聲明並初始化一個客戶端的socket地址結構
  struct sockaddr_in client_addr;
  bzero(&client_addr, sizeof(client_addr));
  client_addr.sin_family = AF_INET;
  client_addr.sin_addr.s_addr = htons(INADDR_ANY);
  client_addr.sin_port = htons(0);  
  // 建立socket,若成功,返回socket描述符
  int client_socket_fd = socket(AF_INET, SOCK_STREAM, 0);
  if(client_socket_fd < 0)
  {
    perror("Create Socket Failed:");
    exit(1);
  }
   
  // 綁定客戶端的socket和客戶端的socket地址結構 非必需
  if(-1 == (bind(client_socket_fd, (struct sockaddr*)&client_addr, sizeof(client_addr))))
  {
    perror("Client Bind Failed:");
    exit(1);
  }
   
  // 聲明一個服務器端的socket地址結構,並用服務器那邊的IP地址及端口對其進行初始化,用於後面的鏈接
  struct sockaddr_in server_addr;
  bzero(&server_addr, sizeof(server_addr));
  server_addr.sin_family = AF_INET;
  if(inet_pton(AF_INET, "169.254.12.125", &server_addr.sin_addr) == 0)
  {
    perror("Server IP Address Error:");
    exit(1);
  }
  server_addr.sin_port = htons(SERVER_PORT);
  socklen_t server_addr_length = sizeof(server_addr);
   
  // 向服務器發起鏈接,鏈接成功後client_socket_fd表明了客戶端和服務器的一個socket鏈接
  if(connect(client_socket_fd, (struct sockaddr*)&server_addr, server_addr_length) < 0)
  {
    perror("Can Not Connect To Server IP:");
    exit(0);
  }
   
  // 輸入文件名 並放到緩衝區buffer中等待發送
  char file_name[FILE_NAME_MAX_SIZE+1];
  bzero(file_name, FILE_NAME_MAX_SIZE+1);
  printf("Please Input File Name On Server:\t");
  scanf("%s", file_name);
   
  char buffer[BUFFER_SIZE];
  bzero(buffer, BUFFER_SIZE);
  strncpy(buffer, file_name, strlen(file_name)>BUFFER_SIZE?BUFFER_SIZE:strlen(file_name));
     
  // 向服務器發送buffer中的數據
  if(send(client_socket_fd, buffer, BUFFER_SIZE, 0) < 0)
  {
    perror("Send File Name Failed:");
    exit(1);
  }
   
  // 打開文件,準備寫入
  FILE *fp = fopen(file_name, "w");
  if(NULL == fp)
  {
    printf("File:\t%s Can Not Open To Write\n", file_name);
    exit(1);
  }
   
  // 從服務器接收數據到buffer中
  // 每接收一段數據,便將其寫入文件中,循環直到文件接收完並寫完爲止
  bzero(buffer, BUFFER_SIZE);
  int length = 0;
  while((length = recv(client_socket_fd, buffer, BUFFER_SIZE, 0)) > 0)
  {
    if(fwrite(buffer, sizeof(char), length, fp) < length)
    {
      printf("File:\t%s Write Failed\n", file_name);
      break;
    }
    bzero(buffer, BUFFER_SIZE);
  }
   
  // 接收成功後,關閉文件,關閉socket
  printf("Receive File:\t%s From Server IP Successful!\n", file_name);
  close(fp);
  close(client_socket_fd);
  /*讀取文件中的遷移數據*/
   char    file[512]="./tpm.c";
   FILE *fp1=fopen(file,"w");
   if(NULL==fp1){
      printf("file:\t%s can not open \n",file);
      exit(1);
   }
   else{
      printf("打開文件成功\n");
   }
   /*將遷移數據讀取到migBlob*/
   if(fread(migBlob,sizeof(BYTE),migBlobLen,fp1)<0){
      printf("file:\t%s read failed\n",file);
   }
   /*解密遷移數據*/
   result=Tspi_Context_Create(&hContext);
   Debug("create context",result);
   result=Tspi_Context_Connect(hContext,NULL);
   Debug("get connect",result);
   result=Tspi_Context_GetTpmObject(hContext,&hTPM);
   Debug("get tpm handle",result);
   result=Tspi_GetPolicyObject(hTPM,TSS_POLICY_USAGE,&hownerpolicy);
   Debug("get ownerpolicy",result);
   result=Tspi_Policy_SetSecret(hownerpolicy,TSS_SECRET_MODE_POPUP,0,NULL);
   Debug("set ownerpolicy sercet",result);
   result=Tspi_Context_LoadKeyByUUID(hContext,TSS_PS_TYPE_SYSTEM,SRK_UUID,&hSRK);
   Debug("load srk",result);
   result=Tspi_GetPolicyObject(hSRK,TSS_POLICY_USAGE,&hSRKPolicy);
   Debug("get srk policy",result);
   result=Tspi_Policy_SetSecret(hSRKPolicy,TSS_SECRET_MODE_POPUP,0,NULL);
   Debug("set srkpolicy sercet",result);
   result=Tspi_Key_ConvertMigrationBlob(hKeyToMigrate,hSRK,0,0,migBlobLen,migBlob);
   Debug("covert migblob data",result);

   return 0;
}

編譯運行:gcc -g -o  key key.c -ltspi -lcrypto -lssl     

                    gcc file_client.c  -o mig -ltspi

                    ./key

                   ./mig

錯誤總結:

未完待續……………………

相關文章
相關標籤/搜索