public void MakeAndReadFragments5_2()
        {
            var origmsgs = new List <TunnelMessage>();

            for (int i = 0; i < 5; ++i)
            {
                var adatarec = new DataMessage(new BufLen(BufUtils.RandomBytes(2048)));

                var amsg = new TunnelMessageRouter(
                    adatarec,
                    new I2PIdentHash(true));

                origmsgs.Add(amsg);
            }

            var msgs = TunnelDataMessage.MakeFragments(origmsgs, BufUtils.RandomUint());

            var mkmsg     = new TunnelDataFragmentReassembly();
            var recvtmsgs = msgs
                            .Chunk(a => 2)
                            .Shuffle()
                            .Select(m => mkmsg.Process(m, out var _))
                            .SelectMany(b => b);

            Assert.IsTrue(origmsgs.All(o => recvtmsgs.Any(m =>
                                                          m.Delivery == o.Delivery &&
                                                          m.Message.CreateHeader16.HeaderAndPayload == o.Message.CreateHeader16.HeaderAndPayload
                                                          )));
        }
Esempio n. 2
0
        public void TestSimpleTunnelDataCreation()
        {
            var smalldata = BufUtils.RandomBytes(38);

            var srcmsgs = new List <TunnelMessage>();

            srcmsgs.Add(new TunnelMessageLocal(new DeliveryStatusMessage(1234)));
            var msgfrags = TunnelDataMessage.MakeFragments(srcmsgs, 0x3e5c);

            Assert.IsTrue(msgfrags.Count() == 1);

            var firstmsg   = msgfrags.First();
            var serialized = firstmsg.CreateHeader16.HeaderAndPayload;

            var recovered = I2NPMessage.ReadHeader16(new BufRefLen(serialized));

            var reassembler     = new TunnelDataFragmentReassembly();
            var reassembledmsgs = reassembler.Process(
                new TunnelDataMessage[]
            {
                (TunnelDataMessage)recovered.Message
            }, out var _);

            Assert.IsTrue(reassembledmsgs.Count() == 1);

            var firstrecinstr = reassembledmsgs.First();

            Assert.IsTrue(firstrecinstr.Delivery == TunnelMessage.DeliveryTypes.Local);
            Assert.IsTrue(firstrecinstr.Message.MessageType == I2NPMessage.MessageTypes.DeliveryStatus);
            Assert.IsTrue(((DeliveryStatusMessage)firstrecinstr.Message).StatusMessageId == 1234);
        }
Esempio n. 3
0
        public void TestAESBlock()
        {
            for (int runs = 0; runs < 10; ++runs)
            {
                var buf    = new BufLen(new byte[30000]);
                var writer = new BufRefLen(buf);

                var data  = BufUtils.RandomBytes(1 + BufUtils.RandomInt(45));
                var datar = new BufRefLen(data);
                var tags  = new List <I2PSessionTag>();
                for (int i = 0; i < BufUtils.RandomInt(5); ++i)
                {
                    tags.Add(new I2PSessionTag());
                }

                var newsession = BufUtils.RandomDouble(1.0) < 0.3 ? new I2PSessionKey() : null;
                var b1         = new GarlicAESBlock(writer, tags, newsession, datar);

                var bldata = new BufLen(buf, 0, writer - buf).Clone();

                var b2 = new GarlicAESBlock(new BufRefLen(bldata));

                var b1ar = new BufLen(b1.ToByteArray());
                var b2ar = new BufLen(b2.ToByteArray());
                Assert.IsTrue(b1ar == b2ar);

                var bufs = new BufRefStream();
                b1.Write(bufs);

                var b3 = new GarlicAESBlock(new BufRefLen(bufs.ToByteArray()));

                var b3ar = new BufLen(b3.ToByteArray());
                Assert.IsTrue(b1ar == b3ar);
            }
        }
Esempio n. 4
0
        internal static BufLen Send(DHHandshakeContext context)
        {
            context.TimestampA = (uint)Math.Ceiling((DateTime.UtcNow - I2PDate.RefDate).TotalSeconds);

            var cleartext = new BufRefStream();
            var ri        = RouterContext.Inst.MyRouterIdentity.ToByteArray();

            cleartext.Write(BufUtils.Flip16B((ushort)ri.Length));
            cleartext.Write(ri);

            cleartext.Write(BufUtils.Flip32B(context.TimestampA));

            Logging.LogDebugData($"SessionConfirmA send TimestampA: {I2PDate.RefDate.AddSeconds( context.TimestampA )}");
            Logging.LogDebugData($"SessionConfirmA send TimestampB: {I2PDate.RefDate.AddSeconds( context.TimestampB )}");

            var sign = I2PSignature.DoSign(RouterContext.Inst.PrivateSigningKey,
                                           context.X.Key,
                                           context.Y.Key,
                                           context.RemoteRI.IdentHash.Hash,
                                           BufUtils.Flip32BL(context.TimestampA),
                                           BufUtils.Flip32BL(context.TimestampB));

            var padsize = BufUtils.Get16BytePadding((int)(sign.Length + cleartext.Length));

            cleartext.Write(BufUtils.RandomBytes(padsize));

            cleartext.Write(sign);

            var buf = new BufLen(cleartext.ToArray());

            context.Encryptor.ProcessBytes(buf);

            return(buf);
        }
        public void MakeAndReadFragmentsWithSerialize()
        {
            var origmsgs = new List <TunnelMessage>();

            for (int i = 0; i < 200; ++i)
            {
                switch (BufUtils.RandomInt(3))
                {
                case 0:
                    var adatarec = new DataMessage(
                        new BufLen(
                            BufUtils.RandomBytes(2048 + BufUtils.RandomInt(1024))));

                    origmsgs.Add(new TunnelMessageLocal(adatarec));
                    break;

                case 1:
                    var arec = new DatabaseLookupMessage(
                        new I2PIdentHash(true),
                        new I2PIdentHash(true),
                        DatabaseLookupMessage.LookupTypes.RouterInfo);

                    origmsgs.Add(new TunnelMessageRouter(
                                     arec,
                                     new I2PIdentHash(true)));
                    break;

                case 2:
                    var adatarec2 = new DataMessage(
                        new BufLen(
                            BufUtils.RandomBytes(2048 + BufUtils.RandomInt(1024))));

                    origmsgs.Add(new TunnelMessageTunnel(adatarec2,
                                                         new I2PIdentHash(true),
                                                         BufUtils.RandomUint()));
                    break;
                }
            }

            var msgs     = TunnelDataMessage.MakeFragments(origmsgs, BufUtils.RandomUint());
            var recvlist = new List <TunnelDataMessage>();

            foreach (var msg in msgs)
            {
                recvlist.Add((TunnelDataMessage)I2NPMessage.ReadHeader16(
                                 new BufRefLen(msg.CreateHeader16.HeaderAndPayload)).Message);
            }

            var mkmsg     = new TunnelDataFragmentReassembly();
            var recvtmsgs = mkmsg.Process(recvlist, out var _);

            foreach (var rmsg in recvtmsgs)
            {
                Assert.IsTrue(origmsgs.SingleOrDefault(m =>
                                                       m.Delivery == rmsg.Delivery &&
                                                       m.Message.CreateHeader16.HeaderAndPayload == rmsg.Message.CreateHeader16.HeaderAndPayload
                                                       ) != null);
            }
        }
