content.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. // https://stackoverflow.com/questions/40645538/communicate-data-from-popup-to-content-script-injected-by-popup-with-executescri
  2. let derivedKeyGlobal;
  3. let ownPublicKeyGlobalTesting;
  4. console.log('from content script');
  5. async function sendFieldsForEncryption(fields_array, regenerateOwnPublicKeyBoolean, getOwnPublicKeyBoolean)
  6. {
  7. let message={"url": document.URL, "fields" : fields_array};
  8. if(regenerateOwnPublicKeyBoolean)
  9. message.regenerateOwnPublicKey = true;
  10. if(getOwnPublicKeyBoolean)
  11. message.getOwnPublicKey = true;
  12. try {
  13. returnValue = await browser.runtime.sendMessage(message);
  14. }
  15. catch(err) {
  16. console.log("Error in browser.runtime.sendMessage in sendFieldsForEncryption");
  17. console.log(err);
  18. returnValue={error: err};
  19. };
  20. if(returnValue.error)
  21. {
  22. console.log(returnValue.error);
  23. return returnValue;
  24. }
  25. return returnValue;
  26. }
  27. // This function assumes that there is just 1 eventlistener, itself
  28. // In case of multiple event handlers, we need to make sure that the 1) other event handlers handle the user data in a privacy-preserving way and
  29. // 2) usability - this event handler is executed after all other ones that expect plaintext data (if there are handlers run chronologically after it, then they need to send the current - encrypted - content of the form data)
  30. async function handleButtonClick(event)
  31. {
  32. event.preventDefault();
  33. console.log("Helloworld");
  34. let dataObject = {};
  35. let name = document.getElementById("name").value;
  36. let age = document.getElementById("age").value;
  37. dataObject["name"] = name;
  38. dataObject["age"] = age;
  39. // Encrypt name and age
  40. let fields = Object.keys(dataObject);
  41. let returnValue = await sendFieldsForEncryption([...Object.values(dataObject)], true, true);
  42. if(returnValue.error)
  43. return;
  44. let encryptedFields=returnValue.ciphertextFields;
  45. let counter=0;
  46. for(obj of fields)
  47. {
  48. document.getElementById(obj).value=encryptedFields[counter];
  49. console.log(document.getElementById(obj).value);
  50. counter++;
  51. }
  52. console.log("Done with buttonclick handling");
  53. document.getElementById("form").submit();
  54. }
  55. function getRandomString(length)
  56. {
  57. let randomString="";
  58. do {
  59. randomString += Math.random().toString(36).substring(2);
  60. } while (randomString.length < length+1);
  61. return randomString.substring(0,length);
  62. }
  63. async function handleNButtonClicks(event)
  64. {
  65. event.preventDefault();
  66. const url=document.URL + "action.php";
  67. const time_measurements = [];
  68. const number_of_trials=10;
  69. console.log("Hello starting this many trials for case with native server or with SGX:" + number_of_trials);
  70. for(let counter=0; counter<number_of_trials; counter++)
  71. {
  72. const randomName=getRandomString(30);
  73. const randomAge=getRandomString(30);
  74. const post_data = `name=${randomName}&age=${randomAge}`; // JSON.stringify({name: randomName, age: randomAge});
  75. const old_time = Date.now();
  76. const ball = await fetch(url, {
  77. method: "POST", // *GET, POST, PUT, DELETE, etc.
  78. headers: {
  79. "Content-Type": "application/x-www-form-urlencoded",
  80. },
  81. body: post_data
  82. });
  83. const new_time = Date.now();
  84. const response_text= await ball.text();
  85. [returnedName, returnedAge] = response_text.slice(12,-12).trim().split(" ");
  86. if(returnedName !== randomName || returnedAge !== randomAge)
  87. {
  88. console.log("Didnt get the right name and age.");
  89. console.log(returnedName);
  90. console.log(returnedAge);
  91. console.log(randomName);
  92. console.log(randomAge);
  93. break;
  94. }
  95. const time_lag = new_time - old_time;
  96. time_measurements.push(time_lag);
  97. if(counter % (number_of_trials/10) === 0)
  98. {
  99. console.log(time_measurements);
  100. }
  101. }
  102. console.log("Done");
  103. compute_stats_on_array(time_measurements);
  104. }
  105. async function handleNSgxButtonClicks(event)
  106. {
  107. sendOrLogSgxRequests(event, false, 100, 5);
  108. //logSgxRequests(event, 1000, 1);
  109. }
  110. async function logSgxRequests(event, number_of_trials, maxNumberOfFormFields)
  111. {
  112. const send_url=document.URL + "/action.php";
  113. const myHeaders = new Headers();
  114. myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
  115. let expected_response_string = "";
  116. let curl_string = "";
  117. let numberOfFormFields=1;
  118. let formFieldCounter=0;
  119. for(numberOfFormFields=1; numberOfFormFields<=maxNumberOfFormFields; numberOfFormFields++)
  120. {
  121. for(let counter=0; counter<number_of_trials; counter++)
  122. {
  123. let expected_response="";
  124. let arrayOfFormFields = [];
  125. // Initializing the array of form fields, of numberOfFormFields length, with random values.
  126. expected_response+="<html><body> ";
  127. for(formFieldCounter=0; formFieldCounter<numberOfFormFields; formFieldCounter++)
  128. {
  129. const formField=getRandomString(15);
  130. expected_response+=formField + " ";
  131. arrayOfFormFields.push(formField);
  132. }
  133. expected_response+="</body></html>\n";
  134. expected_response_string+=expected_response;
  135. // Encrypting the array of form fields
  136. // encryptionStartTime=Date.now();
  137. returnValue = await sendFieldsForEncryption(arrayOfFormFields, false, true);
  138. if(returnValue.error)
  139. break;
  140. // encryptionEndTime=Date.now();
  141. // encryptionTimeMeasurements[numberOfFormFields-1][counter]=(encryptionEndTime - encryptionStartTime);
  142. // Initializing the ciphertext array of form fields
  143. let ciphertextArrayOfFormFields=returnValue.ciphertextFields;
  144. let post_data="";
  145. for(formFieldCounter=0; formFieldCounter<numberOfFormFields; formFieldCounter++)
  146. {
  147. const encodedCiphertext=encodeURIComponent(ciphertextArrayOfFormFields[formFieldCounter]);
  148. post_data+=`f${formFieldCounter+1}=${encodedCiphertext}&`;
  149. }
  150. post_data=post_data.slice(0,-1);
  151. curl_string += post_data +"\n";
  152. }
  153. if(returnValue.error)
  154. {
  155. console.log("breaking");
  156. break;
  157. }
  158. }
  159. if(returnValue.error)
  160. return; // woulda been logged at this point
  161. console.log(expected_response_string);
  162. console.log(curl_string);
  163. expected_response_string="";
  164. curl_string="";
  165. //let localStorageObject=window.localStorage;
  166. //localStorageObject.setItem('expected_response', expected_response_string);
  167. //localStorageObject.setItem('curl_string', curl_string);
  168. }
  169. async function sendOrLogSgxRequests(event, sendRequestsBoolean, number_of_trials, maxNumberOfFormFields)
  170. {
  171. console.log("Starting tests for this many trials for SGX extension case: " + number_of_trials);
  172. console.log("sendRequestsBoolean is " + sendRequestsBoolean);
  173. let expected_response_string = "";
  174. let curl_string = "";
  175. let networkTimeMeasurements="";
  176. let encryptionTimeMeasurements="";
  177. let noMitigatorTimeMeasurements="";
  178. let noSgxTimeMeasurements="";
  179. let returnValue, encryptionStartTime, encryptionEndTime, networkSendTime, networkReceiveTime;
  180. let numberOfFormFields=1;
  181. let formFieldCounter=0;
  182. const send_url=document.URL + "/action.php";
  183. const nomitigator_url="http://crysp-server1.cs.uwaterloo.ca:8045/action.php";
  184. const nosgx_url="http://crysp-server1.cs.uwaterloo.ca:8046/action.php";
  185. const myHeaders = new Headers();
  186. myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
  187. for(let counter=0; counter<number_of_trials; counter++)
  188. {
  189. // For each of the number_of_trials run of the experiment, do it with a different number of form fields being sent each time.
  190. for(numberOfFormFields=1; numberOfFormFields<=maxNumberOfFormFields; numberOfFormFields++)
  191. {
  192. let expected_response="";
  193. let arrayOfFormFields = [];
  194. // Initializing the array of form fields, of numberOfFormFields length, with random values.
  195. expected_response+="<html><body> ";
  196. for(formFieldCounter=0; formFieldCounter<numberOfFormFields; formFieldCounter++)
  197. {
  198. const formField=getRandomString(32);
  199. expected_response+=formField + " ";
  200. arrayOfFormFields.push(formField);
  201. }
  202. expected_response+="</body></html>\n";
  203. // Encrypting the array of form fields
  204. encryptionStartTime=Date.now();
  205. returnValue = await sendFieldsForEncryption(arrayOfFormFields, false, true);
  206. encryptionEndTime=Date.now();
  207. if(returnValue.error)
  208. break;
  209. encryptionTimeMeasurements+=encryptionStartTime + " " + encryptionEndTime + "\n";
  210. // Initializing the ciphertext array of form fields
  211. let ciphertextArrayOfFormFields=returnValue.ciphertextFields;
  212. let post_data="";
  213. for(formFieldCounter=0; formFieldCounter<numberOfFormFields; formFieldCounter++)
  214. {
  215. const encodedCiphertext=encodeURIComponent(ciphertextArrayOfFormFields[formFieldCounter]);
  216. post_data+=`f${formFieldCounter+1}=${encodedCiphertext}&`;
  217. }
  218. post_data=post_data.slice(0,-1);
  219. ownPublicKey=returnValue.ownPublicKey.ownPublicKey;
  220. if(sendRequestsBoolean)
  221. {
  222. // Setting header and sending request
  223. myHeaders.set("Mitigator-Client-Public-Key", ownPublicKey);
  224. networkSendTime = Date.now();
  225. const ball = await fetch(send_url, {
  226. method: "POST", // *GET, POST, PUT, DELETE, etc.
  227. headers: myHeaders,
  228. body: post_data
  229. });
  230. networkReceiveTime = Date.now();
  231. networkTimeMeasurements+=networkSendTime + " " + networkReceiveTime +"\n";
  232. const response_text= await ball.text();
  233. // Checking returned values.
  234. let returnedTextsArray = response_text.slice(12,-14).trim().split(" ");
  235. for(formFieldCounter=0; formFieldCounter<numberOfFormFields; formFieldCounter++)
  236. {
  237. if(returnedTextsArray[formFieldCounter] !== arrayOfFormFields[formFieldCounter])
  238. {
  239. returnValue = {error: "Didnt get the right name and age."};
  240. console.log("Didnt get the right name and age.");
  241. console.log(returnedTextsArray[formFieldCounter]);
  242. console.log(arrayOfFormFields[formFieldCounter]);
  243. break;
  244. }
  245. }
  246. // Sending identical values to the Graphene-SGX server.
  247. networkSendTime = Date.now();
  248. let ball2 = await fetch(nomitigator_url, {
  249. method: "POST", // *GET, POST, PUT, DELETE, etc.
  250. headers: myHeaders,
  251. body: post_data
  252. });
  253. networkReceiveTime = Date.now();
  254. noMitigatorTimeMeasurements+=networkSendTime + " " + networkReceiveTime +"\n";
  255. // Sending identical values to the control server.
  256. networkSendTime = Date.now();
  257. ball2 = await fetch(nosgx_url, {
  258. method: "POST", // *GET, POST, PUT, DELETE, etc.
  259. headers: myHeaders,
  260. body: post_data
  261. });
  262. networkReceiveTime = Date.now();
  263. noSgxTimeMeasurements+=networkSendTime + " " + networkReceiveTime +"\n";
  264. }
  265. else {
  266. expected_response_string+=expected_response;
  267. curl_string += post_data +"\n";
  268. }
  269. }
  270. if(returnValue.error)
  271. {
  272. console.log("breaking");
  273. break;}
  274. }
  275. if(returnValue.error)
  276. return; // woulda been logged at this point
  277. console.log("Done");
  278. if(sendRequestsBoolean)
  279. {
  280. console.log("Network times");
  281. console.log(JSON.stringify(networkTimeMeasurements));
  282. console.log("Network times for no Mitigator case");
  283. console.log(JSON.stringify(noMitigatorTimeMeasurements));
  284. console.log("Network times for no SGX case");
  285. console.log(JSON.stringify(noSgxTimeMeasurements));
  286. console.log("Encryption times");
  287. console.log(JSON.stringify(encryptionTimeMeasurements));
  288. }
  289. else
  290. {
  291. console.log(expected_response_string);
  292. console.log(curl_string);
  293. }
  294. }
  295. document.getElementById("form").addEventListener("submit", handleButtonClick, { once: true});
  296. document.getElementById("experimenter1Button").addEventListener("click", handleNButtonClicks);
  297. document.getElementById("experimenter2Button").addEventListener("click", handleNSgxButtonClicks);