This is the brains of the security system. Each SecurityAssociation represents a Secure connection via an ISender, such that two different ISenders would need their own SecurityAssociation.
Inheritance: Brunet.SimpleSource, IDataHandler, ISender
コード例 #1
0
        public void TestRemoteRestart()
        {
            Timer t   = new Timer(Timeout, null, 0, 500);
            int   spi = 123333;

            new SecurityPolicy(spi, "Rijndael", "SHA1", true);
            SecurityOverlord so0 = CreateValidSO("valid0");
            SecurityOverlord so1 = CreateValidSO("valid1");

            MockSender ms0 = new MockSender(null, null, so1, 0);
            MockSender ms1 = new MockSender(ms0, null, so0, 0);

            ms0.ReturnPath = ms1;

            SecurityAssociation sa0 = so0.CreateSecurityAssociation(ms0, spi, true);
            SecurityAssociation sa1 = so1.CreateSecurityAssociation(ms1, spi, true);

            Assert.AreEqual(sa0.State, SecurityAssociation.SAState.Active, "sa0 should be active!");
            Assert.AreEqual(sa1.State, SecurityAssociation.SAState.Active, "sa1 should be active!");
            Assert.AreEqual(so0.SACount, 1, "so0 should contain just one!");
            Assert.AreEqual(so1.SACount, 1, "so1 should contain just one!");

            sa0.GarbageCollect();
            sa0.GarbageCollect();
            Assert.AreEqual(so0.SACount, 0, "so0 should contain just zero!");
            sa1.GarbageCollect();
            Assert.AreEqual(so1.SACount, 1, "so1 should contain just one!");
            sa1.Send(MemBlock.Reference(new byte[] { 0, 1, 2, 3 }));
            Assert.AreEqual(so0.SACount, 1, "so0 should contain just one!");
            Assert.AreEqual(so1.SACount, 1, "so1 should contain just one!");

            t.Dispose();
        }
コード例 #2
0
        protected void Setup(ref SecurityAssociation sa1, ref SecurityAssociation sa2)
        {
            sa1.Reset();
            sa2.Reset();
            sa1.RDHE.Value = sa2.LDHE;
            sa2.RDHE.Value = sa1.LDHE;

            Random rand = new Random();

            byte[] b = new byte[128];
            rand.NextBytes(b);
            MemBlock mb = MemBlock.Reference(b);

            sa1.DHEWithCertificateAndCAsOutHash.Value = mb;
            sa1.VerifyResponse(mb);

            b = new byte[128];
            rand.NextBytes(b);
            mb = MemBlock.Reference(b);

            sa2.DHEWithCertificateHash.Value = mb;
            sa2.VerifyRequest(mb);

            sa1.Enable();
            sa2.Enable();
            // This is just for kicks
            sa1.Enable();
        }
コード例 #3
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;
                }
            }
        }
コード例 #4
0
        /// <summary>Whenever an SA changes amongst inactive, active, and closed
        /// this is called.</summary>
        /// <param name="o">The SA whose state changes.</summary>
        protected void SAStateChange(SecurityAssociation sa,
                                     SecurityAssociation.States state)
        {
            if (state == SecurityAssociation.States.Active)
            {
                if (_sub != null)
                {
                    sa.Subscribe(_sub.Handler, null);
                }
                else
                {
                    sa.Subscribe(this, null);
                }
            }
            else if (state == SecurityAssociation.States.Updating)
            {
                sa.Subscribe(this, null);
            }
            else if (sa.Closed)
            {
                RemoveSA(sa);
            }

            if (AnnounceSA != null)
            {
                AnnounceSA(sa, state);
            }
        }
