Exemple #1
0
        /**
         * Abandon any attempts to get requests for the given ID.
         * @throw Exception if handler is not the original handler for this Request
         */
        public void StopRequest(int request_id, IReplyHandler handler)
        {
            RequestState rs = null;

            lock ( _sync ) {
                if (!_req_state_table.TryTake(request_id, out rs))
                {
                    rs = null;
                }
            }
            if (rs != null)
            {
                /*
                 * Send an ack for this reply:
                 */
                byte[] ack_payload = new byte[5];
                ack_payload[0] = (byte)ReqrepType.ReplyAck;
                NumberSerializer.WriteInt(request_id, ack_payload, 1);
                ICopyable data = new CopyList(_prefix, MemBlock.Reference(ack_payload));
                foreach (ISender ret_path in rs.Repliers)
                {
                    try {
                        //Try to send an ack, but if we can't, oh well...
                        ret_path.Send(data);
                    }
                    catch { }
                }
            }
        }
        protected void SendControlPacket(EndPoint end, int remoteid, int localid,
                                         ControlCode c, object state)
        {
            using (MemoryStream ms = new MemoryStream()) {
                NumberSerializer.WriteInt((int)c, ms);
                if (c == ControlCode.EdgeDataAnnounce)
                {
                    UdpEdge e = (UdpEdge)_id_ht[localid];
                    if ((e != null) && (e.RemoteID == remoteid))
                    {
                        Hashtable t = new Hashtable();
                        t["RemoteTA"] = e.RemoteTA.ToString();
                        t["LocalTA"]  = e.LocalTA.ToString();
                        AdrConverter.Serialize(t, ms);
                    }
                    else
                    {
                        if (ProtocolLog.UdpEdge.Enabled)
                        {
                            ProtocolLog.Write(ProtocolLog.UdpEdge, String.Format(
                                                  "Problem sending EdgeData: EndPoint: {0}, remoteid: {1}, " +
                                                  "localid: {2}, Edge: {3}", end, remoteid, localid, e));
                        }
                    }
                }

                _send_queue.Enqueue(new UdpMessage(localid, ~remoteid, MemBlock.Reference(ms.ToArray()), end));
                if (ProtocolLog.UdpEdge.Enabled)
                {
                    ProtocolLog.Write(ProtocolLog.UdpEdge, String.Format(
                                          "Sending control {1} to: {0}", end, c));
                }
            }
        }
Exemple #3
0
        /// <summary>Constructor for a TunnelEdge, RemoteID == -1 for out bound.</summary>
        public TunnelEdge(IEdgeSendHandler send_handler, TunnelTransportAddress local_ta,
                          TunnelTransportAddress remote_ta, IForwarderSelector ias, List <Connection> overlap,
                          int remote_id) : base(send_handler, remote_id != -1)
        {
            _remote_id = remote_id;
            lock (_rand) {
                LocalID = _rand.Next();
            }
            byte[] bid = new byte[8];
            NumberSerializer.WriteInt(LocalID, bid, 0);
            NumberSerializer.WriteInt(_remote_id, bid, 4);
            _mid       = MemBlock.Reference(bid);
            _local_ta  = local_ta;
            _remote_ta = remote_ta;
            _tunnels   = new List <Connection>(overlap);
            _ias       = ias;
            _ias.Update(_tunnels);

            AHHeader ahh = new AHHeader(1, 20, local_ta.Target, remote_ta.Target,
                                        AHHeader.Options.Exact);
            ICopyable header = new CopyList(PType.Protocol.AH, ahh,
                                            PType.Protocol.Tunneling);

            Header = MemBlock.Copy(header);
        }
