///<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);
      }
    }
Exemple #3
0
    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");
    }
Exemple #4
0
 /// <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);
     }
   }
 }
Exemple #5
0
    ///<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;
    }
Exemple #6
0
    ///<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;
    }
Exemple #7
0
 /// <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;
     }
   }
 }