// ============================================================================= // Tesla.SecureConfig — First-boot secure provisioning (assembly: TeslaSecureConfiguration) // ============================================================================= // Reconstructed verbatim (ilspycmd) from the original proprietary // TeslaSecureConfiguration.dll. Provides the Console-side pod provisioning // protocol: UDP RQST/RPLY beacons, PBKDF2-from-passphrase key derivation, the // OFB crypto-stream handshake (NegotiateCryptoStreams), and RSA session-key // exchange. Previously consumed by the Console (and the Tesla.Contract client) // as a vendored binary; now built from source as the single definition. // // The wire/crypto behaviour is load-bearing: it must stay byte-compatible with // the pod-side counterpart (the Launcher's hand-written OFBDuplexStream / // CryptoHelper in Launcher/SecureConfig.cs). Byte-identity against the original // binary is asserted by SecureConfigCompatTests in the differential suite. // // NOTE: this is a faithful decompilation — local names and some control flow // differ from the lost original source (e.g. the dead GetInterface(byte[]) // comparison loop is preserved as-is for behavioural fidelity). // ============================================================================= using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; using System.Reflection; using System.Security.Cryptography; using System.Text; using System.Threading; using System.Timers; using Microsoft.Win32; namespace Tesla { public class PodConfigurationClient : IDisposable { private static readonly Random sRandom = new Random(); private static readonly char[] sPassphraseAlphabet = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ".ToCharArray(); private Process mPasscodeDisplay; private string mPassphrase; private string mRequestId; private static TextWriter mLogger; public string Passphrase => mPassphrase; public string RequestId => mRequestId; public static TextWriter Logger { get { return mLogger; } set { mLogger = value; } } public PodConfigurationClient(uint passpharaseLength, uint requestIdLength) { mPassphrase = GenerateRandomString(passpharaseLength); mRequestId = GenerateRandomString(requestIdLength); mPasscodeDisplay = new Process(); mPasscodeDisplay.StartInfo = new ProcessStartInfo("TeslaPasscodeDisplay.exe", $"{mRequestId} {mPassphrase}"); mPasscodeDisplay.StartInfo.CreateNoWindow = false; mPasscodeDisplay.StartInfo.UseShellExecute = true; mPasscodeDisplay.StartInfo.WorkingDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); mPasscodeDisplay.Start(); } private string GenerateRandomString(uint length) { char[] array = new char[length]; for (int i = 0; i < array.Length; i++) { array[i] = sPassphraseAlphabet[sRandom.Next(sPassphraseAlphabet.Length)]; } return new string(array); } public byte[] WaitForEncryptionKey(ushort localPort, ushort remotePort, IPAddress identifyingAddress) { mLogger.WriteLine("Waiting for configuration. Request ID: {0}\tPassphrase: {1}", mRequestId, mPassphrase); mLogger.WriteLine("Configuring temporary ip address."); mLogger.Flush(); string adapterName; byte[] @interface = GetInterface(identifyingAddress, out adapterName); try { ConfigureTempIp(adapterName); } catch (Exception innerException) { throw new Exception("Could not initalize temporary IP address.", innerException); } mLogger.WriteLine("Temp IP configured."); mLogger.Flush(); byte[] array = PodConfigurationServer.GenerateKeyFromPassphrase(mPassphrase); mLogger.WriteLine("Setting up broadcast."); mLogger.Flush(); byte[] bytes = Encoding.ASCII.GetBytes(mRequestId); byte[] array2 = new byte[@interface.Length + bytes.Length]; @interface.CopyTo(array2, 0); bytes.CopyTo(array2, @interface.Length); UdpBeacon udpBeacon = new UdpBeacon(PodConfigurationServer.sMessageRequestID, array2, 10000.0, remotePort, null); udpBeacon.Start(); mLogger.WriteLine("Broadcasting... waiting for packets."); mLogger.Flush(); BasicConfigResponse basicConfigResponse = ReceiveUdpResponse(localPort, array); mLogger.WriteLine("Packets received."); mLogger.Flush(); udpBeacon.Stop(); mLogger.WriteLine("Attempting to configure final IP."); mLogger.Flush(); try { SetNetworkProperties(adapterName, basicConfigResponse.Address, basicConfigResponse.Mask, basicConfigResponse.Gateway, basicConfigResponse.Dns, basicConfigResponse.HostName); } catch (Exception innerException2) { throw new Exception("Could not initalize final IP address.", innerException2); } mLogger.WriteLine("Waiting for console to connect."); mLogger.Flush(); TcpListener tcpListener = new TcpListener(IPAddress.Any, localPort); tcpListener.Start(); while (true) { TcpClient tcpClient = null; try { mLogger.WriteLine("Console connection received. Negotiating..."); mLogger.Flush(); tcpClient = tcpListener.AcceptTcpClient(); if (!PodConfigurationServer.NegotiateCryptoStreams(tcpClient.GetStream(), array, out var outStream, out var inStream)) { continue; } BinaryWriter binaryWriter = new BinaryWriter(outStream); BinaryReader binaryReader = new BinaryReader(inStream); mLogger.WriteLine("Secure connection to console negotiated."); mLogger.Flush(); RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider(); int dwKeySize = rSACryptoServiceProvider.KeySize; KeySizes[] legalKeySizes = rSACryptoServiceProvider.LegalKeySizes; foreach (KeySizes keySizes in legalKeySizes) { if (keySizes.MaxSize > rSACryptoServiceProvider.KeySize) { if (keySizes.MaxSize > 2048) { dwKeySize = 2048; break; } rSACryptoServiceProvider.KeySize = keySizes.MaxSize; } } mLogger.WriteLine("Sending console final key."); mLogger.Flush(); rSACryptoServiceProvider = new RSACryptoServiceProvider(dwKeySize); binaryWriter.Write(rSACryptoServiceProvider.ToXmlString(includePrivateParameters: false)); mLogger.WriteLine("Receiving console key."); mLogger.Flush(); byte[] rgb = binaryReader.ReadBytes(binaryReader.ReadInt32()); byte[] result = rSACryptoServiceProvider.Decrypt(rgb, fOAEP: false); mLogger.WriteLine("Console key received."); mLogger.Flush(); return result; } finally { try { tcpClient.Close(); } catch { } try { tcpListener.Stop(); } catch { } } } } private static byte[] GetInterface(IPAddress identifyingAddress, out string adapterName) { NetworkInterface[] allNetworkInterfaces = NetworkInterface.GetAllNetworkInterfaces(); foreach (NetworkInterface networkInterface in allNetworkInterfaces) { foreach (UnicastIPAddressInformation unicastAddress in networkInterface.GetIPProperties().UnicastAddresses) { if (unicastAddress.Address == identifyingAddress) { adapterName = networkInterface.Name; return networkInterface.GetPhysicalAddress().GetAddressBytes(); } } } NetworkInterface[] allNetworkInterfaces2 = NetworkInterface.GetAllNetworkInterfaces(); foreach (NetworkInterface networkInterface2 in allNetworkInterfaces2) { if (networkInterface2.OperationalStatus == OperationalStatus.Up && networkInterface2.NetworkInterfaceType != NetworkInterfaceType.Loopback) { adapterName = networkInterface2.Name; return networkInterface2.GetPhysicalAddress().GetAddressBytes(); } } throw new Exception("Could not find a valid network adapter."); } private static string GetInterface(byte[] identifyingMacAddress) { NetworkInterface[] allNetworkInterfaces = NetworkInterface.GetAllNetworkInterfaces(); int num = 0; if (num < allNetworkInterfaces.Length) { NetworkInterface networkInterface = allNetworkInterfaces[num]; byte[] addressBytes = networkInterface.GetPhysicalAddress().GetAddressBytes(); if (addressBytes.Length == identifyingMacAddress.Length) { for (int i = 0; i < addressBytes.Length; i++) { _ = addressBytes[i]; _ = identifyingMacAddress[i]; } } return networkInterface.Name; } NetworkInterface[] allNetworkInterfaces2 = NetworkInterface.GetAllNetworkInterfaces(); foreach (NetworkInterface networkInterface2 in allNetworkInterfaces2) { if (networkInterface2.OperationalStatus == OperationalStatus.Up && networkInterface2.NetworkInterfaceType != NetworkInterfaceType.Loopback) { return networkInterface2.Name; } } throw new Exception("Could not find a valid network adapter."); } public static void SetNetworkProperties(byte[] macAddress, IPAddress address, IPAddress mask, IPAddress gateway, IPAddress dns, string hostName) { SetNetworkProperties(GetInterface(macAddress), address, mask, gateway, dns, hostName); } public static void SetNetworkProperties(string adapterName, IPAddress address, IPAddress mask, IPAddress gateway, IPAddress dns, string hostName) { if (adapterName == null) { throw new ArgumentNullException("adapterName"); } if (adapterName.Length == 0) { throw new ArgumentOutOfRangeException("adapterName", "Adapter name can not be empty."); } if (address.AddressFamily != AddressFamily.InterNetwork) { throw new ArgumentOutOfRangeException("address", "Address must be an IPv4 address."); } if (mask.AddressFamily != AddressFamily.InterNetwork) { throw new ArgumentOutOfRangeException("mask", "Mask must be an IPv4 address."); } if (gateway.AddressFamily != AddressFamily.InterNetwork) { throw new ArgumentOutOfRangeException("gateway", "Default gateway must be an IPv4 address."); } if (dns.AddressFamily != AddressFamily.InterNetwork) { throw new ArgumentOutOfRangeException("dns", "DNS server address must be an IPv4 address."); } mLogger.WriteLine(string.Format("Setting data for adapter \"{0}\": IP {1}, Mask {2}, Gateway {3}, DNS {4}, Host {5}.", adapterName, address.ToString(), mask.ToString(), gateway.Equals(IPAddress.Any) ? "none" : gateway.ToString(), dns.Equals(IPAddress.Any) ? "none" : dns.ToString(), string.IsNullOrEmpty(hostName) ? "no change" : hostName)); mLogger.Flush(); using (Process process = new Process()) { process.StartInfo.FileName = "netsh"; process.StartInfo.Arguments = string.Format("interface ip set address \"{0}\" static {1} {2} {3}", adapterName, address, mask, gateway.Equals(IPAddress.Any) ? "none" : (gateway.ToString() + " 1")); process.Start(); process.WaitForExit(); if (process.ExitCode != 0) { throw new Exception("Could not initalize IP address."); } } mLogger.WriteLine("IP Set"); mLogger.Flush(); using (Process process2 = new Process()) { process2.StartInfo.FileName = "netsh"; process2.StartInfo.Arguments = string.Format("interface ip set dns \"{0}\" static {1}", adapterName, dns.Equals(IPAddress.Any) ? "none" : dns.ToString()); process2.Start(); process2.WaitForExit(); if (process2.ExitCode != 0) { throw new Exception("Could not set DNS server."); } } mLogger.WriteLine("DNS set."); mLogger.Flush(); if (string.IsNullOrEmpty(hostName)) { return; } using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ComputerName", writable: true)) { try { registryKey.SetValue("ComputerName", hostName, RegistryValueKind.String); } catch (Exception innerException) { throw new Exception("Could not set host name.", innerException); } finally { registryKey.Close(); } } using (RegistryKey registryKey2 = Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters", writable: true)) { try { registryKey2.SetValue("NV Hostname", hostName, RegistryValueKind.String); } catch (Exception innerException2) { throw new Exception("Could not set host name.", innerException2); } finally { registryKey2.Close(); } } mLogger.WriteLine("Host set."); mLogger.Flush(); } private static void ConfigureTempIp(string adapterName) { byte[] array = new byte[4]; sRandom.NextBytes(array); array[0] = 172; array[1] = (byte)((array[1] & 0xFu) | 0x10u); IPAddress address = new IPAddress(array); IPAddress mask = IPAddress.Parse("255.240.0.0"); SetNetworkProperties(adapterName, address, mask, IPAddress.Any, IPAddress.Any, null); } private static BasicConfigResponse ReceiveUdpResponse(ushort localPort, byte[] weakAesKey) { UdpBeaconListener udpBeaconListener = new UdpBeaconListener(PodConfigurationServer.sMessageReplyID, localPort, weakAesKey); BasicConfigResponse basicConfigResponse; do { basicConfigResponse = new BasicConfigResponse(udpBeaconListener.Receive()); } while (basicConfigResponse == null); return basicConfigResponse; } public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (disposing && mPasscodeDisplay != null && mPasscodeDisplay.Responding) { mPasscodeDisplay.Kill(); } } } public delegate void ConfigurationRequestReceivedDelegate(byte[] macAddress, string reqeustId); public class PodConfigurationServer { internal static readonly byte[] sMessageRequestID = Encoding.UTF8.GetBytes("RQST"); internal static readonly byte[] sMessageReplyID = Encoding.UTF8.GetBytes("RPLY"); private static readonly byte[] sMessageConfID = Encoding.UTF8.GetBytes("CONF"); private static readonly byte[] mPassphraseSalt = new byte[32] { 23, 171, 81, 217, 236, 209, 212, 116, 169, 9, 74, 52, 39, 251, 31, 242, 222, 196, 249, 241, 166, 216, 158, 218, 21, 17, 71, 101, 50, 231, 231, 239 }; private readonly ushort mLocalPort; private readonly ushort mRemotePort; private readonly ConfigurationRequestReceivedDelegate mRequestDelegate; private UdpBeaconListener mBeaconListener; private List mActiveConfigPods = new List(); internal static byte[] GenerateKeyFromPassphrase(string passphrase) { return new Rfc2898DeriveBytes(passphrase, mPassphraseSalt, 1000).GetBytes(32); } public static bool NegotiateCryptoStreams(NetworkStream clientStream, byte[] key, out Stream outStream, out Stream inStream) { outStream = null; inStream = null; Rijndael rijndael = Rijndael.Create(); rijndael.Mode = CipherMode.ECB; rijndael.Key = key; rijndael.GenerateIV(); clientStream.Write(rijndael.IV, 0, rijndael.IV.Length); inStream = new OFBCryptoStream(clientStream, rijndael.CreateEncryptor(), CryptoStreamMode.Read, rijndael.IV); byte[] array = new byte[rijndael.IV.Length]; for (int i = 0; i < array.Length; i += clientStream.Read(array, i, array.Length - i)) { } rijndael.IV = array; outStream = new OFBCryptoStream(clientStream, rijndael.CreateEncryptor(), CryptoStreamMode.Write, array); outStream.Write(sMessageConfID, 0, sMessageConfID.Length); byte[] array2 = new byte[sMessageConfID.Length]; for (int j = 0; j < array2.Length; j += inStream.Read(array2, j, array2.Length - j)) { } for (int k = 0; k < array2.Length; k++) { if (array2[k] != sMessageConfID[k]) { return false; } } return true; } public PodConfigurationServer(ushort localPort, ushort remotePort, ConfigurationRequestReceivedDelegate requestDelegate) { if (requestDelegate == null) { throw new ArgumentNullException("requestDelegate"); } mLocalPort = localPort; mRemotePort = remotePort; mRequestDelegate = requestDelegate; mBeaconListener = new UdpBeaconListener(sMessageRequestID, mLocalPort, null); mBeaconListener.BeginReceive(BeaconReceived, null); } private void BeaconReceived(IAsyncResult ar) { byte[] array; try { array = mBeaconListener.EndReceive(ar); } catch { mBeaconListener = new UdpBeaconListener(sMessageRequestID, mLocalPort, null); mBeaconListener.BeginReceive(BeaconReceived, null); return; } mBeaconListener.BeginReceive(BeaconReceived, null); byte[] array2 = new byte[6]; byte[] array3 = new byte[array.Length - array2.Length]; Buffer.BlockCopy(array, 0, array2, 0, array2.Length); Buffer.BlockCopy(array, array2.Length, array3, 0, array3.Length); byte[] array4 = new byte[8]; Array.Copy(array2, array4, array2.Length); long item = BitConverter.ToInt64(array4, 0); lock (mActiveConfigPods) { if (mActiveConfigPods.Contains(item)) { return; } mActiveConfigPods.Add(item); } try { mRequestDelegate(array2, Encoding.ASCII.GetString(array3)); } finally { lock (mActiveConfigPods) { mActiveConfigPods.Remove(item); } } } public byte[] SendEncryptionKey(string passphrase, IPAddress ipAddress, IPAddress mask, IPAddress gateway, IPAddress dns, string hostName, TimeSpan timeout) { DateTime dateTime = DateTime.Now + timeout; byte[] array = GenerateKeyFromPassphrase(passphrase); UdpBeacon udpBeacon = new UdpBeacon(sMessageReplyID, new BasicConfigResponse(ipAddress, mask, gateway, dns, hostName).ToBytes(), 10000.0, mRemotePort, array); udpBeacon.Start(); try { do { TcpClient tcpClient = null; try { tcpClient = new TcpClient(AddressFamily.InterNetwork); tcpClient.Connect(new IPEndPoint(ipAddress, mRemotePort)); if (NegotiateCryptoStreams(tcpClient.GetStream(), array, out var outStream, out var inStream)) { BinaryWriter binaryWriter = new BinaryWriter(outStream); BinaryReader binaryReader = new BinaryReader(inStream); RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider(); rSACryptoServiceProvider.FromXmlString(binaryReader.ReadString()); Rijndael rijndael = Rijndael.Create(); rijndael.KeySize = 256; rijndael.GenerateKey(); byte[] key = rijndael.Key; byte[] array2 = rSACryptoServiceProvider.Encrypt(key, fOAEP: false); binaryWriter.Write(array2.Length); binaryWriter.Write(array2); return key; } } catch (SocketException) { } finally { try { tcpClient.Close(); } catch { } } } while (DateTime.Now < dateTime); throw new TimeoutException(); } finally { udpBeacon.Stop(); } } } public class UdpBeaconListener { private class InternalAsyncResult : IAsyncResult { public AsyncCallback UserCallback; public IAsyncResult UdpAsyncResult; public Exception ThrownException; public byte[] ReceivedMessage; private object mState; public EventWaitHandle WaitHandle = new EventWaitHandle(initialState: false, EventResetMode.ManualReset); private bool mIsCompleted; public object AsyncState => mState; public WaitHandle AsyncWaitHandle => WaitHandle; public bool CompletedSynchronously => false; public bool IsCompleted { get { return mIsCompleted; } set { mIsCompleted = value; } } public InternalAsyncResult(AsyncCallback userCallback, object userState) { UserCallback = userCallback; mState = userState; } } private readonly byte[] mHeader; private readonly Rijndael mAes; private readonly SHA1 mSha1; private UdpClient mClient; public UdpBeaconListener(byte[] header, ushort port, byte[] encryptionKey) { mHeader = (byte[])header.Clone(); mClient = new UdpClient(port); mClient.EnableBroadcast = true; if (encryptionKey != null) { mAes = UdpBeacon.CreateRijndael(encryptionKey); mSha1 = SHA1.Create(); } } public IAsyncResult BeginReceive(AsyncCallback requestCallback, object state) { InternalAsyncResult internalAsyncResult = new InternalAsyncResult(requestCallback, state); internalAsyncResult.UdpAsyncResult = mClient.BeginReceive(InternalEndReceive, internalAsyncResult); return internalAsyncResult; } public byte[] EndReceive(IAsyncResult ar) { InternalAsyncResult internalAsyncResult = (InternalAsyncResult)ar; internalAsyncResult.AsyncWaitHandle.WaitOne(); if (internalAsyncResult.ThrownException != null) { throw internalAsyncResult.ThrownException; } return internalAsyncResult.ReceivedMessage; } public byte[] Receive() { return EndReceive(BeginReceive(null, null)); } private void InternalEndReceive(IAsyncResult udpAr) { InternalAsyncResult internalAsyncResult = (InternalAsyncResult)udpAr.AsyncState; ReceiveAndTransform(internalAsyncResult); if (internalAsyncResult.ThrownException != null || internalAsyncResult.ReceivedMessage != null) { internalAsyncResult.IsCompleted = true; internalAsyncResult.WaitHandle.Set(); if (internalAsyncResult.UserCallback != null) { internalAsyncResult.UserCallback(internalAsyncResult); } } else { internalAsyncResult.UdpAsyncResult = mClient.BeginReceive(InternalEndReceive, internalAsyncResult); } } private void ReceiveAndTransform(InternalAsyncResult ar) { IPEndPoint remoteEP = new IPEndPoint(0L, 0); byte[] array; try { array = mClient.EndReceive(ar.UdpAsyncResult, ref remoteEP); } catch (Exception thrownException) { Exception ex = (ar.ThrownException = thrownException); return; } finally { ar.UdpAsyncResult = null; } try { if (array.Length < mHeader.Length) { return; } for (int i = 0; i < mHeader.Length; i++) { if (array[i] != mHeader[i]) { return; } } if (mAes == null) { ar.ReceivedMessage = new byte[array.Length - mHeader.Length]; Buffer.BlockCopy(array, mHeader.Length, ar.ReceivedMessage, 0, ar.ReceivedMessage.Length); return; } byte[] array2 = new byte[mAes.IV.Length]; if (array.Length < mHeader.Length + array2.Length) { return; } Buffer.BlockCopy(array, mHeader.Length, array2, 0, array2.Length); ICryptoTransform transform = mAes.CreateDecryptor(mAes.Key, array2); MemoryStream memoryStream = new MemoryStream(); CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write); cryptoStream.Write(array, mHeader.Length + array2.Length, array.Length - (mHeader.Length + array2.Length)); cryptoStream.FlushFinalBlock(); byte[] array3 = memoryStream.ToArray(); int num = array3.Length - mSha1.HashSize / 8; if (num <= 0) { return; } byte[] array4 = mSha1.ComputeHash(array3, 0, num); for (int j = 0; j < array4.Length; j++) { if (array3[j + num] != array4[j]) { return; } } ar.ReceivedMessage = new byte[num]; Buffer.BlockCopy(array3, 0, ar.ReceivedMessage, 0, num); } catch { } } } public class UdpBeacon { private readonly byte[] mHeader; private readonly byte[] mMessage; private readonly double mMilliseconds; private readonly IPEndPoint mBroadcast; private readonly object mSynchronizer; private readonly Rijndael mAes; private readonly SHA1 mSha1; private UdpClient mClient; private System.Timers.Timer mTimer; internal static Rijndael CreateRijndael(byte[] encryptionKey) { Rijndael rijndael = Rijndael.Create(); rijndael.Key = (byte[])encryptionKey.Clone(); return rijndael; } public UdpBeacon(byte[] header, byte[] message, double milliseconds, ushort port, byte[] encryptionKey) { mHeader = (byte[])header.Clone(); mMessage = (byte[])message.Clone(); if (encryptionKey != null) { mAes = CreateRijndael(encryptionKey); mSha1 = SHA1.Create(); } mMilliseconds = milliseconds; mBroadcast = new IPEndPoint(IPAddress.Broadcast, port); mSynchronizer = new object(); } public void Start() { lock (mSynchronizer) { Initalize(); BroadcastBeacon(allowReset: false); mTimer.Start(); } } public void Stop() { lock (mSynchronizer) { if (mTimer != null) { mTimer.Stop(); } mTimer = null; if (mClient != null) { mClient.Close(); } mClient = null; } } private void Initalize() { try { Stop(); } catch { } mClient = new UdpClient(); mClient.EnableBroadcast = true; mTimer = new System.Timers.Timer(mMilliseconds); mTimer.Elapsed += mTimer_Elapsed; mTimer.AutoReset = true; } private void mTimer_Elapsed(object sender, ElapsedEventArgs e) { lock (mSynchronizer) { BroadcastBeacon(allowReset: true); } } private void BroadcastBeacon(bool allowReset) { try { List list = new List(mHeader); if (mAes == null) { list.AddRange(mMessage); } else { mAes.GenerateIV(); list.AddRange(mAes.IV); byte[] array = mSha1.ComputeHash(mMessage); byte[] array2 = new byte[mMessage.Length + array.Length]; mMessage.CopyTo(array2, 0); array.CopyTo(array2, mMessage.Length); MemoryStream memoryStream = new MemoryStream(); CryptoStream cryptoStream = new CryptoStream(memoryStream, mAes.CreateEncryptor(), CryptoStreamMode.Write); cryptoStream.Write(array2, 0, array2.Length); cryptoStream.FlushFinalBlock(); list.AddRange(memoryStream.ToArray()); } byte[] array3 = list.ToArray(); mClient.Send(array3, array3.Length, mBroadcast); } catch { if (allowReset) { Stop(); Initalize(); Start(); } } } } } namespace System.Security.Cryptography { public class OFBCryptoStream : Stream { private Stream mStream; private ICryptoTransform mTransform; private CryptoStreamMode mStreamMode; private byte[] mOutputBuffer; private byte[] mOutputBufferAlternate; private int mOutputBufferPosition; public override bool CanRead => mStreamMode == CryptoStreamMode.Read; public override bool CanSeek => false; public override bool CanWrite => mStreamMode == CryptoStreamMode.Write; public override long Length { get { throw new NotSupportedException(); } } public override long Position { get { throw new NotSupportedException(); } set { throw new NotSupportedException(); } } public OFBCryptoStream(Stream stream, ICryptoTransform transform, CryptoStreamMode mode, byte[] IV) { if (transform.InputBlockSize != transform.OutputBlockSize) { throw new ArgumentException("transform"); } if (!transform.CanTransformMultipleBlocks) { throw new ArgumentException("transform"); } if (mode != 0 && mode != CryptoStreamMode.Write) { throw new ArgumentOutOfRangeException("mode"); } if ((mode == CryptoStreamMode.Read && !stream.CanRead) || (mode != CryptoStreamMode.Write && !stream.CanWrite)) { throw new ArgumentException("mode"); } mStream = stream; mTransform = transform; mStreamMode = mode; mOutputBuffer = IV; mOutputBufferAlternate = new byte[mTransform.OutputBlockSize]; NextBuffer(); } private void NextBuffer() { mTransform.TransformBlock(mOutputBuffer, 0, mOutputBuffer.Length, mOutputBufferAlternate, 0); byte[] array = mOutputBuffer; mOutputBuffer = mOutputBufferAlternate; mOutputBufferAlternate = array; mOutputBufferPosition = 0; } public override void Flush() { mStream.Flush(); } public override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); } public override void SetLength(long value) { throw new NotSupportedException(); } public override int Read(byte[] buffer, int offset, int count) { if (!CanRead) { throw new NotSupportedException(); } byte[] array = new byte[count]; int num = mStream.Read(array, 0, count); int num2 = 0; while (num2 < num) { if (mOutputBufferPosition >= mOutputBuffer.Length) { NextBuffer(); } while (mOutputBufferPosition < mOutputBuffer.Length && num2 < num) { buffer[offset++] = (byte)(mOutputBuffer[mOutputBufferPosition++] ^ array[num2++]); } } return num; } public override void Write(byte[] buffer, int offset, int count) { if (!CanWrite) { throw new NotSupportedException(); } byte[] array = new byte[count]; int num = 0; while (num < count) { if (mOutputBufferPosition >= mOutputBuffer.Length) { NextBuffer(); } while (mOutputBufferPosition < mOutputBuffer.Length && num < count) { array[num++] = (byte)(mOutputBuffer[mOutputBufferPosition++] ^ buffer[offset++]); } } mStream.Write(array, 0, count); } } } namespace Tesla { public class BasicConfigResponse { private IPAddress mAddress; private IPAddress mMask; private IPAddress mGateway; private IPAddress mDns; private string mHostName; public IPAddress Address => mAddress; public IPAddress Mask => mMask; public IPAddress Gateway => mGateway; public IPAddress Dns => mDns; public string HostName => mHostName; public BasicConfigResponse(IPAddress address, IPAddress mask, IPAddress gateway, IPAddress dns, string hostName) { if (address.AddressFamily != AddressFamily.InterNetwork) { throw new ArgumentOutOfRangeException("address", "Address must be an IPv4 address."); } if (mask.AddressFamily != AddressFamily.InterNetwork) { throw new ArgumentOutOfRangeException("mask", "Address mask must be an IPv4 address."); } if (gateway.AddressFamily != AddressFamily.InterNetwork) { throw new ArgumentOutOfRangeException("gateway", "Default gateway must be an IPv4 address."); } if (dns.AddressFamily != AddressFamily.InterNetwork) { throw new ArgumentOutOfRangeException("dns", "DNS server must be an IPv4 address."); } if (hostName == null) { throw new ArgumentNullException("hostName"); } mAddress = address; mMask = mask; mGateway = gateway; mDns = dns; mHostName = hostName; } public byte[] ToBytes() { List list = new List(8); list.AddRange(mAddress.GetAddressBytes()); list.AddRange(mMask.GetAddressBytes()); list.AddRange(mGateway.GetAddressBytes()); list.AddRange(mDns.GetAddressBytes()); list.AddRange(Encoding.UTF8.GetBytes(mHostName)); return list.ToArray(); } public BasicConfigResponse(byte[] data) { byte[] array = new byte[4]; Buffer.BlockCopy(data, 0, array, 0, array.Length); mAddress = new IPAddress(array); Buffer.BlockCopy(data, 4, array, 0, array.Length); mMask = new IPAddress(array); Buffer.BlockCopy(data, 8, array, 0, array.Length); mGateway = new IPAddress(array); Buffer.BlockCopy(data, 12, array, 0, array.Length); mDns = new IPAddress(array); mHostName = Encoding.UTF8.GetString(data, 16, data.Length - 16); } } }