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 +}