Esempio n. 6
0
 public I2PSigningPrivateKey(I2PCertificate cert)
     : base(new BufLen(BufUtils.RandomBytes(cert.SigningPrivateKeyLength)), cert)
 {
     if (cert.SignatureType == SigningKeyTypes.EdDSA_SHA512_Ed25519)
     {
         ExpandedPrivateKey = Chaos.NaCl.Ed25519.ExpandedPrivateKeyFromSeed(ToByteArray());
     }
 }
Esempio n. 7
0
        public void TestBufLen()
        {
            BufLen b1null = null;
            var    b1     = new BufLen(BufUtils.RandomBytes(70));
            var    b2     = new BufLen(BufUtils.RandomBytes(70));

            b1[0] = 2;
            b2[0] = 1;

#pragma warning disable 1718
            Assert.IsTrue(b1null == b1null);
            Assert.IsTrue(b1null == null);
            Assert.IsTrue(b1 != b1null);
            Assert.IsTrue(b1 != null);
            Assert.IsTrue(null != b1);
            Assert.IsTrue(b1 == b1);
            Assert.IsTrue(b1 != b2);
            Assert.IsTrue(b1 == b1.Clone());
            Assert.IsTrue(b1.AsEnumerable().Average(b => b) == b1.Clone().AsEnumerable().Average(b => b));
            Assert.IsTrue(((IComparable <BufLen>)b1).CompareTo(b1.Clone()) == 0);
#pragma warning restore 1718

            var list = new List <byte>(b1);
            Assert.IsTrue(b1 == new BufLen(list.ToArray()));

            var buf = new byte[5];
            b2.Peek(buf, 30);
            Assert.IsTrue((new BufLen(b2, 30, 5)) == new BufLen(buf));

            Assert.IsTrue(b1 != b2);
            Assert.IsTrue(((IComparable <BufLen>)b1).CompareTo(b2) > 0);
            Assert.IsTrue(b1 > b2);
            Assert.IsFalse(b1 < b2);
            Assert.IsTrue(b1 > new BufLen(b1, 0, 20));
            Assert.IsFalse(b1 < new BufLen(b1, 0, 20));
            Assert.IsTrue(new BufLen(b1, 0, 20) < b1);
            Assert.IsFalse(new BufLen(b1, 0, 20) > b1);

            Assert.IsTrue(b1.GetHashCode() == b1.GetHashCode());
            Assert.IsTrue(b1.GetHashCode() == b1.Clone().GetHashCode());

            b1.PokeFlip32(0x326de4f7, 20);
            Assert.IsTrue(b1[20] == 0x32);
            Assert.IsTrue(b1[21] == 0x6d);
            Assert.IsTrue(b1[22] == 0xe4);
            Assert.IsTrue(b1[23] == 0xf7);

            b1.Poke32(0x326de4f7, 21);
            Assert.IsTrue(b1[20] == 0x32);
            Assert.IsTrue(b1[21] == 0xf7);
            Assert.IsTrue(b1[22] == 0xe4);
            Assert.IsTrue(b1[23] == 0x6d);
            Assert.IsTrue(b1[24] == 0x32);
        }
Esempio n. 8
0
        public void Write(BufRefStream dest)
        {
            Id.Write(dest);
            LastSeen.Write(dest);
            Created.Write(dest);
            dest.Write(BufUtils.RandomBytes(52));     // Reserved space

            var mapping = CreateMapping();

            mapping.Write(dest);
        }
Esempio n. 9
0
        public void TestElGamal()
        {
            for (int i = 0; i < 20; ++i)
            {
                var data     = new BufLen(BufUtils.RandomBytes(222));
                var origdata = data.Clone();

                var enc = new BufLen(ElGamalCrypto.Encrypt(data, Public, true));

                var decryptdata = ElGamalCrypto.Decrypt(enc, Private, true);

                Assert.IsTrue(decryptdata == origdata);
            }
        }
