// Knows only protobuf_sgx objects, protobuf header. // For socket programming #include #include #include #include #include #include #include #include "ProtobufLAMessages.pb.h" #include #include using namespace google::protobuf::io; #include "protobufLAInitiator.h" #include "../Decryptor/Decryptor_u.h" #include #include "LocalAttestationUntrusted.h" #include #include #include #include uint32_t LocalAttestationUntrusted::session_id=0; protobuf_sgx_dh_msg1_t LocalAttestationUntrusted::protobuf_msg1; uint8_t* LocalAttestationUntrusted::output_ciphertext_plus_tag=NULL; int LocalAttestationUntrusted::read_protobuf_msg_from_fd(int accept_fd, google::protobuf::MessageLite& message) { ZeroCopyInputStream* raw_input; CodedInputStream* coded_input; uint32_t size; CodedInputStream::Limit limit; raw_input = new FileInputStream(accept_fd); coded_input = new CodedInputStream(raw_input); if(!coded_input->ReadVarint32(&size)) { printf("Error in reading size of msg"); fflush(stdout); return -1; } //printf("size of msg was read to be %" PRIu32 " \n", size); fflush(stdout); limit = coded_input->PushLimit(size); if(!message.ParseFromCodedStream(coded_input)) { printf("Error in parsing msg"); fflush(stdout); return -1; } coded_input->PopLimit(limit); delete raw_input; delete coded_input; return 0; } int LocalAttestationUntrusted::write_protobuf_msg_to_fd(int accept_fd, google::protobuf::MessageLite& message) { ZeroCopyOutputStream* raw_output = new FileOutputStream(accept_fd); CodedOutputStream* coded_output = new CodedOutputStream(raw_output); coded_output->WriteVarint32(message.ByteSize()); if(!message.SerializeToCodedStream(coded_output)) { printf("SerializeToCodedStream failed"); fflush(stdout); return -1; } // As per this - https://stackoverflow.com/questions/22881876/protocol-buffers-how-to-serialize-and-deserialize-multiple-messages-into-a-file?noredirect=1&lq=1 // 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) delete coded_output; delete raw_output; fflush(stdout); return 0; } // Sets up a socket to bind and listen to the given port. Returns FD of the socket on success, -1 on failure (and prints a msg to stdout with the errno) int LocalAttestationUntrusted::set_up_socket(int port, sockaddr_in* address) { int server_fd = 0; // Creating socket file descriptor for listening for attestation requests. server_fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); if (server_fd == -1) { printf("Error in creating a socket - %d", errno); return -1; } // Preparing the address struct for binding address->sin_family = AF_INET; address->sin_addr.s_addr = INADDR_ANY; // Todo: should this be localhost? address->sin_port = htons(port); // memset(address->sin_zero,0,sizeof(address->sin_zero)); socklen_t addrlen = sizeof(*address); // Binding if (bind(server_fd, (sockaddr*)address, addrlen)<0) { printf("Error in binding %d - port was %d - ", errno, port); return -1; } // Listening if (listen(server_fd, 128) < 0) { printf("Error in listening %d", errno); return -1; } return server_fd; } uint32_t LocalAttestationUntrusted::local_attestation_msg2_msg3(uint32_t own_enclave_id, int accept_fd) { uint32_t protobuf_sgx_ret; protobuf_sgx_dh_msg2_t protobuf_msg2; protobuf_sgx_dh_msg3_t protobuf_msg3; printf("Writing message 1\n"); fflush(stdout); if(write_protobuf_msg_to_fd(accept_fd, protobuf_msg1)!=0) return 0x1; printf("Reading message 2\n"); fflush(stdout); if(read_protobuf_msg_from_fd(accept_fd, protobuf_msg2)!=0) return 0x2; protobuf_sgx_ret = process_protobuf_dh_msg2_generate_protobuf_dh_msg3(own_enclave_id, protobuf_msg2, protobuf_msg3, &LocalAttestationUntrusted::session_id); if(protobuf_sgx_ret != 0) { printf("Error in generate_protobuf_dh_msg2: 0x%x", protobuf_sgx_ret); fflush(stdout); return protobuf_sgx_ret; } printf("Writing message 3\n"); fflush(stdout); if(write_protobuf_msg_to_fd(accept_fd, protobuf_msg3)!=0) return 0x3; return 0; } int LocalAttestationUntrusted::decrypt_client_data(uint32_t own_enclave_id, int fd, uint8_t* output_ciphertext_plus_tag, uint8_t* input_ciphertext_plus_tag, int time_file_fd) { protobuf_post_LA_encrypted_msg_t protobuf_msg; protobuf_post_LA_encrypted_msg_t protobuf_msg_response; unsigned char* protobuf_msg_ptr; uint32_t sgx_ret_status=0; uint32_t input_ciphertext_plus_tag_length; uint32_t output_ciphertext_plus_tag_length; struct timeval tv1, tv2; char time_buf[60] = {0}; size_t bytes_written; unsigned long int new_time, old_time; uint32_t count; if(read_protobuf_msg_from_fd(fd, protobuf_msg)!=0) return 0xfe; gettimeofday(&tv1, NULL); input_ciphertext_plus_tag_length = protobuf_msg.msg().length(); protobuf_msg_ptr = (uint8_t*) protobuf_msg.msg().c_str(); // Just so that the ciphertext - client data - is returned back to Apache in case this function fails. // client data is after public key (64 bytes) protobuf_msg_response.set_msg((void*) protobuf_msg_ptr + 64, input_ciphertext_plus_tag_length - 64); for(count=0;count