/// <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; } }
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"); }