Add back xml to SharedSecretExchange

This commit is contained in:
D1GQ authored and GitHub committed 2026-03-17 14:10:39 -05:00
1 parent d9de9da91c
commit 17fed3cb07
1 file changed
+55 -1
+55 -1
View File
@@ -3,6 +3,9 @@ using System.Security.Cryptography;
namespace BetterAmongUs.Data;
/// <summary>
/// Handles secure key exchange using Elliptic Curve Diffie-Hellman (ECDH) for establishing shared secrets.
/// </summary>
internal sealed class SharedSecretExchange
{
private readonly ECDiffieHellman dh;
@@ -11,11 +14,21 @@ internal sealed class SharedSecretExchange
private byte[] sharedSecret = [];
private bool cryptoDisabled;
/// <summary>
/// Gets a value indicating whether cryptographic operations are available.
/// </summary>
internal bool CryptoAvailable => !cryptoDisabled;
/// <summary>
/// Gets or sets a value indicating whether to use the fallback key exchange mechanism.
/// </summary>
internal bool UseFallback { get; set; }
private int? remoteTempKey;
/// <summary>
/// Initializes a new instance of the SharedSecretExchange class with a new ECDH key pair.
/// </summary>
internal SharedSecretExchange()
{
try
@@ -35,6 +48,10 @@ internal sealed class SharedSecretExchange
tempKey = GenerateSecureTempKey();
}
/// <summary>
/// Generates a cryptographically secure random temporary key.
/// </summary>
/// <returns>A random positive integer used as a temporary key.</returns>
private static int GenerateSecureTempKey()
{
byte[] buffer = new byte[4];
@@ -42,27 +59,48 @@ internal sealed class SharedSecretExchange
return Math.Abs(BitConverter.ToInt32(buffer, 0));
}
/// <summary>
/// Sets the temporary key received from the remote party.
/// </summary>
/// <param name="key">The temporary key from the remote party.</param>
internal void SetRemoteTempKey(int key)
{
remoteTempKey = key;
}
/// <summary>
/// Gets the public key for key exchange.
/// </summary>
/// <returns>The public key in SubjectPublicKeyInfo format, or an empty array if cryptography is disabled.</returns>
internal byte[] GetPublicKey()
{
if (cryptoDisabled) return [];
return publicKey;
}
/// <summary>
/// Gets the temporary key used for initial communication.
/// </summary>
/// <returns>A random integer used as a temporary key.</returns>
internal int GetTempKey()
{
return tempKey;
}
/// <summary>
/// Gets the established shared secret.
/// </summary>
/// <returns>The shared secret byte array.</returns>
internal byte[] GetSharedSecret()
{
return sharedSecret;
}
/// <summary>
/// Generates a shared secret using another party's public key.
/// </summary>
/// <param name="otherPartyPublicKey">The other party's public key in SubjectPublicKeyInfo format.</param>
/// <returns>The shared secret byte array, or an empty array if generation fails.</returns>
internal byte[] GenerateSharedSecret(byte[] otherPartyPublicKey)
{
if (sharedSecret.Length > 0) return sharedSecret;
@@ -96,6 +134,10 @@ internal sealed class SharedSecretExchange
}
}
/// <summary>
/// Gets a numeric hash of the shared secret for verification purposes.
/// </summary>
/// <returns>A 32-bit integer hash of the shared secret, or 0 if no shared secret exists.</returns>
internal int GetSharedSecretHash()
{
if (sharedSecret.Length == 0) return 0;
@@ -111,6 +153,12 @@ internal sealed class SharedSecretExchange
return Math.Abs(numericHash);
}
/// <summary>
/// Derives a fallback shared secret using temporary keys when ECDH is unavailable.
/// </summary>
/// <param name="local">The local temporary key.</param>
/// <param name="remote">The remote temporary key.</param>
/// <returns>A 256-bit hash derived from the ordered temporary keys.</returns>
private static byte[] DeriveFallbackSecret(int local, int remote)
{
using SHA256 sha256 = SHA256.Create();
@@ -126,8 +174,14 @@ internal sealed class SharedSecretExchange
return sha256.ComputeHash(buffer);
}
/// <summary>
/// Gets a value indicating whether the key exchange data has been cleared for security.
/// </summary>
internal bool HasBeenCleared { get; private set; }
/// <summary>
/// Clears all sensitive key exchange data for security purposes.
/// </summary>
internal void ClearData()
{
if (HasBeenCleared) return;
@@ -136,4 +190,4 @@ internal sealed class SharedSecretExchange
tempKey = 0;
sharedSecret = [];
}
}
}