///<summary>All incoming data filters through here.</summary> public void HandleData(MemBlock data, ISender return_path, object state) { if(!_active) { if(_closed == 0) { UpdateSH(null, null); } return; } SecurityDataMessage sdm = new SecurityDataMessage(data); if(sdm.SPI != _spi) { throw new Exception("Invalid SPI!"); } try { // try to decrypt the data lock(_sync) { _current_sh.DecryptAndVerify(sdm); } } catch { // Maybe this is just a late arriving packet, if it is, we'll just ignore it if(sdm.Epoch == _last_epoch) { return; // bad packet, let's throw it away! } else { throw; } } // Hand it to our subscriber if(_sub != null) { _sub.Handle(sdm.Data, this); } _incoming = true; _running = true; }
///<summary>All outgoing data filters through here.</summary> public void Send(ICopyable data) { if(!_active) { if(_closed == 1) { throw new SendException(false, "SA closed, unable to send!"); } UpdateSH(null, null); return; } // prepare the packet SecurityDataMessage sdm = new SecurityDataMessage(); sdm.SPI = _spi; sdm.Data = data as MemBlock; if(sdm.Data == null) { byte[] b = new byte[data.Length]; data.CopyTo(b, 0); sdm.Data = MemBlock.Reference(b); } // Encrypt it! lock(_sync) { _current_sh.SignAndEncrypt(sdm); } // Prepare for sending and send over the underlying ISender! data = new CopyList(SecurityOverlord.Security, SecurityOverlord.SecureData, sdm.ICPacket); try { _sender.Send(data); _running = true; } catch (Exception e) { Close("Failed on sending"); throw new SendException(false, "Failed on sending closing...", e); } }
public void Incoming() { SymmetricAlgorithm sa = new RijndaelManaged(); SymmetricEncryption se = new SymmetricEncryption(sa); HashAlgorithm hash = new SHA1CryptoServiceProvider(); int spi = 12345; int epoch = 67890; int seqid = 1222; Random rand = new Random(); byte[] data = new byte[144]; rand.NextBytes(data); MemBlock mdata = MemBlock.Reference(data); byte[] to_sign = new byte[12 + data.Length]; int pos = 0; NumberSerializer.WriteInt(spi, to_sign, pos); pos += 4; NumberSerializer.WriteInt(epoch, to_sign, pos); pos += 4; NumberSerializer.WriteInt(seqid, to_sign, pos); pos += 4; data.CopyTo(to_sign, pos); byte[] signature = hash.ComputeHash(to_sign); byte[] to_encrypt = new byte[4 + data.Length + signature.Length]; pos = 0; NumberSerializer.WriteInt(data.Length, to_encrypt, pos); pos += 4; data.CopyTo(to_encrypt, pos); pos += data.Length; signature.CopyTo(to_encrypt, pos); byte[] encrypted = se.EncryptData(to_encrypt); byte[] packet = new byte[12 + encrypted.Length]; pos = 0; NumberSerializer.WriteInt(spi, packet, pos); pos += 4; NumberSerializer.WriteInt(epoch, packet, pos); pos += 4; NumberSerializer.WriteInt(seqid, packet, pos); pos += 4; encrypted.CopyTo(packet, pos); MemBlock mpacket = MemBlock.Reference(packet); // check SecurityDataMessage sdm_e = new SecurityDataMessage(packet); sdm_e.Decrypt(se); Assert.AreEqual(spi, sdm_e.SPI, "SPI"); Assert.AreEqual(epoch, sdm_e.Epoch, "Epoch"); Assert.AreEqual(seqid, sdm_e.Seqid, "Seqid"); Assert.AreEqual(mdata, sdm_e.Data, "Data"); Assert.IsTrue(sdm_e.Verify(hash), "Signature"); Assert.AreEqual(mpacket, sdm_e.Packet, "Packet"); SecurityDataMessage sdm_d = new SecurityDataMessage(); sdm_d.SPI = spi; sdm_d.Epoch = epoch; sdm_d.Seqid = seqid; sdm_d.Data = data; sdm_d.Sign(hash); sdm_d.Encrypt(se); sdm_e = new SecurityDataMessage(sdm_d.Packet); sdm_e.Decrypt(se); Assert.AreEqual(spi, sdm_e.SPI, "SPI"); Assert.AreEqual(epoch, sdm_e.Epoch, "Epoch"); Assert.AreEqual(seqid, sdm_e.Seqid, "Seqid"); Assert.AreEqual(mdata, sdm_e.Data, "Data"); Assert.IsTrue(sdm_e.Verify(hash), "Signature"); Assert.AreEqual(sdm_d.Packet, sdm_e.Packet, "Packet"); }
/// <summary>This is SecureData that needs to get to an SA.</summary> protected void HandleData(MemBlock b, ISender return_path) { SecurityDataMessage sdm = new SecurityDataMessage(b); Dictionary<ISender, PeerSecAssociation> sender_to_sa = null; PeerSecAssociation sa = null; try { sender_to_sa = _spi[sdm.SPI]; sa = sender_to_sa[return_path]; sa.HandleData(b, return_path, null); } catch(Exception e) { if(sender_to_sa == null && !SecurityPolicy.Supports(sdm.SPI)) { ProtocolLog.WriteIf(ProtocolLog.SecurityExceptions, String.Format( "Unsupported SPI, from {0}, message: {1}", return_path, sdm)); } else { if(sa == null) { ProtocolLog.WriteIf(ProtocolLog.SecurityExceptions, String.Format( "No SA, from {0}, message: {1}", return_path, sdm)); } else if(sa.Closed) { ProtocolLog.WriteIf(ProtocolLog.SecurityExceptions, String.Format( "SA, {0}, has been closed, from {1}, message: {2}.", sa, return_path, sdm)); } else { ProtocolLog.WriteIf(ProtocolLog.SecurityExceptions, String.Format( "SA, {0}, from {1}, message: {2}, causes unhandled exception : {3}", sa, return_path, sdm, e)); } NoSuchSA(sdm.SPI, return_path); } } }
///<summary>All outgoing data filters through here.</summary> override protected bool HandleOutgoing(ICopyable app_data, out ICopyable data) { if(!_active) { if(_closed == 1) { throw new SendException(false, "SA closed, unable to send!"); } UpdateSH(null, null); data = null; return false; } // prepare the packet SecurityDataMessage sdm = new SecurityDataMessage(); sdm.SPI = _spi; sdm.Data = app_data as MemBlock; if(sdm.Data == null) { byte[] b = new byte[app_data.Length]; app_data.CopyTo(b, 0); sdm.Data = MemBlock.Reference(b); } // Encrypt it! lock(_sync) { _current_sh.SignAndEncrypt(sdm); } data = new CopyList(PeerSecOverlord.Security, PeerSecOverlord.SecureData, sdm.ICPacket); return true; }
///<summary>All incoming data filters through here.</summary> override protected bool HandleIncoming(MemBlock data, out MemBlock app_data) { if(!_active) { if(_closed == 0) { UpdateSH(null, null); } app_data = null; return false; } SecurityDataMessage sdm = new SecurityDataMessage(data); if(sdm.SPI != _spi) { throw new Exception("Invalid SPI!"); } try { // try to decrypt the data lock(_sync) { _current_sh.DecryptAndVerify(sdm); } } catch { // Maybe this is just a late arriving packet, if it is, we'll just ignore it if(sdm.Epoch == _last_epoch) { app_data = null; return false; // bad packet, let's throw it away! } else { throw; } } app_data = sdm.Data; return true; }
/// <summary>This is SecureData that needs to get to an SA.</summary> protected void HandleData(MemBlock b, ISender return_path) { SecurityDataMessage sdm = new SecurityDataMessage(b); Dictionary<ISender, PeerSecAssociation> sender_to_sa = null; PeerSecAssociation sa = null; try { sender_to_sa = _spi[sdm.SPI]; sa = sender_to_sa[return_path]; sa.HandleData(b, return_path, null); } catch { if(sender_to_sa == null && !SecurityPolicy.Supports(sdm.SPI)) { throw new Exception("Invalid SPI: " + sdm.SPI); } else if(sa == null) { NoSuchSA(sdm.SPI, return_path); throw new Exception("No SA for: " + return_path); } else if(sa.Closed) { throw new Exception("SA has been closed."); } else { throw; } } }