Exemplo n.º 1
0
        private static ZipArchive GetRouterInfoFiles(BufLen data)
        {
            try
            {
                var reader = new BufRefLen(data);
                var header = new I2PSU3Header(reader);

                if (header.FileType != I2PSU3Header.SU3FileTypes.Zip)
                {
                    throw new ArgumentException($"Unknown FileType in SU3: {header.FileType}");
                }

                if (header.ContentType != I2PSU3Header.SU3ContentTypes.SeedData)
                {
                    throw new ArgumentException($"Unknown ContentType in SU3: {header.ContentType}");
                }

                // TODO: Verify signature

                var s = new BufRefStream();
                s.Write(reader);

                return(new ZipArchive(s));
            }
            catch (Exception ex)
            {
                Logging.Log(ex);
            }

            return(null);
        }
Exemplo n.º 2
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);
            }
        }
Exemplo n.º 3
0
        internal static byte[] Send(DHHandshakeContext context)
        {
            var dest   = new byte[288];
            var writer = new BufRefLen(dest);

            var keys = I2PPrivateKey.GetNewKeyPair();

            context.PrivateKey = keys.PrivateKey;
            context.X          = keys.PublicKey;
            context.XBuf       = context.X.Key;

            context.HXxorHI = new BufLen(I2PHashSHA256.GetHash(context.XBuf));

#if LOG_ALL_TRANSPORT
            Logging.LogTransport(
                "SessionRequest: Remote cert: " + context.RemoteRI.Certificate.ToString() + ". XBuf len: " + context.XBuf.Length.ToString());
#endif
            var idenhash = context.RemoteRI.IdentHash;
            for (int i = 0; i < context.HXxorHI.Length; ++i)
            {
                context.HXxorHI[i] ^= idenhash.Hash[i];
            }

            writer.Write(context.XBuf);
            writer.Write(context.HXxorHI);

            return(dest);
        }
Exemplo n.º 4
0
        public GarlicAESBlock(BufRefLen reader)
        {
            var start = new BufLen(reader);

            TagCount = reader.ReadBufLen(2);
            var tags = TagCount.PeekFlip16(0);

            if (tags > 0)
            {
                if (tags * I2PSessionTag.TagLength > start.Length)
                {
                    throw new ArgumentException("GarlicAESBlock: Not enough data for the tags supplied.");
                }
                for (int i = 0; i < tags; ++i)
                {
                    Tags.Add(reader.ReadBufLen(I2PSessionTag.TagLength));
                }
            }
            PayloadSize = reader.ReadBufLen(4);
            PayloadHash = reader.ReadBufLen(32);
            Flag        = reader.ReadBufLen(1);
            if (Flag[0] != 0)
            {
                NewSessionKey = reader.ReadBufLen(32);
            }
            var pllen = PayloadSize.PeekFlip32(0);

            if (pllen > reader.Length)
            {
                throw new ArgumentException("GarlicAESBlock: Not enough data payload supplied.");
            }
            Payload = reader.ReadBufLen((int)pllen);
            Padding = reader.ReadBufLen(BufUtils.Get16BytePadding(reader - start));
        }
Exemplo n.º 5
0
        internal static byte[] Send(DHHandshakeContext context)
        {
            var dest   = new byte[288];
            var writer = new BufRefLen(dest);

            var keys = I2PPrivateKey.GetNewKeyPair();

            context.PrivateKey = keys.PrivateKey;
            context.X          = keys.PublicKey;
            context.XBuf       = context.X.Key;

            context.HXxorHI = new BufLen(I2PHashSHA256.GetHash(context.XBuf));

            Logging.LogDebugData(
                $"SessionRequest: Remote cert: {context.RemoteRI.Certificate}. XBuf len: {context.XBuf.Length}");

            var idenhash = context.RemoteRI.IdentHash;

            for (int i = 0; i < context.HXxorHI.Length; ++i)
            {
                context.HXxorHI[i] ^= idenhash.Hash[i];
            }

            writer.Write(context.XBuf);
            writer.Write(context.HXxorHI);

            return(dest);
        }
