@@ -49,6 +49,10 @@ public bool isHost
4949
5050 public NetworkingConfiguration NetworkConfig ;
5151
52+ private EllipticDiffieHellman clientDiffieHellman ;
53+ private Dictionary < int , byte [ ] > diffieHellmanPublicKeys ;
54+ private byte [ ] clientAesKey ;
55+
5256 private void OnValidate ( )
5357 {
5458 if ( SpawnablePrefabs != null )
@@ -86,6 +90,7 @@ private ConnectionConfig Init(NetworkingConfiguration netConfig)
8690 pendingClients = new HashSet < int > ( ) ;
8791 connectedClients = new Dictionary < int , NetworkedClient > ( ) ;
8892 messageBuffer = new byte [ NetworkConfig . MessageBufferSize ] ;
93+ diffieHellmanPublicKeys = new Dictionary < int , byte [ ] > ( ) ;
8994 MessageManager . channels = new Dictionary < string , int > ( ) ;
9095 MessageManager . messageTypes = new Dictionary < string , ushort > ( ) ;
9196 MessageManager . messageCallbacks = new Dictionary < ushort , Dictionary < int , Action < int , byte [ ] > > > ( ) ;
@@ -372,15 +377,29 @@ private void Update()
372377 }
373378 else
374379 {
380+ byte [ ] diffiePublic = new byte [ 0 ] ;
381+ if ( NetworkConfig . EnableEncryption )
382+ {
383+ clientDiffieHellman = new EllipticDiffieHellman ( EllipticDiffieHellman . DEFAULT_CURVE , EllipticDiffieHellman . DEFAULT_GENERATOR , EllipticDiffieHellman . DEFAULT_ORDER ) ;
384+ diffiePublic = clientDiffieHellman . GetPublicKey ( ) ;
385+ }
386+
375387 int sizeOfStream = 32 ;
376388 if ( NetworkConfig . ConnectionApproval )
377389 sizeOfStream += 2 + NetworkConfig . ConnectionData . Length ;
390+ if ( NetworkConfig . EnableEncryption )
391+ sizeOfStream += 2 + diffiePublic . Length ;
378392
379393 using ( MemoryStream writeStream = new MemoryStream ( sizeOfStream ) )
380394 {
381395 using ( BinaryWriter writer = new BinaryWriter ( writeStream ) )
382396 {
383397 writer . Write ( NetworkConfig . GetConfig ( ) ) ;
398+ if ( NetworkConfig . EnableEncryption )
399+ {
400+ writer . Write ( ( ushort ) diffiePublic . Length ) ;
401+ writer . Write ( diffiePublic ) ;
402+ }
384403 if ( NetworkConfig . ConnectionApproval )
385404 {
386405 writer . Write ( ( ushort ) NetworkConfig . ConnectionData . Length ) ;
@@ -469,6 +488,14 @@ private void HandleIncomingData(int clientId, byte[] data, int channelId)
469488
470489 ushort bytesToRead = reader . ReadUInt16 ( ) ;
471490 byte [ ] incommingData = reader . ReadBytes ( bytesToRead ) ;
491+ if ( NetworkConfig . EncryptedChannels . Contains ( channelId ) )
492+ {
493+ //Encrypted message
494+ if ( isServer )
495+ incommingData = CryptographyHelper . Decrypt ( incommingData , connectedClients [ clientId ] . AesKey ) ;
496+ else
497+ incommingData = CryptographyHelper . Decrypt ( incommingData , clientAesKey ) ;
498+ }
472499
473500 if ( isServer && isPassthrough && ! NetworkConfig . RegisteredPassthroughMessageTypes . Contains ( messageType ) )
474501 {
@@ -550,6 +577,18 @@ private void HandleIncomingData(int clientId, byte[] data, int channelId)
550577 DisconnectClient ( clientId ) ;
551578 return ;
552579 }
580+ byte [ ] aesKey = new byte [ 0 ] ;
581+ if ( NetworkConfig . EnableEncryption )
582+ {
583+ ushort diffiePublicSize = reader . ReadUInt16 ( ) ;
584+ byte [ ] diffiePublic = reader . ReadBytes ( diffiePublicSize ) ;
585+ diffieHellmanPublicKeys . Add ( clientId , diffiePublic ) ;
586+ /*
587+ EllipticDiffieHellman diffieHellman = new EllipticDiffieHellman(EllipticDiffieHellman.DEFAULT_CURVE, EllipticDiffieHellman.DEFAULT_GENERATOR, EllipticDiffieHellman.DEFAULT_ORDER);
588+ aesKey = diffieHellman.GetSharedSecret(diffiePublic);
589+ */
590+
591+ }
553592 if ( NetworkConfig . ConnectionApproval )
554593 {
555594 ushort bufferSize = messageReader . ReadUInt16 ( ) ;
@@ -578,6 +617,12 @@ private void HandleIncomingData(int clientId, byte[] data, int channelId)
578617 sceneIndex = messageReader . ReadUInt32 ( ) ;
579618 }
580619
620+ if ( NetworkConfig . EnableEncryption )
621+ {
622+ ushort keyLength = reader . ReadUInt16 ( ) ;
623+ clientAesKey = clientDiffieHellman . GetSharedSecret ( reader . ReadBytes ( keyLength ) ) ;
624+ }
625+
581626 float netTime = messageReader . ReadSingle ( ) ;
582627 int remoteStamp = messageReader . ReadInt32 ( ) ;
583628 int msDelay = NetworkTransport . GetRemoteDelayTimeMS ( hostId , clientId , remoteStamp , out error ) ;
@@ -894,8 +939,18 @@ internal void PassthroughSend(int targetId, int sourceId, ushort messageType, in
894939 writer . Write ( orderId . Value ) ;
895940 writer . Write ( true ) ;
896941 writer . Write ( sourceId ) ;
897- writer . Write ( ( ushort ) data . Length ) ;
898- writer . Write ( data ) ;
942+ if ( NetworkConfig . EncryptedChannels . Contains ( channelId ) )
943+ {
944+ //Encrypted message
945+ byte [ ] encrypted = CryptographyHelper . Encrypt ( data , connectedClients [ targetId ] . AesKey ) ;
946+ writer . Write ( ( ushort ) encrypted . Length ) ;
947+ writer . Write ( encrypted ) ;
948+ }
949+ else
950+ {
951+ writer . Write ( ( ushort ) data . Length ) ;
952+ writer . Write ( data ) ;
953+ }
899954 }
900955 NetworkTransport . QueueMessageForSending ( hostId , targetId , channelId , stream . GetBuffer ( ) , sizeOfStream , out error ) ;
901956 }
@@ -944,8 +999,25 @@ internal void Send(int clientId, string messageType, string channelName, byte[]
944999 writer . Write ( isPassthrough ) ;
9451000 if ( isPassthrough )
9461001 writer . Write ( clientId ) ;
947- writer . Write ( ( ushort ) data . Length ) ;
948- writer . Write ( data ) ;
1002+
1003+ if ( NetworkConfig . EncryptedChannels . Contains ( MessageManager . channels [ channelName ] ) )
1004+ {
1005+ //This is an encrypted message.
1006+ byte [ ] encrypted ;
1007+ if ( isServer )
1008+ encrypted = CryptographyHelper . Encrypt ( data , connectedClients [ clientId ] . AesKey ) ;
1009+ else
1010+ encrypted = CryptographyHelper . Encrypt ( data , clientAesKey ) ;
1011+
1012+ writer . Write ( ( ushort ) encrypted . Length ) ;
1013+ writer . Write ( encrypted ) ;
1014+ }
1015+ else
1016+ {
1017+ //Send in plaintext.
1018+ writer . Write ( ( ushort ) data . Length ) ;
1019+ writer . Write ( data ) ;
1020+ }
9491021 }
9501022 if ( isPassthrough )
9511023 clientId = serverClientId ;
@@ -958,7 +1030,12 @@ internal void Send(int clientId, string messageType, string channelName, byte[]
9581030
9591031 internal void Send ( int [ ] clientIds , string messageType , string channelName , byte [ ] data , uint ? networkId = null , ushort ? orderId = null )
9601032 {
961- int sizeOfStream = 6 ;
1033+ if ( NetworkConfig . EncryptedChannels . Contains ( MessageManager . channels [ channelName ] ) )
1034+ {
1035+ Debug . LogWarning ( "MLAPI: Cannot send messages over encrypted channel to multiple clients." ) ;
1036+ return ;
1037+ }
1038+ int sizeOfStream = 6 ;
9621039 if ( networkId != null )
9631040 sizeOfStream += 4 ;
9641041 if ( orderId != null )
@@ -1000,6 +1077,12 @@ internal void Send(int[] clientIds, string messageType, string channelName, byte
10001077
10011078 internal void Send ( List < int > clientIds , string messageType , string channelName , byte [ ] data , uint ? networkId = null , ushort ? orderId = null )
10021079 {
1080+ if ( NetworkConfig . EncryptedChannels . Contains ( MessageManager . channels [ channelName ] ) )
1081+ {
1082+ Debug . LogWarning ( "MLAPI: Cannot send messages over encrypted channel to multiple clients." ) ;
1083+ return ;
1084+ }
1085+
10031086 //2 bytes for messageType, 2 bytes for buffer length and one byte for target bool
10041087 int sizeOfStream = 6 ;
10051088 if ( networkId != null )
@@ -1043,6 +1126,12 @@ internal void Send(List<int> clientIds, string messageType, string channelName,
10431126
10441127 internal void Send ( string messageType , string channelName , byte [ ] data , uint ? networkId = null , ushort ? orderId = null )
10451128 {
1129+ if ( NetworkConfig . EncryptedChannels . Contains ( MessageManager . channels [ channelName ] ) )
1130+ {
1131+ Debug . LogWarning ( "MLAPI: Cannot send messages over encrypted channel to multiple clients." ) ;
1132+ return ;
1133+ }
1134+
10461135 //2 bytes for messageType, 2 bytes for buffer length and one byte for target bool
10471136 int sizeOfStream = 6 ;
10481137 if ( networkId != null )
@@ -1087,6 +1176,12 @@ internal void Send(string messageType, string channelName, byte[] data, uint? ne
10871176
10881177 internal void Send ( string messageType , string channelName , byte [ ] data , int clientIdToIgnore , uint ? networkId = null , ushort ? orderId = null )
10891178 {
1179+ if ( NetworkConfig . EncryptedChannels . Contains ( MessageManager . channels [ channelName ] ) )
1180+ {
1181+ Debug . LogWarning ( "MLAPI: Cannot send messages over encrypted channel to multiple clients." ) ;
1182+ return ;
1183+ }
1184+
10901185 //2 bytes for messageType, 2 bytes for buffer length and one byte for target bool
10911186 int sizeOfStream = 5 ;
10921187 if ( networkId != null )
@@ -1134,10 +1229,16 @@ private void DisconnectClient(int clientId)
11341229 {
11351230 if ( ! isServer )
11361231 return ;
1232+
11371233 if ( pendingClients . Contains ( clientId ) )
11381234 pendingClients . Remove ( clientId ) ;
1235+
11391236 if ( connectedClients . ContainsKey ( clientId ) )
11401237 connectedClients . Remove ( clientId ) ;
1238+
1239+ if ( diffieHellmanPublicKeys . ContainsKey ( clientId ) )
1240+ diffieHellmanPublicKeys . Remove ( clientId ) ;
1241+
11411242 NetworkTransport . Disconnect ( hostId , clientId , out error ) ;
11421243 }
11431244
@@ -1180,9 +1281,23 @@ private void HandleApproval(int clientId, bool approved)
11801281 //Inform new client it got approved
11811282 if ( pendingClients . Contains ( clientId ) )
11821283 pendingClients . Remove ( clientId ) ;
1284+
1285+ byte [ ] aesKey = new byte [ 0 ] ;
1286+ byte [ ] publicKey = new byte [ 0 ] ;
1287+ if ( NetworkConfig . EnableEncryption )
1288+ {
1289+ EllipticDiffieHellman diffieHellman = new EllipticDiffieHellman ( EllipticDiffieHellman . DEFAULT_CURVE , EllipticDiffieHellman . DEFAULT_GENERATOR , EllipticDiffieHellman . DEFAULT_ORDER ) ;
1290+ aesKey = diffieHellman . GetSharedSecret ( diffieHellmanPublicKeys [ clientId ] ) ;
1291+ publicKey = diffieHellman . GetPublicKey ( ) ;
1292+
1293+ if ( diffieHellmanPublicKeys . ContainsKey ( clientId ) )
1294+ diffieHellmanPublicKeys . Remove ( clientId ) ;
1295+ }
1296+
11831297 NetworkedClient client = new NetworkedClient ( )
11841298 {
1185- ClientId = clientId
1299+ ClientId = clientId ,
1300+ AesKey = aesKey
11861301 } ;
11871302 connectedClients . Add ( clientId , client ) ;
11881303
@@ -1193,7 +1308,6 @@ private void HandleApproval(int clientId, bool approved)
11931308 connectedClients [ clientId ] . PlayerObject = go ;
11941309 }
11951310
1196-
11971311 int sizeOfStream = 16 + ( ( connectedClients . Count - 1 ) * 4 ) ;
11981312
11991313 int amountOfObjectsToSend = SpawnManager . spawnedObjects . Values . Count ( x => x . ServerOnly == false ) ;
@@ -1203,6 +1317,10 @@ private void HandleApproval(int clientId, bool approved)
12031317 sizeOfStream += 4 ;
12041318 sizeOfStream += 14 * amountOfObjectsToSend ;
12051319 }
1320+ if ( NetworkConfig . EnableEncryption )
1321+ {
1322+ sizeOfStream += 2 + publicKey . Length ;
1323+ }
12061324 if ( NetworkConfig . EnableSceneSwitching )
12071325 {
12081326 sizeOfStream += 4 ;
@@ -1217,8 +1335,16 @@ private void HandleApproval(int clientId, bool approved)
12171335 {
12181336 writer . Write ( NetworkSceneManager . CurrentSceneIndex ) ;
12191337 }
1338+
1339+ if ( NetworkConfig . EnableEncryption )
1340+ {
1341+ writer . Write ( ( ushort ) publicKey . Length ) ;
1342+ writer . Write ( publicKey ) ;
1343+ }
1344+
12201345 writer . Write ( NetworkTime ) ;
12211346 writer . Write ( NetworkTransport . GetNetworkTimestamp ( ) ) ;
1347+
12221348 writer . Write ( connectedClients . Count - 1 ) ;
12231349 foreach ( KeyValuePair < int , NetworkedClient > item in connectedClients )
12241350 {
@@ -1284,6 +1410,10 @@ private void HandleApproval(int clientId, bool approved)
12841410 {
12851411 if ( pendingClients . Contains ( clientId ) )
12861412 pendingClients . Remove ( clientId ) ;
1413+
1414+ if ( diffieHellmanPublicKeys . ContainsKey ( clientId ) )
1415+ diffieHellmanPublicKeys . Remove ( clientId ) ;
1416+
12871417 NetworkTransport . Disconnect ( hostId , clientId , out error ) ;
12881418 }
12891419 }
0 commit comments