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>

#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))

#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";
    }
}

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

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

错误总结:

未完待续……………………

 

 

 

 

 

 

 

 

 

 

 

 

转载于:https://my.oschina.net/u/3548719/blog/1545591

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值