Esempio n. 10
0
        public void TestGarlicCreate()
        {
            var ls = new I2PDate(DateTime.Now + TimeSpan.FromMinutes(5));

            var origmessage = new DeliveryStatusMessage(I2NPMessage.GenerateMessageId());
            var bigmessage  = new DataMessage(new BufLen(BufUtils.RandomBytes(14 * 1024)));

            var garlic = new Garlic(
                new GarlicClove(
                    new GarlicCloveDeliveryLocal(origmessage),
                    ls),
                new GarlicClove(
                    new GarlicCloveDeliveryLocal(bigmessage),
                    ls)
                );

            var egmsg = Garlic.EGEncryptGarlic(
                garlic,
                Public,
                new I2PSessionKey(),
                null);

            var origegdata  = I2NPMessage.Clone(egmsg);
            var origegdata2 = I2NPMessage.Clone(egmsg);

            // Decrypt

            var(aesblock, sessionkey1) = Garlic.EGDecryptGarlic(origegdata, Private);

            var newgarlic = new Garlic((BufRefLen)aesblock.Payload);

            var g1 = new BufLen(garlic.ToByteArray());
            var g2 = new BufLen(newgarlic.ToByteArray());

            Assert.IsTrue(g1 == g2);

            // Retrieve

            var(aesblock2, sessionkey2) = Garlic.RetrieveAESBlock(origegdata2, Private, null);

            newgarlic = new Garlic((BufRefLen)aesblock2.Payload);

            g1 = new BufLen(garlic.ToByteArray());
            g2 = new BufLen(newgarlic.ToByteArray());

            Assert.IsTrue(g1 == g2);
            Assert.IsTrue(sessionkey1 == sessionkey2);
        }
Esempio n. 11
0
        static void MyDestination_DataReceived(ClientDestination dest, BufLen data)
        {
            Logging.LogInformation($"Program {PublishedDestination}: data received {data:15}");

            var reader = new BufRefLen(data);
            var unzip  = LZUtils.BCGZipDecompressNew((BufLen)reader);
            var packet = new StreamingPacket((BufRefLen)unzip);

            Logging.LogInformation($"Program {PublishedDestination}: {packet} {packet.Payload}");

            PublishedDestination.LookupDestination(packet?.From.IdentHash, (hash, ls, tag) =>
            {
                if (ls is null)
                {
                    Logging.LogInformation($"Program {PublishedDestination}: Failed to lookup {hash?.Id32Short}.");
                    return;
                }

                var s  = new BufRefStream();
                var sh = new StreamingPacket(
                    PacketFlags.SYNCHRONIZE
                    | PacketFlags.FROM_INCLUDED
                    | PacketFlags.SIGNATURE_INCLUDED
                    | PacketFlags.MAX_PACKET_SIZE_INCLUDED
                    | PacketFlags.NO_ACK)
                {
                    From            = PublishedDestination.Destination,
                    SigningKey      = MyDestinationInfo.PrivateSigningKey,
                    ReceiveStreamId = packet.ReceiveStreamId,
                    SendStreamId    = SendId,
                    NACKs           = new List <uint>(),
                    Payload         = new BufLen(BufUtils.RandomBytes(30)),
                };

                sh.Write(s);
                var buf    = s.ToByteArray();
                var zipped = LZUtils.BCGZipCompressNew(new BufLen(buf));
                zipped.PokeFlip16(4353, 4);                // source port
                zipped.PokeFlip16(25, 6);                  // dest port
                zipped[9] = (byte)PayloadFormat.Streaming; // streaming

                Logging.LogInformation($"Program {PublishedDestination}: Sending {zipped:20}.");
                PublishedDestination.Send(ls.Destination, zipped);
            });
        }
Esempio n. 12
0
        public void TestRoulette()
        {
            var l = BufUtils.RandomBytes(10000).AsEnumerable();
            var r = new I2PCore.Utils.RouletteSelection <byte, byte>(l, v => v, k => k == 42 ? 30f : 1f);

            int is42    = 0;
            int samples = 10000;

            for (int i = 0; i < samples; ++i)
            {
                if (r.GetWeightedRandom(null) == 42)
                {
                    ++is42;
                }
            }

            Assert.IsTrue(is42 > (3 * samples) / 256);
        }
Esempio n. 13
0
        public void TestBufLenHex()
        {
            var b1        = new BufLen(BufUtils.RandomBytes(200));
            var st        = b1.ToHexDump();
            var linecount = st.Split(new char[] { '\n' }).Count();

            Assert.IsTrue(linecount == 14);

            b1        = new BufLen(BufUtils.RandomBytes(400));
            st        = b1.ToHexDump();
            linecount = st.Split(new char[] { '\n' }).Count();
            Assert.IsTrue(linecount == 26);

            b1        = new BufLen(BufUtils.RandomBytes(400));
            st        = b1.ToHexDump(8);
            linecount = st.Split(new char[] { '\n' }).Count();
            Assert.IsTrue(linecount == 51);
        }
Esempio n. 14
0
        public void TestSingleLargeTunnelDataCreation()
        {
            var sourcedata = new BufLen(BufUtils.RandomBytes(9000));

            var srcmsgs = new List <TunnelMessage>();

            srcmsgs.Add(new TunnelMessageTunnel(new DataMessage(sourcedata), new I2PIdentHash(true), 4242));
            var msgfrags = TunnelDataMessage.MakeFragments(srcmsgs, 0x3e5c);

            Assert.IsTrue(msgfrags.Count() == 10);

            var serbuf = new List <byte>();

            foreach (var frag in msgfrags)
            {
                serbuf.AddRange(frag.CreateHeader16.HeaderAndPayload);
            }
            var serbufarray = serbuf.ToArray();

            var reassembler = new TunnelDataFragmentReassembly();
            var reader      = new BufRefLen(serbufarray);
            var readmsgs    = new List <TunnelDataMessage>();

            while (reader.Length > 0)
            {
                readmsgs.Add((TunnelDataMessage)(I2NPMessage.ReadHeader16(reader)).Message);
            }

            var reassembledmsgs = reassembler.Process(readmsgs, out var _);

            Assert.IsTrue(reassembledmsgs.Count() == 1);
            Assert.IsTrue(reassembler.BufferedFragmentCount == 0);

            var firstrecinstr = reassembledmsgs.First();

            Assert.IsTrue(firstrecinstr.Delivery == TunnelMessage.DeliveryTypes.Tunnel);
            Assert.IsTrue(((TunnelMessageTunnel)firstrecinstr).Tunnel == 4242);
            Assert.IsTrue(firstrecinstr.Message.MessageType == I2NPMessage.MessageTypes.Data);

            var datamsg = (DataMessage)firstrecinstr.Message;

            Assert.IsTrue(datamsg.DataMessagePayloadLength == sourcedata.Length);
            Assert.IsTrue(datamsg.DataMessagePayload == sourcedata);
        }
