| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386 |
- /*
- * Copyright (c) 2014, Oculus VR, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
- #include <cstdio>
- #include <cstring>
- #include <stdlib.h>
- #include "GetTime.h"
- #include "Rand.h"
- #include "Rand.h"
- #include "RakPeerInterface.h"
- #include "MessageIdentifiers.h"
- #include "RakNetTypes.h"
- #include "NativeFeatureIncludes.h"
- #include <assert.h>
- #include "RakSleep.h"
- #include "BitStream.h"
- #include "SecureHandshake.h" // Include header for secure handshake
- #include "Gets.h"
- using namespace RakNet;
- #if LIBCAT_SECURITY!=1
- #error "Define LIBCAT_SECURITY 1 in NativeFeatureIncludesOverrides.h to enable Encryption"
- #endif
- void PrintOptions(void)
- {
- printf("1. Generate keys and save to disk.\n");
- printf("2. Load keys from disk.\n");
- printf("3. Test peers with key.\n");
- printf("4. Test peers with key and use two-way authentication.\n");
- printf("(H)elp.\n");
- printf("(Q)uit.\n");
- }
- #define TEST_SERVER_ADDRSTR "127.0.0.1"
- #define TEST_SERVER_PORT 6842
- RakPeerInterface *rakPeer1, *rakPeer2;
- void PrintPacketHeader(Packet *packet)
- {
- switch (packet->data[0])
- {
- case ID_REMOTE_SYSTEM_REQUIRES_PUBLIC_KEY:
- printf("Connection request failed - Remote system requires secure connections, pass a public key to RakPeerInterface::Connect()\n");
- break;
- case ID_OUR_SYSTEM_REQUIRES_SECURITY:
- printf("Connection request failed - We passed a public key to RakPeerInterface::Connect(), but the other system did not have security turned on\n");
- break;
- case ID_PUBLIC_KEY_MISMATCH:
- printf("Connection request failed - Wrong public key passed to Connect().\n");
- break;
- case ID_CONNECTION_REQUEST_ACCEPTED:
- printf("Connection request accepted.\n");
- break;
- case ID_CONNECTION_ATTEMPT_FAILED:
- printf("Connection request FAILED.\n");
- break;
- case ID_NEW_INCOMING_CONNECTION:
- {
- char client_public_key[cat::EasyHandshake::PUBLIC_KEY_BYTES];
- printf("New incoming connection.\n");
- if (rakPeer1->GetClientPublicKeyFromSystemAddress(packet->systemAddress, client_public_key))
- {
- printf("Client public key:\n");
- for (int ii = 0; ii < (int)sizeof(client_public_key); ++ii)
- printf("%02x ", (cat::u8)client_public_key[ii]);
- printf("\n");
- }
- else
- {
- printf("Server: New connected client provided no public key. (This is an error if you are doing two-way authentication)\n");
- }
- // Transmit test message
- RakNet::BitStream testBlockLargerThanMTU;
- testBlockLargerThanMTU.Write((MessageID) ID_USER_PACKET_ENUM);
- testBlockLargerThanMTU.PadWithZeroToByteLength(10000);
- rakPeer1->Send(&testBlockLargerThanMTU, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
- }
- break;
- case ID_USER_PACKET_ENUM:
- printf("Got test message\n");
- break;
- case ID_DISCONNECTION_NOTIFICATION:
- printf("RakPeer - The system specified in Packet::systemAddress has disconnected from us. For the client, this would mean the server has shutdown.\n");
- break;
- default:
- printf("Got type %i : ", (int)packet->data[0]);
- for (int ii = 0; ii < (int)packet->length; ++ii)
- printf("%02x ", (cat::u8)packet->data[ii]);
- printf("\n");
- break;
- }
- }
- int main(void)
- {
- char str[256];
- bool keyLoaded;
- bool doTwoWayAuthentication;
- FILE *fp;
- rakPeer1=RakPeerInterface::GetInstance();
- rakPeer2=RakPeerInterface::GetInstance();
- Packet *packet;
- bool peer1GotMessage, peer2GotMessage;
- keyLoaded=false;
- printf("Demonstrates how to setup RakNet to use secure connections\n");
- printf("Also shows how to read and write keys to and from disk\n");
- printf("Difficulty: Intermediate\n\n");
- printf("Select option:\n");
- PrintOptions();
- cat::EasyHandshake handshake;
- char public_key[cat::EasyHandshake::PUBLIC_KEY_BYTES];
- char private_key[cat::EasyHandshake::PRIVATE_KEY_BYTES];
- // Optional: used only for two-way authentication mode (a slower mode not recommended for normal client-server or peer-peer connections)
- char client_public_key[cat::EasyHandshake::PUBLIC_KEY_BYTES];
- char client_private_key[cat::EasyHandshake::PRIVATE_KEY_BYTES];
- while (1)
- {
- Gets(str, sizeof(str));
- if (str[0]=='1')
- {
- printf("Generating keys...");
- // Generate a (public, private) server key pair
- if (!handshake.GenerateServerKey(public_key, private_key))
- {
- printf("ERROR:Unable to generate server keys for some reason!\n");
- keyLoaded=false;
- }
- else
- {
- keyLoaded=true;
- printf("Keys generated. Save to disk? (y/n)\n");
- Gets(str, sizeof(str));
- if (str[0]=='y' || str[0]=='Y')
- {
- printf("Enter filename to save public key to: ");
- Gets(str, sizeof(str));
- if (str[0])
- {
- printf("Writing public key... ");
- fp=fopen(str, "wb");
- fwrite(public_key, sizeof(public_key), 1, fp);
- fclose(fp);
- printf("Done.\n");
- }
- else
- printf("\nKey not written.\n");
- printf("Enter filename to save private key to: ");
- Gets(str, sizeof(str));
- if (str[0])
- {
- printf("Writing private key... ");
- fp=fopen(str, "wb");
- fwrite(private_key, sizeof(private_key), 1, fp);
- fclose(fp);
- printf("Done.\n");
- }
- else
- printf("\nKey not written.\n");
- }
- }
- PrintOptions();
- }
- else if (str[0]=='2')
- {
- printf("Enter filename to load public key from: ");
- Gets(str, sizeof(str));
- if (str[0])
- {
- fp=fopen(str, "rb");
- if (fp)
- {
- printf("Loading public key... ");
- fread(public_key, sizeof(public_key), 1, fp);
- fclose(fp);
- printf("Done.\n");
- printf("Enter filename to load private key from: ");
- Gets(str, sizeof(str));
- if (str[0])
- {
- fp=fopen(str, "rb");
- if (fp)
- {
- printf("Loading private key... ");
- fread(private_key, sizeof(private_key), 1, fp);
- fclose(fp);
- printf("Done.\n");
- keyLoaded=true;
- }
- else
- {
- printf("ERROR:Failed to open %s.\n", str);
- }
- }
- else
- printf("Not loading private key.\n");
- }
- else
- {
- printf("ERROR:Failed to open %s.\n", str);
- }
- }
- else
- printf("Not loading public keys.\n");
- PrintOptions();
- }
- else if (str[0]=='3' || str[0] == '4')
- {
- bool run_test = true;
- // NOTE: Reiterating, normally you should not use two-way authentication for client-server or peer-peer applications
- // as it only makes sense for server-server connections that rarely occur or if you know what you are doing.
- doTwoWayAuthentication = (str[0] == '4');
- if (keyLoaded)
- {
- // Tell Peer1 to use the key pair
- if (!rakPeer1->InitializeSecurity(public_key, private_key, doTwoWayAuthentication))
- {
- printf("ERROR:Public/private keys are invalid!\n");
- run_test = false;
- }
- }
- else
- {
- printf("Generating server keys...");
- // Generate a (public, private) server key pair
- if (!handshake.GenerateServerKey(public_key, private_key))
- {
- printf("ERROR:Unable to generate server keys for some reason!\n");
- run_test = false;
- }
- else
- {
- printf("Key generation complete.\n");
- // Tell Peer1 to use the key pair
- if (!rakPeer1->InitializeSecurity(public_key, private_key, doTwoWayAuthentication))
- {
- printf("ERROR:Public/private keys are invalid!\n");
- run_test = false;
- }
- }
- }
- if (str[0] == '4')
- {
- printf("Generating client keys...");
- // Generate a (public, private) server key pair
- if (!handshake.GenerateServerKey(client_public_key, client_private_key))
- {
- printf("ERROR:Unable to generate client keys for some reason!\n");
- run_test = false;
- }
- else
- {
- printf("Key generation complete.\n");
- }
- }
- if (!run_test)
- {
- printf("Unable to run test due to error\n");
- }
- else
- {
- printf("Initializing peers.\n");
- SocketDescriptor socketDescriptor(TEST_SERVER_PORT,0);
- rakPeer1->Startup(8,&socketDescriptor, 1);
- rakPeer1->SetMaximumIncomingConnections(8);
- socketDescriptor.port=0;
- rakPeer2->Startup(1,&socketDescriptor, 1);
- printf("Connecting to server with known public key...\n");
- // Pass in the public key on Connect()
- PublicKey pk;
- pk.remoteServerPublicKey = public_key;
- if (str[0] == '4')
- {
- pk.publicKeyMode = PKM_USE_TWO_WAY_AUTHENTICATION; // Optional not recommended mode
- pk.myPublicKey = client_public_key;
- pk.myPrivateKey = client_private_key;
- }
- else
- {
- pk.publicKeyMode = PKM_USE_KNOWN_PUBLIC_KEY; // Recommended mode
- }
- if (CONNECTION_ATTEMPT_STARTED != rakPeer2->Connect(TEST_SERVER_ADDRSTR, TEST_SERVER_PORT, 0, 0, &pk))
- {
- printf("ERROR: Connect() returned false - invalid public key most likely\n");
- }
- printf("Running connection for 12 seconds.\n");
- peer1GotMessage=false;
- peer2GotMessage=false;
- TimeMS time = RakNet::GetTimeMS() + 12000;
- while (RakNet::GetTimeMS() < time)
- {
- packet=rakPeer1->Receive();
- if (packet)
- {
- peer1GotMessage=true;
- printf("Host got: ");
- PrintPacketHeader(packet);
- if (doTwoWayAuthentication)
- {
- char client_public_key_copy[cat::EasyHandshake::PUBLIC_KEY_BYTES];
- RakAssert(rakPeer1->GetClientPublicKeyFromSystemAddress(packet->systemAddress, client_public_key_copy)==true)
- }
- rakPeer1->DeallocatePacket(packet);
- }
- packet=rakPeer2->Receive();
- if (packet)
- {
- peer2GotMessage=true;
- printf("Connecting system got: ");
- PrintPacketHeader(packet);
- if (doTwoWayAuthentication)
- {
- char client_public_key_copy[cat::EasyHandshake::PUBLIC_KEY_BYTES];
- RakAssert(rakPeer2->GetClientPublicKeyFromSystemAddress(packet->systemAddress, client_public_key_copy)==true)
- }
- rakPeer2->DeallocatePacket(packet);
- }
- RakSleep(30);
- }
- if (peer1GotMessage==false)
- printf("ERROR: Host got no packets\n");
- if (peer2GotMessage==false)
- printf("ERROR: Connecting system got no packets\n");
- if (peer1GotMessage && peer2GotMessage)
- printf("Test successful as long as you got no error messages\n");
- rakPeer2->Shutdown(0);
- rakPeer1->Shutdown(0);
- }
- PrintOptions();
- }
- else if (str[0]=='h' || str[0]=='H')
- {
- PrintOptions();
- }
- else if (str[0]=='q' || str[0]=='Q')
- break;
- str[0]=0;
- }
- RakPeerInterface::DestroyInstance(rakPeer1);
- RakPeerInterface::DestroyInstance(rakPeer2);
- }
|