Exemple #4
0
        /*
         * Start sending packets
         */
        public void Run()
        {
            byte[] buf     = new byte[UInt16.MaxValue];
            Random ran_obj = new Random();

            for (int counter = 0; counter < count; counter++)
            {
                try {
                    int size = ran_obj.Next(4, Int16.MaxValue);
                    ran_obj.NextBytes(buf);
                    NumberSerializer.WriteInt(counter, buf, 0);
                    MemBlock cp = MemBlock.Copy(buf, 0, Math.Max(4, counter));
                    lock (_sync) { _sent_blocks[cp] = counter; }
                    _e.Send(cp);
                    Thread.Sleep(10);
                    Console.WriteLine("Sending Packet #: " + counter);
                }
                catch (Exception x) {
                    Console.WriteLine("send: {0} caused exception: {1}", counter, x);
                    break;
                }
            }
            //Let all the responses get back
            Thread.Sleep(5000);
            Check();
            _e.Close();
        }
        protected void SendThread()
        {
            byte[] buffer   = new byte[8 + Int16.MaxValue];
            bool   timedout = false;

            while (_running == 1)
            {
                UdpMessage to_send = _send_queue.Dequeue(-1, out timedout);
                if (to_send == null)
                {
                    break;
                }
                NumberSerializer.WriteInt(to_send.LocalID, buffer, 0);
                NumberSerializer.WriteInt(to_send.RemoteID, buffer, 4);

                try {
                    int length = to_send.Data.CopyTo(buffer, 8);
                    _s.SendTo(buffer, 8 + length, SocketFlags.None, to_send.Dst);
                } catch (SocketException x) {
                    if ((1 == _running) && ProtocolLog.UdpEdge.Enabled)
                    {
                        ProtocolLog.Write(ProtocolLog.UdpEdge, x.ToString());
                    }
                }
            }
        }
Exemple #6
0
        /// <summary>Continues a broadcast to the overlay.</summary>
        public BroadcastSender(StructuredNode node, AHAddress source,
                               AHAddress from, AHAddress to, int forwarders, int hops)
        {
            Node             = node;
            Source           = source;
            From             = from;
            To               = to;
            _distance_sorter = new AbsoluteDistanceComparer(node.Address as AHAddress);
            _address_sorter  = new LeftDistanceComparer(node.Address as AHAddress);
            Forwarders       = forwarders;
            Hops             = hops;

            byte[] hops_data = new byte[4];
            NumberSerializer.WriteInt(hops, hops_data, 0);
            _hops = MemBlock.Reference(hops_data);

            if (forwarders == DEFAULT_FORWARDERS)
            {
                _forwarders = DEFAULT_FORWARDERS_MB;
            }
            else
            {
                byte[] def = new byte[4];
                NumberSerializer.WriteInt(forwarders, def, 0);
                _forwarders = MemBlock.Reference(def);
            }
        }
 /// <summary>Change in either local or remote IDs, time to update the
 /// header to match.</summary>
 protected void UpdateHeader()
 {
     byte[] header = new byte[8];
     NumberSerializer.WriteInt(_local_id, header, SOURCE_OFFSET);
     NumberSerializer.WriteInt(_remote_id, header, DESTINATION_OFFSET);
     _header = MemBlock.Reference(header);
 }
Exemple #8
0
 public DirectionalAddress(DirectionalAddress.Direction bearing) : base()
 {
     byte[] buffer = new byte[MemSize];
     NumberSerializer.WriteInt((int)bearing, buffer, 0);
     SetClass(buffer, this.Class);
     _dir    = bearing;
     _buffer = MemBlock.Reference(buffer, 0, MemSize);
 }
Exemple #9
0
        protected ICopyable MakeRequest(ReqrepType rt, int next_rep, ICopyable data)
        {
            byte[] header = new byte[5];
            header[0] = (byte)rt;
            NumberSerializer.WriteInt(next_rep, header, 1);
            MemBlock mb_header = MemBlock.Reference(header);

            return(new CopyList(_prefix, mb_header, data));
        }
Exemple #10
0
        protected byte[] CalculateCookie(int uid)
        {
            byte[] cookie_base = _cookie;
            byte[] cookie_full = new byte[cookie_base.Length + 4];
            cookie_base.CopyTo(cookie_full, 0);
            NumberSerializer.WriteInt(uid, cookie_full, cookie_base.Length);
            SHA1 sha = new SHA1CryptoServiceProvider();

            return(sha.ComputeHash(cookie_full));
        }
Exemple #11
0
            public void SendAck()
            {
                _have_sent_ack = 1;
                byte[] header = new byte[5];
                header[0] = (byte)ReqrepType.RequestAck;
                NumberSerializer.WriteInt(RequestID, header, 1);
                MemBlock mb_header = MemBlock.Reference(header);

                ReturnPath.Send(new CopyList(_prefix, mb_header));
            }
