Пример #1
0
        private void HandleGatewayTunnelRequest(
            II2NPHeader msg,
            IEnumerable <AesEGBuildRequestRecord> records,
            EGBuildRequestRecord myrec,
            BuildRequestRecord drec)
        {
            var tunnel   = new GatewayTunnel(drec);
            var replykey = drec.ReplyKey.Key.Clone();
            var replyiv  = drec.ReplyIV.Clone();

            tunnel.EstablishedTime.SetNow();

            var doaccept = AcceptingTunnels(drec);

            var response = doaccept ? BuildResponseRecord.RequestResponse.Accept : BuildResponseRecord.DefaultErrorReply;

            Logging.LogDebug(() => string.Format("HandleGatewayTunnelRequest {3}: {0} Gateway tunnel request: {1} for tunnel id {2}.",
                                                 tunnel.Destination.Id32Short,
                                                 response,
                                                 tunnel.ReceiveTunnelId,
                                                 tunnel.TunnelDebugTrace));
            TunnelProvider.UpdateTunnelBuildReply(records, myrec, replykey, replyiv, response);

            if (response == BuildResponseRecord.RequestResponse.Accept)
            {
                AddTunnel(tunnel);
                TunnelMgr.AddExternalTunnel(tunnel);
                AcceptedTunnelBuildRequest(drec);
            }
            TransportProvider.Send(tunnel.Destination, msg.Message);
        }
Пример #2
0
        internal void HandleTunnelBuildRecords(
            II2NPHeader msg,
            IEnumerable <AesEGBuildRequestRecord> records,
            EGBuildRequestRecord myrec,
            BuildRequestRecord drec)
        {
            if (drec.ToAnyone)
            {
                // Im outbound endpoint
                Logging.LogDebug("HandleTunnelBuildRecords: Outbound endpoint request " + drec.ToString());
                HandleEndpointTunnelRequest(msg, records, myrec, drec);
                return;
            }

            if (drec.FromAnyone)
            {
                // Im inbound gateway
                Logging.LogDebug("HandleTunnelBuildRecords: Inbound gateway request " + drec.ToString());
                HandleGatewayTunnelRequest(msg, records, myrec, drec);
                return;
            }

            if (drec.NextIdent != RouterContext.Inst.MyRouterIdentity.IdentHash)
            {
                // Im passthrough tunnel
                Logging.LogDebug("HandleTunnelBuildRecords: Passthrough tunnel request " + drec.ToString());
                HandlePassthroughTunnelRequest(msg, records, myrec, drec);
                return;
            }

            throw new NotSupportedException();
        }
        private void HandleEndpointTunnelRequest(
            II2NPHeader msg,
            IEnumerable <AesEGBuildRequestRecord> records,
            EGBuildRequestRecord myrec,
            BuildRequestRecord drec)
        {
            var tunnel   = new EndpointTunnel(drec);
            var replykey = drec.ReplyKey.Key.Clone();
            var replyiv  = drec.ReplyIV.Clone();

            tunnel.EstablishedTime.SetNow();

            var doaccept = AcceptingTunnels(drec);

            var response = doaccept ? BuildResponseRecord.RequestResponse.Accept : BuildResponseRecord.DefaultErrorReply;

            DebugUtils.LogDebug(() => string.Format("HandleEndpointTunnelRequest {3}: {0} Endpoint tunnel request: {1} for tunnel id {2}.",
                                                    tunnel.Destination.Id32Short,
                                                    response,
                                                    tunnel.ReceiveTunnelId,
                                                    tunnel.TunnelDebugTrace));
            TunnelProvider.UpdateTunnelBuildReply(records, myrec, replykey, replyiv, response);

            var responsemessage = new VariableTunnelBuildReplyMessage(records.Select(r => new BuildResponseRecord(r)));
            var buildreplymsg   = new TunnelGatewayMessage(responsemessage.GetHeader16(tunnel.ResponseMessageId), tunnel.ResponseTunnelId);

            if (response == BuildResponseRecord.RequestResponse.Accept)
            {
                AddTunnel(tunnel);
                TunnelMgr.AddExternalTunnel(tunnel);
                AcceptedTunnelBuildRequest(drec);
            }
            TransportProvider.Send(tunnel.Destination, buildreplymsg);
        }
Пример #4
0
        public TunnelBuildRequestDecrypt(
            IEnumerable <AesEGBuildRequestRecord> records,
            I2PIdentHash me,
            I2PPrivateKey key)
        {
            RecordsField = records;
            Me           = me;
            Key          = key;

            ToMeField = RecordsField.FirstOrDefault(rec => Me.Hash16 == rec.ToPeer16);

            if (ToMeField != null)
            {
                MyRecord        = new EGBuildRequestRecord(ToMeField);
                DecryptedRecord = MyRecord.Decrypt(key);
            }
        }