Exemplo n.º 6
0
        public DatabaseStoreMessage(
            I2PLeaseSet leaseset,
            uint replytoken,
            I2PIdentHash replygw,
            I2PTunnelId replytunnelid)
        {
            var ls = leaseset.ToByteArray();

            AllocateBuffer(32 + 5 + (replytoken != 0 ? 4 + 32: 0) + ls.Length);
            var writer = new BufRefLen(Payload);

            writer.Write(leaseset.Destination.IdentHash.Hash);
            writer.Write8((byte)MessageContent.LeaseSet);
            writer.Write32(replytoken);
            if (replytoken != 0)
            {
                writer.Write32(replytunnelid);
                if (replygw == null || replygw.Hash.Length != 32)
                {
                    throw new FormatException("ReplyGateway has to be 32 bytes long!");
                }
                writer.Write(replygw.Hash);
            }

            writer.Write(ls);
            UpdateCachedFields((BufRefLen)Payload);
        }
Exemplo n.º 7
0
        public virtual SSUState DatagramReceived(BufRefLen recv, IPEndPoint RemoteEP)
        {
            // Verify the MAC
            var reader   = new BufRefLen(recv);
            var header   = new SSUHeader(reader);
            var recvencr = header.EncryptedBuf;

            var macstate = VerifyMAC(header, CurrentMACKey);

            var usekey = CurrentPayloadKey;

            switch (macstate)
            {
            case MACHealth.AbandonSession: return(null);

            case MACHealth.Missmatch: return(this);

            case MACHealth.UseOurIntroKey:
                usekey = Session.MyRouterContext.IntroKey;
                break;
            }

            // Decrypt
            Cipher.Init(false, usekey.ToParametersWithIV(header.IV));
            Cipher.ProcessBytes(recvencr);

            header.SkipExtendedHeaders(reader);

            return(HandleMessage(header, reader));
        }
Exemplo n.º 8
0
        public DataFragment Send(BufRefLen writer)
        {
            if (AllFragmentsSent || writer.Length < 10)
            {
                return(null);
            }

            var fragsize = Math.Min(FragmentReader.Length, writer.Length - 7);

            // This would be nice, but it would limit the size of I2NP messages.
            //fragsize = Math.Min( ( Session.MTUMin / 4 ) * 3, fragsize ); // To make resends work with reduced MTU

            var newdata  = FragmentReader.ReadBufLen(fragsize);
            var fragment = new DataFragment(newdata);

            fragment.MessageId = MessageId;
            fragment.IsLast    = FragmentReader.Length == 0;
            lock ( Fragments )
            {
                fragment.FragmentNumber = (byte)Fragments.Count;
                Fragments.Add(fragment);
            }

#if LOG_ALL_TRANSPORT
            DebugUtils.LogDebug(() => string.Format(
                                    "SSU sending {0} fragment {1}, {2} bytes. IsLast: {3}",
                                    MessageId, fragment.FragmentNumber, fragment.Data.Length, fragment.IsLast));
#endif
            ++SendCount;
            fragment.WriteTo(writer);
            return(fragment);
        }
Exemplo n.º 9
0
        public DatabaseLookupMessage(
            I2PIdentHash key,
            I2PIdentHash from,
            LookupTypes flags,
            IEnumerable <I2PIdentHash> excludelist)
        {
            var excludecount = excludelist == null ? 0 : excludelist.Count();

            AllocateBuffer(2 * 32 + 1 + 2 + 32 * excludecount);
            var writer = new BufRefLen(Payload);

            writer.Write(key.Hash);
            writer.Write(from.Hash);
            writer.Write8((byte)((byte)flags & ~0x01));

            if (excludecount > 0)
            {
                writer.WriteFlip16((ushort)excludecount);
                foreach (var addr in excludelist)
                {
                    writer.Write(addr.Hash);
                }
            }
            else
            {
                writer.Write16(0);
            }

            //dest.Add( 0 ); // Tags
        }
Exemplo n.º 10
0
        private SSUState AssembleFragments(SSUHeader header, BufRefLen reader, byte info, ushort cursize)
        {
            var fragnr    = info >> 4;
            var fragcount = info & 0x0f;

            if (fragnr == fragcount - 1)
            {
                ASignonTime = reader.Read32();
                reader.Seek(reader.Length - Session.RemoteRouter.Certificate.SignatureLength);
                ASign = new I2PSignature(reader, Session.RemoteRouter.Certificate);
            }
            else
            {
                Fragments[fragnr] = reader.ReadBufLen(cursize);
            }

            if (Fragments.Any(f => f == null))
            {
                return(this);
            }

            Session.RemoteRouter = new I2PRouterIdentity(new BufRefLen(Fragments.SelectMany(f => f.ToByteArray()).ToArray()));

            return(VerifyRemoteSignature());
        }