Exemple #12
0
        /// <summary>We take in an object, take its hash code, concatenate it
        /// to our cookie, then sha hash the resulting value, creating the remote
        /// cookie.</summary>
        public MemBlock CalculateCookie(object o)
        {
            int hash = o.GetHashCode();

            byte[] data = new byte[4 + _cookie.Length];
            _cookie.CopyTo(data, 0);
            NumberSerializer.WriteInt(hash, data, _cookie.Length);
            HashAlgorithm sha1 = new SHA1CryptoServiceProvider();

            byte[] cookie = sha1.ComputeHash(data);
            return(MemBlock.Reference(cookie));
        }
Exemple #13
0
        public void Send(ICopyable data)
        {
            //We always use the fragmenting header to signal
            //to the receiving end that we support (and want)
            //fragmentation.
            MemBlock rest = data as MemBlock;

            if (null == rest)
            {
                rest = MemBlock.Copy(data);
            }
            int len = rest.Length;

            if (len > MAX_SEND_SIZE)
            {
                throw new SendException(true,
                                        System.String.Format("Packet too large: {0}, MaxSize = {1}", len,
                                                             MAX_SEND_SIZE));
            }
            uint crc32 = rest.Read <uint>(Crc32.ComputeChecksum);
            //Avoid a RNG operation for now, might need to reconsider
            //If we use RNG, we have to touch state, that has thread-safety issues
            int id = _wrapped_sender.GetHashCode() ^ rest.GetHashCode();

            byte[] header = new byte[HEADER_SIZE - 2];
            int    off    = FragPType.CopyTo(header, 0);

            NumberSerializer.WriteInt((int)crc32, header, off);
            NumberSerializer.WriteInt(id, header, off + 4);
            MemBlock header_mb = MemBlock.Reference(header);

            ushort block     = 0;
            int    blocksize = ComputeBlockSize(len);

            while (rest.Length > 0)
            {
                int      this_size  = System.Math.Min(blocksize, rest.Length);
                MemBlock this_block = rest.Slice(0, this_size);
                rest = rest.Slice(this_size);
                //Check to see if this is the last block:
                if (rest.Length == 0)
                {
                    block = (ushort)(block ^ (0x8000)); //Set the highest bit, this is last
                }
                byte[] block_b = new byte[2];
                NumberSerializer.WriteShort((short)block, block_b, 0);
                MemBlock block_mb = MemBlock.Reference(block_b);

                _wrapped_sender.Send(new CopyList(header_mb, block_mb, this_block));
                block += 1;
            }
        }
        ///<summary>Encrypts the packet given a SymmetricEncryption.</summary>
        public void Encrypt(SymmetricEncryption se)
        {
            byte[] to_encrypt = new byte[4 + _data.Length + _signature.Length];
            int    pos        = 0;

            NumberSerializer.WriteInt(_data.Length, to_encrypt, pos);
            pos += 4;
            _data.CopyTo(to_encrypt, pos);
            pos += _data.Length;
            _signature.CopyTo(to_encrypt, pos);
            _encrypted_data  = se.EncryptData(to_encrypt);
            _update_icpacket = true;
        }
 protected override void UpdatePacket()
 {
     try {
         byte[] b   = new byte[4 + 4 + 4];
         int    pos = 0;
         NumberSerializer.WriteInt(_spi, b, pos);
         pos += 4;
         NumberSerializer.WriteInt(_epoch, b, pos);
         pos += 4;
         NumberSerializer.WriteInt(_seqid, b, pos);
         MemBlock header = MemBlock.Reference(b);
         _icpacket = new CopyList(header, _encrypted_data);
     } catch (Exception e) {
         throw new Exception("Missing data to build packet!");
     }
     base.UpdatePacket();
 }
Exemple #16
0
        /**
         * When UdpEdge objects call Send, it calls this packet
         * callback:
         * @todo The previous interface did not throw an exception to a user
         * since the send was called in another thread.  All code that calls this
         * could be updated to handle exceptions that the socket might throw.
         */
        public void HandleEdgeSend(Edge from, ICopyable p)
        {
            UdpEdge sender = (UdpEdge)from;

            lock (_send_sync) {
                //Write the IDs of the edge:
                //[local id 4 bytes][remote id 4 bytes][packet]
                NumberSerializer.WriteInt(sender.ID, _send_buffer, 0);
                NumberSerializer.WriteInt(sender.RemoteID, _send_buffer, 4);
                int plength = p.CopyTo(_send_buffer, 8);
                try {
                    _s.SendTo(_send_buffer, 8 + plength, SocketFlags.None, sender.End);
                }
                catch (Exception x) {
                    bool transient = (1 == _running);
                    throw new SendException(transient, String.Format("Problem sending on: {0}", sender), x);
                }
            }
        }