Esempio n. 15
0
        public void TestGZip()
        {
            var smalldata = BufUtils.RandomBytes(200);
            var bigdata   = BufUtils.RandomBytes(2 * 1024 * 1024);

            var smalldata_zero = new byte[200];
            var bigdata_zero   = new byte[2 * 1024 * 1024];

            var b1 = LZUtils.BCGZipCompressNew(new BufLen(smalldata));
            var b2 = LZUtils.BCGZipDecompressNew(b1);

            Assert.IsTrue(b2 == new BufLen(smalldata));

            b1 = LZUtils.BCGZipCompressNew(new BufLen(bigdata));
            b2 = LZUtils.BCGZipDecompressNew(b1);
            Assert.IsTrue(b2 == new BufLen(bigdata));

            b1 = LZUtils.BCGZipCompressNew(new BufLen(smalldata_zero));
            b2 = LZUtils.BCGZipDecompressNew(b1);
            Assert.IsTrue(b2 == new BufLen(smalldata_zero));

            b1 = LZUtils.BCGZipCompressNew(new BufLen(bigdata_zero));
            b2 = LZUtils.BCGZipDecompressNew(b1);
            Assert.IsTrue(b2 == new BufLen(bigdata_zero));

            var ba1 = LZUtils.BCGZipCompress(bigdata);

            b2 = LZUtils.BCGZipDecompressNew(new BufLen(ba1));
            Assert.IsTrue(b2 == new BufLen(bigdata));

            b1 = LZUtils.BCGZipCompressNew(new BufLen(bigdata_zero));
            var ba2 = LZUtils.BCGZipDecompress(b1);

            Assert.IsTrue(new BufLen(ba2) == new BufLen(bigdata_zero));

            for (int i = bigdata.Length / 10; i < bigdata.Length - bigdata.Length / 10; ++i)
            {
                bigdata[i] = 42;
            }
            b1 = LZUtils.BCGZipCompressNew(new BufLen(bigdata));
            b2 = LZUtils.BCGZipDecompressNew(b1);
            Assert.IsTrue(b2 == new BufLen(bigdata));
        }
Esempio n. 16
0
        public void TestElGamal2()
        {
            var buf = new byte[514];

            for (int i = 0; i < 20; ++i)
            {
                var data     = new BufLen(BufUtils.RandomBytes(222));
                var origdata = data.Clone();

                var start  = new BufRefLen(buf);
                var writer = new BufRefLen(buf);
                ElGamalCrypto.Encrypt(writer, data, Public, true);
                var enc = new BufLen(start, 0, writer - start);

                var decryptdata = ElGamalCrypto.Decrypt(enc, Private, true);

                Assert.IsTrue(decryptdata == origdata);
            }
        }
Esempio n. 17
0
        private void SendUnfragmentedSessionConfirmed()
        {
            var ri = new BufLen(Session.MyRouterContext.MyRouterInfo.ToByteArray());

            SendMessage(
                SSUHeader.MessageTypes.SessionConfirmed,
                Session.MACKey,
                Session.SharedKey,
                (start, writer) =>
            {
                writer.Write8((byte)((0 << 4) + 1));
                writer.WriteFlip16((ushort)ri.Length);
                writer.Write(ri);

                Session.SignOnTimeA = BufUtils.Flip32(SSUHost.SSUTime(DateTime.UtcNow));
                writer.Write32(Session.SignOnTimeA);
                var padding = BufUtils.Get16BytePadding(Session.MyRouterContext.Certificate.SignatureLength + (writer - start));
                writer.Write(BufUtils.RandomBytes(padding));

                var baddr = new BufLen(Session.RemoteEP.Address.GetAddressBytes());
                var bport = BufUtils.Flip16BL((ushort)Session.RemoteEP.Port);
#if LOG_MUCH_TRANSPORT
                Logging.LogTransport($"SSU {this}: X for signature {Request.X.Key}.");
                Logging.LogTransport($"SSU {this}: Y for signature {Request.Y.Key}.");
                Logging.LogTransport($"SSU {this}: Alice address for signature {Request.SCMessage.Address}. Port {Request.SCMessage.Port}.");
                Logging.LogTransport($"SSU {this}: Bob address for signature {baddr}. Port {bport}.");
                Logging.LogTransport($"SSU {this}: Relay tag {Request.SCMessage.RelayTag}. Signon time {(BufLen)Session.SignOnTimeA}.");
#endif

                var sign = I2PSignature.DoSign(Session.MyRouterContext.PrivateSigningKey,
                                               Request.X.Key, Request.Y.Key,
                                               Request.SCMessage.Address, Request.SCMessage.Port,
                                               baddr, bport,
                                               Request.SCMessage.RelayTag, BufUtils.To32BL(Session.SignOnTimeA)
                                               );
                writer.Write(sign);

                Logging.LogTransport($"SSU {this}: {Session.RemoteEP} " +
                                     $"sending unfragmented SessionConfirmed [0x{writer - start - SSUHeader.FIXED_HEADER_SIZE:X}] bytes.");
                return(true);
            });
        }
Esempio n. 18
0
        public void TestRoulette2()
        {
            var l = BufUtils.RandomBytes(10000).AsEnumerable();

            l = l.Concat(BufUtils.Populate <byte>(42, 10000));
            var r = new I2PCore.Utils.RouletteSelection <byte, byte>(l, v => v, k => 1f);

            int is42    = 0;
            int samples = 10000;

            for (int i = 0; i < samples; ++i)
            {
                if (r.GetWeightedRandom(null) == 42)
                {
                    ++is42;
                }
            }

            Assert.IsTrue(is42 > samples / 1000);
        }
