Skip to content

Commit 17de52b

Browse files
committed
Fixed encryption issues with non seeking CryptoStream
1 parent efd3627 commit 17de52b

File tree

3 files changed

+76
-17
lines changed

3 files changed

+76
-17
lines changed

MLAPI/Data/NetworkConfig.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ public class NetworkConfig
6868
/// </summary>
6969
public int MessageBufferSize = 1024;
7070
/// <summary>
71+
/// The size of the encryption buffer, this is the buffer where messages will be decrypted to.
72+
/// </summary>
73+
public int EncryptionBufferSize = 265;
74+
/// <summary>
7175
/// Amount of times per second the receive queue is emptied and all messages inside are processed.
7276
/// </summary>
7377
public int ReceiveTickrate = 64;
@@ -205,6 +209,7 @@ public string ToBase64()
205209
}
206210

207211
writer.WriteInt32Packed(config.MessageBufferSize);
212+
writer.WriteInt32Packed(config.EncryptionBufferSize);
208213
writer.WriteInt32Packed(config.ReceiveTickrate);
209214
writer.WriteInt32Packed(config.MaxReceiveEventsPerTickRate);
210215
writer.WriteInt32Packed(config.SendTickrate);
@@ -285,6 +290,7 @@ public void FromBase64(string base64, bool createDummyObject = false)
285290
}
286291

287292
config.MessageBufferSize = reader.ReadInt32Packed();
293+
config.EncryptionBufferSize = reader.ReadInt32Packed();
288294
config.ReceiveTickrate = reader.ReadInt32Packed();
289295
config.MaxReceiveEventsPerTickRate = reader.ReadInt32Packed();
290296
config.SendTickrate = reader.ReadInt32Packed();

MLAPI/MonoBehaviours/Core/NetworkingManager.cs