Exemple #17
0
 public void Send(ICopyable data)
 {
     if (0 == Interlocked.Exchange(ref have_sent, 1))
     {
         //Make the header:
         byte[] header = new byte[5];
         header[0] = (byte)ReqrepType.Reply;
         NumberSerializer.WriteInt(RequestID, header, 1);
         MemBlock mb_header = MemBlock.Reference(header);
         Reply = new CopyList(_prefix, mb_header, data);
         Resend();
     }
     else
     {
         /*
          * Something goofy is going on here.  Multiple
          * sends for one request.  we are ignoring it for
          * now
          */
     }
 }
        /// <summary>Create a new revocation message.</summary>
        public UserRevocationMessage(RSACryptoServiceProvider private_key, string username)
        {
            Username = username;
            int signature_length = private_key.KeySize / 8;

            byte[] data = null;

            using (MemoryStream ms = new MemoryStream()) {
                AdrConverter.Serialize(Username, ms);
                Random rand = new Random();
                NumberSerializer.WriteInt(rand.Next(), ms);
                NumberSerializer.WriteLong(DateTime.UtcNow.Ticks, ms);
                data        = new byte[ms.Length + signature_length];
                ms.Position = 0;
                ms.Read(data, 0, (int)ms.Length);
            }

            SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();

            Hash      = sha1.ComputeHash(data, 0, data.Length - signature_length);
            Signature = private_key.SignHash(Hash, CryptoConfig.MapNameToOID("SHA1"));
            Signature.CopyTo(data, data.Length - signature_length);
            _data = MemBlock.Reference(data);
        }
        public void Test()
        {
            CertificateHandler ch = new CertificateHandler();

            ch.AddCACertificate(_ca_cert.X509);
            ch.AddCertificateVerification(this);

            ArrayList revoked_users = new ArrayList();

            revoked_users.Add("joker");
            revoked_users.Add("bad_guy");
            revoked_users.Add("adversary");
            revoked_users.Add("noobs");

            // create revocation list
            byte[] to_sign = null;
            using (MemoryStream ms = new MemoryStream()) {
                NumberSerializer.WriteLong(DateTime.UtcNow.Ticks, ms);
                AdrConverter.Serialize(revoked_users, ms); to_sign = ms.ToArray();
            }

            // sign revocation list
            SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();

            byte[] hash      = sha1.ComputeHash(to_sign);
            byte[] signature = _private_key.SignHash(hash, CryptoConfig.MapNameToOID("SHA1"));
            byte[] data      = new byte[4 + to_sign.Length + signature.Length];
            NumberSerializer.WriteInt(to_sign.Length, data, 0);
            to_sign.CopyTo(data, 4);
            signature.CopyTo(data, 4 + to_sign.Length);

            UpdateRl(data);

            X509Certificate likable_guy  = CreateCert("likable_guy");
            X509Certificate joker        = CreateCert("joker");
            X509Certificate bad_guy      = CreateCert("bad_guy");
            X509Certificate good_guy     = CreateCert("good_guy");
            X509Certificate adversary    = CreateCert("adversary");
            X509Certificate noobs        = CreateCert("noobs");
            X509Certificate friendly_guy = CreateCert("friendly_guy");

            Assert.IsTrue(ch.Verify(likable_guy, null, _remote_id), "Likable guy");
            bool success = false;

            try {
                success = ch.Verify(adversary, null, _remote_id);
            } catch { }
            Assert.AreEqual(success, false, "adversary");

            try {
                success = ch.Verify(joker, null, _remote_id);
            } catch { }
            Assert.AreEqual(success, false, "joker");

            Assert.IsTrue(ch.Verify(friendly_guy, null, _remote_id), "friendly guy");

            try {
                success = ch.Verify(noobs, null, _remote_id);
            } catch { }
            Assert.AreEqual(success, false, "noobs");

            try {
                success = ch.Verify(bad_guy, null, _remote_id);
            } catch { }
            Assert.AreEqual(success, false, "bad_guy");

            Assert.IsTrue(ch.Verify(good_guy, null, _remote_id), "good guy");
        }
