Skip to content

Commit f0a1b0b

Browse files
committed
feat: Added DSA certificate support
1 parent 0123e8a commit f0a1b0b

File tree

2 files changed

+67
-53
lines changed

2 files changed

+67
-53
lines changed

MLAPI/Core/NetworkingManager.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -652,18 +652,33 @@ private void Update()
652652
// Write public part signature (signed by certificate private)
653653
X509Certificate2 certificate = NetworkConfig.ServerX509Certificate;
654654
if (!certificate.HasPrivateKey) throw new CryptographicException("[MLAPI] No private key was found in server certificate. Unable to sign key exchange");
655+
655656
RSACryptoServiceProvider rsa = certificate.PrivateKey as RSACryptoServiceProvider;
657+
DSACryptoServiceProvider dsa = certificate.PrivateKey as DSACryptoServiceProvider;
656658

657659
if (rsa != null)
658660
{
661+
// RSA is 0
662+
hailWriter.WriteByte(0);
663+
659664
using (SHA256Managed sha = new SHA256Managed())
660665
{
661666
hailWriter.WriteByteArray(rsa.SignData(diffieHellmanPublicPart, sha));
662667
}
663668
}
669+
else if (dsa != null)
670+
{
671+
// DSA is 1
672+
hailWriter.WriteByte(1);
673+
674+
using (SHA256Managed sha = new SHA256Managed())
675+
{
676+
hailWriter.WriteByteArray(dsa.SignData(sha.ComputeHash(diffieHellmanPublicPart)));
677+
}
678+
}
664679
else
665680
{
666-
throw new CryptographicException("[MLAPI] Only RSA certificates are supported. No valid RSA key was found");
681+
throw new CryptographicException("[MLAPI] Only RSA and DSA certificates are supported. No valid RSA or DSA key was found");
667682
}
668683
}
669684
}

MLAPI/Messaging/InternalMessageHandler.cs