コード例 #5
0
        /// <summary>3a) Receive a DHEWithCertificate, verify the certificate and DHE and
        /// send a Confirm that you are ready to Verify the stack and start the
        /// system.</summary>
        /// <param name="sa">A security association that we wish to perform the
        /// specified control operation on.</param>
        /// <param name="scm">The received SecurityControlMessage.</param>
        /// <param name="scm_reply">A prepared reply message (with headers and such.</param>
        /// <param name="return_path">Where to send the result.</param>
        /// <param name="low_level_sender">We expect the return_path to not be an edge or
        /// some other type of "low level" sender, so this contains the parsed out value.</param>
        protected void HandleControlDHEWithCertificates(SecurityAssociation sa,
                                                        SecurityControlMessage scm, SecurityControlMessage scm_reply,
                                                        ISender return_path, ISender low_level_sender)
        {
            ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Received DHEWithCertificate from: " + low_level_sender);
            if (sa == null)
            {
                throw new Exception("No valid SA!");
            }
            byte[] cert = new byte[scm.Certificate.Length];
            scm.Certificate.CopyTo(cert, 0);
            X509Certificate rcert = new X509Certificate(cert);
            HashAlgorithm   sha1  = new SHA1CryptoServiceProvider();

            scm.Verify((RSACryptoServiceProvider)rcert.RSA, sha1);
            _ch.Verify(rcert);

            sa.RemoteCertificate.Value = rcert;
            sa.RDHE.Value = scm.DHE;

            scm_reply.LocalCookie  = scm.RemoteCookie;
            scm_reply.RemoteCookie = scm.LocalCookie;
            scm_reply.Hash         = MemBlock.Reference(sha1.ComputeHash((byte[])scm.Packet));
            scm_reply.Type         = SecurityControlMessage.MessageType.Confirm;
            lock (_private_key_lock) {
                scm_reply.Sign(_private_key, sha1);
            }

            ICopyable to_send = new CopyList(Security, SecureControl, scm_reply.Packet);

            _rrman.SendRequest(return_path, ReqrepManager.ReqrepType.Request,
                               to_send, this, sa);
            ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Successful DHEWithCertificate from: " + low_level_sender);
        }
コード例 #6
0
        /// <summary>Whenever an SA changes amongst inactive, active, and closed
        /// this is called.</summary>
        /// <param name="o">The SA whose state changes.</summary>
        protected void SAStateChange(object o, EventArgs ea)
        {
            SecurityAssociation sa = o as SecurityAssociation;

            if (sa == null)
            {
                throw new Exception("Object should be a SecurityAssociation!");
            }
            else if (sa.Active)
            {
                if (_sub != null)
                {
                    sa.Subscribe(_sub.Handler, null);
                }
                else
                {
                    sa.Subscribe(this, null);
                }
            }
            else if (sa.Closed)
            {
                RemoveSA(sa);
            }
            if (AnnounceSA != null)
            {
                AnnounceSA(sa, null);
            }
        }
コード例 #7
0
        /// <summary>Higher level SOs may have a better way to verify these SAs
        /// then we do.  They can override this and do as they please.</summary>
        protected virtual bool Verify(SecurityAssociation sa)
        {
#if BRUNET_NUNIT
            return(true);
#else
            return(sa.Sender is Edge);
#endif
        }
コード例 #8
0
 /// <summary>Removes the specified SA from our database.</summary>
 protected virtual void RemoveSA(SecurityAssociation sa)
 {
     lock (_sync) {
         if (_spi.ContainsKey(sa.SPI))
         {
             _spi[sa.SPI].Remove(sa.Sender);
         }
     }
 }
コード例 #9
0
        /// <summary>When an SA wants to be updated, we instigate a new Security
        /// exchange.</summary>
        protected void SARequestUpdate(object o, EventArgs ea)
        {
            SecurityAssociation sa = o as SecurityAssociation;

            if (sa != null)
            {
                StartSA(sa);
            }
        }
コード例 #10
0
        public void SHUpdateTest()
        {
            callback_count = 0;
            int                 spi     = SecurityPolicy.DefaultSPI;
            MockSender          sender1 = new MockSender(null, null, null, 2);
            MockSender          sender2 = new MockSender(null, null, null, 2);
            SecurityAssociation sa1     = new SecurityAssociation(sender1, spi);

            sa1.StateChange += StateChange;
            sender2.Receiver = sa1;
            MockDataHandler mdh1 = new MockDataHandler();

            sa1.Subscribe(mdh1, null);
            SecurityAssociation sa2 = new SecurityAssociation(sender2, spi);

            sender1.Receiver = sa2;
            MockDataHandler mdh2 = new MockDataHandler();

            sa2.Subscribe(mdh2, null);

            Setup(ref sa1, ref sa2);

            sa1.RequestUpdate += Callback;
            sa2.RequestUpdate += Callback;

            byte[]   b    = null;
            Random   rand = new Random();
            MemBlock mb   = null;

            int current_epoch = sa1.CurrentEpoch;

            for (int i = 0; i < 80; i++)
            {
                b = new byte[128];
                rand.NextBytes(b);
                mb = MemBlock.Reference(b);
                sa1.Send(mb);
                Assert.IsTrue(mdh2.Contains(mb), "Contains" + i);
                if (i % 20 == 0 && i != 0)
                {
                    Assert.AreEqual(callback_count, 1, "Callback count " + i);
                    callback_count = 0;
                    Thread.Sleep(SecurityAssociation.TIMEOUT * 2 + 5);
                    Setup(ref sa1, ref sa2);
                }
                else
                {
                    if (i % 20 == 1 && i != 1)
                    {
                        Assert.IsFalse(current_epoch == sa1.CurrentEpoch, "Current epoch " + i);
                        current_epoch = sa1.CurrentEpoch;
                    }
                    Assert.AreEqual(current_epoch, sa1.CurrentEpoch, "Current epoch " + i);
                }
            }
        }
