Encryption.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. #include <cstdio>
  11. #include <cstring>
  12. #include <stdlib.h>
  13. #include "GetTime.h"
  14. #include "Rand.h"
  15. #include "Rand.h"
  16. #include "RakPeerInterface.h"
  17. #include "MessageIdentifiers.h"
  18. #include "RakNetTypes.h"
  19. #include "NativeFeatureIncludes.h"
  20. #include <assert.h>
  21. #include "RakSleep.h"
  22. #include "BitStream.h"
  23. #include "SecureHandshake.h" // Include header for secure handshake
  24. #include "Gets.h"
  25. using namespace RakNet;
  26. #if LIBCAT_SECURITY!=1
  27. #error "Define LIBCAT_SECURITY 1 in NativeFeatureIncludesOverrides.h to enable Encryption"
  28. #endif
  29. void PrintOptions(void)
  30. {
  31. printf("1. Generate keys and save to disk.\n");
  32. printf("2. Load keys from disk.\n");
  33. printf("3. Test peers with key.\n");
  34. printf("4. Test peers with key and use two-way authentication.\n");
  35. printf("(H)elp.\n");
  36. printf("(Q)uit.\n");
  37. }
  38. #define TEST_SERVER_ADDRSTR "127.0.0.1"
  39. #define TEST_SERVER_PORT 6842
  40. RakPeerInterface *rakPeer1, *rakPeer2;
  41. void PrintPacketHeader(Packet *packet)
  42. {
  43. switch (packet->data[0])
  44. {
  45. case ID_REMOTE_SYSTEM_REQUIRES_PUBLIC_KEY:
  46. printf("Connection request failed - Remote system requires secure connections, pass a public key to RakPeerInterface::Connect()\n");
  47. break;
  48. case ID_OUR_SYSTEM_REQUIRES_SECURITY:
  49. printf("Connection request failed - We passed a public key to RakPeerInterface::Connect(), but the other system did not have security turned on\n");
  50. break;
  51. case ID_PUBLIC_KEY_MISMATCH:
  52. printf("Connection request failed - Wrong public key passed to Connect().\n");
  53. break;
  54. case ID_CONNECTION_REQUEST_ACCEPTED:
  55. printf("Connection request accepted.\n");
  56. break;
  57. case ID_CONNECTION_ATTEMPT_FAILED:
  58. printf("Connection request FAILED.\n");
  59. break;
  60. case ID_NEW_INCOMING_CONNECTION:
  61. {
  62. char client_public_key[cat::EasyHandshake::PUBLIC_KEY_BYTES];
  63. printf("New incoming connection.\n");
  64. if (rakPeer1->GetClientPublicKeyFromSystemAddress(packet->systemAddress, client_public_key))
  65. {
  66. printf("Client public key:\n");
  67. for (int ii = 0; ii < (int)sizeof(client_public_key); ++ii)
  68. printf("%02x ", (cat::u8)client_public_key[ii]);
  69. printf("\n");
  70. }
  71. else
  72. {
  73. printf("Server: New connected client provided no public key. (This is an error if you are doing two-way authentication)\n");
  74. }
  75. // Transmit test message
  76. RakNet::BitStream testBlockLargerThanMTU;
  77. testBlockLargerThanMTU.Write((MessageID) ID_USER_PACKET_ENUM);
  78. testBlockLargerThanMTU.PadWithZeroToByteLength(10000);
  79. rakPeer1->Send(&testBlockLargerThanMTU, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
  80. }
  81. break;
  82. case ID_USER_PACKET_ENUM:
  83. printf("Got test message\n");
  84. break;
  85. case ID_DISCONNECTION_NOTIFICATION:
  86. printf("RakPeer - The system specified in Packet::systemAddress has disconnected from us. For the client, this would mean the server has shutdown.\n");
  87. break;
  88. default:
  89. printf("Got type %i : ", (int)packet->data[0]);
  90. for (int ii = 0; ii < (int)packet->length; ++ii)
  91. printf("%02x ", (cat::u8)packet->data[ii]);
  92. printf("\n");
  93. break;
  94. }
  95. }
  96. int main(void)
  97. {
  98. char str[256];
  99. bool keyLoaded;
  100. bool doTwoWayAuthentication;
  101. FILE *fp;
  102. rakPeer1=RakPeerInterface::GetInstance();
  103. rakPeer2=RakPeerInterface::GetInstance();
  104. Packet *packet;
  105. bool peer1GotMessage, peer2GotMessage;
  106. keyLoaded=false;
  107. printf("Demonstrates how to setup RakNet to use secure connections\n");
  108. printf("Also shows how to read and write keys to and from disk\n");
  109. printf("Difficulty: Intermediate\n\n");
  110. printf("Select option:\n");
  111. PrintOptions();
  112. cat::EasyHandshake handshake;
  113. char public_key[cat::EasyHandshake::PUBLIC_KEY_BYTES];
  114. char private_key[cat::EasyHandshake::PRIVATE_KEY_BYTES];
  115. // Optional: used only for two-way authentication mode (a slower mode not recommended for normal client-server or peer-peer connections)
  116. char client_public_key[cat::EasyHandshake::PUBLIC_KEY_BYTES];
  117. char client_private_key[cat::EasyHandshake::PRIVATE_KEY_BYTES];
  118. while (1)
  119. {
  120. Gets(str, sizeof(str));
  121. if (str[0]=='1')
  122. {
  123. printf("Generating keys...");
  124. // Generate a (public, private) server key pair
  125. if (!handshake.GenerateServerKey(public_key, private_key))
  126. {
  127. printf("ERROR:Unable to generate server keys for some reason!\n");
  128. keyLoaded=false;
  129. }
  130. else
  131. {
  132. keyLoaded=true;
  133. printf("Keys generated. Save to disk? (y/n)\n");
  134. Gets(str, sizeof(str));
  135. if (str[0]=='y' || str[0]=='Y')
  136. {
  137. printf("Enter filename to save public key to: ");
  138. Gets(str, sizeof(str));
  139. if (str[0])
  140. {
  141. printf("Writing public key... ");
  142. fp=fopen(str, "wb");
  143. fwrite(public_key, sizeof(public_key), 1, fp);
  144. fclose(fp);
  145. printf("Done.\n");
  146. }
  147. else
  148. printf("\nKey not written.\n");
  149. printf("Enter filename to save private key to: ");
  150. Gets(str, sizeof(str));
  151. if (str[0])
  152. {
  153. printf("Writing private key... ");
  154. fp=fopen(str, "wb");
  155. fwrite(private_key, sizeof(private_key), 1, fp);
  156. fclose(fp);
  157. printf("Done.\n");
  158. }
  159. else
  160. printf("\nKey not written.\n");
  161. }
  162. }
  163. PrintOptions();
  164. }
  165. else if (str[0]=='2')
  166. {
  167. printf("Enter filename to load public key from: ");
  168. Gets(str, sizeof(str));
  169. if (str[0])
  170. {
  171. fp=fopen(str, "rb");
  172. if (fp)
  173. {
  174. printf("Loading public key... ");
  175. fread(public_key, sizeof(public_key), 1, fp);
  176. fclose(fp);
  177. printf("Done.\n");
  178. printf("Enter filename to load private key from: ");
  179. Gets(str, sizeof(str));
  180. if (str[0])
  181. {
  182. fp=fopen(str, "rb");
  183. if (fp)
  184. {
  185. printf("Loading private key... ");
  186. fread(private_key, sizeof(private_key), 1, fp);
  187. fclose(fp);
  188. printf("Done.\n");
  189. keyLoaded=true;
  190. }
  191. else
  192. {
  193. printf("ERROR:Failed to open %s.\n", str);
  194. }
  195. }
  196. else
  197. printf("Not loading private key.\n");
  198. }
  199. else
  200. {
  201. printf("ERROR:Failed to open %s.\n", str);
  202. }
  203. }
  204. else
  205. printf("Not loading public keys.\n");
  206. PrintOptions();
  207. }
  208. else if (str[0]=='3' || str[0] == '4')
  209. {
  210. bool run_test = true;
  211. // NOTE: Reiterating, normally you should not use two-way authentication for client-server or peer-peer applications
  212. // as it only makes sense for server-server connections that rarely occur or if you know what you are doing.
  213. doTwoWayAuthentication = (str[0] == '4');
  214. if (keyLoaded)
  215. {
  216. // Tell Peer1 to use the key pair
  217. if (!rakPeer1->InitializeSecurity(public_key, private_key, doTwoWayAuthentication))
  218. {
  219. printf("ERROR:Public/private keys are invalid!\n");
  220. run_test = false;
  221. }
  222. }
  223. else
  224. {
  225. printf("Generating server keys...");
  226. // Generate a (public, private) server key pair
  227. if (!handshake.GenerateServerKey(public_key, private_key))
  228. {
  229. printf("ERROR:Unable to generate server keys for some reason!\n");
  230. run_test = false;
  231. }
  232. else
  233. {
  234. printf("Key generation complete.\n");
  235. // Tell Peer1 to use the key pair
  236. if (!rakPeer1->InitializeSecurity(public_key, private_key, doTwoWayAuthentication))
  237. {
  238. printf("ERROR:Public/private keys are invalid!\n");
  239. run_test = false;
  240. }
  241. }
  242. }
  243. if (str[0] == '4')
  244. {
  245. printf("Generating client keys...");
  246. // Generate a (public, private) server key pair
  247. if (!handshake.GenerateServerKey(client_public_key, client_private_key))
  248. {
  249. printf("ERROR:Unable to generate client keys for some reason!\n");
  250. run_test = false;
  251. }
  252. else
  253. {
  254. printf("Key generation complete.\n");
  255. }
  256. }
  257. if (!run_test)
  258. {
  259. printf("Unable to run test due to error\n");
  260. }
  261. else
  262. {
  263. printf("Initializing peers.\n");
  264. SocketDescriptor socketDescriptor(TEST_SERVER_PORT,0);
  265. rakPeer1->Startup(8,&socketDescriptor, 1);
  266. rakPeer1->SetMaximumIncomingConnections(8);
  267. socketDescriptor.port=0;
  268. rakPeer2->Startup(1,&socketDescriptor, 1);
  269. printf("Connecting to server with known public key...\n");
  270. // Pass in the public key on Connect()
  271. PublicKey pk;
  272. pk.remoteServerPublicKey = public_key;
  273. if (str[0] == '4')
  274. {
  275. pk.publicKeyMode = PKM_USE_TWO_WAY_AUTHENTICATION; // Optional not recommended mode
  276. pk.myPublicKey = client_public_key;
  277. pk.myPrivateKey = client_private_key;
  278. }
  279. else
  280. {
  281. pk.publicKeyMode = PKM_USE_KNOWN_PUBLIC_KEY; // Recommended mode
  282. }
  283. if (CONNECTION_ATTEMPT_STARTED != rakPeer2->Connect(TEST_SERVER_ADDRSTR, TEST_SERVER_PORT, 0, 0, &pk))
  284. {
  285. printf("ERROR: Connect() returned false - invalid public key most likely\n");
  286. }
  287. printf("Running connection for 12 seconds.\n");
  288. peer1GotMessage=false;
  289. peer2GotMessage=false;
  290. TimeMS time = RakNet::GetTimeMS() + 12000;
  291. while (RakNet::GetTimeMS() < time)
  292. {
  293. packet=rakPeer1->Receive();
  294. if (packet)
  295. {
  296. peer1GotMessage=true;
  297. printf("Host got: ");
  298. PrintPacketHeader(packet);
  299. if (doTwoWayAuthentication)
  300. {
  301. char client_public_key_copy[cat::EasyHandshake::PUBLIC_KEY_BYTES];
  302. RakAssert(rakPeer1->GetClientPublicKeyFromSystemAddress(packet->systemAddress, client_public_key_copy)==true)
  303. }
  304. rakPeer1->DeallocatePacket(packet);
  305. }
  306. packet=rakPeer2->Receive();
  307. if (packet)
  308. {
  309. peer2GotMessage=true;
  310. printf("Connecting system got: ");
  311. PrintPacketHeader(packet);
  312. if (doTwoWayAuthentication)
  313. {
  314. char client_public_key_copy[cat::EasyHandshake::PUBLIC_KEY_BYTES];
  315. RakAssert(rakPeer2->GetClientPublicKeyFromSystemAddress(packet->systemAddress, client_public_key_copy)==true)
  316. }
  317. rakPeer2->DeallocatePacket(packet);
  318. }
  319. RakSleep(30);
  320. }
  321. if (peer1GotMessage==false)
  322. printf("ERROR: Host got no packets\n");
  323. if (peer2GotMessage==false)
  324. printf("ERROR: Connecting system got no packets\n");
  325. if (peer1GotMessage && peer2GotMessage)
  326. printf("Test successful as long as you got no error messages\n");
  327. rakPeer2->Shutdown(0);
  328. rakPeer1->Shutdown(0);
  329. }
  330. PrintOptions();
  331. }
  332. else if (str[0]=='h' || str[0]=='H')
  333. {
  334. PrintOptions();
  335. }
  336. else if (str[0]=='q' || str[0]=='Q')
  337. break;
  338. str[0]=0;
  339. }
  340. RakPeerInterface::DestroyInstance(rakPeer1);
  341. RakPeerInterface::DestroyInstance(rakPeer2);
  342. }
粤ICP备19079148号