Ejemplo n.º 1
0
 public override void Write(BufRefStream dest)
 {
     dest.Write((BufRefLen)BufUtils.Flip16BL(SessionId));
     dest.Write(TwentyBytes);
     PrivateKey.Write(dest);
     Leases.Write(dest);
 }
Ejemplo n.º 2
0
        public PeerTest(BufLen nonce, IPAddress aliceip, int aliceport, BufLen introkey)
        {
            TestNonce = nonce;
            var ab = aliceip.GetAddressBytes();

            AliceIPAddrSize = (BufLen)(byte)ab.Length;
            AliceIPAddr     = new BufLen(ab);
            AlicePort       = BufUtils.Flip16BL((ushort)aliceport);
            IntroKey        = introkey;
        }
Ejemplo n.º 3
0
        protected MACHealth VerifyMAC(SSUHeader header, BufLen key)
        {
            var macdata = new BufLen[] {
                header.MACDataBuf,
                header.IV,
                BufUtils.Flip16BL((ushort)((ushort)header.MACDataBuf.Length ^ I2PConstants.SSU_PROTOCOL_VERSION))
            };
            var recvhash = I2PHMACMD5Digest.Generate(macdata, key, MACBuf);
            var ok       = header.MAC.Equals(recvhash);

            if (ok)
            {
                IntroMACsReceived = 0;
            }
            else
            {
                DebugUtils.LogDebug(() => string.Format("SSU {0}: {1} Current MAC check fail. Payload {2} bytes. ",
                                                        this, Session.DebugId, header.MACDataBuf.Length));

                if ((int)DebugUtils.LogLevel <= (int)DebugUtils.LogLevels.Debug)
                {
                    if (Session.IntroKey != null)
                    {
                        var recvhashi = I2PHMACMD5Digest.Generate(macdata, new BufLen(Session.IntroKey), MACBuf);
                        var oki       = header.MAC.Equals(recvhashi);
                        DebugUtils.Log("SSU " + this.ToString() + ": " + Session.DebugId + ". " +
                                       "Session Intro key match: " + oki.ToString());
                    }
                }

                var recvhash2 = I2PHMACMD5Digest.Generate(macdata, new BufLen(Session.MyRouterContext.IntroKey), MACBuf);
                var ok2       = header.MAC.Equals(recvhash2);
                DebugUtils.LogDebug(() => string.Format("SSU {0}: {1} My intro MAC key match: {3}. Payload {2} bytes. ",
                                                        this, Session.DebugId, header.MACDataBuf.Length, ok2));

                if (ok2)
                {
                    if (++IntroMACsReceived > 5)
                    {
                        var reason = string.Format("SSU {0}: {1}. {2} intro key matches in a row. The other side seems to have started a new session.",
                                                   this, Session.DebugId, IntroMACsReceived);

                        DebugUtils.Log(reason);
                        return(MACHealth.AbandonSession);
                    }

                    return(MACHealth.UseOurIntroKey);
                }
            }

            return(ok ? MACHealth.Match : MACHealth.Missmatch);
        }
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.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.º 5
0
        private SSUState VerifyRemoteSignature()
        {
            var baaddr = new BufLen(AAddr);
            var bbport = BufUtils.Flip16BL((ushort)Session.MyRouterContext.UDPPort);

#if LOG_ALL_TRANSPORT
            DebugUtils.Log(string.Format("SSU SessionCreatedState {0}: X for signature {1}.",
                                         Session.DebugId, Request.X));
            DebugUtils.Log(string.Format("SSU SessionCreatedState {0}: Y for signature {1}.",
                                         Session.DebugId, Y.Key));
            DebugUtils.Log(string.Format("SSU SessionCreatedState {0}: Alice address for signature {1}. Port {2}.",
                                         Session.DebugId, baaddr, (BufLen)APort));
            DebugUtils.Log(string.Format("SSU SessionCreatedState {0}: Bob address for signature {1}. Port {2}.",
                                         Session.DebugId, Request.Address, bbport));
            DebugUtils.Log(string.Format("SSU SessionCreatedState {0}: Relay tag {1}. Signon time {2}.",
                                         Session.DebugId, (BufLen)RelayTag, (BufLen)ASignonTime));
#endif

            var signdata = new BufLen[] {
                Request.X, Y.Key,
                baaddr, (BufLen)APort,
                Request.Address, bbport,
                (BufLen)RelayTag, (BufLen)ASignonTime
            };
            var ok = I2PSignature.DoVerify(Session.RemoteRouter.SigningPublicKey, ASign, signdata);
#if LOG_ALL_TRANSPORT
            DebugUtils.Log("SSU SessionCreatedState " + Session.DebugId + ": " +
                           Session.RemoteRouter.Certificate.SignatureType.ToString() +
                           " signature check: " + ok.ToString());
#endif
            if (!ok)
            {
                throw new SignatureCheckFailureException("SSU SessionCreatedState recv sig check failure");
            }

            DebugUtils.Log("SSU SessionCreatedState: Session " + Session.DebugId + " established. Moving to Established state.");
            var next = new EstablishedState(Session);

            Session.ReportConnectionEstablished();

            if (NetDb.Inst != null)
            {
                NetDb.Inst.Statistics.SuccessfulConnect(Session.RemoteRouter.IdentHash);
            }
            return(next);
        }
