Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
0
        internal static BufLen Send(DHHandshakeContext context)
        {
            context.TimestampA = (uint)Math.Ceiling((DateTime.UtcNow - I2PDate.RefDate).TotalSeconds);

            var cleartext = new List <byte>();
            var ri        = RouterContext.Inst.MyRouterIdentity.ToByteArray();

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

            cleartext.AddRange(BufUtils.Flip32B(context.TimestampA));
#if LOG_ALL_TRANSPORT
            DebugUtils.Log("SessionConfirmA send TimestampA: " + (I2PDate.RefDate.AddSeconds(context.TimestampA).ToString()));
            DebugUtils.Log("SessionConfirmA send TimestampB: " + (I2PDate.RefDate.AddSeconds(context.TimestampB).ToString()));
#endif

            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(sign.Length + cleartext.Count);
            cleartext.AddRange(BufUtils.Random(padsize));

            cleartext.AddRange(sign);

            var buf = new BufLen(cleartext.ToArray());
            context.Encryptor.ProcessBytes(buf);

            return(buf);
        }
Ejemplo n.º 3
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.Random(padding));

                var baddr = new BufLen(Session.RemoteEP.Address.GetAddressBytes());
                var bport = BufUtils.Flip16BL((ushort)Session.RemoteEP.Port);
#if LOG_ALL_TRANSPORT
                Logging.LogTransport(string.Format("SSU SessionConfirmedState {0}: X for signature {1}.",
                                                   Session.DebugId, Request.X.Key));
                Logging.LogTransport(string.Format("SSU SessionConfirmedState {0}: Y for signature {1}.",
                                                   Session.DebugId, Request.Y.Key));
                Logging.LogTransport(string.Format("SSU SessionConfirmedState {0}: Alice address for signature {1}. Port {2}.",
                                                   Session.DebugId, Request.SCMessage.Address, Request.SCMessage.Port));
                Logging.LogTransport(string.Format("SSU SessionConfirmedState {0}: Bob address for signature {1}. Port {2}.",
                                                   Session.DebugId, baddr, bport));
                Logging.LogTransport(string.Format("SSU SessionConfirmedState {0}: Relay tag {1}. Signon time {2}.",
                                                   Session.DebugId, Request.SCMessage.RelayTag, (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, (BufLen)Session.SignOnTimeA
                                               );
                writer.Write(sign);

#if LOG_ALL_TRANSPORT
                Logging.LogTransport(string.Format("SessionConfirmedState {0}: sending unfragmented SessionConfirmed. {1} bytes [0x{1:X}].",
                                                   Session.DebugId,
                                                   writer - start - SSUHeader.FIXED_HEADER_SIZE));
#endif

                return(true);
            });
        }
Ejemplo n.º 4
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);
            });
        }
Ejemplo n.º 5
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,
                                             (BufLen)BufUtils.Flip32(context.TimestampA),
                                             (BufLen)BufUtils.Flip32(context.TimestampB));

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

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

            return(writer.ToByteArray());
        }
Ejemplo n.º 6
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), (BufLen)APort,
                                               Request.Address, (BufLen)BufUtils.Flip16((ushort)Session.MyRouterContext.UDPPort),
                                               (BufLen)RelayTag, (BufLen)Session.SignOnTimeB);

                var signstart = new BufLen(writer);
                writer.Write(sign);
                var padding = BufUtils.Get16BytePadding(writer - signstart);
                writer.Write(BufUtils.Random(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);
            });
        }
Ejemplo n.º 7
0
        private void SendFragmentedSessionConfirmed()
        {
            var ri       = new BufLen(Session.MyRouterContext.MyRouterInfo.ToByteArray());
            var rireader = new BufRefLen(ri);

            var datafragments = new List <BufLen>();

            while (rireader.Length > 0)
            {
                datafragments.Add(rireader.ReadBufLen(Math.Min(rireader.Length, 472)));
            }

            for (int i = 0; i < datafragments.Count; ++i)
            {
#if LOG_ALL_TRANSPORT
                Logging.LogTransport(string.Format("SessionConfirmedState {0}: sending fragment {1} of {2}, {3} bytes [0x{3:X}].",
                                                   Session.DebugId,
                                                   i + 1,
                                                   datafragments.Count + 1,
                                                   datafragments[i].Length));
#endif
                SendMessage(
                    SSUHeader.MessageTypes.SessionConfirmed,
                    Session.MACKey,
                    Session.SharedKey,
                    (start, writer) =>
                {
                    writer.Write8((byte)((i << 4) + datafragments.Count + 1));
                    writer.WriteFlip16((ushort)datafragments[i].Length);
                    writer.Write(datafragments[i]);

                    return(true);
                });
            }

            SendMessage(
                SSUHeader.MessageTypes.SessionConfirmed,
                Session.MACKey,
                Session.SharedKey,
                (start, writer) =>
            {
                var frag = datafragments.Count;
                writer.Write8((byte)((frag << 4) + frag + 1));
                writer.WriteFlip16(0);

                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.Random(padding));

                var baddr = new BufLen(Session.RemoteEP.Address.GetAddressBytes());

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

#if LOG_ALL_TRANSPORT
                Logging.LogTransport(string.Format("SessionConfirmedState {0}: sending fragment {1} of {2}, {3} bytes [0x{3:X}].",
                                                   Session.DebugId,
                                                   frag + 1,
                                                   datafragments.Count + 1,
                                                   writer - start - SSUHeader.FIXED_HEADER_SIZE));
#endif

                return(true);
            });
        }