コード例 #11
0
        /// <summary></summary>
        protected void SACloseHandler(object o, EventArgs ea)
        {
            SecurityAssociation sa = o as SecurityAssociation;

            if (sa == null)
            {
                throw new Exception("Object should be a SecurityAssociation!");
            }
            RemoveSA(sa);
        }
コード例 #12
0
        /// <summary>This (idempotently) returns a new SecurityAssociation for the
        /// specified sender using the specified SPI and starts it if requested to.</summary>
        public SecurityAssociation CreateSecurityAssociation(ISender Sender, int SPI, bool start)
        {
            SecurityAssociation sa = CreateSecurityAssociation(Sender, SPI);

            if (start && sa.State != SecurityAssociation.SAState.Active)
            {
                StartSA(sa);
            }

            return(sa);
        }
コード例 #13
0
        /// <summary>If the request really failed, we'll have to close the SA.</summary>
        public void HandleError(ReqrepManager man, int message_number,
                                ReqrepManager.ReqrepError err, ISender returnpath, object state)
        {
            if (man.RequestActive(message_number))
            {
                return;
            }

            SecurityAssociation sa = state as SecurityAssociation;

            sa.Failure();
        }
コード例 #14
0
 /// <summary>1a) Send a Cookie</summary>
 /// <param name="sa">A security association that we wish to perform the
 /// specified control operation on.</param>
 protected void HandleControlNoSuchSA(SecurityAssociation sa)
 {
     if (sa == null)
     {
         ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " NoSuchSA received, but we have no SA either!");
     }
     else
     {
         ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " NoSuchSA received, handling...");
         StartSA(sa);
     }
 }
コード例 #15
0
        public void Test()
        {
            int                 spi     = SecurityPolicy.DefaultSPI;
            MockSender          sender1 = new MockSender(null, null, null, 2);
            MockSender          sender2 = new MockSender(null, null, null, 2);
            SecurityAssociation sa1     = new SecurityAssociation(sender1, spi);

            sa1.StateChange += StateChange;
            sender2.Receiver = sa1;
            MockDataHandler mdh1 = new MockDataHandler();

            sa1.Subscribe(mdh1, null);
            SecurityAssociation sa2 = new SecurityAssociation(sender2, spi);

            sender1.Receiver = sa2;
            MockDataHandler mdh2 = new MockDataHandler();

            sa2.Subscribe(mdh2, null);

            byte[]   b    = null;
            Random   rand = new Random();
            MemBlock mb   = null;

            int current_epoch = sa1.CurrentEpoch;

            for (int i = 0; i < 5; i++)
            {
                Thread.Sleep(SecurityAssociation.TIMEOUT * 2 + 5);
                Setup(ref sa1, ref sa2);

                b = new byte[128];
                rand.NextBytes(b);
                mb = MemBlock.Reference(b);
                sa1.Send(mb);
                Assert.IsTrue(mdh2.Contains(mb), "Contains" + i);
                Assert.AreEqual(state, sa1.State, "State == Active" + i);
                Assert.IsFalse(current_epoch == sa1.CurrentEpoch, "Current epoch " + i);
                current_epoch = sa1.CurrentEpoch;
            }

            sa1.GarbageCollect();
            sa1.GarbageCollect();
            b = new byte[128];
            rand.NextBytes(b);
            mb = MemBlock.Reference(b);
            try {
                sa1.Send(mb);
            } catch {}
            Assert.IsTrue(!mdh2.Contains(mb), "Failed!");
            Assert.AreEqual(state, sa1.State, "State == Failed");
        }