Пример #5
0
        public static VariableTunnelBuildMessage BuildOutboundTunnel(
            TunnelInfo setup,
            I2PIdentHash replyaddr, I2PTunnelId replytunnel,
            uint replymessageid)
        {
            byte usehops = (byte)(setup.Hops.Count > 5 ? 8 : 5);
            //byte usehops = 7; // 8 makes the response "TunnelBuildReply"
            var result = new VariableTunnelBuildMessage(usehops);

            // Hop sort order
            var requests = new List <BuildRequestRecord>();

            for (int i = 0; i < setup.Hops.Count; ++i)
            {
                // Hop order: Our out dest -> Endpoint
                var endpoint = i == setup.Hops.Count - 1;
                var gateway  = i == 0;

                var rec = new BuildRequestRecord();

                rec.Data.Randomize();
                rec.Flag = 0;

                var hop = setup.Hops[i];

                rec.OurIdent      = hop.Peer.IdentHash;
                rec.ReceiveTunnel = hop.TunnelId;

                if (!endpoint)
                {
                    var nexthop = setup.Hops[i + 1];

                    rec.NextIdent  = nexthop.Peer.IdentHash;
                    rec.NextTunnel = nexthop.TunnelId;
                }
                else
                {
                    rec.SendMessageId = replymessageid;

                    rec.NextIdent  = replyaddr;
                    rec.NextTunnel = replytunnel;
                }

                rec.RequestTime = DateTime.UtcNow;
                rec.ToAnyone    = endpoint;

                hop.LayerKey = new I2PSessionKey(rec.LayerKey.Clone());
                hop.IVKey    = new I2PSessionKey(rec.IVKey.Clone());

                requests.Add(rec);

#if LOG_ALL_TUNNEL_TRANSFER
                Logging.Log(rec.ToString());
#endif
            }

            // Physical record sort order
            var order = new List <AesEGBuildRequestRecord>(result.Records);
            order.Shuffle();

            // Scramble the rest
            for (int i = setup.Hops.Count; i < usehops; ++i)
            {
                order[i].Data.Randomize();
            }

            // ElGamal encrypt all of the non random records
            // and place them in shuffled order.
            for (int i = 0; i < setup.Hops.Count; ++i)
            {
                var hop   = setup.Hops[i];
                var egrec = new EGBuildRequestRecord(order[i].Data, requests[i], hop.Peer.IdentHash, hop.Peer.PublicKey);
            }

            var cipher = new CbcBlockCipher(new AesEngine());

            // Dont Aes the first destination
            for (int i = setup.Hops.Count - 2; i >= 0; --i)
            {
                var prevhop = requests[i];

                cipher.Init(false, prevhop.ReplyKeyBuf.ToParametersWithIV(prevhop.ReplyIV));

                for (int j = i + 1; j < setup.Hops.Count; ++j)
                {
                    cipher.Reset();
                    cipher.ProcessBytes(order[j].Data);
                }
            }

            for (int i = 0; i < setup.Hops.Count; ++i)
            {
                setup.Hops[i].ReplyProcessing = new ReplyProcessingInfo()
                {
                    BuildRequestIndex = result.Records.IndexOf(order[i]),
                    ReplyIV           = requests[i].ReplyIV.Clone(),
                    ReplyKey          = new I2PSessionKey(requests[i].ReplyKeyBuf.Clone())
                };
            }

            return(result);
        }
Пример #6
0
        public static VariableTunnelBuildMessage BuildInboundTunnel(
            TunnelInfo setup)
        {
            byte usehops = (byte)(setup.Hops.Count > 5 ? 8 : 5);
            var  result  = new VariableTunnelBuildMessage(usehops);

            // Hop sort order
            var requests = new List <BuildRequestRecord>();

            for (int i = 0; i < setup.Hops.Count; ++i)
            {
                // Hop order: GW -> us
                var endpoint = i == setup.Hops.Count - 1;
                var gateway  = i == 0;

                var rec = new BuildRequestRecord();

                rec.Data.Randomize();
                rec.Flag = 0;

                var hop = setup.Hops[i];

                rec.OurIdent      = hop.Peer.IdentHash;
                rec.ReceiveTunnel = hop.TunnelId;

                if (!endpoint)
                {
                    var nexthop = setup.Hops[i + 1];

                    rec.NextIdent  = nexthop.Peer.IdentHash;
                    rec.NextTunnel = nexthop.TunnelId;
                }
                else
                {
                    // Used to identify the record as the last in an inbound tunnel to us
                    rec.NextIdent  = hop.Peer.IdentHash;
                    rec.NextTunnel = hop.TunnelId;
                }

                rec.RequestTime = DateTime.UtcNow;
                rec.FromAnyone  = gateway;

                hop.LayerKey = new I2PSessionKey(rec.LayerKey.Clone());
                hop.IVKey    = new I2PSessionKey(rec.IVKey.Clone());

                requests.Add(rec);

#if LOG_ALL_TUNNEL_TRANSFER
                Logging.Log(rec.ToString());
#endif
            }

            // Physical record sort order
            var order = new List <AesEGBuildRequestRecord>(result.Records);
            order.Shuffle();

            // Scramble the rest
            for (int i = setup.Hops.Count; i < usehops; ++i)
            {
                order[i].Data.Randomize();
            }

            // ElGamal encrypt all of the non random records
            // and place them in shuffled order.
            for (int i = 0; i < setup.Hops.Count; ++i)
            {
                var hop   = setup.Hops[i];
                var egrec = new EGBuildRequestRecord(order[i].Data, requests[i], hop.Peer.IdentHash, hop.Peer.PublicKey);
            }

            var cipher = new BufferedBlockCipher(new CbcBlockCipher(new AesEngine()));

            // Dont Aes the first block
            for (int i = setup.Hops.Count - 2; i >= 0; --i)
            {
                var prevhop = requests[i];

                cipher.Init(false, new ParametersWithIV(new KeyParameter(prevhop.ReplyKey.ToByteArray()), prevhop.ReplyIV.ToByteArray()));

                for (int j = i + 1; j < setup.Hops.Count; ++j)
                {
                    cipher.Reset();
                    order[j].Process(cipher);
                }
            }

            for (int i = 0; i < setup.Hops.Count; ++i)
            {
                setup.Hops[i].ReplyProcessing = new ReplyProcessingInfo()
                {
                    BuildRequestIndex = result.Records.IndexOf(order[i]),
                    ReplyIV           = requests[i].ReplyIV.Clone(),
                    ReplyKey          = new I2PSessionKey(requests[i].ReplyKeyBuf.Clone())
                };
            }

            return(result);
        }