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