Ejemplo n.º 8
0
        private void SendFragmentedSessionConfirmed()
        {
            var ri       = new BufLen(Session.MyRouterContext.MyRouterInfo.ToByteArray());
            var rireader = new BufRefLen(ri);

            var datafragments = new List <BufLen>();

            while (rireader.Length > 0)
            {
                datafragments.Add(rireader.ReadBufLen(Math.Min(rireader.Length, 472)));
            }

            for (int i = 0; i < datafragments.Count; ++i)
            {
                Logging.LogTransport($"SSU {this}: {Session.RemoteEP} " +
                                     $"sending fragment {i + 1} of {datafragments.Count + 1}, [0x{datafragments[i].Length:X}] bytes.");

                SendMessage(
                    SSUHeader.MessageTypes.SessionConfirmed,
                    Session.MACKey,
                    Session.SharedKey,
                    (start, writer) =>
                {
                    writer.Write8((byte)((i << 4) + datafragments.Count + 1));
                    writer.WriteFlip16((ushort)datafragments[i].Length);
                    writer.Write(datafragments[i]);

                    return(true);
                });
            }

            SendMessage(
                SSUHeader.MessageTypes.SessionConfirmed,
                Session.MACKey,
                Session.SharedKey,
                (start, writer) =>
            {
                var frag = datafragments.Count;
                writer.Write8((byte)((frag << 4) + frag + 1));
                writer.WriteFlip16(0);

                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 sign = I2PSignature.DoSign(Session.MyRouterContext.PrivateSigningKey,
                                               Request.X.Key, Request.Y.Key,
                                               Request.SCMessage.Address, Request.SCMessage.Port,
                                               baddr, BufUtils.Flip16BL((ushort)Session.RemoteEP.Port),
                                               Request.SCMessage.RelayTag, BufUtils.To32BL(Session.SignOnTimeA)
                                               );
                writer.Write(sign);

                Logging.LogTransport($"SSU {this}: {Session.RemoteEP} " +
                                     $"sending fragment {frag + 1} of {datafragments.Count + 1}, [0x{writer - start - SSUHeader.FIXED_HEADER_SIZE:X}] bytes.");

                return(true);
            });
        }
Ejemplo n.º 9
0
        public void Write(BufRefStream dest)
        {
            // Not including options
            var headersize = 4 * 4 + 1 + NACKs.Count * 4 + 1 + 2 + 2;

            // Options
            var optionssize = (Flags & PacketFlags.FROM_INCLUDED) != 0
                ? From.Size : 0;

            optionssize += (Flags & PacketFlags.SIGNATURE_INCLUDED) != 0
                ? From.SigningPublicKey.Certificate.SignatureLength
                : 0;

            optionssize += (Flags & PacketFlags.MAX_PACKET_SIZE_INCLUDED) != 0
                ? 2 : 0;

            optionssize += (Flags & PacketFlags.DELAY_REQUESTED) != 0
                ? 2 : 0;

            var header = new BufLen(new byte[headersize + optionssize]);
            var writer = new BufRefLen(header);

            writer.WriteFlip32(SendStreamId);
            writer.WriteFlip32(ReceiveStreamId);
            writer.WriteFlip32(SequenceNumber);
            writer.WriteFlip32(AckTrhough);

            writer.Write8((byte)NACKs.Count);
            foreach (var nak in NACKs)
            {
                writer.WriteFlip32(nak);
            }

            writer.Write8(ResendDelay);

            writer.WriteFlip16((ushort)Flags);
            writer.WriteFlip16((ushort)optionssize);

            // Options order
            // DELAY_REQUESTED
            // FROM_INCLUDED
            if ((Flags & PacketFlags.FROM_INCLUDED) != 0)
            {
                writer.Write(From.ToByteArray());
            }
            // MAX_PACKET_SIZE_INCLUDED
            if ((Flags & PacketFlags.MAX_PACKET_SIZE_INCLUDED) != 0)
            {
                writer.WriteFlip16(MTU);
            }
            // OFFLINE_SIGNATURE
            // SIGNATURE_INCLUDED
            if ((Flags & PacketFlags.SIGNATURE_INCLUDED) != 0)
            {
                writer.Write(I2PSignature.DoSign(SigningKey, header));
            }

#if DEBUG
            if (writer.Length != 0)
            {
                throw new InvalidOperationException("StreamingPacket Write buffer size error");
            }
#endif

            dest.Write((BufRefLen)header);
            dest.Write((BufRefLen)Payload);
        }