networkClient.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. #include "networkClient.hpp"
  2. std::string random_string(size_t length)
  3. {
  4. auto randchar = []() -> char
  5. {
  6. const char charset[] =
  7. "0123456789_-"
  8. "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  9. "abcdefghijklmnopqrstuvwxyz";
  10. const size_t max_index = (sizeof(charset) - 1);
  11. return charset[ rand() % max_index ];
  12. };
  13. std::string str(length,0);
  14. std::generate_n(str.begin(), length, randchar);
  15. return str;
  16. }
  17. PrsonaClientWebSocketHandler::PrsonaClientWebSocketHandler(
  18. const PrsonaClient *prsonaClient,
  19. const std::vector<std::string> serverIPs,
  20. const std::string selfIP)
  21. : prsonaClient(prsonaClient), serverIPs(serverIPs), selfIP(selfIP)
  22. { /* */ }
  23. virtual bool PrsonaClientWebSocketHandler::handleConnection(
  24. CivetServer *server,
  25. const struct mg_connection *conn)
  26. {
  27. const struct mg_request_info *info = mg_get_request_info(conn);
  28. flag = (info->query_string && info->query_string[0] == PRSONA_VERIFY_REPUTATION_PROOF);
  29. return flag;
  30. }
  31. void PrsonaServerWebSocketHandler::set_temp_filename(
  32. struct mg_connection *conn) const
  33. {
  34. std::string filename = random_string(TMP_FILE_SIZE);
  35. char *c_filename = new char[TMP_FILE_SIZE+TMP_DIR_SIZE+1];
  36. strncpy(c_filename, TMP_DIR, TMP_DIR_SIZE);
  37. for (size_t i = 0; i < TMP_FILE_SIZE; i++)
  38. c_filename[i + TMP_DIR_SIZE] = filename[i];
  39. c_filename[TMP_DIR_SIZE + TMP_FILE_SIZE] = 0;
  40. mg_set_user_connection_data(conn, c_filename);
  41. }
  42. virtual void PrsonaClientWebSocketHandler::handleReadyState(
  43. CivetServer *server,
  44. struct mg_connection *conn)
  45. {
  46. const struct mg_request_info *info = mg_get_request_info(conn);
  47. switch (info->query_string[0])
  48. {
  49. case PRSONA_VERIFY_REPUTATION_PROOF:
  50. set_temp_filename(conn);
  51. break;
  52. default:
  53. mg_set_user_connection_data(conn, NULL);
  54. break;
  55. }
  56. }
  57. virtual bool PrsonaClientWebSocketHandler::handleData(
  58. CivetServer *server,
  59. struct mg_connection *conn,
  60. int bits,
  61. char *data,
  62. size_t data_len)
  63. {
  64. char *filename = (char *) mg_get_user_connection_data(conn);
  65. if ((bits & 0xf) == MG_WEBSOCKET_OPCODE_DATACOMPLETE)
  66. {
  67. generate_response(conn, filename);
  68. return false;
  69. }
  70. if ((bits & 0xf) != MG_WEBSOCKET_OPCODE_BINARY && (bits & 0xf) != MG_WEBSOCKET_OPCODE_CONTINUATION)
  71. {
  72. std::cerr << "Unknown opcode: failing." << std::endl;
  73. return false;
  74. }
  75. FILE *currFile = fopen(filename, "ab");
  76. fwrite(data, sizeof(char), data_len, currFile);
  77. fclose(currFile);
  78. return true;
  79. }
  80. void PrsonaServerWebSocketHandler::generate_response(
  81. struct mg_connection *conn,
  82. char *filename)
  83. {
  84. const struct mg_request_info *info = mg_get_request_info(conn);
  85. switch (info->query_string[0])
  86. {
  87. case PRSONA_VERIFY_REPUTATION_PROOF:
  88. verify_reputation_proof(conn, filename);
  89. break;
  90. default:
  91. break;
  92. }
  93. }
  94. virtual void PrsonaClientWebSocketHandler::handleClose(
  95. CivetServer *server,
  96. const struct mg_connection *conn)
  97. {
  98. char *filename = (char *) mg_get_user_connection_data(conn);
  99. if (!filename)
  100. return;
  101. remove(filename);
  102. delete filename;
  103. }
  104. EGCiphertext PrsonaClientWebSocketHandler::get_first_encrypted_score(
  105. const std::string& server,
  106. Proof& pi,
  107. const Twistpoint& shortTermPublicKey) const
  108. {
  109. struct synchronization_tool synch;
  110. std::unique_lock<std::mutex> lck(synch.mtx, std::defer_lock);
  111. bool flag = false;
  112. while (!flag)
  113. {
  114. struct mg_connection *conn =
  115. mg_connect_websocket_client(
  116. server.c_str(),
  117. PRSONA_PORT,
  118. USE_SSL,
  119. NULL,
  120. 0,
  121. USER_TALLY_URI,
  122. "null",
  123. score_websocket_data_handler,
  124. score_websocket_close_handler,
  125. (void *) &synch);
  126. if (!conn)
  127. {
  128. std::cerr << "Trouble getting encrypted score from server at " << recipient << std::endl;
  129. continue;
  130. }
  131. lck.lock();
  132. synch.val = 0;
  133. mg_websocket_client_write(
  134. conn,
  135. MG_WEBSOCKET_OPCODE_DATACOMPLETE,
  136. "",
  137. 0);
  138. flag = true;
  139. }
  140. while (!synch.val)
  141. synch.cv.wait(lck)
  142. // TODO: Finish retrieving first score
  143. }
  144. void PrsonaClientWebSocketHandler::get_additional_commitment(
  145. const std::vector<std::string>& server,
  146. std::vector<Proof>& pi,
  147. const Twistpoint& shortTermPublicKey) const
  148. {
  149. bool flag = false;
  150. while (!flag)
  151. {
  152. struct mg_connection *conn =
  153. mg_connect_websocket_client(
  154. server.c_str(),
  155. PRSONA_PORT,
  156. USE_SSL,
  157. NULL,
  158. 0,
  159. USER_TALLY_COMMIT_URI,
  160. "null",
  161. synchro_websocket_data_handler,
  162. empty_websocket_close_handler,
  163. (void *) synch);
  164. if (!conn)
  165. {
  166. std::cerr << "Trouble getting encrypted score commitment from server at " << recipient << std::endl;
  167. continue;
  168. }
  169. mg_websocket_client_write(
  170. conn,
  171. MG_WEBSOCKET_OPCODE_DATACOMPLETE,
  172. "",
  173. 0);
  174. flag = true;
  175. }
  176. // TODO: Finish retrieving rest of score commitments
  177. }
  178. EGCiphertext PrsonaClientWebSocketHandler::get_encrypted_score(
  179. std::vector<Proof>& pi,
  180. const Twistpoint& shortTermPublicKey) const
  181. {
  182. pi.clear();
  183. Proof firstProof;
  184. EGCiphertext retval =
  185. get_first_encrypted_score(
  186. serverIPs[0], firstProof, shortTermPublicKey);
  187. pi.push_back(firstProof);
  188. get_additional_commitment(serverIPs, pi, shortTermPublicKey);
  189. return retval;
  190. }
  191. void PrsonaClientWebSocketHandler::verify_reputation_proof(
  192. struct mg_connection *conn, const char *filename) const
  193. {
  194. ifstream file(filename);
  195. std::vector<Proof> pi;
  196. Twistpoint shortTermPublicKey;
  197. Scalar threshold;
  198. size_t sizeOfVector;
  199. file >> sizeOfVector;
  200. for (size_t i = 0; i < sizeOfVector; i++)
  201. {
  202. Proof currProof;
  203. file >> currProof;
  204. pi.push_back(currProof);
  205. }
  206. file >> shortTermPublicKey;
  207. file >> threshold;
  208. for (size_t i = 0; i < sizeOfVector; i++)
  209. {
  210. CurveBipoint currScore;
  211. file >> currScore;
  212. serverScores.push_back(currScore);
  213. }
  214. std::vector<Proof> encryptedScoreProof;
  215. EGCiphertext encryptedScore =
  216. get_encrypted_score(encryptedScoreProof);
  217. bool flag =
  218. prsonaClient->verify_reputation_proof(
  219. pi,
  220. shortTermPublicKey,
  221. threshold,
  222. encryptedScoreProof,
  223. encryptedScore);
  224. string data = flag ? "\x01" : "\x00";
  225. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), 1);
  226. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
  227. }