Esempio n. 19
0
        internal static byte[] Send(DHHandshakeContext context)
        {
            var clear  = new byte[304];
            var writer = new BufRefLen(clear);

            var keys = I2PPrivateKey.GetNewKeyPair();

            context.PrivateKey = keys.PrivateKey;
            context.Y          = keys.PublicKey;
            context.YBuf       = new BufLen(context.Y.Key);

            var sharedkey = BufUtils.DHI2PToByteArray(context.X.ToBigInteger().ModPow(context.PrivateKey.ToBigInteger(), I2PConstants.ElGamalP));

            context.SessionKey = new I2PSessionKey(sharedkey);

            writer.Write(context.YBuf);

            context.TimestampB = (uint)(DateTime.UtcNow - I2PDate.RefDate).TotalSeconds;

            writer.Write(I2PHashSHA256.GetHash(context.XBuf, context.YBuf));
            writer.WriteFlip32(context.TimestampB);
            writer.Write(BufUtils.RandomBytes(12));

            var key = new KeyParameter(context.SessionKey.Key.ToByteArray());

            var iv = context.YBuf.PeekB(context.YBuf.Length - 16, 16);

            context.Encryptor = new CbcBlockCipher(new AesEngine());
            context.Encryptor.Init(true, new ParametersWithIV(key, iv, 0, 16));

            iv = context.HXxorHI.PeekB(context.HXxorHI.Length - 16, 16);

            context.Dectryptor = new CbcBlockCipher(new AesEngine());
            context.Dectryptor.Init(false, new ParametersWithIV(key, iv, 0, 16));

            context.Encryptor.ProcessBytes(new BufLen(clear, 256, 48));

            return(clear);
        }
Esempio n. 20
0
        internal static byte[] Send(DHHandshakeContext context)
        {
            var msglen = RouterContext.Inst.MyRouterIdentity.Certificate.SignatureLength;

            msglen += BufUtils.Get16BytePadding(msglen);

            var writer = new BufRefLen(new byte[msglen]);

            var SigBuf = I2PSignature.DoSign(RouterContext.Inst.PrivateSigningKey,
                                             context.XBuf,
                                             context.YBuf,
                                             context.RemoteRI.IdentHash.Hash,
                                             BufUtils.Flip32BL(context.TimestampA),
                                             BufUtils.Flip32BL(context.TimestampB));

            writer.Write(SigBuf);
            writer.Write(BufUtils.RandomBytes(writer.Length));

            writer.Reset();
            context.Encryptor.ProcessBytes((BufLen)writer);

            return(writer.ToByteArray());
        }
Esempio n. 21
0
        private void SendSessionCreated()
        {
            SendMessage(
                SSUHeader.MessageTypes.SessionCreated,
                Session.MyRouterContext.IntroKey,
                Session.MyRouterContext.IntroKey,
                (start, writer) =>
            {
                writer.Write(Y.Key);
                AAddr = Session.RemoteEP.Address.GetAddressBytes();
                writer.Write8((byte)AAddr.Length);
                writer.Write(AAddr);
                APort = BufUtils.Flip16((ushort)Session.RemoteEP.Port);
                writer.Write16(APort);
                writer.WriteFlip32(RelayTag);
                Session.SignOnTimeB = BufUtils.Flip32(SSUHost.SSUTime(DateTime.UtcNow));
                writer.Write32(Session.SignOnTimeB);

                var sign = I2PSignature.DoSign(Session.MyRouterContext.PrivateSigningKey,
                                               Request.X, Y.Key,
                                               new BufLen(AAddr), BufUtils.To16BL(APort),
                                               Request.Address, BufUtils.Flip16BL((ushort)Session.MyRouterContext.UDPPort),
                                               BufUtils.To32BL(RelayTag), BufUtils.To32BL(Session.SignOnTimeB));

                var signstart = new BufLen(writer);
                writer.Write(sign);
                var padding = BufUtils.Get16BytePadding(writer - signstart);
                writer.Write(BufUtils.RandomBytes(padding));

                var cipher       = new CbcBlockCipher(new AesEngine());
                var signcryptbuf = new BufLen(signstart, 0, writer - signstart);
                cipher.Init(true, Session.SharedKey.ToParametersWithIV(new BufLen(start, 16, 16)));
                cipher.ProcessBytes(signcryptbuf);
                return(true);
            });
        }
        public void MakeAndReadFragmentLarge()
        {
            var arec = new DataMessage(new BufLen(BufUtils.RandomBytes(2048)));

            var msg = new TunnelMessageRouter(
                arec,
                new I2PIdentHash(true));

            var refmsgdata = msg.Message.CreateHeader16.HeaderAndPayload;

            var fragments = TunnelDataMessage.MakeFragments(
                new TunnelMessage[] { msg },
                BufUtils.RandomUint());

            var mkmsg     = new TunnelDataFragmentReassembly();
            var recvtmsgs = mkmsg.Process(fragments.Shuffle().ToArray(), out var _);

            foreach (var rmsg in recvtmsgs)
            {
                var rmsgdata = rmsg.Message.CreateHeader16.HeaderAndPayload;
                Assert.IsTrue(msg.Delivery == rmsg.Delivery);
                Assert.IsTrue(refmsgdata == rmsgdata);
            }
        }
        public void MakeAndReadFragments100()
        {
            var origmsgs = new List <TunnelMessage>();

            for (int i = 0; i < 100; ++i)
            {
                switch (BufUtils.RandomInt(3))
                {
                case 0:
                    var adatarec = new DataMessage(new BufLen(BufUtils.RandomBytes(2048)));

                    origmsgs.Add(new TunnelMessageTunnel(
                                     adatarec,
                                     new I2PIdentHash(true),
                                     BufUtils.RandomUint()));
                    break;

                case 1:
                    var arec = new DatabaseLookupMessage(
                        new I2PIdentHash(true),
                        new I2PIdentHash(true),
                        DatabaseLookupMessage.LookupTypes.Normal);

                    origmsgs.Add(new TunnelMessageRouter(
                                     arec,
                                     new I2PIdentHash(true)));
                    break;

                case 2:
                    var adatarec2 = new DataMessage(
                        new BufLen(
                            BufUtils.RandomBytes(2048 + BufUtils.RandomInt(1024))));

                    origmsgs.Add(new TunnelMessageLocal(adatarec2));
                    break;
                }
            }

            var msgs   = TunnelDataMessage.MakeFragments(origmsgs, BufUtils.RandomUint());
            var mkmsg  = new TunnelDataFragmentReassembly();
            var chunks = msgs
                         .Shuffle()
                         .ToArray()
                         .Chunk(a => 1 + BufUtils.RandomInt(10))
                         .Shuffle();

            var recvtmsgs = chunks.SelectMany(c => mkmsg.Process(c, out var _)).ToArray();

            Assert.IsTrue(origmsgs.All(o => recvtmsgs.Any(m =>
                                                          m.Delivery == o.Delivery &&
                                                          m.Message.CreateHeader16.HeaderAndPayload == o.Message.CreateHeader16.HeaderAndPayload
                                                          )));

            var mkmsg2  = new TunnelDataFragmentReassembly();
            var chunks2 = msgs
                          .Shuffle()
                          .ToArray()
                          .Skip(1)
                          .Chunk(a => 1 + BufUtils.RandomInt(10))
                          .Shuffle();

            var recvtmsgs2 = chunks2.SelectMany(c => mkmsg2.Process(c, out var _)).ToArray();

            Assert.IsFalse(origmsgs.All(o => recvtmsgs2.Any(m =>
                                                            m.Delivery == o.Delivery &&
                                                            m.Message.CreateHeader16.HeaderAndPayload == o.Message.CreateHeader16.HeaderAndPayload
                                                            )));
        }