Exemple #20
0
 static BroadcastSender()
 {
     byte[] def = new byte[4];
     NumberSerializer.WriteInt(DEFAULT_FORWARDERS, def, 0);
     DEFAULT_FORWARDERS_MB = MemBlock.Reference(def);
 }
Exemple #21
0
        public void Incoming()
        {
            Random rand = new Random();

            byte[] local_cookie           = new byte[SecurityControlMessage.CookieLength];
            byte[] remote_cookie          = new byte[SecurityControlMessage.CookieLength];
            byte[] dhe                    = new byte[144];
            byte[] cas                    = new byte[120];
            byte[] cert                   = new byte[100];
            RSACryptoServiceProvider rsa  = new RSACryptoServiceProvider();
            HashAlgorithm            hash = new SHA1CryptoServiceProvider();

            rand.NextBytes(local_cookie);
            rand.NextBytes(remote_cookie);
            rand.NextBytes(dhe);
            rand.NextBytes(cas);
            rand.NextBytes(cert);

            MemBlock        mlocal_cookie  = MemBlock.Reference(local_cookie);
            MemBlock        mremote_cookie = MemBlock.Reference(remote_cookie);
            MemBlock        mdhe           = MemBlock.Reference(dhe);
            MemBlock        mcert          = MemBlock.Reference(cert);
            MemBlock        mcas           = MemBlock.Reference(cas);
            List <MemBlock> lcas           = new List <MemBlock>();

            for (int i = 0; i < cas.Length; i += SecurityControlMessage.CALength)
            {
                lcas.Add(MemBlock.Reference(mcas.Slice(i, SecurityControlMessage.CALength)));
            }

            int length = 4 + 4 + 4 + 2 * SecurityControlMessage.CookieLength +
                         4 + cas.Length + 4 + dhe.Length +
                         4 + cert.Length;

            byte[] b   = new byte[length];
            int    pos = 0;

            NumberSerializer.WriteInt(5, b, pos);
            pos += 4;
            NumberSerializer.WriteInt(12345, b, pos);
            pos += 4;
            NumberSerializer.WriteInt((int)SecurityControlMessage.MessageType.DHEWithCertificateAndCAs, b, pos);
            pos += 4;
            local_cookie.CopyTo(b, pos);
            pos += SecurityControlMessage.CookieLength;
            remote_cookie.CopyTo(b, pos);
            pos += SecurityControlMessage.CookieLength;

            NumberSerializer.WriteInt(dhe.Length, b, pos);
            pos += 4;
            dhe.CopyTo(b, pos);
            pos += dhe.Length;

            NumberSerializer.WriteInt(cert.Length, b, pos);
            pos += 4;
            cert.CopyTo(b, pos);
            pos += cert.Length;

            NumberSerializer.WriteInt(cas.Length, b, pos);
            pos += 4;
            mcas.CopyTo(b, pos);
            pos += cas.Length;

            byte[] signature = rsa.SignData(b, hash);
            byte[] nb        = new byte[b.Length + signature.Length];
            b.CopyTo(nb, 0);
            signature.CopyTo(nb, b.Length);
            MemBlock packet = MemBlock.Reference(nb);

            // check
            SecurityControlMessage scm = new SecurityControlMessage(packet);

            Assert.AreEqual(5, scm.Version, "Version");
            Assert.AreEqual(12345, scm.SPI, "SPI");
            Assert.AreEqual(SecurityControlMessage.MessageType.DHEWithCertificateAndCAs, scm.Type, "Type");
            Assert.AreEqual(mlocal_cookie, scm.LocalCookie, "LocalCookie");
            Assert.AreEqual(mremote_cookie, scm.RemoteCookie, "RemoteCookie");
            Assert.AreEqual(mdhe, scm.DHE, "DHE");
            Assert.AreEqual(mcert, scm.Certificate, "Certificate");
            int contains = 0;

            foreach (MemBlock ca in scm.CAs)
            {
                if (scm.CAs.Contains(ca))
                {
                    contains++;
                }
            }
            Assert.AreEqual(contains, lcas.Count, "Contains CAs");
            Assert.IsTrue(scm.Verify(rsa, hash), "Signature");
            Assert.AreEqual(packet, scm.Packet, "Packet");

            // change a few things around and check again!
            scm.Version = 0;
            SecurityControlMessage scm1 = new SecurityControlMessage(scm.Packet);

            scm1.Sign(rsa, hash);
            Assert.AreEqual(scm1.Version, scm.Version, "Version 1");
            Assert.AreEqual(scm1.SPI, scm.SPI, "SPI 1");
            Assert.AreEqual(scm1.Type, scm.Type, "Type 1");
            Assert.AreEqual(scm1.LocalCookie, scm.LocalCookie, "LocalCookie 1");
            Assert.AreEqual(scm1.RemoteCookie, scm.RemoteCookie, "RemoteCookie 1");
            Assert.AreEqual(mdhe, scm.DHE, "DHE 1");
            Assert.AreEqual(mcert, scm.Certificate, "Certificate 1");
            contains = 0;
            foreach (MemBlock ca in scm.CAs)
            {
                if (scm.CAs.Contains(ca))
                {
                    contains++;
                }
            }
            Assert.AreEqual(contains, lcas.Count, "Contains CAs 1");
            Assert.IsTrue(scm1.Signature != scm.Signature, "Signature 1");
            Assert.AreEqual(scm1.Packet.Slice(4, scm1.Signature.Length),
                            scm.Packet.Slice(4, scm.Signature.Length), "Packet 1");
        }