Exemplo n.º 11
0
        public BufLen GetPayload()
        {
            if (!AllFragmentsFound)
            {
                throw new Exception("Cannot reassemble payload without all the fragments!");
            }

            var messagesize = Fragments.Sum(f => f.Data.Length);

            const int h5inh16offset = 11;
            var       result        = new BufLen(new byte[h5inh16offset + messagesize]);

            var writer = new BufRefLen(result, h5inh16offset);

            foreach (var onef in Fragments)
            {
                writer.Write(onef.Data);
            }

            // Fake a I2NP16 header
            var exp = new I2PDate(SSUHost.SSUDateTime(result.PeekFlip32(1 + h5inh16offset)));

            result[0] = result[h5inh16offset];
            result.PokeFlip64((ulong)exp, 5);
            result.PokeFlip16((ushort)(messagesize - 5), 13);
            // Not wasting time on faking checksum

            return(result);
        }
Exemplo n.º 12
0
        public void Receive(BufRefLen recvbuf)
        {
            if (Terminated)
            {
                throw new EndOfStreamEncounteredException();
            }

            int len;

            lock ( ReceiveQueue )
            {
                len = ReceiveQueue.Count;

                if (len < ReceiveQueueLengthUpperLimit)
                {
                    ReceiveQueue.AddLast(recvbuf);
                    return;
                }
            }
#if DEBUG
            DebugUtils.LogWarning(
                string.Format("SSUSession {0}: ReceiveQueue is {1} messages long! Dropping new message.",
                              DebugId, len));
#endif
        }
Exemplo n.º 13
0
        private void SaveConfig(Store s)
        {
            var lookup = s.GetMatching(e => (StoreRecordId)e[0] == StoreRecordId.StoreIdConfig, 1);
            var str2ix = new Dictionary <I2PString, int>();

            foreach (var one in lookup)
            {
                var reader = new BufRefLen(one.Value);
                reader.Read32();
                var key = new I2PString(reader);
                str2ix[key] = one.Key;
            }

            AccessConfig(delegate(Dictionary <I2PString, I2PString> settings)
            {
                foreach (var one in settings)
                {
                    var rec = new BufLen[] {
                        BufUtils.To32BL((int)StoreRecordId.StoreIdConfig),
                        new BufLen(one.Key.ToByteArray()), new BufLen(one.Value.ToByteArray())
                    };

                    if (str2ix.ContainsKey(one.Key))
                    {
                        s.Write(rec, str2ix[one.Key]);
                    }
                    else
                    {
                        s.Write(rec);
                    }
                }
            });
        }
Exemplo n.º 14
0
        public static GarlicMessage AESEncryptGarlic(
            Garlic msg,
            I2PSessionKey sessionkey,
            I2PSessionTag tag,
            List <I2PSessionTag> newtags)
        {
            var cipher = new CbcBlockCipher(new AesEngine());

            var payload = msg.ToByteArray();
            var dest    = new BufLen(new byte[65536]);
            // Reserve header + 4 bytes for GarlicMessageLength
            var writer = new BufRefLen(dest, I2NPMaxHeaderSize + 4);

            // Tag as header
            writer.Write(tag.Value);

            // AES block
            var aesstart = new BufLen(writer);
            var aesblock = new GarlicAESBlock(writer, newtags, null, new BufRefLen(payload));

            var pivh = I2PHashSHA256.GetHash(tag.Value);

            cipher.Init(true, sessionkey.Key.ToParametersWithIV(new BufLen(pivh, 0, 16)));
            cipher.ProcessBytes(aesblock.DataBuf);

            var length = writer - dest;

            dest.PokeFlip32((uint)(length - 4), I2NPMaxHeaderSize);

            return(new GarlicMessage(new BufRefLen(dest, I2NPMaxHeaderSize, length)));
        }
