From 17fed3cb0737af6399526b8face92fd6b46ac997 Mon Sep 17 00:00:00 2001
From: D1GQ <83262852+D1GQ@users.noreply.github.com>
Date: Tue, 17 Mar 2026 14:10:39 -0500
Subject: [PATCH] Add back xml to SharedSecretExchange
---
src/Data/SharedSecretExchange.cs | 56 +++++++++++++++++++++++++++++++-
1 file changed, 55 insertions(+), 1 deletion(-)
diff --git a/src/Data/SharedSecretExchange.cs b/src/Data/SharedSecretExchange.cs
index 87115dd..c208b2d 100644
--- a/src/Data/SharedSecretExchange.cs
+++ b/src/Data/SharedSecretExchange.cs
@@ -3,6 +3,9 @@ using System.Security.Cryptography;
namespace BetterAmongUs.Data;
+///
+/// Handles secure key exchange using Elliptic Curve Diffie-Hellman (ECDH) for establishing shared secrets.
+///
internal sealed class SharedSecretExchange
{
private readonly ECDiffieHellman dh;
@@ -11,11 +14,21 @@ internal sealed class SharedSecretExchange
private byte[] sharedSecret = [];
private bool cryptoDisabled;
+ ///
+ /// Gets a value indicating whether cryptographic operations are available.
+ ///
internal bool CryptoAvailable => !cryptoDisabled;
+
+ ///
+ /// Gets or sets a value indicating whether to use the fallback key exchange mechanism.
+ ///
internal bool UseFallback { get; set; }
private int? remoteTempKey;
+ ///
+ /// Initializes a new instance of the SharedSecretExchange class with a new ECDH key pair.
+ ///
internal SharedSecretExchange()
{
try
@@ -35,6 +48,10 @@ internal sealed class SharedSecretExchange
tempKey = GenerateSecureTempKey();
}
+ ///
+ /// Generates a cryptographically secure random temporary key.
+ ///
+ /// A random positive integer used as a temporary key.
private static int GenerateSecureTempKey()
{
byte[] buffer = new byte[4];
@@ -42,27 +59,48 @@ internal sealed class SharedSecretExchange
return Math.Abs(BitConverter.ToInt32(buffer, 0));
}
+ ///
+ /// Sets the temporary key received from the remote party.
+ ///
+ /// The temporary key from the remote party.
internal void SetRemoteTempKey(int key)
{
remoteTempKey = key;
}
+ ///
+ /// Gets the public key for key exchange.
+ ///
+ /// The public key in SubjectPublicKeyInfo format, or an empty array if cryptography is disabled.
internal byte[] GetPublicKey()
{
if (cryptoDisabled) return [];
return publicKey;
}
+ ///
+ /// Gets the temporary key used for initial communication.
+ ///
+ /// A random integer used as a temporary key.
internal int GetTempKey()
{
return tempKey;
}
+ ///
+ /// Gets the established shared secret.
+ ///
+ /// The shared secret byte array.
internal byte[] GetSharedSecret()
{
return sharedSecret;
}
+ ///
+ /// Generates a shared secret using another party's public key.
+ ///
+ /// The other party's public key in SubjectPublicKeyInfo format.
+ /// The shared secret byte array, or an empty array if generation fails.
internal byte[] GenerateSharedSecret(byte[] otherPartyPublicKey)
{
if (sharedSecret.Length > 0) return sharedSecret;
@@ -96,6 +134,10 @@ internal sealed class SharedSecretExchange
}
}
+ ///
+ /// Gets a numeric hash of the shared secret for verification purposes.
+ ///
+ /// A 32-bit integer hash of the shared secret, or 0 if no shared secret exists.
internal int GetSharedSecretHash()
{
if (sharedSecret.Length == 0) return 0;
@@ -111,6 +153,12 @@ internal sealed class SharedSecretExchange
return Math.Abs(numericHash);
}
+ ///
+ /// Derives a fallback shared secret using temporary keys when ECDH is unavailable.
+ ///
+ /// The local temporary key.
+ /// The remote temporary key.
+ /// A 256-bit hash derived from the ordered temporary keys.
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);
}
+ ///
+ /// Gets a value indicating whether the key exchange data has been cleared for security.
+ ///
internal bool HasBeenCleared { get; private set; }
+ ///
+ /// Clears all sensitive key exchange data for security purposes.
+ ///
internal void ClearData()
{
if (HasBeenCleared) return;
@@ -136,4 +190,4 @@ internal sealed class SharedSecretExchange
tempKey = 0;
sharedSecret = [];
}
-}
\ No newline at end of file
+}