コード例 #16
0
        /// <summary>2a) Receive a CookieResponse that contains a list of CAs, if you have
        /// a Certificate that supports one of the CAs send it along with a DHE
        /// and a list of your supported CAs in a DHEWithCertificateAndCAs.</summary>
        /// <param name="sa">A security association that we wish to perform the
        /// specified control operation on.</param>
        /// <param name="scm">The received SecurityControlMessage.</param>
        /// <param name="scm_reply">A prepared reply message (with headers and such.</param>
        /// <param name="return_path">Where to send the result.</param>
        /// <param name="low_level_sender">We expect the return_path to not be an edge or
        /// some other type of "low level" sender, so this contains the parsed out value.</param>
        protected void HandleControlCookieResponse(SecurityAssociation sa,
                                                   SecurityControlMessage scm, SecurityControlMessage scm_reply,
                                                   ISender return_path, ISender low_level_sender)
        {
            ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Received CookieResponse from: " + low_level_sender);
            if (sa == null)
            {
                throw new Exception("No valid SA!");
            }
            // This seems like unnecessary code
            scm_reply.Type = SecurityControlMessage.MessageType.CookieResponse;
            X509Certificate lcert = null;

            if (SecurityPolicy.GetPolicy(scm.SPI).PreExchangedKeys)
            {
                lcert = _ch.DefaultCertificate;
            }
            else
            {
                lcert = _ch.FindCertificate(scm.CAs);
            }

            sa.RemoteCookie.Value     = scm.LocalCookie;
            sa.LocalCertificate.Value = lcert;
            scm_reply.Certificate     = lcert.RawData;

            scm_reply.DHE          = sa.LDHE;
            scm_reply.LocalCookie  = scm.RemoteCookie;
            scm_reply.RemoteCookie = scm.LocalCookie;
            scm_reply.Type         = SecurityControlMessage.MessageType.DHEWithCertificateAndCAs;
            if (SecurityPolicy.GetPolicy(scm.SPI).PreExchangedKeys)
            {
                scm_reply.CAs = new List <MemBlock>(0);
            }
            else
            {
                scm_reply.CAs = _ch.SupportedCAs;
            }
            HashAlgorithm sha1 = new SHA1CryptoServiceProvider();

            lock (_private_key_lock) {
                scm_reply.Sign(_private_key, sha1);
            }

            sa.DHEWithCertificateAndCAsOutHash.Value = sha1.ComputeHash((byte[])scm_reply.Packet);
            ICopyable to_send = new CopyList(Security, SecureControl, scm_reply.Packet);

            _rrman.SendRequest(return_path, ReqrepManager.ReqrepType.Request,
                               to_send, this, sa);
            ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Successful CookieResponse from: " + low_level_sender);
        }
コード例 #17
0
        /// <summary>This begins the SecurityAssociation exchange protocol over the
        /// specified SecurityAssociation.</summary>
        protected void StartSA(SecurityAssociation sa)
        {
            SecurityControlMessage scm_reply = new SecurityControlMessage();

            scm_reply.Version     = Version;
            scm_reply.SPI         = sa.SPI;
            scm_reply.Type        = SecurityControlMessage.MessageType.Cookie;
            scm_reply.LocalCookie = CalculateCookie(sa.Sender);

            ICopyable to_send = new CopyList(Security, SecureControl, scm_reply.Packet);

            _rrman.SendRequest(sa.Sender, ReqrepManager.ReqrepType.Request,
                               to_send, this, sa);
        }
コード例 #18
0
        /// <summary>2b) Receive a DHEWithCertificateAndCAs, verify the certificate and attempt
        /// to find a matching Certificate for the list of CAs, if you find one,
        /// finish the DHE handshake and send the certificate via a DHEWithCertificate</summary>
        /// <param name="sa">A security association that we wish to perform the
        /// specified control operation on.</param>
        /// <param name="scm">The received SecurityControlMessage.</param>
        /// <param name="scm_reply">A prepared reply message (with headers and such.</param>
        /// <param name="return_path">Where to send the result.</param>
        /// <param name="low_level_sender">We expect the return_path to not be an edge or
        /// some other type of "low level" sender, so this contains the parsed out value.</param>
        protected void HandleControlDHEWithCertificateAndCAs(SecurityAssociation sa,
                                                             SecurityControlMessage scm, SecurityControlMessage scm_reply,
                                                             ISender return_path, ISender low_level_sender)
        {
            ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Received DHEWithCertificateAndCAs from: " + low_level_sender);
            if (sa == null)
            {
                sa = CreateSecurityAssociation(low_level_sender, scm.SPI, false);
            }
            byte[] cert = new byte[scm.Certificate.Length];
            scm.Certificate.CopyTo(cert, 0);
            X509Certificate rcert = new X509Certificate(cert);

            _ch.Verify(rcert);
            HashAlgorithm sha1 = new SHA1CryptoServiceProvider();

            scm.Verify((RSACryptoServiceProvider)rcert.RSA, sha1);

            X509Certificate lcert = null;

            if (SecurityPolicy.GetPolicy(scm.SPI).PreExchangedKeys)
            {
                lcert = _ch.DefaultCertificate;
            }
            else
            {
                lcert = _ch.FindCertificate(scm.CAs);
            }

            sa.LocalCertificate.Value  = lcert;
            sa.RemoteCertificate.Value = rcert;
            sa.RDHE.Value = scm.DHE;
            sa.DHEWithCertificateAndCAsInHash.Value = MemBlock.Reference(sha1.ComputeHash((byte[])scm.Packet));

            scm_reply.LocalCookie  = scm.RemoteCookie;
            scm_reply.RemoteCookie = scm.LocalCookie;
            scm_reply.DHE          = sa.LDHE;
            scm_reply.Certificate  = MemBlock.Reference(lcert.RawData);
            scm_reply.Type         = SecurityControlMessage.MessageType.DHEWithCertificate;
            lock (_private_key_lock) {
                scm_reply.Sign(_private_key, sha1);
            }
            sa.DHEWithCertificateHash.Value = MemBlock.Reference(sha1.ComputeHash((byte[])scm_reply.Packet));

            ICopyable to_send = new CopyList(SecureControl, scm_reply.Packet);

            return_path.Send(to_send);
            ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Successful DHEWithCertificateAndCAs from: " + low_level_sender);
        }