Esempio n. 24
0
 bool RandomExtraPadding(BufLen start, BufRefLen writer)
 {
     writer.Write(BufUtils.RandomBytes(BufUtils.RandomInt(16)));
     return(true);
 }
Esempio n. 25
0
        /**
         * From PacketBuilder.java
         * -----8<-----
         * @param packet prepared packet with the first 32 bytes empty and a length
         *               whose size is mod 16.
         *               As of 0.9.7, length non-mod-16 is allowed; the
         *               last 1-15 bytes are included in the MAC calculation but are not encrypted.
         * -----8<-----
         */

        protected void SendMessage(
            IPEndPoint dest,
            SSUHeader.MessageTypes message,
            BufLen mackey,
            BufLen cryptokey,
            SendMessageGenerator gen,
            SendMessageGenerator genextrapadding)
        {
            var start = Session.Host.SendBuffers.Pop();

            var writer = new BufRefLen(start);
            var header = new SSUHeader(writer, message);

            if (!gen(start, writer))
            {
                return;
            }

            // Do not cut to datalen & ~0xf as that might make data at the end unencrypted
            var datapadding = BufUtils.Get16BytePadding(writer - start);

            writer.Write(BufUtils.RandomBytes(datapadding));
            var datalen = writer - start;

            var encryptedbuf = new BufLen(start, 32, datalen - 32);

            // TODO: Adding extra padding does not seem to work
            if (genextrapadding != null)
            {
                if (!genextrapadding(start, writer))
                {
                    return;
                }
            }

            var packetlen = writer - start;
            var data      = new BufLen(start, 0, packetlen);
            var hmac      = new BufLen(data, 32);

            SendMessageCipher.Init(true, cryptokey.ToParametersWithIV(header.IV));
            SendMessageCipher.ProcessBytes(encryptedbuf);

            I2PHMACMD5Digest.Generate(new BufLen[] {
                hmac,
                header.IV,
                BufUtils.Flip16BL((ushort)((ushort)hmac.Length ^ I2PConstants.SSU_PROTOCOL_VERSION))
            }, mackey, header.MAC);

#if LOG_MUCH_TRANSPORT
            Logging.LogTransport(string.Format("SSUState SendMessage {0}: encrlen {1} bytes [0x{1:X}] (padding {2} bytes [0x{2:X}]), " +
                                               "hmac {3} bytes [0x{3:X}], sendlen {4} bytes [0x{4:X}]",
                                               Session.DebugId,
                                               encryptedbuf.Length,
                                               datapadding,
                                               hmac.Length,
                                               data.Length));
#endif

            DataSent();
            Send(dest, data);
        }
Esempio n. 26
0
 public I2PRawData(int bytes, bool random)
 {
     Data = random ? BufUtils.RandomBytes(bytes): new byte[bytes];
 }
