//file system
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//openssl
#include<openssl/rsa.h>
#include<openssl/aes.h>
#include<openssl/hmac.h>
#include<openssl/pem.h>
#include<openssl/err.h>
//socket
#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
//time
#include<time.h>
#include <stdio.h>
#include <sys/time.h>
//file path
#define PUBPARENT "parent_pub.key"
#define PRIPARENT "parent.key"
#define PRIMIG "mig.key"
#define PUBMIG "mig_pub.key"
#define NPPUBKEY "nparent_pub.key"
#define NPPRIKEY "nparent.key"
#define PUBDA "DA_pub.key"
#define PRIDA "DA.key"
//socket parameter
#define SERVER_PORT 8000
#define LENGTH_OF_LISTEN_QUEUE 20
#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512
#define NAME 32
//#define seed "seed"
#define npNameAlg "ecc"
//unsigned char* dupSensitive;
char *se=NULL;
/*
char* sign()
{
EVP_MD_CTX mdctx;
EVP_PKEY *evpkey=NULL,*evpkey1=NULL;
}*/
void aes_box_decrypt(unsigned char* source_string, unsigned char* des_string)
{
int iLoop = 0;
int iLen =0;
AES_KEY aes;
unsigned char key[AES_BLOCK_SIZE];
unsigned char iv[AES_BLOCK_SIZE];
if(NULL == source_string || NULL == des_string)
{
return;
}
//Generate own AES Key
for(iLoop = 0; iLoop < 16; iLoop++)
{
key[iLoop] = 32 + iLoop;
}
// Set encryption key
for (iLoop=0; iLoop<AES_BLOCK_SIZE; iLoop++)
{
iv[iLoop] = 0;
}
if (AES_set_decrypt_key(key, 128, &aes) < 0)
{
return ;
}
iLen = strlen(source_string)+1;
AES_cbc_encrypt(source_string, des_string, iLen, &aes, iv, AES_DECRYPT);
}
void aes_box_encrypt(unsigned char* source_string, unsigned char* des_string)
{
int iLoop = 0;
int iLen =0;
AES_KEY aes;
unsigned char key[AES_BLOCK_SIZE];
unsigned char iv[AES_BLOCK_SIZE];
if(NULL == source_string || NULL == des_string)
{
return;
}
//Generate own AES Key
for(iLoop = 0; iLoop < 16; iLoop++)
{
key[iLoop] = 32 + iLoop;
}
// Set encryption key
for (iLoop=0; iLoop<AES_BLOCK_SIZE; iLoop++)
{
iv[iLoop] = 0;
}
if (AES_set_encrypt_key(key, 128, &aes) < 0)
{
return ;
}
iLen = strlen(source_string)+1;
AES_cbc_encrypt(source_string, des_string, iLen, &aes, iv, AES_ENCRYPT);
}
char *my_encrypt(char *str,char *path_key){
char *p_en;
RSA *p_rsa;
FILE *file;
int flen,rsa_len;
if((file=fopen(path_key,"r"))==NULL){
perror("source TPM: open key file error");
return NULL;
}
//if((p_rsa=PEM_read_RSA_PUBKEY(file,NULL,NULL,NULL))==NULL){
if((p_rsa=PEM_read_RSAPublicKey(file,NULL,NULL,NULL))==NULL){ // 换成这句死活通不过,无论是否将公钥分离源文件
ERR_print_errors_fp(stdout);
return NULL;
}
flen=strlen(str);
rsa_len=RSA_size(p_rsa);
p_en=(unsigned char *)malloc(rsa_len+1);
memset(p_en,0,rsa_len+1);
if(RSA_public_encrypt(rsa_len,(unsigned char *)str,(unsigned char*)p_en,p_rsa,RSA_NO_PADDING)<0){
return NULL;
}
RSA_free(p_rsa);
fclose(file);
printf("target TPM:encrypt finished\n");
return p_en;
}
char *my_decrypt(char *str,char *path_key){
char *p_de;
RSA *p_rsa;
FILE *file;
int rsa_len;
if((file=fopen(path_key,"r"))==NULL){
perror("source TPM: open key file error");
return NULL;
}
if((p_rsa=PEM_read_RSAPrivateKey(file,NULL,NULL,NULL))==NULL){
ERR_print_errors_fp(stdout);
return NULL;
}
rsa_len=RSA_size(p_rsa);
p_de=(unsigned char *)malloc(rsa_len+1);
memset(p_de,0,rsa_len+1);
if(RSA_private_decrypt(rsa_len,(unsigned char *)str,(unsigned char*)p_de,p_rsa,RSA_NO_PADDING)<0){
return NULL;
}
RSA_free(p_rsa);
fclose(file);
return p_de;
}
int my_client(int cases,unsigned char *serverIp)
{
//-------------------连接source TPM start----------
// 声明并初始化一个客户端的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("DA:Create Socket Failed");
exit(1);
}
// 绑定客户端的socket和客户端的socket地址结构 非必需
if(-1 == (bind(client_socket_fd, (struct sockaddr*)&client_addr, sizeof(client_addr))))
{
perror("DA: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("DA:source TPM 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("DA:Can Not Connect To source TPM IP:");
exit(0);
}
else
{
printf("DA:connect source TPM success\n");
}
//------------连接source TPM end-------------
//------------连接target TPM start-----------
// 声明并初始化一个客户端的socket地址结构
struct sockaddr_in client_addr2;
bzero(&client_addr2, sizeof(client_addr2));
client_addr2.sin_family = AF_INET;
client_addr2.sin_addr.s_addr = htons(INADDR_ANY);
client_addr2.sin_port = htons(0);
// 创建socket,若成功,返回socket描述符
int client_socket_fd2 = socket(AF_INET, SOCK_STREAM, 0);
if(client_socket_fd2 < 0)
{
perror("DA:Create Socket Failed");
exit(1);
}
// 绑定客户端的socket和客户端的socket地址结构 非必需
if(-1 == (bind(client_socket_fd2, (struct sockaddr*)&client_addr2, sizeof(client_addr2))))
{
perror("DA:Client Bind Failed");
exit(1);
}
// 声明一个服务器端的socket地址结构,并用服务器那边的IP地址及端口对其进行初始>化,用于后面的连接
struct sockaddr_in server_addr2;
bzero(&server_addr2, sizeof(server_addr2));
server_addr2.sin_family = AF_INET;
if(inet_pton(AF_INET, "169.254.12.45", &server_addr2.sin_addr) == 0)
{
perror("DA:target TPM IP Address Error:");
exit(1);
}
server_addr2.sin_port = htons(SERVER_PORT);
socklen_t server_addr_length2 = sizeof(server_addr2);
// 向服务器发起连接,连接成功后client_socket_fd2代表了客户端和服务器的一个socket连接
if(connect(client_socket_fd2, (struct sockaddr*)&server_addr2, server_addr_length2) < 0)
{
perror("DA:Can Not Connect To target TPM:");
exit(0);
}
else
{
printf("DA:connect target TPM success\n");
}
//--------------连接target TPM end-------------
// 输入文件名 并放到缓冲区buffer中等待发送
char file_name[FILE_NAME_MAX_SIZE+1]="mig.key";
char buffer[BUFFER_SIZE];
char *seed,*dups,*outerhmac,*encryptionKeyout;
int length = 0;
char dups1[17]={0},sens[17]={0},du[17]={0},*keyout,privatekey[17]={0};
int RA=0;
int Ntpmt=1,Nda1=1,tmpNda=0;//target TPM 发过来的现时;DA的现时
char *nPH=NULL,*nPH_S=NULL,*nPH_ALG=NULL,*objH=NULL,*IDs="NO1",*IDt="NO2",*DRequest="migrate";
unsigned char source_string[]="KEY&ECC&NO2&2",des_string[128]={0};
if(cases==0)
{
printf("------------DA:verify and get stage start-----------\n");
printf("DA:recieve data from target TPM....\n");
bzero(buffer, BUFFER_SIZE);
seed=buffer;
length = recv(client_socket_fd2, seed, BUFFER_SIZE, 0);//收到加密后的ks1值
printf("DA:using DA privatekey dencrypt to get ks1\n");
se=my_decrypt(seed,PRIDA);//解密的到ks1
//printf("解密后的数据为:%s\n",se);
bzero(buffer, BUFFER_SIZE);
length = recv(client_socket_fd2, du, BUFFER_SIZE, 0);//收到加密后的属性数据
strcpy(dups1,du);
printf("DA:using ks decrypt to get ID,CertEK,IDtpm,SignID,Ntpm...\n");
aes_box_decrypt(du,sens);
//printf("DA:解密后的数据为:%s\n",sens);
printf("DA:Verify source TPM ID.....\n");
printf("DA:Verify target TPM ID.....\n");
//Verifysign();
printf("DA:Verify success ,continuing...\n");
//用DA私钥签名DRequest||Nda1
//sign();
printf("DA:send data to source TPM\n");
send(client_socket_fd,DRequest,BUFFER_SIZE,0);
send(client_socket_fd,"djsadaf&y8*&*&*^&6shd",BUFFER_SIZE,0);
//从source TPM接受现时和共享密钥数据
printf("DA:recieve data from source TPM\n");
bzero(buffer,BUFFER_SIZE);
length=recv(client_socket_fd,buffer,BUFFER_SIZE,0);
printf("DA:using DA privatekey dencrypt to get ks2\n");
se=my_decrypt(buffer,PRIDA);
bzero(buffer,BUFFER_SIZE);
length=recv(client_socket_fd,buffer,BUFFER_SIZE,0);
aes_box_decrypt(buffer,sens);
tmpNda=1;
if(tmpNda!=Nda1)
return -1;
//用ks2加密新父密钥相关参数
aes_box_encrypt(source_string,des_string);
//发送给source TPM
printf("DA:send data to source TPM\n");
send(client_socket_fd,des_string,BUFFER_SIZE,0);
printf("DA:recieve data from source TPM...\n");
bzero(buffer, BUFFER_SIZE);
length = recv(client_socket_fd, buffer, BUFFER_SIZE, 0);
//printf("recieve Nda is:%s\n",buffer);
printf("DA:using ks2 decrypt to get data...\n");
aes_box_decrypt(buffer,dups1);
//printf("DA:解密后的数据为:%s\n",dups1);
printf("DA:verify Nda2....\n");
printf("DA:send data to target TPM\n");
bzero(buffer,BUFFER_SIZE);
aes_box_encrypt("3",buffer);
send(client_socket_fd2,buffer,BUFFER_SIZE,0);
printf("------------DA:verify and get stage end------------\n");
}
}
int main(void){
int c,timeuse;
unsigned char *prikey,*dups1;
unsigned char str[10]="migratekey";
FILE *migkeyfp;
char *seed1;
char source[202];
struct timeval start, end;
gettimeofday( &start, NULL );
//my_client(0,"169.254.12.125");
my_client(0,"169.254.12.45");
gettimeofday( &end, NULL );
timeuse = 1000000 * ( end.tv_sec - start.tv_sec ) + end.tv_usec - start.tv_usec;
printf("DA:init total run time: %d us\n", timeuse);
return 0;
}