private static byte[] crypto(byte[] input, CryptoCommand cmd) { if (input == null || input.Length == 0) return input; IBuffer _iv = null; IBuffer _src = null; IBuffer _dest = null; IBuffer _fullData = null; SymmetricKeyAlgorithmProvider _algorithm = SymmetricKeyAlgorithmProvider.OpenAlgorithm(ALGORITHM_NAME); CryptographicKey _key = getKey(_algorithm); try { switch (cmd) { case CryptoCommand.ENCRYPT: if (ALGORITHM_NAME.Contains("CBC")) _iv = CryptographicBuffer.GenerateRandom(_algorithm.BlockLength); _src = CryptographicBuffer.CreateFromByteArray(input); _dest = Windows.Security.Cryptography.Core.CryptographicEngine.Encrypt(_key, _src, _iv); byte[] _encFull = new byte[_iv.Length + _dest.Length]; System.Array.Copy(WindowsRuntimeBufferExtensions.ToArray(_iv), 0, _encFull, 0, (int)_iv.Length); System.Array.Copy(WindowsRuntimeBufferExtensions.ToArray(_dest), 0, _encFull, (int)_iv.Length, (int)_dest.Length); _fullData = CryptographicBuffer.CreateFromByteArray(_encFull); break; case CryptoCommand.DECRYPT: byte[] _sepIv = new byte[_algorithm.BlockLength]; byte[] _sepEnc = new byte[input.Length - _sepIv.Length]; System.Array.Copy(input, 0, _sepIv, 0, _sepIv.Length); System.Array.Copy(input, _sepIv.Length, _sepEnc, 0, _sepEnc.Length); if (ALGORITHM_NAME.Contains("CBC")) _iv = CryptographicBuffer.CreateFromByteArray(_sepIv); _src = CryptographicBuffer.CreateFromByteArray(_sepEnc); _dest = Windows.Security.Cryptography.Core.CryptographicEngine.Decrypt(_key, _src, _iv); _fullData = _dest; break; } } catch (Exception e) { System.Diagnostics.Debug.WriteLine(e.Message); _fullData = CryptographicBuffer.CreateFromByteArray(input); } return WindowsRuntimeBufferExtensions.ToArray(_fullData); }
public void CryptoCommandTest() { var cmd = new CryptoCommand(Manager, Station.Address, new StartElectionCommand(Manager.Address)); Assert.That(cmd.Sender == Manager.Address); Assert.That(!Station.ElectionInProgress); cmd.Execute(Station); Assert.That(Station.ElectionInProgress); //Station sending to NewPeer NewPeer.RemovePeer(Manager.Address); cmd = new CryptoCommand(Station, NewPeer.Address, new StartElectionCommand(Station.Address)); Assert.That(!NewPeer.ElectionInProgress); Assert.Throws <TheOnlyException>(() => cmd.Execute(NewPeer)); Assert.That(!NewPeer.ElectionInProgress); }
private static byte[] crypto(byte[] input, CryptoCommand cmd) { if (input == null || input.Length == 0) { return(input); } IBuffer _iv = null; IBuffer _src = null; IBuffer _dest = null; IBuffer _fullData = null; SymmetricKeyAlgorithmProvider _algorithm = SymmetricKeyAlgorithmProvider.OpenAlgorithm(ALGORITHM_NAME); CryptographicKey _key = getKey(_algorithm); try { switch (cmd) { case CryptoCommand.ENCRYPT: if (ALGORITHM_NAME.Contains("CBC")) { _iv = CryptographicBuffer.GenerateRandom(_algorithm.BlockLength); } _src = CryptographicBuffer.CreateFromByteArray(input); _dest = Windows.Security.Cryptography.Core.CryptographicEngine.Encrypt(_key, _src, _iv); byte[] _encFull = new byte[_iv.Length + _dest.Length]; System.Array.Copy(WindowsRuntimeBufferExtensions.ToArray(_iv), 0, _encFull, 0, (int)_iv.Length); System.Array.Copy(WindowsRuntimeBufferExtensions.ToArray(_dest), 0, _encFull, (int)_iv.Length, (int)_dest.Length); _fullData = CryptographicBuffer.CreateFromByteArray(_encFull); break; case CryptoCommand.DECRYPT: byte[] _sepIv = new byte[_algorithm.BlockLength]; byte[] _sepEnc = new byte[input.Length - _sepIv.Length]; System.Array.Copy(input, 0, _sepIv, 0, _sepIv.Length); System.Array.Copy(input, _sepIv.Length, _sepEnc, 0, _sepEnc.Length); if (ALGORITHM_NAME.Contains("CBC")) { _iv = CryptographicBuffer.CreateFromByteArray(_sepIv); } _src = CryptographicBuffer.CreateFromByteArray(_sepEnc); _dest = Windows.Security.Cryptography.Core.CryptographicEngine.Decrypt(_key, _src, _iv); _fullData = _dest; break; } } catch (Exception e) { System.Diagnostics.Debug.WriteLine(e.Message); _fullData = CryptographicBuffer.CreateFromByteArray(input); } return(WindowsRuntimeBufferExtensions.ToArray(_fullData)); }
public void Send(ICommand command, IPEndPoint target) { if (Parent.Logger != null && !(command is IsAliveCommand)) { Parent.Logger.Log("Attempting to send " + command.GetType() + " to " + target, Level.Info); } var isBallotReceived = command is BallotReceivedCommand || command is BallotReceivedCPROnlyCommand; if (!(command is PublicKeyExchangeCommand || command is IsAliveCommand || command is CryptoCommand)) { command = new CryptoCommand(Parent, target, command); } try { using (var client = new TcpClient()) { var ar = client.BeginConnect(target.Address, target.Port, null, null); var wh = ar.AsyncWaitHandle; try { if (!ar.AsyncWaitHandle.WaitOne(TimeSpan.FromMilliseconds(1000), false)) { throw new SocketException(); } client.EndConnect(ar); } finally { wh.Close(); } var bytes = Bytes.From(command); const int packetSize = 2048; var packetAmount = (int)Math.Ceiling((double)bytes.Length / packetSize); using (var stream = client.GetStream()) { for (var i = 0; i < packetAmount; i++) { var offset = i * packetSize; var size = (i == packetAmount - 1 ? bytes.Length % packetSize : packetSize); stream.Write(bytes, offset, size); } } } } catch (SocketException) { if (command is IsAliveCommand || isBallotReceived) { throw; } if (Parent.Logger != null) { Parent.Logger.Log("SocketException thrown while sending, attempting to handle.", Level.Error); } if (Parent.IsManager && Parent.Peers.ContainsKey(target)) { Parent.AnnounceRemovePeer(target); } else if (target.Equals(Parent.Manager)) { Parent.StartNewManagerElection(); Send(command, target); } else if (Parent.Peers.ContainsKey(target)) { Parent.RemovePeer(target); } } catch (IOException) { if (Parent.Logger != null) { Parent.Logger.Log("Problem sending due to IOException, retrying send.", Level.Error); } Send(command, target); } }
public void MessageSendThread() { while (!_cancel.IsCancellationRequested || _outgoingQueue.Count > 0) { Tuple <IPEndPoint, ICommand, int> message; try { message = _outgoingQueue.Take(_cancel.Token); } catch (Exception e) { // we still send messages until we are done if (_outgoingQueue.Count > 0) { message = _outgoingQueue.Take(); } else { break; } } IPEndPoint target = message.Item1; ICommand command = message.Item2; int tries = message.Item3; int attempt = _maxTries - tries + 1; bool retry = false; Type commandType = command.GetType(); if (command is CryptoCommand) { CryptoCommand c = (CryptoCommand)command; commandType = c.GetEncapsulatedType(); } if (tries > 0) { if (Parent.Logger != null && !(command is IsAliveCommand)) { Parent.Logger.Log("Attempt #" + attempt + " to send " + commandType + " to " + target, Level.Info); } if (!(command is PublicKeyExchangeCommand || command is IsAliveCommand || command is CryptoCommand || command is DisconnectStationCommand)) { if (Parent.Peers.ContainsKey(target)) { command = new CryptoCommand(Parent, target, command); } else { if (Parent.Logger != null) { Parent.Logger.Log("Attempt to send a message to non-peer " + target, Level.Error); } return; } } TcpClient client = new TcpClient(); client.ReceiveTimeout = _tcpTimeout; WaitHandle wh = null; try { IAsyncResult ar = client.BeginConnect(target.Address, target.Port, null, null); wh = ar.AsyncWaitHandle; if (!ar.AsyncWaitHandle.WaitOne(TimeSpan.FromMilliseconds(2000), false)) { throw new SocketException(); } client.EndConnect(ar); } catch (SocketException e) { if (Parent.Logger != null) { Parent.Logger.Log("Problem sending due to SocketException " + e + ", retrying.", Level.Error); } else { Console.WriteLine("Problem sending due to SocketException " + e + ", retrying."); } retry = true; } finally { if (wh != null) { wh.Close(); } } if (!retry) { byte[] commandBytes = Bytes.From(command); byte[] length = BitConverter.GetBytes(commandBytes.Count()); using (NetworkStream stream = client.GetStream()) { try { stream.Write(length, 0, length.Count()); stream.Write(commandBytes, 0, commandBytes.Count()); if (Parent.Logger != null) { Parent.Logger.Log(commandType + " successfully sent to " + target + " on attempt #" + attempt, Level.Info); } else { Console.WriteLine(commandType + " successfully sent to " + target + " on attempt #" + attempt); } } catch (Exception e) { if (Parent.Logger != null) { Parent.Logger.Log(commandType + " failed to " + target + " on attempt #" + attempt + ": " + e, Level.Info); } else { Console.WriteLine(commandType + " failed to " + target + " on attempt #" + attempt + ": " + e); } if (!(command is DisconnectStationCommand)) { retry = true; } } } } } else { if (Parent.Logger != null) { Parent.Logger.Log("Maximum number of retries reached, recording absent host " + target, Level.Error); } else { Console.WriteLine("Maximum number of retries reached, recording absent host " + target); } if (Parent.IsManager && Parent.Peers.ContainsKey(target)) { Console.WriteLine("I am manager, alerting other peers of absent host."); Parent.AnnounceRemovePeer(target); Parent.RemovePeer(target, false); } else if (target.Equals(Parent.Manager)) { Console.WriteLine("Absent host was manager, attempting to elect new manager."); Parent.StartNewManagerElection(); } else { Parent.RemovePeer(target, false); } } if (retry) { Send(command, target, tries - 1); } } }