Lines changed: 51 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ internal static void HandleHailRequest(ulong clientId, Stream stream)
3838
{
3939
// The certificate is not valid :(
4040
// Man in the middle.
41-
if (LogHelper.CurrentLogLevel <= LogLevel.Normal) if (LogHelper.CurrentLogLevel <= LogLevel.Normal) LogHelper.LogWarning("Invalid certificate. Disconnecting");
41+
if (LogHelper.CurrentLogLevel <= LogLevel.Normal) LogHelper.LogWarning("Invalid certificate. Disconnecting");
4242
NetworkingManager.Singleton.StopClient();
4343
return;
4444
}
@@ -55,22 +55,62 @@ internal static void HandleHailRequest(ulong clientId, Stream stream)
5555
// Verify the key exchange
5656
if (NetworkingManager.Singleton.NetworkConfig.SignKeyExchange)
5757
{
58+
int signatureType = reader.ReadByte();
59+
5860
byte[] serverDiffieHellmanPublicPartSignature = reader.ReadByteArray();
5961

60-
RSACryptoServiceProvider rsa = certificate.PublicKey.Key as RSACryptoServiceProvider;
62+
if (signatureType == 0)
63+
{
64+
RSACryptoServiceProvider rsa = certificate.PublicKey.Key as RSACryptoServiceProvider;
6165

62-
if (rsa != null)
66+
if (rsa != null)
67+
{
68+
using (SHA256Managed sha = new SHA256Managed())
69+
{
70+
if (!rsa.VerifyData(serverDiffieHellmanPublicPart, sha, serverDiffieHellmanPublicPartSignature))
71+
{
72+
if (LogHelper.CurrentLogLevel <= LogLevel.Normal) LogHelper.LogWarning("Invalid RSA signature. Disconnecting");
73+
NetworkingManager.Singleton.StopClient();
74+
return;
75+
}
76+
}
77+
}
78+
else
79+
{
80+
if (LogHelper.CurrentLogLevel <= LogLevel.Normal) LogHelper.LogWarning("No RSA key found in certificate. Disconnecting");
81+
NetworkingManager.Singleton.StopClient();
82+
return;
83+
}
84+
}
85+
else if (signatureType == 1)
6386
{
64-
using (SHA256Managed sha = new SHA256Managed())
87+
DSACryptoServiceProvider dsa = certificate.PublicKey.Key as DSACryptoServiceProvider;
88+
89+
if (dsa != null)
6590
{
66-
if (!rsa.VerifyData(serverDiffieHellmanPublicPart, sha, serverDiffieHellmanPublicPartSignature))
91+
using (SHA256Managed sha = new SHA256Managed())
6792
{
68-
if (LogHelper.CurrentLogLevel <= LogLevel.Normal) if (LogHelper.CurrentLogLevel <= LogLevel.Normal) LogHelper.LogWarning("Invalid signature. Disconnecting");
69-
NetworkingManager.Singleton.StopClient();
70-
return;
71-
}
93+
if (!dsa.VerifyData(sha.ComputeHash(serverDiffieHellmanPublicPart), serverDiffieHellmanPublicPartSignature))
94+
{
95+
if (LogHelper.CurrentLogLevel <= LogLevel.Normal) LogHelper.LogWarning("Invalid DSA signature. Disconnecting");
96+
NetworkingManager.Singleton.StopClient();
97+
return;
98+
}
99+
}
100+
}
101+
else
102+
{
103+
if (LogHelper.CurrentLogLevel <= LogLevel.Normal) LogHelper.LogWarning("No DSA key found in certificate. Disconnecting");
104+
NetworkingManager.Singleton.StopClient();
105+
return;
72106
}
73107
}
108+
else
109+
{
110+
if (LogHelper.CurrentLogLevel <= LogLevel.Normal) LogHelper.LogWarning("Invalid signature type. Disconnecting");
111+
NetworkingManager.Singleton.StopClient();
112+
return;
113+
}
74114
}
75115
}
76116
}
@@ -86,24 +126,9 @@ internal static void HandleHailRequest(ulong clientId, Stream stream)
86126
NetworkingManager.Singleton.clientAesKey = diffieHellman.GetSharedSecret(serverDiffieHellmanPublicPart);
87127
byte[] diffieHellmanPublicKey = diffieHellman.GetPublicKey();
88128
writer.WriteByteArray(diffieHellmanPublicKey);
89-
if (NetworkingManager.Singleton.NetworkConfig.SignKeyExchange)
90-
{
91-
RSACryptoServiceProvider rsa = certificate.PublicKey.Key as RSACryptoServiceProvider;
92-
93-
if (rsa != null)
94-
{
95-
using (SHA256CryptoServiceProvider sha = new SHA256CryptoServiceProvider())
96-
{
97-
writer.WriteByteArray(rsa.Encrypt(sha.ComputeHash(diffieHellmanPublicKey), false));
98-
}
99-
}
100-
else
101-
{
102-
throw new CryptographicException("[MLAPI] Only RSA certificates are supported. No valid RSA key was found");
103-
}
104-
}
105129
}
106130
}
131+
107132
// Send HailResponse
108133
InternalMessageSender.Send(NetworkingManager.Singleton.ServerClientId, MLAPIConstants.MLAPI_CERTIFICATE_HAIL_RESPONSE, "MLAPI_INTERNAL", outStream, SecuritySendFlags.None, null, true);
109134
}
@@ -121,33 +146,6 @@ internal static void HandleHailResponse(ulong clientId, Stream stream)
121146
{
122147
byte[] diffieHellmanPublic = reader.ReadByteArray();
123148
NetworkingManager.Singleton.PendingClients[clientId].AesKey = NetworkingManager.Singleton.PendingClients[clientId].KeyExchange.GetSharedSecret(diffieHellmanPublic);
124-
if (NetworkingManager.Singleton.NetworkConfig.SignKeyExchange)
125-
{
126-
byte[] diffieHellmanPublicSignature = reader.ReadByteArray();
127-
X509Certificate2 certificate = NetworkingManager.Singleton.NetworkConfig.ServerX509Certificate;
128-
RSACryptoServiceProvider rsa = certificate.PrivateKey as RSACryptoServiceProvider;
129-
130-
if (rsa != null)
131-
{
132-
using (SHA256Managed sha = new SHA256Managed())
133-
{
134-
byte[] clientHash = rsa.Decrypt(diffieHellmanPublicSignature, false);
135-
byte[] serverHash = sha.ComputeHash(diffieHellmanPublic);
136-
137-
if (!CryptographyHelper.ConstTimeArrayEqual(clientHash, serverHash))
138-
{
139-
//Man in the middle.
140-
if (LogHelper.CurrentLogLevel <= LogLevel.Normal) if (LogHelper.CurrentLogLevel <= LogLevel.Normal) LogHelper.LogWarning("Signature doesnt match for the key exchange public part. Disconnecting");
141-
NetworkingManager.Singleton.DisconnectClient(clientId);
142-
return;
143-
}
144-
}
145-
}
146-
else
147-
{
148-
throw new CryptographicException("[MLAPI] Only RSA certificates are supported. No valid RSA key was found");
149-
}
150-
}
151149
}
152150
}
153151

@@ -161,6 +159,7 @@ internal static void HandleHailResponse(ulong clientId, Stream stream)
161159
{
162160
writer.WriteInt64Packed(DateTime.Now.Ticks); // This serves no purpose.
163161
}
162+
164163
InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_GREETINGS, "MLAPI_INTERNAL", outStream, SecuritySendFlags.None, null, true);
165164
}
166165
}

0 commit comments

Comments
 (0)