Ejemplo n.º 6
0
        protected MACHealth VerifyMAC(SSUHeader header, BufLen key)
        {
            var macdata = new BufLen[] {
                header.MACDataBuf,
                header.IV,
                BufUtils.Flip16BL((ushort)((ushort)header.MACDataBuf.Length ^ I2PConstants.SSU_PROTOCOL_VERSION))
            };

            var recvhash = I2PHMACMD5Digest.Generate(macdata, key, MACBuf);
            var ok       = header.MAC.Equals(recvhash);
            var result   = ok ? MACHealth.Match : MACHealth.Missmatch;

            if (!ok)
            {
                if (++ConsecutiveMACCheckFailures > 3)
                {
                    result = MACHealth.AbandonSession;
                }
            }
            else
            {
                ConsecutiveMACCheckFailures = 0;
            }

#if DEBUG
            if (result != MACHealth.Match)
            {
                Logging.LogTransport($"SSU {this}: VerifyMAC {result} [{ConsecutiveMACCheckFailures}] {key}");
            }
            else
            {
                Logging.LogDebugData($"SSU {this}: VerifyMAC {result} [{ConsecutiveMACCheckFailures}] {key}");
            }
#endif

#if DEBUG && SSU_TRACK_OLD_MAC_KEYS
            if (result != MACHealth.Match)
            {
                result = CheckOldKeys(header, macdata, MACBuf, result);
            }
#endif
            return(result);
        }
Ejemplo n.º 7
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.º 8
0
        private SSUState VerifyRemoteSignature()
        {
            var baaddr = new BufLen(AAddr);
            var bbport = BufUtils.Flip16BL((ushort)Session.MyRouterContext.UDPPort);

#if LOG_MUCH_TRANSPORT
            Logging.LogTransport($"SSU {this}: X for signature {Request.X}.");
            Logging.LogTransport($"SSU {this}: Y for signature {Y.Key}.");
            Logging.LogTransport($"SSU {this}: Alice address for signature {baaddr}. Port {(BufLen)APort}.");
            Logging.LogTransport($"SSU {this}: Bob address for signature {Request.Address}. Port {bbport}.");
            Logging.LogTransport($"SSU {this}: Relay tag {(BufLen)RelayTag}. Signon time {(BufLen)ASignonTime}.");
#endif

            var signdata = new BufLen[] {
                Request.X, Y.Key,
                baaddr, BufUtils.To16BL(APort),
                Request.Address, bbport,
                BufUtils.To32BL(RelayTag), BufUtils.To32BL(ASignonTime)
            };

            var ok = I2PSignature.DoVerify(Session.RemoteRouter.SigningPublicKey, ASign, signdata);

            Logging.LogTransport($"SSU SessionCreatedState {Session.DebugId}: " +
                                 $"{Session.RemoteRouter.Certificate.SignatureType} " +
                                 $"signature check: {ok}");

            if (!ok)
            {
                throw new SignatureCheckFailureException("SSU SessionCreatedState recv sig check failure");
            }

            Logging.LogTransport("SSU SessionCreatedState: Session " + Session.DebugId + " established. Moving to Established state.");
            var next = new EstablishedState(Session);

            Session.ReportConnectionEstablished();

            NetDb.Inst.Statistics.SuccessfulConnect(Session.RemoteRouter.IdentHash);
            return(next);
        }
