ProtobufLAInitiator.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. // Knows only protobuf_sgx objects, protobuf header.
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <errno.h>
  5. #include<unistd.h>
  6. #include <stdio.h>
  7. #include "ProtobufLAMessages.h"
  8. #include <google/protobuf/io/coded_stream.h>
  9. #include <google/protobuf/io/zero_copy_stream_impl.h>
  10. using namespace google::protobuf::io;
  11. #include "SgxProtobufLAInitiator.h"
  12. #include "crypto.h"
  13. // For socket programming
  14. #include <arpa/inet.h>
  15. #include <sys/socket.h>
  16. #include <netinet/in.h>
  17. // TODO: Make these private functions
  18. int read_protobuf_msg_from_fd(int accept_fd, google::protobuf::MessageLite& message)
  19. {
  20. ZeroCopyInputStream* raw_input;
  21. CodedInputStream* coded_input;
  22. uint32_t size;
  23. CodedInputStream::Limit limit;
  24. raw_input = new FileInputStream(accept_fd);
  25. coded_input = new CodedInputStream(raw_input);
  26. if(!coded_input->ReadVarint32(&size))
  27. {
  28. printf("Error in reading size of msg");
  29. fflush(stdout);
  30. return -1;
  31. }
  32. //printf("size of msg was read to be %" PRIu32 " \n", size);
  33. fflush(stdout);
  34. limit = coded_input->PushLimit(size);
  35. if(!message.ParseFromCodedStream(coded_input))
  36. {
  37. printf("Error in parsing msg");
  38. fflush(stdout);
  39. return -1;
  40. }
  41. coded_input->PopLimit(limit);
  42. return 0;
  43. }
  44. // TODO: private functions
  45. int write_protobuf_msg_to_fd(int accept_fd, google::protobuf::MessageLite& message)
  46. {
  47. ZeroCopyOutputStream* raw_output = new FileOutputStream(accept_fd);
  48. CodedOutputStream* coded_output = new CodedOutputStream(raw_output);
  49. coded_output->WriteVarint32(message.ByteSize());
  50. if(!message.SerializeToCodedStream(coded_output))
  51. {
  52. printf("SerializeToCodedStream failed");
  53. fflush(stdout);
  54. return -1;
  55. }
  56. // As per this - https://stackoverflow.com/questions/22881876/protocol-buffers-how-to-serialize-and-deserialize-multiple-messages-into-a-file?noredirect=1&lq=1
  57. // TODO: There may be a better way to do this - 1) this happens with every accept now and 2) make it happen on the stack vs heap - destructor will be called on return from this function (main) and the items will then be written out. (We probably don't want that, actually)
  58. delete coded_output;
  59. delete raw_output;
  60. fflush(stdout);
  61. return 0;
  62. }
  63. // Sets up a socket connected to the port passed as input - returns the socket FD on success and -1 on error.
  64. // Also prints the errno on error.
  65. int set_up_socket_connect(int port)
  66. {
  67. int sock = 0;
  68. if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  69. {
  70. printf("\n Error in socket call - errno is %d \n", errno);
  71. return -1;
  72. }
  73. struct sockaddr_in serv_addr;
  74. memset(&serv_addr, '0', sizeof(serv_addr));
  75. serv_addr.sin_family = AF_INET;
  76. serv_addr.sin_port = htons(port);
  77. // Convert IPv4 and IPv6 addresses from text to binary form
  78. if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0)
  79. {
  80. printf("\nError in inet_pton - errno is %d\n", errno);
  81. return -1;
  82. }
  83. if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
  84. {
  85. printf("\nError in connect - errno is %d \n", errno);
  86. return -1;
  87. }
  88. return sock;
  89. }
  90. int local_attestation_initiator(int port, unsigned char* base64_encoded)
  91. {
  92. // declare msg1, msg2, msg3 protobuf objects
  93. protobuf_sgx_dh_msg1_t protobuf_msg1;
  94. protobuf_sgx_dh_msg2_t protobuf_msg2;
  95. protobuf_sgx_dh_msg3_t protobuf_msg3;
  96. uint32_t protobuf_sgx_ret;
  97. // uint8_t encrypted_hash[32]; uint8_t encrypted_tag[16]; size_t post_la_bytes_written;
  98. // uint8_t tokenT_and_tag[176]; size_t bytes_read;
  99. // For socket to listen to the Apache enclave.
  100. // int server_fd=0; int accept_fd = 0;
  101. // struct sockaddr_in own_addr;
  102. // struct sockaddr_storage apache_addr; socklen_t apache_addr_size = sizeof(apache_addr);
  103. uint32_t session_id;
  104. // int counter;
  105. int decryptor_fd;
  106. setbuf(stdout,NULL);
  107. decryptor_fd=set_up_socket_connect(port);
  108. if(decryptor_fd == -1)
  109. {
  110. perror("\nCould not set up the socket: had the following error: ");
  111. fflush(stderr);
  112. }
  113. // printf("");
  114. if(read_protobuf_msg_from_fd(decryptor_fd, protobuf_msg1)!=0)
  115. return -1;
  116. protobuf_sgx_ret = process_protobuf_dh_msg1_generate_protobuf_dh_msg2(protobuf_msg1, protobuf_msg2, &session_id);
  117. if(protobuf_sgx_ret != 0)
  118. {
  119. printf("Error in process_protobuf_dh_msg1_generate_protobuf_dh_msg2: 0x%x", protobuf_sgx_ret); fflush(stdout); return protobuf_sgx_ret;
  120. }
  121. if(write_protobuf_msg_to_fd(decryptor_fd, protobuf_msg2)!=0)
  122. return -1;
  123. if(read_protobuf_msg_from_fd(decryptor_fd, protobuf_msg3)!=0)
  124. return -1;
  125. protobuf_sgx_ret = process_protobuf_dh_msg3(protobuf_msg3, &session_id);
  126. if(protobuf_sgx_ret != 0)
  127. {
  128. printf("Error in process_protobuf_dh_msg3: 0x%x", protobuf_sgx_ret); fflush(stdout); return protobuf_sgx_ret;
  129. }
  130. /* memset(encrypted_hash,0, 32); memset(encrypted_tag, 0, 16);
  131. protobuf_sgx_ret=generate_encrypted_rsa_keypair_hash(encrypted_hash, encrypted_tag);
  132. if(protobuf_sgx_ret==0)
  133. {
  134. printf("Done encryption of hash.\n"); fflush(stdout);
  135. }
  136. else
  137. {
  138. printf("Error in enc/dec of hash: 0x%x", protobuf_sgx_ret); fflush(stdout); return protobuf_sgx_ret;
  139. }
  140. /* uint32_t count;
  141. for(count=0;count<32;count++)
  142. printf("0x%x ", hash_and_tag[count]);
  143. printf("\n");fflush(stdout);
  144. */
  145. uint8_t tokenT_and_tag[176]; size_t bytes_read;
  146. bytes_read = read(decryptor_fd, tokenT_and_tag, 176);
  147. // post_la_bytes_written = write(decryptor_fd, encrypted_tag, 16);
  148. if(bytes_read != 176)
  149. {
  150. printf("Not all of the post-LA message was read\n"); fflush(stdout); return 0xfe;
  151. }
  152. printf("Read encrypted signature and tag from the decryptor socket.\n"); fflush(stdout);
  153. if(close(decryptor_fd)!= 0)
  154. {
  155. printf("Error in closing the socket connection.\n"); fflush(stdout); return 0xfd;
  156. }
  157. uint32_t count;
  158. printf("Encrypted data:\n");
  159. for(count=0;count<176;count++)
  160. printf("0x%02x ", tokenT_and_tag[count]);
  161. printf("\n"); fflush(stdout);
  162. uint8_t plaintext_token[160]; int plaintext_length=0;
  163. uint32_t ret_decrypt=decrypt_wrapper(tokenT_and_tag, 160, plaintext_token, &plaintext_length, tokenT_and_tag+160);
  164. //int aes_cipher(int enc, unsigned char *key, unsigned char *iv, unsigned char* plaintext, int plaintext_len, unsigned char *ciphertext, int* op_ciphertext_len, unsigned char* tag);
  165. if(ret_decrypt!=0)
  166. {
  167. printf("Errorin decryption 0x%x", ret_decrypt); fflush(stdout); return 0xed;
  168. }
  169. printf("Decryption keypair\n");
  170. for(count=0;count<64;count++)
  171. printf("0x%02x ", plaintext_token[count]);
  172. printf("\n"); fflush(stdout);
  173. printf("Decryption verifier mrenclave\n");
  174. for(count=64;count<96;count++)
  175. printf("0x%02x ", plaintext_token[count]);
  176. printf("\n"); fflush(stdout);
  177. count=base64_encoding_wrapper(plaintext_token, base64_encoded, 160);
  178. if(count != 216)
  179. {
  180. printf("Somehow not the entire token was encoded in base64:0x%x\n", count); fflush(stdout); return 0x55;
  181. }
  182. printf("Successfully done Local attestation\n");
  183. fflush(stdout);
  184. return 0;
  185. }