Example #1
0
void read_server_msg(Client* client)
{
    int valread = read(client->maintainer_fd, client->server_msg.buffer+client->server_msg.offset, BUFFER_SIZE-client->server_msg.offset);
    if(valread == 0)
        exit(1);
    client->server_msg.offset += valread;
    if(client->server_msg.offset == client->server_msg.total_len) {
        if(ENCRYPTION_ENABLED)
            decrypt_msg(client->server_msg.buffer, client->keypair);
        client->server_msg.offset=0;
        logger("<Client><read_server_msg>got message from server\n");
        process_server_msg(client);
    }
}
Example #2
0
int main(int argc, const char * argv[])
{
  int returnvalue;
  
  settimestamp(TRUE);
  set_sigchld_handler();
  
  returnvalue = 0;
  
  switch(getParam(argc, argv))
  {
    case ENCRYPT:
    {
      //encode
      char buffer[BUF_SIZE];
      char * result;
      unsigned int i;
      
      setKey(loadKey("test.key"));
      
      while(!feof(stdin))
      {
        if(fgets(buffer, BUF_SIZE, stdin) == 0)
          break;
        buffer[strlen(buffer)] = '\0';
        printf("%s\n", encrypt_msg(buffer));
      }
      
      break;
    }
    case DECRYPT:
    {
      char buffer[BUF_SIZE];
      
      setKey(loadKey("test.key"));
      
      while(!feof(stdin))
      {
        if(fgets(buffer, BUF_SIZE, stdin) == 0)
          break;
        printf("%s\n", decrypt_msg(buffer));
      }
      
      break;
    }  
    case GENERATE_KEY:
    {
      //generate key
      unsigned int len;
      
      if(argc == 3)
        sscanf(argv[2], "%i", &len);
      else
        len=64;
      
      printf("%s\n", generateKey(len));
      
      break;
    }
    case BASE64ENCODE:
    {
      char buffer[BUF_SIZE];
      
      while(!feof(stdin))
      {
        if(fgets(buffer, BUF_SIZE, stdin) == 0)
          break;
        printf("%s\n", base64encode(buffer, strlen(buffer)));
      }
      
      break;
    }
    case BASE64DECODE:
    {
      char buffer[BUF_SIZE];
      
      while(!feof(stdin))
      {
        if(fgets(buffer, BUF_SIZE, stdin) == 0)
          break;
        printf("%s\n", base64decode(buffer).data);
      }
      
      break;
    }
    case SERVER:
    {
      daemonize();
    
      if(argc > 2)
      {
        setlogdir(argv[2]);
      }
      else
      {
        setlogdir("~/logs");
      }
      
      initlogfile(SERVER_LOG);
      
      serverlog("server started");
      //sleep(60); //debug...
      returnvalue = start_server();
      serverlog("server stopped");
      terminate_log();
      break;
    }
    case NOPARAM:
    default:
    {
      //print usage:
      printf("usage: %s <option>\noptions: [ -g <length> | -d | -e ]\n", argv[0]);
      break;
    }
  }
  
  return 0;
}
Example #3
0
/*******************************************************************
**  Function name: invoke_service_wrapper
**  Descrption: 
**  This function is used to invoke a service call
**  Parameters:
**         tick - the number of milliseconds that have elapsed since the system was started,
**                used to detect which session is idle for the longest time.
**         req_msg - service request message
**         req_msg_size - size of request message
**         resp_msg - service response message
**         resp_msg_size - size of response message
**  Returns: ae_error_t
*******************************************************************/
ae_error_t invoke_service_wrapper (
    /* IN  */ uint64_t  tick,
    /* IN  */ uint8_t*  req_msg,
    /* IN  */ uint32_t  req_msg_size,
    /* OUT */ uint8_t*  resp_msg,
    /* IN  */ uint32_t  resp_msg_size)
{
    // check parameter
    ae_error_t ae_ret = AE_SUCCESS;
    pse_message_t* pse_req_msg  = (pse_message_t*)req_msg;
    pse_message_t* pse_resp_msg = (pse_message_t*)resp_msg;
    pse_op_error_t op_ret;

    if (!req_msg || !resp_msg)
    {
        return PSE_OP_PARAMETER_ERROR;
    }

	//
	// make sure the header is inside enclave
	//
	if (req_msg_size < sizeof(pse_message_t))
	{
		return PSE_OP_PARAMETER_ERROR;
	}

	//
	// if this mispredicts, we might overflow below
	//
	sgx_lfence();

	if (pse_req_msg->payload_size > UINT32_MAX - sizeof(pse_message_t)   // check potential overflow
        || req_msg_size != sizeof(pse_message_t) + pse_req_msg->payload_size)
    {
        return PSE_OP_PARAMETER_ERROR;
    }

    if (resp_msg_size < sizeof(pse_message_t)           // make sure the header is inside enclave
        || pse_req_msg->exp_resp_size > UINT32_MAX - sizeof(pse_message_t)   // check potential overflow
        || resp_msg_size < sizeof(pse_message_t) + pse_req_msg->exp_resp_size)
    {
        return PSE_OP_PARAMETER_ERROR;
    }

	//
	// put LFENCE here mostly for pse_req_msg->payload_size 
	// check above. I don't think we use 
	// pse_req_msg->exp_resp_size to calculate 
	// any pointers.
	//
	sgx_lfence();

    pse_session_t* session = sid2session(pse_req_msg->session_id);

    // ephemeral session must have been established 
    if(!is_eph_session_active())
    {
        // the ephemeral session is not active
        return PSE_OP_EPHEMERAL_SESSION_INVALID;
    }
    
    //if session is invalid (session not exists or established, or sequence num overflow)
    if (!is_isv_session_valid(session))
    {
        return PSE_OP_SESSION_INVALID;
    }

    // update session tick
    update_session_tick_count(session, tick);

    //clear response message
    memset(resp_msg, 0, resp_msg_size);

    uint8_t* req = (uint8_t*)malloc(pse_req_msg->payload_size);
    uint8_t* resp= NULL;
    uint32_t session_seq_num = get_session_seq_num(session);
    do
    {
        BREAK_ON_MALLOC_FAIL(req, ae_ret)

        // decrypt service request message using session key
        if(false == decrypt_msg(pse_req_msg, req, (sgx_key_128bit_t*)session->active.AEK))
        {
            ae_ret = PSE_OP_SERVICE_MSG_ERROR;
            break;
        }
        pse_req_hdr_t* req_hdr = (pse_req_hdr_t*)req;

        // check session sequence number
        if(req_hdr->seq_num != session_seq_num)
        {
            ae_ret = PSE_OP_SESSION_INVALID;
            //close session
            free_session(session);
            break;
        }

        // Dispatch the service request to the proper handler
        int i;
        int service_count = static_cast<int>(sizeof(service_handler) / sizeof(service_handler_t));
        for (i = 0; i < service_count; i++)
        {
			//
			// might mispredict the end of the loop
			//
			sgx_lfence();

            if (req_hdr->service_id == service_handler[i].service_id &&
                req_hdr->service_cmd == service_handler[i].service_cmd)
            {
                if (pse_req_msg->payload_size != service_handler[i].req_size ||
                    pse_req_msg->exp_resp_size < service_handler[i].resp_size) // response message buffer must be large enough to hold response data 
                {
                    ae_ret = PSE_OP_SERVICE_MSG_ERROR;
                    goto clean_up;
                }
                resp = (uint8_t*)malloc(service_handler[i].resp_size);
                if (resp == NULL)
                {
                    ae_ret = PSE_OP_INTERNAL_ERROR;
                    goto clean_up;
                }

				//
				// in case payload_size, req_size comparisons
				// mispredict
				//
				sgx_lfence();


                // serve the request
                op_ret = service_handler[i].srv_pfn(session->isv_attributes, req, resp);
                if(op_ret != OP_SUCCESS)
                {
                    ae_ret = error_reinterpret(op_ret);
                    goto clean_up;
                }

                // set payload size for valid requests
                pse_resp_msg->payload_size = service_handler[i].resp_size;
                
                break;
            }
        }
        if (i == service_count)
        {
            // service_id or service_cmd mismatch
            resp = (uint8_t*)malloc(sizeof(pse_resp_hdr_t));
            BREAK_ON_MALLOC_FAIL(resp, ae_ret)

            // for unknown requests, payload data only includes response header
            pse_resp_msg->payload_size = sizeof(pse_resp_hdr_t);

            // set error status
            ((pse_resp_hdr_t*)resp)->status = PSE_ERROR_UNKNOWN_REQ;
        }

        // prepare the response message
        pse_resp_hdr_t* resp_hdr = (pse_resp_hdr_t*)resp;

        pse_resp_msg->exp_resp_size = 0;
        pse_resp_msg->session_id = pse_req_msg->session_id;

        //set response header, status code is already set in service functions
        resp_hdr->seq_num = session_seq_num + 1;    // addition overflow already checked in is_isv_session_valid()
        resp_hdr->service_id = req_hdr->service_id;
        resp_hdr->service_cmd = req_hdr->service_cmd;

        // update sequence number for current session
        set_session_seq_num(session, resp_hdr->seq_num + 1);

        // encrypt the response message
        if(false == encrypt_msg((pse_message_t*)pse_resp_msg, 
                                (uint8_t*)resp, 
                                (sgx_key_128bit_t*)session->active.AEK))
        {
            ae_ret = PSE_OP_INTERNAL_ERROR;
            break;
        }
    } while (0);

clean_up:
    SAFE_FREE(req);
    SAFE_FREE(resp);
    return ae_ret;
}