コード例 #19
0
        /// <summary>3b) Receive a Confirm, verify the entire stack and send a Confirm
        /// 4a)Receive a Confirm, verify the entire stack and all set to go</summary>
        /// <param name="sa">A security association that we wish to perform the
        /// specified control operation on.</param>
        /// <param name="scm">The received SecurityControlMessage.</param>
        /// <param name="scm_reply">A prepared reply message (with headers and such.</param>
        /// <param name="return_path">Where to send the result.</param>
        /// <param name="low_level_sender">We expect the return_path to not be an edge or
        /// some other type of "low level" sender, so this contains the parsed out value.</param>
        protected void HandleControlConfirm(SecurityAssociation sa,
                                            SecurityControlMessage scm, SecurityControlMessage scm_reply,
                                            ISender return_path, ISender low_level_sender)
        {
            ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Received Confirm from: " + low_level_sender);
            if (sa == null)
            {
                throw new Exception("No valid SA!");
            }
            HashAlgorithm sha1 = new SHA1CryptoServiceProvider();

            scm.Verify((RSACryptoServiceProvider)sa.RemoteCertificate.Value.RSA, sha1);

            if (return_path == low_level_sender)
            {
                sa.VerifyResponse(scm.Hash);
            }
            else
            {
                sa.VerifyRequest(scm.Hash);
                scm_reply.LocalCookie  = scm.RemoteCookie;
                scm_reply.RemoteCookie = scm.LocalCookie;
                scm_reply.Hash         = sa.DHEWithCertificateAndCAsInHash.Value;
                scm_reply.Type         = SecurityControlMessage.MessageType.Confirm;
                lock (_private_key_lock) {
                    scm_reply.Sign(_private_key, sha1);
                }
                ICopyable to_send = new CopyList(SecureControl, scm_reply.Packet);
                return_path.Send(to_send);
            }
            if (Verify(sa))
            {
                sa.Enable();
            }
            else
            {
                sa.Close("Unable to verify the SA as being valid!");
            }

            ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Successful Confirm from: " + low_level_sender);
        }
コード例 #20
0
        /// <summary>1b) Receive a Cookie which responds with a CookieResponse</summary>
        /// <param name="sa">A security association that we wish to perform the
        /// specified control operation on.</param>
        /// <param name="calc_cookie">Cookie value for the association sender.</param>
        /// <param name="scm">The received SecurityControlMessage.</param>
        /// <param name="scm_reply">A prepared reply message (with headers and such.</param>
        /// <param name="return_path">Where to send the result.</param>
        /// <param name="low_level_sender">We expect the return_path to not be an edge or
        /// some other type of "low level" sender, so this contains the parsed out value.</param>
        protected void HandleControlCookie(SecurityAssociation sa,
                                           MemBlock calc_cookie, SecurityControlMessage scm,
                                           SecurityControlMessage scm_reply, ISender return_path,
                                           ISender low_level_sender)
        {
            ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Received Cookie from: " + low_level_sender);
            scm_reply.Type         = SecurityControlMessage.MessageType.CookieResponse;
            scm_reply.RemoteCookie = scm.LocalCookie;
            scm_reply.LocalCookie  = calc_cookie;
            if (SecurityPolicy.GetPolicy(scm.SPI).PreExchangedKeys)
            {
                scm_reply.CAs = new List <MemBlock>(0);
            }
            else
            {
                scm_reply.CAs = _ch.SupportedCAs;
            }
            ICopyable to_send = new CopyList(SecureControl, scm_reply.Packet);

            return_path.Send(to_send);
            ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Successful Cookie from: " + low_level_sender);
        }