Lines changed: 68 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ internal set
100100
/// </summary>
101101
public bool isListening { get; internal set; }
102102
private byte[] messageBuffer;
103+
private byte[] encryptionBuffer;
103104
/// <summary>
104105
/// Gets if we are connected as a client
105106
/// </summary>
@@ -282,9 +283,12 @@ private object Init(bool server)
282283
lastReceiveTickTime = 0f;
283284
eventOvershootCounter = 0f;
284285
connectionPendingClients.Clear();
286+
hailPendingClients.Clear();
287+
pendingClientAesKeys.Clear();
285288
ConnectedClients.Clear();
286289
ConnectedClientsList.Clear();
287290
messageBuffer = new byte[NetworkConfig.MessageBufferSize];
291+
encryptionBuffer = new byte[NetworkConfig.EncryptionBufferSize];
288292
#if !DISABLE_CRYPTOGRAPHY
289293
pendingKeyExchanges.Clear();
290294
#endif
@@ -523,6 +527,19 @@ public void StopServer()
523527
NetworkConfig.NetworkTransport.DisconnectClient(clientId);
524528
}
525529
}
530+
531+
foreach (uint clientId in hailPendingClients)
532+
{
533+
if (!disconnectedIds.Contains(clientId))
534+
{
535+
disconnectedIds.Add(clientId);
536+
if (clientId == NetworkConfig.NetworkTransport.ServerClientId)
537+
continue;
538+
539+
NetworkConfig.NetworkTransport.DisconnectClient(clientId);
540+
}
541+
}
542+
526543
isServer = false;
527544
Shutdown();
528545
}
@@ -812,13 +829,21 @@ private IEnumerator ApprovalTimeout(uint clientId)
812829
{
813830
float timeStarted = NetworkTime;
814831
//We yield every frame incase a pending client disconnects and someone else gets its connection id
815-
while (NetworkTime - timeStarted < NetworkConfig.ClientConnectionBufferTimeout && connectionPendingClients.Contains(clientId))
832+
while (NetworkTime - timeStarted < NetworkConfig.ClientConnectionBufferTimeout && (connectionPendingClients.Contains(clientId) || hailPendingClients.Contains(clientId)))
816833
{
817834
yield return null;
818835
}
819-
if(connectionPendingClients.Contains(clientId) && !ConnectedClients.ContainsKey(clientId))
836+
837+
if (connectionPendingClients.Contains(clientId) && !ConnectedClients.ContainsKey(clientId))
838+
{
839+
// Timeout
840+
if (LogHelper.CurrentLogLevel <= LogLevel.Developer) LogHelper.LogInfo("Client " + clientId + " Handshake Timed Out");
841+
DisconnectClient(clientId);
842+
}
843+
844+
if (hailPendingClients.Contains(clientId) && !ConnectedClients.ContainsKey(clientId))
820845
{
821-
//Timeout
846+
// Timeout
822847
if (LogHelper.CurrentLogLevel <= LogLevel.Developer) LogHelper.LogInfo("Client " + clientId + " Handshake Timed Out");
823848
DisconnectClient(clientId);
824849
}
@@ -830,8 +855,7 @@ private void HandleIncomingData(uint clientId, byte[] data, int channelId, int t
830855
{
831856
using (BitStream bitStream = new BitStream(data))
832857
{
833-
RijndaelManaged rijndael = null;
834-
Stream stream = bitStream;
858+
BitStream stream = bitStream;
835859
try
836860
{
837861
if (LogHelper.CurrentLogLevel <= LogLevel.Developer) LogHelper.LogInfo("Unwrapping Data Header");
@@ -845,11 +869,20 @@ private void HandleIncomingData(uint clientId, byte[] data, int channelId, int t
845869
{
846870
headerReader.SkipPadBits();
847871
headerReader.ReadByteArray(IVBuffer, 16);
848-
rijndael = new RijndaelManaged();
849-
rijndael.Padding = PaddingMode.PKCS7;
850-
rijndael.Key = isServer ? (ConnectedClients.ContainsKey(clientId) ? ConnectedClients[clientId].AesKey : pendingClientAesKeys[clientId]) : clientAesKey;
851-
rijndael.IV = IVBuffer;
852-
stream = new CryptoStream(bitStream, rijndael.CreateDecryptor(), CryptoStreamMode.Read);
872+
stream = new BitStream(encryptionBuffer);
873+
using (RijndaelManaged rijndael = new RijndaelManaged())
874+
{
875+
rijndael.Padding = PaddingMode.PKCS7;
876+
rijndael.Key = isServer ? (ConnectedClients.ContainsKey(clientId) ? ConnectedClients[clientId].AesKey : pendingClientAesKeys[clientId]) : clientAesKey;
877+
rijndael.IV = IVBuffer;
878+
using (CryptoStream cryptoStream = new CryptoStream(bitStream, rijndael.CreateDecryptor(), CryptoStreamMode.Read))
879+
{
880+
int readByte = 0;
881+
while ((readByte = cryptoStream.ReadByte()) != -1)
882+
stream.WriteByte((byte)readByte);
883+
}
884+
}
885+
853886
using (PooledBitReader reader = PooledBitReader.Get(stream))
854887
{
855888
messageType = reader.ReadByteDirect();
@@ -860,8 +893,8 @@ private void HandleIncomingData(uint clientId, byte[] data, int channelId, int t
860893
headerReader.SkipPadBits();
861894
using (HMACSHA256 hmac = new HMACSHA256(isServer ? ConnectedClients[clientId].AesKey : clientAesKey))
862895
{
863-
// 1 is the size of the header. 32 is the size of the hmac
864896
headerReader.ReadByteArray(HMACBuffer, 32);
897+
// 1 is the size of the header. 32 is the size of the hmac
865898
byte[] hmacBytes = hmac.ComputeHash(bitStream.GetBuffer(), 1 + 32, totalSize - (1 + 32));
866899
for (int i = 0; i < hmacBytes.Length; i++)
867900
{
@@ -872,6 +905,7 @@ private void HandleIncomingData(uint clientId, byte[] data, int channelId, int t
872905
}
873906
}
874907
}
908+
875909
messageType = headerReader.ReadByteDirect();
876910
}
877911
else
@@ -886,7 +920,7 @@ private void HandleIncomingData(uint clientId, byte[] data, int channelId, int t
886920

887921
//Client tried to send a network message that was not the connection request before he was accepted.
888922
if (isServer && (NetworkConfig.EnableEncryption && hailPendingClients.Contains(clientId) && messageType != MLAPIConstants.MLAPI_CERTIFICATE_HAIL_RESPONSE) ||
889-
(connectionPendingClients.Contains(clientId) && messageType != MLAPIConstants.MLAPI_CONNECTION_REQUEST))
923+
(connectionPendingClients.Contains(clientId) && messageType != MLAPIConstants.MLAPI_CONNECTION_REQUEST))
890924
{
891925
if (LogHelper.CurrentLogLevel <= LogLevel.Normal) LogHelper.LogWarning("Message recieved from clientId " + clientId + " before it has been accepted");
892926
return;
@@ -967,7 +1001,6 @@ private void HandleIncomingData(uint clientId, byte[] data, int channelId, int t
9671001
finally
9681002
{
9691003
if (stream != bitStream) stream.Dispose();
970-
if (rijndael != null) rijndael.Clear();
9711004
}
9721005
}
9731006
}
@@ -983,9 +1016,15 @@ internal void DisconnectClient(uint clientId)
9831016
if (connectionPendingClients.Contains(clientId))
9841017
connectionPendingClients.Remove(clientId);
9851018

1019+
if (hailPendingClients.Contains(clientId))
1020+
hailPendingClients.Remove(clientId);
1021+
9861022
if (ConnectedClients.ContainsKey(clientId))
9871023
ConnectedClients.Remove(clientId);
9881024

1025+
if (pendingClientAesKeys.ContainsKey(clientId))
1026+
pendingClientAesKeys.Remove(clientId);
1027+
9891028
for (int i = ConnectedClientsList.Count - 1; i > -1; i--)
9901029
{
9911030
if (ConnectedClientsList[i].ClientId == clientId)
@@ -1004,6 +1043,13 @@ internal void OnClientDisconnectFromServer(uint clientId)
10041043
{
10051044
if (connectionPendingClients.Contains(clientId))
10061045
connectionPendingClients.Remove(clientId);
1046+
1047+
if (hailPendingClients.Contains(clientId))
1048+
hailPendingClients.Remove(clientId);
1049+
1050+
if (pendingClientAesKeys.ContainsKey(clientId))
1051+
pendingClientAesKeys.Remove(clientId);
1052+
10071053
if (ConnectedClients.ContainsKey(clientId))
10081054
{
10091055
if(NetworkConfig.HandleObjectSpawning)
@@ -1060,12 +1106,16 @@ internal void HandleApproval(uint clientId, int prefabId, bool approved, Vector3
10601106
{
10611107
if(approved)
10621108
{
1063-
//Inform new client it got approved
1109+
// Inform new client it got approved
10641110
if (connectionPendingClients.Contains(clientId))
10651111
connectionPendingClients.Remove(clientId);
10661112

1113+
if (hailPendingClients.Contains(clientId))
1114+
hailPendingClients.Remove(clientId);
1115+
10671116
byte[] aesKey = pendingClientAesKeys.ContainsKey(clientId) ? pendingClientAesKeys[clientId] : null;
1068-
pendingClientAesKeys.Remove(clientId);
1117+
if (pendingClientAesKeys.ContainsKey(clientId))
1118+
pendingClientAesKeys.Remove(clientId);
10691119
NetworkedClient client = new NetworkedClient()
10701120
{
10711121
ClientId = clientId,
@@ -1183,6 +1233,9 @@ internal void HandleApproval(uint clientId, int prefabId, bool approved, Vector3
11831233
if (connectionPendingClients.Contains(clientId))
11841234
connectionPendingClients.Remove(clientId);
11851235

1236+
if (hailPendingClients.Contains(clientId))
1237+
hailPendingClients.Remove(clientId);
1238+
11861239
#if !DISABLE_CRYPTOGRAPHY
11871240
if (pendingKeyExchanges.ContainsKey(clientId))
11881241
pendingKeyExchanges.Remove(clientId);

MLAPI/NetworkingManagerComponents/Cryptography/CryptographyHelper.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ public static class CryptographyHelper
1414
{
1515
public delegate bool VerifyCertificateDelegate(X509Certificate2 certificate, string hostname);
1616
public static VerifyCertificateDelegate OnValidateCertificateCallback = null;
17-
17+
1818
public static bool VerifyCertificate(X509Certificate2 certificate, string hostname)
1919
{
2020
if (OnValidateCertificateCallback != null) return OnValidateCertificateCallback(certificate, hostname);
21-
return certificate.Verify() && hostname == certificate.GetNameInfo(X509NameType.DnsName, false);
21+
return certificate.Verify() && (hostname == certificate.GetNameInfo(X509NameType.DnsName, false) || hostname == "127.0.0.1");
2222
}
2323
}
2424
}

0 commit comments

Comments
 (0)