networkClient.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. #include <cstring>
  2. #include <cstdio>
  3. #include "networkClient.hpp"
  4. template <>
  5. EGCiphertext get_committed_val_from_file<EGCiphertext>(
  6. struct synchronization_tool *sync,
  7. char *filename,
  8. Proof& pi)
  9. {
  10. std::unique_lock<std::mutex> lck(sync->mtx);
  11. std::ifstream valFile(filename);
  12. EGCiphertext retval;
  13. valFile >> pi;
  14. valFile >> retval;
  15. return retval;
  16. }
  17. template <>
  18. std::vector<TwistBipoint> get_committed_val_from_file<std::vector<TwistBipoint>>(
  19. struct synchronization_tool *sync,
  20. char *filename,
  21. Proof& pi)
  22. {
  23. std::unique_lock<std::mutex> lck(sync->mtx);
  24. std::ifstream valFile(filename);
  25. valFile >> pi;
  26. std::vector<TwistBipoint> retval;
  27. BinarySizeT sizeOfVector;
  28. for (size_t i = 0; i < sizeOfVector.val(); i++)
  29. {
  30. TwistBipoint currVote;
  31. valFile >> currVote;
  32. retval.push_back(currVote);
  33. }
  34. return retval;
  35. }
  36. template <typename T>
  37. T get_first_committed_val(
  38. const std::string& server,
  39. Proof& pi,
  40. const Twistpoint& shortTermPublicKey,
  41. const char *firstUri)
  42. {
  43. struct synchronization_tool sync;
  44. std::stringstream buffer;
  45. std::string data;
  46. buffer << shortTermPublicKey;
  47. data = buffer.str();
  48. bool flag = false;
  49. while (!flag)
  50. {
  51. struct mg_connection *conn =
  52. mg_connect_websocket_client(
  53. server.c_str(),
  54. PRSONA_PORT,
  55. USE_SSL,
  56. NULL,
  57. 0,
  58. firstUri,
  59. "null",
  60. file_websocket_data_handler,
  61. file_websocket_close_handler,
  62. (void *) &sync);
  63. if (!conn)
  64. {
  65. std::cerr << "Trouble getting encrypted score from server at " << server << std::endl;
  66. continue;
  67. }
  68. std::unique_lock<std::mutex> lck(sync.mtx);
  69. char *filename = set_temp_filename(conn);
  70. sync.val = 0;
  71. mg_websocket_client_write(
  72. conn,
  73. MG_WEBSOCKET_OPCODE_BINARY,
  74. data.c_str(),
  75. data.length());
  76. mg_websocket_client_write(
  77. conn,
  78. MG_WEBSOCKET_OPCODE_DATACOMPLETE,
  79. "",
  80. 0);
  81. while (!sync.val)
  82. sync.cv.wait(lck)
  83. mg_close_connection(conn);
  84. flag = true;
  85. }
  86. T retval = get_committed_val_from_file<T>(filename, pi);
  87. remove(filename);
  88. delete filename;
  89. return retval;
  90. }
  91. Proof get_commitment_from_file(
  92. struct synchronization_tool *sync,
  93. char *filename)
  94. {
  95. std::unique_lock<std::mutex> lck(sync->mtx);
  96. std::ifstream scoreFile(filename);
  97. Proof retval;
  98. scoreFile >> retval;
  99. return retval;
  100. }
  101. void get_additional_commitment(
  102. const std::vector<std::string>& servers,
  103. const std::string& skip,
  104. std::vector<Proof>& pi,
  105. const Twistpoint& shortTermPublicKey,
  106. char *commitUri)
  107. {
  108. std::vector<char *> commitmentFilenames;
  109. std::vector<struct synchronization_tool *> commitmentSyncs;
  110. for (size_t i = 0; i < servers.size(); i++)
  111. {
  112. if (servers[i] == skip)
  113. continue;
  114. struct synchronization_tool *currSync = new struct synchronization_tool;
  115. commitmentSyncs.push_back(currSync);
  116. bool flag = false;
  117. while (!flag)
  118. {
  119. struct mg_connection *conn =
  120. mg_connect_websocket_client(
  121. servers[i].c_str(),
  122. PRSONA_PORT,
  123. USE_SSL,
  124. NULL,
  125. 0,
  126. commitUri,
  127. "null",
  128. file_websocket_data_handler,
  129. file_websocket_close_handler,
  130. (void *) currSync);
  131. if (!conn)
  132. {
  133. std::cerr << "Trouble getting commitment from server at " << servers[i] << std::endl;
  134. continue;
  135. }
  136. std::unique_lock<std::mutex> lck(currSync->mtx);
  137. currSync->val = 0;
  138. commitmentFilenames.push_back(set_temp_filename(conn));
  139. mg_websocket_client_write(
  140. conn,
  141. MG_WEBSOCKET_OPCODE_DATACOMPLETE,
  142. "",
  143. 0);
  144. while (!currSync->val)
  145. currSync->cv.wait(lck)
  146. mg_close_connection(conn);
  147. flag = true;
  148. }
  149. }
  150. for (size_t i = 0; i < commitmentFilenames.size(); i++)
  151. {
  152. pi.push_back(
  153. get_commitment_from_file(
  154. commitmentSyncs[i], commitmentFilenames[i]));
  155. delete commitmentSyncs[i];
  156. remove(commitmentFilenames[i]);
  157. delete commitmentFilenames[i];
  158. }
  159. }
  160. template <typename T>
  161. T get_server_committed_val(
  162. std::default_random_engine *generator,
  163. const std::vector<std::string>& serverIPs,
  164. std::vector<Proof>& pi,
  165. const Twistpoint& shortTermPublicKey,
  166. const char *firstUri
  167. const char *commitUri)
  168. {
  169. std::uniform_int_distribution<size_t> distribution(0, serverIPs.size() - 1);
  170. size_t whichServer = distribution(*generator);
  171. pi.clear();
  172. Proof firstProof;
  173. T retval =
  174. get_first_committed_val<T>(
  175. serverIPs[whichServer],
  176. firstProof,
  177. shortTermPublicKey
  178. firstUri);
  179. pi.push_back(firstProof);
  180. get_additional_commitment(
  181. serverIPs,
  182. serverIPs[whichServer],
  183. pi,
  184. shortTermPublicKey,
  185. commitUri);
  186. return retval;
  187. }
  188. Twistpoint get_generator_from_file(
  189. struct synchronization_tool *sync,
  190. const char *filename,
  191. std::vector<Proof>& pi)
  192. {
  193. std::ifstream genFile(filename);
  194. BinarySizeT sizeOfVector;
  195. genFile >> sizeOfVector;
  196. for (size_t i = 0; i < sizeOfVector.val(); i++)
  197. {
  198. Proof currProof;
  199. genFile >> currProof;
  200. pi.push_back(currProof);
  201. }
  202. Twistpoint retval;
  203. genFile >> retval;
  204. return retval;
  205. }
  206. Twistpoint get_generator(
  207. std::default_random_engine *randomGenerator,
  208. const std::vector<std::string>& serverIPs,
  209. std::vector<Proof>& pi,
  210. bool fresh)
  211. {
  212. struct synchronization_tool sync;
  213. std::uniform_int_distribution<size_t> distribution(0, serverIPs.size() - 1);
  214. size_t whichServer = distribution(*randomGenerator);
  215. pi.clear();
  216. const char* whichUri = (fresh ? FRESH_GEN_URI : BLIND_GEN_URI);
  217. bool flag = false;
  218. while (!flag)
  219. {
  220. struct mg_connection *conn = mg_connect_websocket_client(
  221. serverIPs[whichServer].c_str(),
  222. PRSONA_PORT,
  223. USE_SSL,
  224. NULL,
  225. 0,
  226. whichUri,
  227. "null",
  228. file_websocket_data_handler,
  229. file_websocket_close_handler,
  230. (void *) &sync);
  231. if (!conn)
  232. {
  233. cerr << "Couldn't obtain BGN details" << endl;
  234. return 1;
  235. }
  236. unique_lock<mutex> lck(sync.mtx);
  237. char *filename = set_temp_filename(conn);
  238. sync.val = 0;
  239. mg_websocket_client_write(
  240. conn,
  241. MG_WEBSOCKET_OPCODE_DATACOMPLETE,
  242. "",
  243. 0);
  244. while (!sync.val)
  245. sync.cv.wait(lck);
  246. mg_close_connection(conn);
  247. flag = true;
  248. }
  249. Twistpoint retval =
  250. get_generator_from_file(&sync, filename, pi);
  251. remove(filename);
  252. delete filename;
  253. return retval;
  254. }
  255. PrsonaClientWebSocketHandler::PrsonaClientWebSocketHandler(
  256. const PrsonaClient *prsonaClient,
  257. const std::vector<std::string>& serverIPs,
  258. const std::string& selfIP,
  259. const std::default_random_engine *generator)
  260. : prsonaClient(prsonaClient), serverIPs(serverIPs),
  261. selfIP(selfIP), generator(generator)
  262. { /* */ }
  263. virtual bool PrsonaClientWebSocketHandler::handleConnection(
  264. CivetServer *server,
  265. const struct mg_connection *conn)
  266. {
  267. const struct mg_request_info *info = mg_get_request_info(conn);
  268. flag = (info->query_string && info->query_string[0] == PRSONA_VERIFY_REPUTATION_PROOF);
  269. return flag;
  270. }
  271. virtual void PrsonaClientWebSocketHandler::handleReadyState(
  272. CivetServer *server,
  273. struct mg_connection *conn)
  274. {
  275. const struct mg_request_info *info = mg_get_request_info(conn);
  276. switch (info->query_string[0])
  277. {
  278. case PRSONA_VERIFY_REPUTATION_PROOF:
  279. set_temp_filename(conn);
  280. break;
  281. default:
  282. mg_set_user_connection_data(conn, NULL);
  283. break;
  284. }
  285. }
  286. virtual bool PrsonaClientWebSocketHandler::handleData(
  287. CivetServer *server,
  288. struct mg_connection *conn,
  289. int bits,
  290. char *data,
  291. size_t data_len)
  292. {
  293. char *filename = (char *) mg_get_user_connection_data(conn);
  294. if ((bits & 0xf) == MG_WEBSOCKET_OPCODE_DATACOMPLETE)
  295. {
  296. generate_response(conn, filename);
  297. return false;
  298. }
  299. if ((bits & 0xf) != MG_WEBSOCKET_OPCODE_BINARY && (bits & 0xf) != MG_WEBSOCKET_OPCODE_CONTINUATION)
  300. {
  301. std::cerr << "Unknown opcode: failing." << std::endl;
  302. return false;
  303. }
  304. FILE *currFile = fopen(filename, "ab");
  305. fwrite(data, sizeof(char), data_len, currFile);
  306. fclose(currFile);
  307. return true;
  308. }
  309. void PrsonaServerWebSocketHandler::generate_response(
  310. struct mg_connection *conn,
  311. char *filename)
  312. {
  313. const struct mg_request_info *info = mg_get_request_info(conn);
  314. switch (info->query_string[0])
  315. {
  316. case PRSONA_VERIFY_REPUTATION_PROOF:
  317. verify_reputation_proof(conn, filename);
  318. break;
  319. default:
  320. break;
  321. }
  322. }
  323. virtual void PrsonaClientWebSocketHandler::handleClose(
  324. CivetServer *server,
  325. const struct mg_connection *conn)
  326. {
  327. char *filename = (char *) mg_get_user_connection_data(conn);
  328. if (!filename)
  329. return;
  330. remove(filename);
  331. delete filename;
  332. }
  333. void PrsonaClientWebSocketHandler::verify_reputation_proof(
  334. struct mg_connection *conn, const char *filename) const
  335. {
  336. ifstream file(filename);
  337. std::vector<Proof> pi;
  338. Twistpoint shortTermPublicKey;
  339. Scalar threshold;
  340. BinarySizeT sizeOfVector;
  341. file >> sizeOfVector;
  342. for (size_t i = 0; i < sizeOfVector.val(); i++)
  343. {
  344. Proof currProof;
  345. file >> currProof;
  346. pi.push_back(currProof);
  347. }
  348. file >> shortTermPublicKey;
  349. file >> threshold;
  350. std::vector<Proof> generatorProof;
  351. Twistpoint freshGenerator =
  352. get_generator(
  353. &generator,
  354. serverIPs,
  355. generatorProof,
  356. true);
  357. std::vector<Proof> encryptedScoreProof;
  358. EGCiphertext encryptedScore =
  359. get_server_committed_val<EGCiphertext>(
  360. &generator,
  361. serverIPs,
  362. encryptedScoreProof,
  363. shortTermPublicKey,
  364. USER_TALLY_URI,
  365. USER_TALLY_COMMIT_URI);
  366. bool flag =
  367. prsonaClient->verify_reputation_proof(
  368. pi,
  369. shortTermPublicKey,
  370. threshold,
  371. encryptedScoreProof,
  372. encryptedScore);
  373. string data = flag ? "\x01" : "\x00";
  374. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), 1);
  375. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
  376. }