Ejemplo n.º 9
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);
            });
        }
Ejemplo n.º 10
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.º 11
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);
        }
Ejemplo n.º 12
0
        public override SSUState HandleMessage(SSUHeader header, BufRefLen reader)
        {
            var tstime = SSUHost.SSUDateTime(header.TimeStamp);

            if (header.MessageType != SSUHeader.MessageTypes.SessionCreated)
            {
#if LOG_ALL_TRANSPORT
                Logging.LogTransport("SSU SessionRequestState: Received unexpected message " + tstime.ToString() + " : " + header.Flag.ToString());
#endif
                return(this);
            }

            SCMessage = new SessionCreated(reader, Session.RemoteRouter.Certificate);

            Session.RelayTag = SCMessage.RelayTag;

            Y = new I2PPublicKey((BufRefLen)SCMessage.Y, Session.RemoteRouter.Certificate);
            BufUtils.DHI2PToSessionAndMAC(out Session.SharedKey, out Session.MACKey,
                                          Y.ToBigInteger().ModPow(PrivateKey.ToBigInteger(), I2PConstants.ElGamalP));

            var    ipaddr = new IPAddress(SCMessage.Address.ToByteArray());
            ushort port   = SCMessage.Port.PeekFlip16(0);
            Session.SignOnTimeB = SCMessage.SignOnTime.Peek32(0);
            var btime = SSUHost.SSUDateTime(BufUtils.Flip32(Session.SignOnTimeB));

#if LOG_ALL_TRANSPORT
            Logging.LogTransport("SSU SessionRequestState " + Session.DebugId + " : Received SessionCreated. " + tstime.ToString() + " : " + btime.ToString());
#endif
            Session.Host.ReportedAddress(ipaddr);

            if (!I2PSignature.SupportedSignatureType(Session.RemoteRouter.Certificate.SignatureType))
            {
                throw new SignatureCheckFailureException("SSU SessionRequestState " + Session.DebugId + " : " +
                                                         "Received non supported signature type: " +
                                                         Session.RemoteRouter.Certificate.SignatureType.ToString());
            }

            var cipher = new CbcBlockCipher(new AesEngine());
            cipher.Init(false, Session.SharedKey.ToParametersWithIV(header.IV));
            cipher.ProcessBytes(SCMessage.SignatureEncrBuf);

            var baddr = new BufLen(Session.RemoteEP.Address.GetAddressBytes());
            var sign  = new I2PSignature((BufRefLen)SCMessage.Signature, Session.RemoteRouter.Certificate);

            var sok = I2PSignature.DoVerify(
                Session.RemoteRouter.SigningPublicKey, sign,
                X.Key, Y.Key,
                SCMessage.Address, SCMessage.Port,
                baddr, BufUtils.Flip16BL((ushort)Session.RemoteEP.Port),
                SCMessage.RelayTag, SCMessage.SignOnTime);

#if LOG_ALL_TRANSPORT
            Logging.LogTransport("SSU SessionRequestState: Signature check: " + sok.ToString() + ". " + Session.RemoteRouter.Certificate.SignatureType.ToString());
#endif
            if (!sok)
            {
                throw new SignatureCheckFailureException("SSU SessionRequestState " + Session.DebugId + ": Received SessionCreated signature check failed." +
                                                         Session.RemoteRouter.Certificate.ToString());
            }

            var relaytag = SCMessage.RelayTag.PeekFlip32(0);
            if (relaytag != 0)
            {
                Session.Host.IntroductionRelayOffered(
                    new IntroducerInfo(
                        Session.RemoteEP.Address,
                        (ushort)Session.RemoteEP.Port,
                        Session.IntroKey, relaytag));
            }

            Logging.LogTransport("SSU SessionRequestState: Session " + Session.DebugId + " created. Moving to SessionConfirmedState.");
            Session.ReportConnectionEstablished();
            return(new SessionConfirmedState(Session, this));
        }
Ejemplo n.º 13
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.º 14
0
 public override void Write(BufRefStream dest)
 {
     dest.Write((BufRefLen)BufUtils.Flip16BL(SessionId));
 }