Esempio n. 27
0
        public void TestSSUOutOfOrderFragmentation()
        {
            var fragmenter = new DataFragmenter();

            var smalldata        = new BufLen(BufUtils.RandomBytes(4 + BufUtils.RandomInt(4)));
            var smalldatamessage = new DataMessage(smalldata);

            var smalldata1        = new BufLen(BufUtils.RandomBytes(40 + BufUtils.RandomInt(14)));
            var smalldatamessage1 = new DataMessage(smalldata1);

            var smalldata2        = new BufLen(BufUtils.RandomBytes(130 + BufUtils.RandomInt(39)));
            var smalldatamessage2 = new DataMessage(smalldata2);

            var smalldata3        = new BufLen(BufUtils.RandomBytes(770 + BufUtils.RandomInt(220)));
            var smalldatamessage3 = new DataMessage(smalldata3);

            var data        = new BufLen(BufUtils.RandomBytes(30000 + BufUtils.RandomInt(30)));
            var datamessage = new DataMessage(data);

            var data2        = new BufLen(BufUtils.RandomBytes(20000 + BufUtils.RandomInt(1040)));
            var datamessage2 = new DataMessage(data2);

            var dest   = new byte[MTUConfig.BufferSize];
            var start  = new BufLen(dest);
            var writer = new BufRefLen(dest);

            var tosend = new LinkedList <II2NPHeader16>();

            tosend.AddLast(smalldatamessage.CreateHeader16);
            tosend.AddLast(datamessage.CreateHeader16);
            tosend.AddLast(smalldatamessage1.CreateHeader16);
            tosend.AddLast(smalldatamessage2.CreateHeader16);
            tosend.AddLast(smalldatamessage3.CreateHeader16);
            tosend.AddLast(datamessage2.CreateHeader16);

            var tosendshuffle  = tosend.Shuffle();
            var tosendshuffled = new ConcurrentQueue <II2NPHeader16>(tosendshuffle);

            var sent = new LinkedList <II2NPHeader16>();

            foreach (var one in tosend)
            {
                sent.AddLast(one);
            }

            var sentdata = new LinkedList <BufLen>();

            while (true)
            {
                var flagbuf      = writer.ReadBufLen(1);
                var fragcountbuf = writer.ReadBufLen(1);

                var fragments = fragmenter.Send(writer, tosendshuffled);
                if (fragments == 0)
                {
                    break;
                }

                flagbuf[0] |= (byte)SSUDataMessage.DataMessageFlags.WantReply;
                // no ACKs
                fragcountbuf[0] = (byte)fragments;

                sentdata.AddLast(new BufLen(start, 0, writer - start));
                dest   = new byte[MTUConfig.BufferSize];
                start  = new BufLen(dest);
                writer = new BufRefLen(dest);
            }

            var shuffled = sentdata.Shuffle();

            var receivedmessages = new LinkedList <II2NPHeader16>();

            var defragmenter = new DataDefragmenter();

            foreach (var frag in shuffled)
            {
                var datamsg = new SSUDataMessage(new BufRefLen(frag), defragmenter);
                if (datamsg.NewMessages != null)
                {
                    foreach (var msg in datamsg.NewMessages)
                    {
                        var i2npmsg = I2NPMessage.ReadHeader16((BufRefLen)msg.GetPayload());
                        receivedmessages.AddLast(i2npmsg);
                    }
                }
            }

            Assert.IsTrue(receivedmessages.Count == sent.Count);

            foreach (var sentmsg in sent)
            {
                Assert.IsTrue(receivedmessages.SingleOrDefault(m => ((DataMessage)m.Message).Payload ==
                                                               ((DataMessage)sentmsg.Message).Payload) != null);
            }
        }
Esempio n. 28
0
        // This test does not work
        //[Test]
        public void TestSSU()
        {
            //Logging.LogToFile( "TestSSU.log" );

            RouterContext testcontext = new RouterContext(new I2PCertificate(I2PSigningKey.SigningKeyTypes.DSA_SHA1));

            testcontext.DefaultTCPPort = 2048 + BufUtils.RandomInt(5000);
            testcontext.DefaultUDPPort = 2048 + BufUtils.RandomInt(5000);

            var host = new SSUHost(testcontext, new FixedMTU());

            host.AllowConnectToSelf = true;

            host.ConnectionCreated += host_ConnectionCreated;

            // Remote
            var dnsa = Dns.GetHostEntry(Dns.GetHostName()).AddressList.Where(a => a.AddressFamily == AddressFamily.InterNetwork).FirstOrDefault();
            var addr = new I2PRouterAddress(dnsa, testcontext.UDPPort, 6, "SSU");

            addr.Options["key"] = FreenetBase64.Encode(testcontext.IntroKey);

            RouterContext remotetestcontext = new RouterContext(new I2PCertificate(I2PSigningKey.SigningKeyTypes.DSA_SHA1));

            remotetestcontext.DefaultTCPPort = testcontext.DefaultTCPPort + 5;
            remotetestcontext.DefaultUDPPort = testcontext.DefaultUDPPort + 5;

            var remotehost = new SSUHost(remotetestcontext, new FixedMTU());

            remotehost.AllowConnectToSelf = true;
            var client = remotehost.AddSession(addr, testcontext.MyRouterIdentity);

            client.Connect();

            var data = new BufLen(BufUtils.RandomBytes(30000));

            var messagecount = 900; // If the out queue is larger than 1000 msgs we start discarding them

            for (int i = 0; i < messagecount; ++i)
            {
                client.Send(new DataMessage(data));
            }

            System.Threading.Thread.Sleep(10000);

            for (int i = 0; i < messagecount; ++i)
            {
                if (i % 10 == 0)
                {
                    System.Threading.Thread.Sleep(100);
                }
                client.Send(new DataMessage(data));
            }

            var start = new TickCounter();

            while (DataReceived.Count < 2 * messagecount)
            {
                if (start.DeltaToNow.ToMinutes >= 1)
                {
                    Assert.Fail("Failed to receive sent data due to a timeout");
                    break;
                }

                System.Threading.Thread.Sleep(500);
            }

            for (int i = 0; i < 100; ++i)
            {
                Assert.IsTrue(((DataMessage)DataReceived.Random().Message).DataMessagePayload ==
                              new BufLen(data));
            }

            System.Threading.Thread.Sleep(500);

            client.Terminate();

            System.Threading.Thread.Sleep(500);

            host.Terminate();

            System.Threading.Thread.Sleep(500);
        }
Esempio n. 29
0
 public I2PPrivateKey(I2PCertificate cert) : base(cert)
 {
     Key     = new BufLen(BufUtils.RandomBytes(KeySizeBytes));
     Key[0] |= 0x80;
     Key[Key.Length - 1] |= 0x01;
 }
