Parses and creates SecurityDataMessages. In general this class is not thread-safe.
The format for said packets is: [security params][epoch][seqid][encrypted [data length][data][signature]]
Inheritance: DataPacket
Exemple #1
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, SecurityAssociation> sender_to_sa = null;
            SecurityAssociation 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;
                }
            }
        }
Exemple #2
0
        ///<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;
        }
Exemple #3
0
        /// <summary>Decrypts the data and then verifys it.</summary>
        /// <param name="EncryptedData">The data to decrypt and verify.</param>
        /// <returns>The verified and decrypted data.</returns>
        public void DecryptAndVerify(SecurityDataMessage sdm)
        {
            if (_closed)
            {
                throw new Exception("SecurityHandler: closed");
            }
            else if (sdm.Epoch != Epoch)
            {
                throw new Exception(String.Format("Wrong index {0}, it should be {1}.",
                                                  sdm.Epoch, Epoch));
            }

            int seqid = sdm.Seqid;

            // Verify the seqid
            // If greater than current, new seqid and allow packet
            // If less than current but within window, allow packet
            // Else throw exception
            if (UseWindow)
            {
                if (seqid == Int32.MaxValue)
                {
                    Close();
                    throw new Exception("Maximum amount of packets sent over SecurityHandler.");
                }
                else if (seqid + WINDOW_SIZE < _last_incoming_seqid)
                {
                    throw new Exception(String.Format("Invalid seqid: {0}, current seqid: {1}, window: {2}.",
                                                      seqid, _last_incoming_seqid, WINDOW_SIZE));
                }
            }

            sdm.Decrypt(_decryptor);
            if (!sdm.Verify(_incoming_auth))
            {
                throw new Exception("Invalid signature");
            }

            if (seqid > _last_incoming_seqid)
            {
                _last_incoming_seqid = seqid;
            }
        }
Exemple #4
0
        public void TDES()
        {
            SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
            SymmetricAlgorithm        sa   = new TripleDESCryptoServiceProvider();
            SecurityHandler           sh   = new SecurityHandler(sa, sa, sha1, sha1, 0);

            byte[] data = new byte[1024];
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();

            rng.GetBytes(data);
            SecurityDataMessage sdm = new SecurityDataMessage();

            sdm.SPI  = 5;
            sdm.Data = MemBlock.Reference(data);
            sh.SignAndEncrypt(sdm);
            SecurityDataMessage sdm_d = new SecurityDataMessage(sdm.Packet);

            sh.DecryptAndVerify(sdm_d);
            Assert.AreEqual(sdm.Data, sdm.Data, "SecurityHandler");
        }
Exemple #5
0
        ///<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 #6
0
        /// <summary>First signs the data and then encrypts it.</summary>
        /// <param name="UnecryptedData">The data to sign and encrypt.</param>
        /// <returns>The signed and encrypted data.</returns>
        public void SignAndEncrypt(SecurityDataMessage sdm)
        {
            if (_closed)
            {
                throw new Exception("SecurityHandler: closed");
            }
            // Get the sequence id and increment the counter
            int seqid = ++_last_outgoing_seqid;

            // We ask for an update at the half life and every 1000 packets thereafter
            if (seqid == HALF_LIFE || (seqid > HALF_LIFE && seqid % 1000 == 0))
            {
                if (Update != null)
                {
                    Update(Epoch, EventArgs.Empty);
                }
            }

            sdm.Seqid = seqid;
            sdm.Epoch = Epoch;
            sdm.Sign(_outgoing_auth);
            sdm.Encrypt(_encryptor);
        }
Exemple #7
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");
        }