コード例 #21
0
        /// <summary>This (idempotently) returns a new SecurityAssociation for the
        /// specified sender using the specified SA.</summary>
        virtual protected SecurityAssociation CreateSecurityAssociation(ISender Sender, int SPI)
        {
            if (!SecurityPolicy.Supports(SPI))
            {
                throw new Exception("Unsupported SPI");
            }

            SecurityAssociation sa = null;
            int count = 0;

            lock (_sync) {
                Dictionary <ISender, SecurityAssociation> sender_to_sa = null;
                if (_spi.ContainsKey(SPI))
                {
                    sender_to_sa = _spi[SPI];
                }
                else
                {
                    sender_to_sa = new Dictionary <ISender, SecurityAssociation>();
                    _spi[SPI]    = sender_to_sa;
                }

                if (sender_to_sa.ContainsKey(Sender))
                {
                    sa = sender_to_sa[Sender];
                }
                else
                {
                    sa = new SecurityAssociation(Sender, SPI);
                    sa.Subscribe(this, null);
                    sa.StateChange      += SAStateChange;
                    sa.RequestUpdate    += SARequestUpdate;
                    sender_to_sa[Sender] = sa;
                }
            }
            return(sa);
        }
コード例 #22
0
        public void TestWithPreExchangedKeys()
        {
            Timer t   = new Timer(Timeout, null, 0, 500);
            int   spi = 123333;

            new SecurityPolicy(spi, "Rijndael", "SHA1", true);
            SecurityOverlord so0 = CreateValidSO("valid0");
            SecurityOverlord so1 = CreateValidSO("valid1");

            MockSender ms0 = new MockSender(null, null, so1, 0);
            MockSender ms1 = new MockSender(ms0, null, so0, 0);

            ms0.ReturnPath = ms1;

            SecurityAssociation sa0 = so0.CreateSecurityAssociation(ms0, spi, true);
            SecurityAssociation sa1 = so1.CreateSecurityAssociation(ms1, spi, true);

            Assert.AreEqual(sa0.State, SecurityAssociation.SAState.Active, "sa0 should be active!");
            Assert.AreEqual(sa1.State, SecurityAssociation.SAState.Active, "sa1 should be active!");
            Assert.AreEqual(so0.SACount, 1, "so0 should contain just one!");
            Assert.AreEqual(so1.SACount, 1, "so1 should contain just one!");

            t.Dispose();
        }
コード例 #23
0
        public void StateChange(Object o, EventArgs ea)
        {
            SecurityAssociation sa = o as SecurityAssociation;

            state = sa.State;
        }
コード例 #24
0
 /// <summary></summary>
 abstract protected void RemoveSA(SecurityAssociation sa);
コード例 #25
0
 /// <summary>Overridden because we know the Brunet address.</summary>
 protected override bool Verify(SecurityAssociation sa)
 {
   lock(_sync) {
     if(_sa_to_address.ContainsKey(sa)) {
       return  sa.VerifyCertificateBySubjectAltName(_sa_to_address[sa].ToString());
     }
   }
   return base.Verify(sa);
 }
コード例 #26
0
 /// <summary>Removes the specified SA from our database.</summary>
 protected override void RemoveSA(SecurityAssociation sa)
 {
   lock(_sync) {
     AHSender sender = sa.Sender as AHSender;
     if(sender != null) {
       _address_to_sa.Remove(sender.Destination);
       _sa_to_address.Remove(sa);
     }
     base.RemoveSA(sa);
   }
 }