Esempio n. 30
0
        static void Main(string[] args)
        {
            PeriodicAction SendInterval = new PeriodicAction(TickSpan.Seconds(20));

            Logging.ReadAppConfig();
            Logging.LogToDebug   = false;
            Logging.LogToConsole = true;

            RouterContext.RouterSettingsFile = "I2PDemo.bin";

            MyDestinationInfo = new I2PDestinationInfo(I2PSigningKey.SigningKeyTypes.EdDSA_SHA512_Ed25519);

            for (int i = 0; i < args.Length; ++i)
            {
                switch (args[i])
                {
                case "--addr":
                case "--address":
                    if (args.Length > i + 1)
                    {
                        RouterContext.Inst.DefaultExtAddress = IPAddress.Parse(args[++i]);
                        Console.WriteLine($"addr {RouterContext.Inst.DefaultExtAddress}");
                    }
                    else
                    {
                        Console.WriteLine("--addr require ip number");
                        return;
                    }
                    break;

                case "--port":
                    if (args.Length > i + 1)
                    {
                        var port = int.Parse(args[++i]);
                        RouterContext.Inst.DefaultTCPPort = port;
                        RouterContext.Inst.DefaultUDPPort = port;
                        Console.WriteLine($"port {port}");
                    }
                    else
                    {
                        Console.WriteLine("--port require port number");
                        return;
                    }
                    break;

                case "--nofw":
                    RouterContext.Inst.IsFirewalled = false;
                    Console.WriteLine($"Firewalled {RouterContext.Inst.IsFirewalled}");
                    break;

                case "--mkdest":
                case "--create-destination":
                    var certtype = 0;
                    if (args.Length > i + 1)
                    {
                        certtype = int.Parse(args[++i]);
                    }

                    I2PSigningKey.SigningKeyTypes ct;
                    I2PDestinationInfo            d;

                    switch (certtype)
                    {
                    default:
                    case 0:
                        ct = I2PSigningKey.SigningKeyTypes.EdDSA_SHA512_Ed25519;
                        d  = new I2PDestinationInfo(ct);
                        break;

                    case 1:
                        ct = I2PSigningKey.SigningKeyTypes.DSA_SHA1;
                        d  = new I2PDestinationInfo(ct);
                        break;

                    case 2:
                        ct = I2PSigningKey.SigningKeyTypes.ECDSA_SHA256_P256;
                        d  = new I2PDestinationInfo(ct);
                        break;

                    case 3:
                        ct = I2PSigningKey.SigningKeyTypes.ECDSA_SHA384_P384;
                        d  = new I2PDestinationInfo(ct);
                        break;
                    }

                    Console.WriteLine($"New destination {ct}: {d.ToBase64()}");
                    return;

                case "--destination":
                    if (args.Length > i + 1)
                    {
                        MyDestinationInfo = new I2PDestinationInfo(args[++i]);
                        Console.WriteLine($"Destination {MyDestinationInfo}");
                    }
                    else
                    {
                        Console.WriteLine("Base64 encoded Destination required");
                        return;
                    }
                    break;

                default:
                    Console.WriteLine(args[i]);
                    Console.WriteLine("Usage: I2P.exe --addr 12.34.56.78 --port 8081 --nofw --create-destination [0-3] --destination b64...");
                    break;
                }
            }

            RouterContext.Inst.ApplyNewSettings();

            var pnp = new UPnp();

            Thread.Sleep(5000);   // Give UPnp a chance

            Router.Start();

            // Create new identities for this run

            MyDestination = MyDestinationInfo.Destination;

#if MANUAL_SIGN
            PublishedDestination = Router.CreateDestination(
                MyDestination,
                MyDestinationInfo.PrivateKey,
                true,
                out _);      // Publish our destinaiton
            PublishedDestination.SignLeasesRequest += MyDestination_SignLeasesRequest;
#else
            PublishedDestination = Router.CreateDestination(MyDestinationInfo, true, out _);   // Publish our destinaiton
#endif
            PublishedDestination.DataReceived += MyDestination_DataReceived;
            PublishedDestination.Name          = "PublishedDestination";

            MyOriginInfo = new I2PDestinationInfo(I2PSigningKey.SigningKeyTypes.DSA_SHA1);
            MyOrigin     = Router.CreateDestination(MyOriginInfo, false, out _);
            MyOrigin.ClientStateChanged += MyOrigin_ClientStateChanged;
            MyOrigin.DataReceived       += MyOrigin_DataReceived;
            MyOrigin.Name = "MyOrigin";

            Logging.LogInformation($"MyDestination: {PublishedDestination.Destination.IdentHash} {MyDestinationInfo.Destination.Certificate}");

            while (true)
            {
                try
                {
                    Connected = true;

                    MyOrigin.LookupDestination(PublishedDestination.Destination.IdentHash, LookupResult);

                    var sendevents = 0;

                    while (Connected)
                    {
                        Thread.Sleep(2000);

                        if (LookedUpDestination != null &&
                            MyOrigin.ClientState == ClientDestination.ClientStates.Established)
                        {
                            SendInterval.Do(() =>
                            {
                                if (sendevents++ < 10)
                                {
                                    // Send some data to the MyDestination
                                    DataSent = new BufLen(
                                        BufUtils.RandomBytes(
                                            (int)(1 + BufUtils.RandomDouble(25) * 1024)));

                                    var ok = MyOrigin.Send(LookedUpDestination, DataSent);
                                    Logging.LogInformation($"Program {MyOrigin}: Send[{sendevents}] {ok}, {DataSent:15}");
                                }

                                if (sendevents > 100)
                                {
                                    sendevents = 0;
                                }
                            });
                        }
                    }
                }
                catch (SocketException ex)
                {
                    Logging.Log(ex);
                }
                catch (IOException ex)
                {
                    Logging.Log(ex);
                }
                catch (Exception ex)
                {
                    Logging.Log(ex);
                }
            }
        }