@@ -51,6 +51,10 @@ public bool isHost
5151
5252 public NetworkingConfiguration NetworkConfig ;
5353
54+ private EllipticDiffieHellman clientDiffieHellman ;
55+ private Dictionary < int , byte [ ] > diffieHellmanPublicKeys ;
56+ private byte [ ] clientAesKey ;
57+
5458 private void OnValidate ( )
5559 {
5660 if ( SpawnablePrefabs != null )
@@ -88,6 +92,7 @@ private ConnectionConfig Init(NetworkingConfiguration netConfig)
8892 pendingClients = new HashSet < int > ( ) ;
8993 connectedClients = new Dictionary < int , NetworkedClient > ( ) ;
9094 messageBuffer = new byte [ NetworkConfig . MessageBufferSize ] ;
95+ diffieHellmanPublicKeys = new Dictionary < int , byte [ ] > ( ) ;
9196 MessageManager . channels = new Dictionary < string , int > ( ) ;
9297 MessageManager . messageTypes = new Dictionary < string , ushort > ( ) ;
9398 MessageManager . messageCallbacks = new Dictionary < ushort , Dictionary < int , Action < int , byte [ ] > > > ( ) ;
@@ -374,15 +379,29 @@ private void Update()
374379 }
375380 else
376381 {
382+ byte [ ] diffiePublic = new byte [ 0 ] ;
383+ if ( NetworkConfig . EnableEncryption )
384+ {
385+ clientDiffieHellman = new EllipticDiffieHellman ( EllipticDiffieHellman . DEFAULT_CURVE , EllipticDiffieHellman . DEFAULT_GENERATOR , EllipticDiffieHellman . DEFAULT_ORDER ) ;
386+ diffiePublic = clientDiffieHellman . GetPublicKey ( ) ;
387+ }
388+
377389 int sizeOfStream = 32 ;
378390 if ( NetworkConfig . ConnectionApproval )
379391 sizeOfStream += 2 + NetworkConfig . ConnectionData . Length ;
392+ if ( NetworkConfig . EnableEncryption )
393+ sizeOfStream += 2 + diffiePublic . Length ;
380394
381395 using ( MemoryStream writeStream = new MemoryStream ( sizeOfStream ) )
382396 {
383397 using ( BinaryWriter writer = new BinaryWriter ( writeStream ) )
384398 {
385399 writer . Write ( NetworkConfig . GetConfig ( ) ) ;
400+ if ( NetworkConfig . EnableEncryption )
401+ {
402+ writer . Write ( ( ushort ) diffiePublic . Length ) ;
403+ writer . Write ( diffiePublic ) ;
404+ }
386405 if ( NetworkConfig . ConnectionApproval )
387406 {
388407 writer . Write ( ( ushort ) NetworkConfig . ConnectionData . Length ) ;
@@ -471,6 +490,14 @@ private void HandleIncomingData(int clientId, byte[] data, int channelId)
471490
472491 ushort bytesToRead = reader . ReadUInt16 ( ) ;
473492 byte [ ] incommingData = reader . ReadBytes ( bytesToRead ) ;
493+ if ( NetworkConfig . EncryptedChannels . Contains ( channelId ) )
494+ {
495+ //Encrypted message
496+ if ( isServer )
497+ incommingData = CryptographyHelper . Decrypt ( incommingData , connectedClients [ clientId ] . AesKey ) ;
498+ else
499+ incommingData = CryptographyHelper . Decrypt ( incommingData , clientAesKey ) ;
500+ }
474501
475502 if ( isServer && isPassthrough && ! NetworkConfig . RegisteredPassthroughMessageTypes . Contains ( messageType ) )
476503 {
@@ -555,6 +582,18 @@ private void HandleIncomingData(int clientId, byte[] data, int channelId)
555582 DisconnectClient ( clientId ) ;
556583 return ;
557584 }
585+ byte [ ] aesKey = new byte [ 0 ] ;
586+ if ( NetworkConfig . EnableEncryption )
587+ {
588+ ushort diffiePublicSize = reader . ReadUInt16 ( ) ;
589+ byte [ ] diffiePublic = reader . ReadBytes ( diffiePublicSize ) ;
590+ diffieHellmanPublicKeys . Add ( clientId , diffiePublic ) ;
591+ /*
592+ EllipticDiffieHellman diffieHellman = new EllipticDiffieHellman(EllipticDiffieHellman.DEFAULT_CURVE, EllipticDiffieHellman.DEFAULT_GENERATOR, EllipticDiffieHellman.DEFAULT_ORDER);
593+ aesKey = diffieHellman.GetSharedSecret(diffiePublic);
594+ */
595+
596+ }
558597 if ( NetworkConfig . ConnectionApproval )
559598 {
560599 ushort bufferSize = messageReader . ReadUInt16 ( ) ;
@@ -583,6 +622,12 @@ private void HandleIncomingData(int clientId, byte[] data, int channelId)
583622 sceneIndex = messageReader . ReadUInt32 ( ) ;
584623 }
585624
625+ if ( NetworkConfig . EnableEncryption )
626+ {
627+ ushort keyLength = reader . ReadUInt16 ( ) ;
628+ clientAesKey = clientDiffieHellman . GetSharedSecret ( reader . ReadBytes ( keyLength ) ) ;
629+ }
630+
586631 float netTime = messageReader . ReadSingle ( ) ;
587632 int remoteStamp = messageReader . ReadInt32 ( ) ;
588633 int msDelay = NetworkTransport . GetRemoteDelayTimeMS ( hostId , clientId , remoteStamp , out error ) ;
@@ -901,8 +946,18 @@ internal void PassthroughSend(int targetId, int sourceId, ushort messageType, in
901946 writer . Write ( orderId . Value ) ;
902947 writer . Write ( true ) ;
903948 writer . Write ( sourceId ) ;
904- writer . Write ( ( ushort ) data . Length ) ;
905- writer . Write ( data ) ;
949+ if ( NetworkConfig . EncryptedChannels . Contains ( channelId ) )
950+ {
951+ //Encrypted message
952+ byte [ ] encrypted = CryptographyHelper . Encrypt ( data , connectedClients [ targetId ] . AesKey ) ;
953+ writer . Write ( ( ushort ) encrypted . Length ) ;
954+ writer . Write ( encrypted ) ;
955+ }
956+ else
957+ {
958+ writer . Write ( ( ushort ) data . Length ) ;
959+ writer . Write ( data ) ;
960+ }
906961 }
907962 NetworkTransport . QueueMessageForSending ( hostId , targetId , channelId , stream . GetBuffer ( ) , sizeOfStream , out error ) ;
908963 }
@@ -951,8 +1006,25 @@ internal void Send(int clientId, string messageType, string channelName, byte[]
9511006 writer . Write ( isPassthrough ) ;
9521007 if ( isPassthrough )
9531008 writer . Write ( clientId ) ;
954- writer . Write ( ( ushort ) data . Length ) ;
955- writer . Write ( data ) ;
1009+
1010+ if ( NetworkConfig . EncryptedChannels . Contains ( MessageManager . channels [ channelName ] ) )
1011+ {
1012+ //This is an encrypted message.
1013+ byte [ ] encrypted ;
1014+ if ( isServer )
1015+ encrypted = CryptographyHelper . Encrypt ( data , connectedClients [ clientId ] . AesKey ) ;
1016+ else
1017+ encrypted = CryptographyHelper . Encrypt ( data , clientAesKey ) ;
1018+
1019+ writer . Write ( ( ushort ) encrypted . Length ) ;
1020+ writer . Write ( encrypted ) ;
1021+ }
1022+ else
1023+ {
1024+ //Send in plaintext.
1025+ writer . Write ( ( ushort ) data . Length ) ;
1026+ writer . Write ( data ) ;
1027+ }
9561028 }
9571029 if ( isPassthrough )
9581030 clientId = serverClientId ;
@@ -965,7 +1037,12 @@ internal void Send(int clientId, string messageType, string channelName, byte[]
9651037
9661038 internal void Send ( int [ ] clientIds , string messageType , string channelName , byte [ ] data , uint ? networkId = null , ushort ? orderId = null )
9671039 {
968- int sizeOfStream = 6 ;
1040+ if ( NetworkConfig . EncryptedChannels . Contains ( MessageManager . channels [ channelName ] ) )
1041+ {
1042+ Debug . LogWarning ( "MLAPI: Cannot send messages over encrypted channel to multiple clients." ) ;
1043+ return ;
1044+ }
1045+ int sizeOfStream = 6 ;
9691046 if ( networkId != null )
9701047 sizeOfStream += 4 ;
9711048 if ( orderId != null )
@@ -1007,6 +1084,12 @@ internal void Send(int[] clientIds, string messageType, string channelName, byte
10071084
10081085 internal void Send ( List < int > clientIds , string messageType , string channelName , byte [ ] data , uint ? networkId = null , ushort ? orderId = null )
10091086 {
1087+ if ( NetworkConfig . EncryptedChannels . Contains ( MessageManager . channels [ channelName ] ) )
1088+ {
1089+ Debug . LogWarning ( "MLAPI: Cannot send messages over encrypted channel to multiple clients." ) ;
1090+ return ;
1091+ }
1092+
10101093 //2 bytes for messageType, 2 bytes for buffer length and one byte for target bool
10111094 int sizeOfStream = 6 ;
10121095 if ( networkId != null )
@@ -1050,6 +1133,12 @@ internal void Send(List<int> clientIds, string messageType, string channelName,
10501133
10511134 internal void Send ( string messageType , string channelName , byte [ ] data , uint ? networkId = null , ushort ? orderId = null )
10521135 {
1136+ if ( NetworkConfig . EncryptedChannels . Contains ( MessageManager . channels [ channelName ] ) )
1137+ {
1138+ Debug . LogWarning ( "MLAPI: Cannot send messages over encrypted channel to multiple clients." ) ;
1139+ return ;
1140+ }
1141+
10531142 //2 bytes for messageType, 2 bytes for buffer length and one byte for target bool
10541143 int sizeOfStream = 6 ;
10551144 if ( networkId != null )
@@ -1094,6 +1183,12 @@ internal void Send(string messageType, string channelName, byte[] data, uint? ne
10941183
10951184 internal void Send ( string messageType , string channelName , byte [ ] data , int clientIdToIgnore , uint ? networkId = null , ushort ? orderId = null )
10961185 {
1186+ if ( NetworkConfig . EncryptedChannels . Contains ( MessageManager . channels [ channelName ] ) )
1187+ {
1188+ Debug . LogWarning ( "MLAPI: Cannot send messages over encrypted channel to multiple clients." ) ;
1189+ return ;
1190+ }
1191+
10971192 //2 bytes for messageType, 2 bytes for buffer length and one byte for target bool
10981193 int sizeOfStream = 5 ;
10991194 if ( networkId != null )
@@ -1142,10 +1237,16 @@ private void DisconnectClient(int clientId)
11421237 {
11431238 if ( ! isServer )
11441239 return ;
1240+
11451241 if ( pendingClients . Contains ( clientId ) )
11461242 pendingClients . Remove ( clientId ) ;
1243+
11471244 if ( connectedClients . ContainsKey ( clientId ) )
11481245 connectedClients . Remove ( clientId ) ;
1246+
1247+ if ( diffieHellmanPublicKeys . ContainsKey ( clientId ) )
1248+ diffieHellmanPublicKeys . Remove ( clientId ) ;
1249+
11491250 NetworkTransport . Disconnect ( hostId , clientId , out error ) ;
11501251 }
11511252
@@ -1188,9 +1289,23 @@ private void HandleApproval(int clientId, bool approved)
11881289 //Inform new client it got approved
11891290 if ( pendingClients . Contains ( clientId ) )
11901291 pendingClients . Remove ( clientId ) ;
1292+
1293+ byte [ ] aesKey = new byte [ 0 ] ;
1294+ byte [ ] publicKey = new byte [ 0 ] ;
1295+ if ( NetworkConfig . EnableEncryption )
1296+ {
1297+ EllipticDiffieHellman diffieHellman = new EllipticDiffieHellman ( EllipticDiffieHellman . DEFAULT_CURVE , EllipticDiffieHellman . DEFAULT_GENERATOR , EllipticDiffieHellman . DEFAULT_ORDER ) ;
1298+ aesKey = diffieHellman . GetSharedSecret ( diffieHellmanPublicKeys [ clientId ] ) ;
1299+ publicKey = diffieHellman . GetPublicKey ( ) ;
1300+
1301+ if ( diffieHellmanPublicKeys . ContainsKey ( clientId ) )
1302+ diffieHellmanPublicKeys . Remove ( clientId ) ;
1303+ }
1304+
11911305 NetworkedClient client = new NetworkedClient ( )
11921306 {
1193- ClientId = clientId
1307+ ClientId = clientId ,
1308+ AesKey = aesKey
11941309 } ;
11951310 connectedClients . Add ( clientId , client ) ;
11961311
@@ -1201,7 +1316,6 @@ private void HandleApproval(int clientId, bool approved)
12011316 connectedClients [ clientId ] . PlayerObject = go ;
12021317 }
12031318
1204-
12051319 int sizeOfStream = 16 + ( ( connectedClients . Count - 1 ) * 4 ) ;
12061320
12071321 int amountOfObjectsToSend = SpawnManager . spawnedObjects . Values . Count ( x => x . ServerOnly == false ) ;
@@ -1211,6 +1325,10 @@ private void HandleApproval(int clientId, bool approved)
12111325 sizeOfStream += 4 ;
12121326 sizeOfStream += 14 * amountOfObjectsToSend ;
12131327 }
1328+ if ( NetworkConfig . EnableEncryption )
1329+ {
1330+ sizeOfStream += 2 + publicKey . Length ;
1331+ }
12141332 if ( NetworkConfig . EnableSceneSwitching )
12151333 {
12161334 sizeOfStream += 4 ;
@@ -1225,8 +1343,16 @@ private void HandleApproval(int clientId, bool approved)
12251343 {
12261344 writer . Write ( NetworkSceneManager . CurrentSceneIndex ) ;
12271345 }
1346+
1347+ if ( NetworkConfig . EnableEncryption )
1348+ {
1349+ writer . Write ( ( ushort ) publicKey . Length ) ;
1350+ writer . Write ( publicKey ) ;
1351+ }
1352+
12281353 writer . Write ( NetworkTime ) ;
12291354 writer . Write ( NetworkTransport . GetNetworkTimestamp ( ) ) ;
1355+
12301356 writer . Write ( connectedClients . Count - 1 ) ;
12311357 foreach ( KeyValuePair < int , NetworkedClient > item in connectedClients )
12321358 {
@@ -1292,6 +1418,10 @@ private void HandleApproval(int clientId, bool approved)
12921418 {
12931419 if ( pendingClients . Contains ( clientId ) )
12941420 pendingClients . Remove ( clientId ) ;
1421+
1422+ if ( diffieHellmanPublicKeys . ContainsKey ( clientId ) )
1423+ diffieHellmanPublicKeys . Remove ( clientId ) ;
1424+
12951425 NetworkTransport . Disconnect ( hostId , clientId , out error ) ;
12961426 }
12971427 }
0 commit comments