コード例 #27
0
        /// <summary>This is the control state machine.  There are three paths in
        /// the state machine, iniator, receiver, and bidirectional.  The
        /// bidirectional case occurs when two remote ISenders that are matched
        /// together initiate a handshake at the same time, otherwise the initiator
        /// /receiver pattern is followed.  The high level overview for the states
        /// are:
        /// 1a) Send a Cookie
        /// 1b) Receive a Cookie which responds with a CookieResponse
        /// 2a) Receive a CookieResponse that contains a list of CAs, if you have
        /// a Certificate that supports one of the CAs send it along with a DHE
        /// and a list of your supported CAs in a DHEWithCertificateAndCAs.
        /// 2b) Receive a DHEWithCertificateAndCAs, verify the certificate and attempt
        /// to find a matching Certificate for the list of CAs, if you find one,
        /// finish the DHE handshake and send the certificate via a DHEWithCertificate
        /// 3a) Receive a DHEWithCertificate, verify the certificate and DHE and
        /// send a Confirm that you are ready to Verify the stack and start the
        /// system.
        /// 3b) Receive a Confirm, verify the entire stack and send a Confirm
        /// 4a)Receive a Confirm, verify the entire stack and all set to go
        /// </summary>
        protected void HandleControl(MemBlock b, ISender return_path)
        {
            ISender low_level_sender = return_path;

            if (low_level_sender is ReqrepManager.ReplyState)
            {
                low_level_sender = ((ReqrepManager.ReplyState)low_level_sender).ReturnPath;
            }

            SecurityControlMessage scm = new SecurityControlMessage(b);
            MemBlock calc_cookie       = CalculateCookie(low_level_sender);

            if (scm.Version != Version)
            {
                throw new Exception("Invalid version: " + scm.Version);
            }
            else if (!SecurityPolicy.Supports(scm.SPI))
            {
                throw new Exception("No support for SPI: " + scm.SPI);
            }
            else if (!scm.RemoteCookie.Equals(calc_cookie))
            {
                if (scm.Type != SecurityControlMessage.MessageType.Cookie &&
                    scm.Type != SecurityControlMessage.MessageType.NoSuchSA)
                {
                    throw new Exception("Invalid cookie!");
                }
            }

            SecurityControlMessage scm_reply = new SecurityControlMessage();

            scm_reply.Version = Version;
            scm_reply.SPI     = scm.SPI;

            SecurityAssociation sa = null;

            // This can be in a try statement since this is best effort anyway
            try {
                Dictionary <ISender, SecurityAssociation> sender_to_sa = _spi[scm.SPI];
                sa = sender_to_sa[low_level_sender];
            } catch { }

            if (sa != null)
            {
                sa.Reset();
                if (sa.Closed)
                {
                    throw new Exception("SA closed!");
                }
                else if (sa.State == SecurityAssociation.SAState.Active)
                {
                    return;
                }
            }

            try {
                switch (scm.Type)
                {
                case SecurityControlMessage.MessageType.NoSuchSA:
                    HandleControlNoSuchSA(sa);
                    break;

                case SecurityControlMessage.MessageType.Cookie:
                    HandleControlCookie(sa, calc_cookie, scm, scm_reply, return_path, low_level_sender);
                    break;

                case SecurityControlMessage.MessageType.CookieResponse:
                    HandleControlCookieResponse(sa, scm, scm_reply, return_path, low_level_sender);
                    break;

                case SecurityControlMessage.MessageType.DHEWithCertificateAndCAs:
                    HandleControlDHEWithCertificateAndCAs(sa, scm, scm_reply, return_path, low_level_sender);
                    break;

                case SecurityControlMessage.MessageType.DHEWithCertificate:
                    HandleControlDHEWithCertificates(sa, scm, scm_reply, return_path, low_level_sender);
                    break;

                case SecurityControlMessage.MessageType.Confirm:
                    HandleControlConfirm(sa, scm, scm_reply, return_path, low_level_sender);
                    break;

                default:
                    throw new Exception("Invalid message!");
                }
            } catch {
                if (sa != null && sa.Closed)
                {
                    throw new Exception("SA closed.");
                }
                else
                {
                    throw;
                }
            }
        }