Exemple #22
0
        ///<summary>Writes the packet.</summary>
        protected void UpdatePacket()
        {
            try {
                int  data_length       = 0;
                bool write_cas         = false;
                bool write_dhe         = false;
                bool write_cert        = false;
                bool write_hash        = false;
                bool require_signature = true;

                switch (_type)
                {
                case MessageType.NoSuchSA:
                    require_signature = false;
                    break;

                case MessageType.Cookie:
                    require_signature = false;
                    break;

                case MessageType.CookieResponse:
                    require_signature = false;
                    data_length       = 4 + _cas.Count * CALength;
                    write_cas         = true;
                    break;

                case MessageType.DHEWithCertificate:
                    data_length = 4 + _dhe.Length + 4 + _certificate.Length;
                    write_cert  = true;
                    write_dhe   = true;
                    break;

                case MessageType.DHEWithCertificateAndCAs:
                    data_length = 4 + _dhe.Length + 4 + _certificate.Length + 4 + _cas.Count * CALength;
                    write_cas   = true;
                    write_dhe   = true;
                    write_cert  = true;
                    break;

                case MessageType.Confirm:
                    data_length = 4 + _hash.Length;
                    write_hash  = true;
                    break;
                }

                int length = 4 + 4 + 4 + 2 * CookieLength + data_length;
                if (require_signature)
                {
                    length += _signature.Length;
                }
                byte[] b   = new byte[length];
                int    pos = 0;
                NumberSerializer.WriteInt(_version, b, pos);
                pos += 4;
                NumberSerializer.WriteInt(_spi, b, pos);
                pos += 4;
                NumberSerializer.WriteInt((int)_type, b, pos);
                pos += 4;
                if (_local_cookie == null)
                {
                    EmptyCookie.CopyTo(b, pos);
                }
                else
                {
                    _local_cookie.CopyTo(b, pos);
                }
                pos += CookieLength;
                if (_remote_cookie == null)
                {
                    EmptyCookie.CopyTo(b, pos);
                }
                else
                {
                    _remote_cookie.CopyTo(b, pos);
                }
                pos += CookieLength;

                if (write_dhe)
                {
                    NumberSerializer.WriteInt(_dhe.Length, b, pos);
                    pos += 4;
                    _dhe.CopyTo(b, pos);
                    pos += _dhe.Length;
                }

                if (write_cert)
                {
                    NumberSerializer.WriteInt(_certificate.Length, b, pos);
                    pos += 4;
                    _certificate.CopyTo(b, pos);
                    pos += _certificate.Length;
                }

                if (write_cas)
                {
                    NumberSerializer.WriteInt(_cas.Count * CALength, b, pos);
                    pos += 4;
                    foreach (MemBlock ca in _cas)
                    {
                        ca.CopyTo(b, pos);
                        pos += CALength;
                    }
                }

                if (write_hash)
                {
                    NumberSerializer.WriteInt(_hash.Length, b, pos);
                    pos += 4;
                    _hash.CopyTo(b, pos);
                    pos += _hash.Length;
                }

                if (require_signature)
                {
                    _signature.CopyTo(b, pos);
                }
                _packet = MemBlock.Reference(b);
            } catch (Exception e) {
                throw new Exception("Missing data for SecurityControlMessage!");
            }
            _update_packet = false;
        }
        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");
        }