Exemplo n.º 15
0
        private void Load(string filename)
        {
            using (var fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
            {
                using (var ms = new MemoryStream())
                {
                    byte[] buf = new byte[8192];
                    int    len;
                    while ((len = fs.Read(buf, 0, buf.Length)) != 0)
                    {
                        ms.Write(buf, 0, len);
                    }

                    var reader = new BufRefLen(ms.ToArray());

                    Certificate       = new I2PCertificate(reader);
                    PrivateSigningKey = new I2PSigningPrivateKey(reader, Certificate);
                    PublicSigningKey  = new I2PSigningPublicKey(reader, Certificate);

                    PrivateKey = new I2PPrivateKey(reader, Certificate);
                    PublicKey  = new I2PPublicKey(reader, Certificate);

                    MyRouterIdentity = new I2PRouterIdentity(reader);
                    Published        = new I2PDate(reader);
                    IntroKey         = reader.ReadBufLen(32);
                }
            }
        }
Exemplo n.º 16
0
 public GarlicClove(BufRefLen reader)
 {
     Delivery   = GarlicCloveDelivery.CreateGarlicCloveDelivery(reader);
     Message    = I2NPMessage.ReadHeader16(reader).Message;
     CloveId    = reader.ReadFlip32();
     Expiration = new I2PDate(reader);
     reader.Seek(3);   // Cert
 }
Exemplo n.º 17
0
        public DeliveryStatusMessage()
        {
            AllocateBuffer(12);
            var writer = new BufRefLen(Payload);

            Timestamp       = new I2PDate(DateTime.UtcNow);
            StatusMessageId = I2NPMessage.GenerateMessageId();
        }
Exemplo n.º 18
0
        public FragmentedMessage(II2NPHeader5 msg)
        {
            Message      = msg;
            MessageBytes = new BufLen(msg.HeaderAndPayload);
            MessageId    = BufUtils.RandomUint();

            FragmentReader = new BufRefLen(MessageBytes);
        }
Exemplo n.º 19
0
        public DeliveryStatusMessage(ulong networkid)
        {
            AllocateBuffer(12);
            var writer = new BufRefLen(Payload);

            writer.PokeFlip64(networkid, 4);
            StatusMessageId = BufUtils.RandomUint();
        }
Exemplo n.º 20
0
        public DeliveryStatusMessage(uint msgid)
        {
            AllocateBuffer(12);
            var writer = new BufRefLen(Payload);

            Timestamp       = new I2PDate(DateTime.UtcNow);
            StatusMessageId = msgid;
        }
Exemplo n.º 21
0
        GarlicCreationInfo UseExistingSessionTags(bool explack, uint trackingid, GarlicCloveDelivery[] cloves)
        {
            Garlic msg;
            DeliveryStatusMessage ackmsg = null;

            if (explack)
            {
                msg = AddExplAck(cloves, out ackmsg);
            }
            else
            {
                var exp = new I2PDate(DateTime.UtcNow.AddMinutes(5));
                msg = new Garlic(cloves.Select(d => new GarlicClove(d, exp)).ToArray());
            }

#if LOG_ALL_TUNNEL_TRANSFER
            Logging.LogDebug(() => string.Format(
                                 "DestinationSession: Garlic generated with {0} cloves. {1} tags available.",
                                 msg.Cloves.Count, SessionTags.Count));
#endif

            var payload = msg.ToByteArray();
            var dest    = new BufLen(new byte[61000]);
            var writer  = new BufRefLen(dest, 4);  // Reserve 4 bytes for GarlicMessageLength

            I2PSessionTag tag;
            lock ( SessionTags )
            {
                var ix = BufUtils.RandomInt(SessionTags.Count);
                tag = SessionTags[ix];
                SessionTags.RemoveAt(ix);
            }

            // Tag as header
            writer.Write(tag.Value);

            // AES block
            var aesstart = new BufLen(writer);
            var aesblock = new GarlicAESBlock(writer, null, null, new BufRefLen(payload));

            var pivh = I2PHashSHA256.GetHash(tag.Value);

            Cipher.Init(true, SessionKey.Key.ToParametersWithIV(new BufLen(pivh, 0, 16)));
            Cipher.ProcessBytes(aesblock.DataBuf);

            var length = writer - dest;
            dest.PokeFlip32((uint)(length - 4), 0);

            return(new GarlicCreationInfo(
                       Destination.IdentHash,
                       cloves,
                       new EGGarlic(new BufRefLen(dest, 0, length)),
                       GarlicCreationInfo.KeyUsed.Aes,
                       SessionTags.Count(),
                       trackingid,
                       explack ? (uint?)ackmsg.MessageId : null,
                       LatestEGAckMessageId));
        }
Exemplo n.º 22
0
        public override void Write(BufRefStream dest)
        {
            var header = new byte[6];
            var writer = new BufRefLen(header);

            writer.WriteFlip16(SessionId);
            writer.WriteFlip32(MessageId);
            dest.Write(header);
        }
Exemplo n.º 23
0
        public int Send(BufRefLen writer, ConcurrentQueue <II2NPHeader16> sendqueue)
        {
            var result = 0;

            while (writer.Length > 10)
            {
                if (CurrentMessage == null || CurrentMessage.AllFragmentsSent)
                {
                    CurrentMessage = null;

                    lock ( sendqueue )
                    {
                        if (sendqueue.IsEmpty)
                        {
                            return(result);
                        }
                        if (sendqueue.TryDequeue(out var msg))
                        {
                            CurrentMessage = new FragmentedMessage(msg);
                        }
                        else
                        {
                            return(result);
                        }
                    }

                    if (CurrentMessage != null)
                    {
                        lock ( Messages )
                        {
                            Messages[CurrentMessage.MessageId] = CurrentMessage;
#if LOG_MUCH_TRANSPORT
                            Logging.LogDebugData($"SSU Message to fragment: {CurrentMessage}");
#endif
                        }
                    }
                }

                if (CurrentMessage.Send(writer) != null)
                {
                    ++result;
                }

                if (CurrentMessage.AllFragmentsSent)
                {
                    lock ( AckQueue )
                    {
                        AckQueue.AddFirst(CurrentMessage);
                    }
#if LOG_MUCH_TRANSPORT
                    Logging.LogTransport("SSU Message " + CurrentMessage.MessageId.ToString() + " all fragments sent.");
#endif
                }
            }

            return(result);
        }
Exemplo n.º 24
0
        public override void Write(BufRefStream dest)
        {
            var header = new byte[3];
            var writer = new BufRefLen(header);

            writer.WriteFlip16(SessionId);
            writer.Write8((byte)SessionState);
            dest.Write(header);
        }
Exemplo n.º 25
0
        public SendMessageMessage(BufRefLen reader)
            : base(ProtocolMessageType.SendMessage)
        {
            SessionId   = reader.ReadFlip16();
            Destination = new I2PDestination(reader);
            var len = reader.ReadFlip32();

            Payload = reader.ReadBufLen((int)len);
            Nonce   = reader.ReadFlip32();
        }
Exemplo n.º 26
0
        static void MyDestination_DataReceived(ClientDestination dest, BufLen data)
        {
            Logging.LogInformation($"Program {UnpublishedDestination}: data received {data:20}");

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

            Logging.LogInformation($"Program {UnpublishedDestination}: {packet}");
        }
Exemplo n.º 27
0
        public override SSUState HandleMessage(SSUHeader header, BufRefLen reader)
        {
            if (header.MessageType == SSUHeader.MessageTypes.RelayResponse)
            {
                var response = new RelayResponse(reader);
                return(HandleRelayResponse(response));
            }

            return(this);
        }
Exemplo n.º 28
0
        public DatabaseLookupMessage(I2PIdentHash key, I2PIdentHash from, LookupTypes flags)
        {
            AllocateBuffer(2 * 32 + 1 + 2);
            var writer = new BufRefLen(Payload);

            writer.Write(key.Hash);
            writer.Write(from.Hash);
            writer.Write8((byte)((byte)flags & ~(byte)LookupTypes.Tunnel));
            writer.Write16(0);
        }
Exemplo n.º 29
0
 public SSUHeader(BufRefLen reader)
 {
     MAC              = reader.ReadBufLen(16);
     IV               = reader.ReadBufLen(16);
     MACDataBuf       = new BufLen(reader);
     EncryptedBuf     = new BufLen(MACDataBuf, 0, MACDataBuf.Length & 0x7ffffff0);
     FlagBuf          = reader.ReadBufLen(1);
     TimeStampBuf     = reader.ReadBufLen(4);
     PostTimestampBuf = new BufLen(reader);
 }
Exemplo n.º 30
0
        static BufLen FindTheZero(BufLen start)
        {
            var result = new BufRefLen(start);

            while (result.Read8() != 0)
            {
                ;
            }
            return(result.View);
        }