コード例 #28
0
        public void Test()
        {
            Timer            t   = new Timer(Timeout, null, 0, 500);
            SecurityOverlord so0 = CreateValidSO("valid0");
            SecurityOverlord so1 = CreateValidSO("valid1");

            //Test block one
            {
                MockSender ms0 = new MockSender(null, null, so1, 0);
                MockSender ms1 = new MockSender(ms0, null, so0, 0);
                ms0.ReturnPath = ms1;

                SecurityAssociation sa0 = so0.CreateSecurityAssociation(ms0, true);
                SecurityAssociation sa1 = so1.CreateSecurityAssociation(ms1, true);
                Assert.AreEqual(sa0.State, SecurityAssociation.SAState.Active, "sa0 should be active!");
                Assert.AreEqual(sa1.State, SecurityAssociation.SAState.Active, "sa1 should be active!");
                Assert.AreEqual(so0.SACount, 1, "so0 should contain just one!");
                Assert.AreEqual(so1.SACount, 1, "so1 should contain just one!");

                Random rand = new Random();
                byte[] b    = new byte[128];
                rand.NextBytes(b);
                MemBlock mb = MemBlock.Reference(b);
                sa1.Send(mb);

                new SecurityPolicy(12345, "DES", "MD5");
                sa0 = so0.CreateSecurityAssociation(ms0, 12345, true);
                Assert.AreEqual(sa0.State, SecurityAssociation.SAState.Active, "sa0 should be active!");
                Assert.AreEqual(so0.SACount, 2, "so0 should contain just one!");
                Assert.AreEqual(so1.SACount, 2, "so1 should contain just one!");

                b = new byte[128];
                rand.NextBytes(b);
                mb = MemBlock.Reference(b);
                sa0.Send(mb);
            }

            // create ~250 valid SAs for one guy...
            for (int i = 2; i < 250; i++)
            {
                SecurityOverlord so  = CreateValidSO("valid" + i);
                MockSender       msa = new MockSender(null, null, so, 0);
                MockSender       msb = new MockSender(msa, null, so0, 0);
                msa.ReturnPath = msb;

                SecurityAssociation sab = so.CreateSecurityAssociation(msb, true);
                Assert.AreEqual(sab.State, SecurityAssociation.SAState.Active, "sab should be active! " + i);
                SecurityAssociation saa = so0.CreateSecurityAssociation(msa, true);
                Assert.AreEqual(saa.State, SecurityAssociation.SAState.Active, "saa should be active! " + i);

                MockDataHandler mdha = new MockDataHandler();
                saa.Subscribe(mdha, null);
                MockDataHandler mdhb = new MockDataHandler();
                sab.Subscribe(mdhb, null);

                Random rand = new Random();
                byte[] b    = new byte[128];
                rand.NextBytes(b);
                MemBlock mb = MemBlock.Reference(b);
                sab.Send(mb);
                Assert.IsTrue(mdha.Contains(mb), "mdhb Contains " + i);

                b = new byte[128];
                rand.NextBytes(b);
                mb = MemBlock.Reference(b);
                sab.Send(mb);
                Assert.IsTrue(mdha.Contains(mb), "mdha Contains " + i);
            }

            for (int i = 250; i < 500; i++)
            {
                int ij = (250 % 3) + 1;
                SecurityOverlord so  = CreateInvalidSO("valid" + i, ij);
                MockSender       msa = new MockSender(null, null, so, 0);
                MockSender       msb = new MockSender(msa, null, so0, 0);
                msa.ReturnPath = msb;

                SecurityAssociation sab = so.CreateSecurityAssociation(msb, true);
                SecurityAssociation saa = so0.CreateSecurityAssociation(msa, true);
                Assert.AreEqual(sab.State, SecurityAssociation.SAState.Waiting, "sab should be waiting! " + i);
                Assert.AreEqual(saa.State, SecurityAssociation.SAState.Waiting, "saa should be waiting! " + i);
            }

            // create ~250 valid SAs for one guy...
            for (int i = 500; i < 750; i++)
            {
                SecurityOverlord so  = CreateValidSO("valid" + i);
                MockSender       msa = new MockSender(null, null, so, 0);
                MockSender       msb = new MockSender(msa, null, so0, 0);
                msa.ReturnPath = msb;

                SecurityAssociation sab = so.CreateSecurityAssociation(msb, true);
                Assert.AreEqual(sab.State, SecurityAssociation.SAState.Active, "sab should be active! " + i);
                SecurityAssociation saa = so0.CreateSecurityAssociation(msa, true);
                Assert.AreEqual(saa.State, SecurityAssociation.SAState.Active, "saa should be active! " + i);

                MockDataHandler mdha = new MockDataHandler();
                saa.Subscribe(mdha, null);
                MockDataHandler mdhb = new MockDataHandler();
                sab.Subscribe(mdhb, null);

                Random rand = new Random();
                byte[] b    = new byte[128];
                rand.NextBytes(b);
                MemBlock mb = MemBlock.Reference(b);
                sab.Send(mb);
                Assert.IsTrue(mdha.Contains(mb), "mdhb Contains " + i);

                b = new byte[128];
                rand.NextBytes(b);
                mb = MemBlock.Reference(b);
                sab.Send(mb);
                Assert.IsTrue(mdha.Contains(mb), "mdha Contains " + i);
            }

            Random randr = new Random();

            byte[] br = new byte[128];
            randr.NextBytes(br);
            MemBlock mbr = MemBlock.Reference(br);

            foreach (Dictionary <ISender, SecurityAssociation> sender_to_sa in so0.SPI.Values)
            {
                foreach (SecurityAssociation sa in sender_to_sa.Values)
                {
                    sa.Send(mbr);
                }
            }

            Thread.Sleep(SecurityAssociation.TIMEOUT * 5);
            so0.SAGarbageCollect();
            Assert.AreEqual(500, so0.SACount, "Count!");

            so0.SAGarbageCollect();
            Assert.AreEqual(0, so0.SACount, "Count!");

            t.Dispose();
        }