Пример #1
0
        protected override void DHNegotiate()
        {
#if LOG_MUCH_TRANSPORT
            Logging.LogTransport("1 +" + TransportInstance.ToString() + "+");
#endif

            DHHandshakeContext dhcontext = new DHHandshakeContext(this);
            dhcontext.RemoteRI   = NTCPContext.RemoteRouterIdentity;
            dhcontext.RunContext = NTCPContext;

            SendRaw(SessionRequest.Send(dhcontext));
            SessionCreated.Receive(dhcontext, BlockReceive(304));
#if LOG_MUCH_TRANSPORT
            Logging.LogTransport("2 +" + TransportInstance.ToString() + "+");
#endif

            SendRaw(SessionConfirmA.Send(dhcontext));
            SessionConfirmB.Receive(dhcontext, NTCPContext.RemoteRouterIdentity);

#if LOG_MUCH_TRANSPORT
            Logging.LogTransport("3 +" + TransportInstance.ToString() + "+");
#endif

            NTCPContext.SessionKey = dhcontext.SessionKey;
            NTCPContext.Encryptor  = dhcontext.Encryptor;
            NTCPContext.Dectryptor = dhcontext.Dectryptor;
        }
Пример #2
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);
        }
Пример #3
0
        protected override void DHNegotiate()
        {
#if LOG_MUCH_TRANSPORT
            Logging.LogTransport("X1X +" + TransportInstance.ToString() + "+");
#endif

            DHHandshakeContext dhcontext = new DHHandshakeContext(this);
            dhcontext.RunContext = NTCPContext;

            SessionRequest.Receive(dhcontext, BlockReceive(288));
#if LOG_MUCH_TRANSPORT
            Logging.LogTransport("X2X +" + TransportInstance.ToString() + "+");
#endif

            SendRaw(SessionCreated.Send(dhcontext));

            SessionConfirmA.Receive(dhcontext, BlockReceiveAtLeast(448, 2048));
#if LOG_MUCH_TRANSPORT
            Logging.LogTransport("X3X +" + TransportInstance.ToString() + "+");
#endif

            SendRaw(SessionConfirmB.Send(dhcontext));

#if LOG_MUCH_TRANSPORT
            Logging.LogTransport("X4X +" + TransportInstance.ToString() + "+");
#endif
            NetDb.Inst.Statistics.SuccessfulConnect(NTCPContext.RemoteRouterIdentity.IdentHash);

            NTCPContext.SessionKey = dhcontext.SessionKey;
            NTCPContext.Encryptor  = dhcontext.Encryptor;
            NTCPContext.Dectryptor = dhcontext.Dectryptor;

            RouterContext.Inst.IsFirewalled = false;
        }
Пример #4
0
        internal static void Receive(DHHandshakeContext context, I2PKeysAndCert ri)
        {
            var responselength = ri.Certificate.SignatureLength;

            responselength += BufUtils.Get16BytePadding(responselength);

            var data = context.Client.BlockReceive(responselength);

            context.Dectryptor.ProcessBytes(data);

            var signature = new I2PSignature(new BufRefLen(data), context.RemoteRI.Certificate);

            if (!I2PSignature.SupportedSignatureType(context.RemoteRI.Certificate.SignatureType))
            {
                throw new SignatureCheckFailureException("NTCP SessionConfirmB recv not supported signature type: " +
                                                         context.RemoteRI.Certificate.SignatureType.ToString());
            }

            var ok = I2PSignature.DoVerify(context.RemoteRI.SigningPublicKey, signature,
                                           context.X.Key,
                                           context.Y.Key,
                                           RouterContext.Inst.MyRouterIdentity.IdentHash.Hash,
                                           BufUtils.Flip32BL(context.TimestampA),
                                           BufUtils.Flip32BL(context.TimestampB));

            Logging.LogTransport($"SessionConfirmB: {context.RemoteRI.Certificate.SignatureType} signature check: {ok}");

            if (!ok)
            {
                throw new SignatureCheckFailureException("NTCP SessionConfirmB recv sig check failure");
            }
        }
Пример #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);
        }
Пример #6
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);
        }
Пример #7
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());
        }
Пример #8
0
        internal static void Receive(DHHandshakeContext context, BufLen data)
        {
            var reader = new BufRefLen(data);

            context.XBuf    = reader.ReadBufLen(256);
            context.X       = new I2PPublicKey(new BufRefLen(context.XBuf), I2PKeyType.DefaultAsymetricKeyCert);
            context.HXxorHI = reader.ReadBufLen(32);

            var HXxorHI = I2PHashSHA256.GetHash(context.XBuf);

            var idenhash = RouterContext.Inst.MyRouterIdentity.IdentHash;

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

            if (!context.HXxorHI.Equals(HXxorHI))
            {
                throw new ChecksumFailureException("NTCP Incoming connection from " +
                                                   context.Client.DebugId + " HXxorHI check failed.");
            }
        }
Пример #9
0
        internal static void Receive(DHHandshakeContext context, BufLen data)
        {
            var reader = new BufRefLen(data);

            context.Y    = new I2PPublicKey(reader, context.RemoteRI.Certificate);
            context.YBuf = context.Y.Key;

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

            context.SessionKey = new I2PSessionKey(sharedkey);

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

            var enciv = new BufLen(context.HXxorHI.BaseArray, context.HXxorHI.Length - 16, 16);
            var deciv = new BufLen(context.YBuf, context.YBuf.Length - 16, 16);

            context.Encryptor = new CbcBlockCipher(new AesEngine());
            context.Encryptor.Init(true, new ParametersWithIV(key, enciv.BaseArray, enciv.BaseArrayOffset, enciv.Length));

            context.Dectryptor = new CbcBlockCipher(new AesEngine());
            context.Dectryptor.Init(false, new ParametersWithIV(key, deciv.BaseArray, deciv.BaseArrayOffset, deciv.Length));

            var encrbuf = new BufLen(reader, 0, 32 + 4 + 12);

            context.Dectryptor.ProcessBytes(encrbuf);

            context.HXY        = reader.ReadBufLen(32);
            context.TimestampB = reader.ReadFlip32();

            var checkhash = I2PHashSHA256.GetHash(context.XBuf, context.YBuf);

            if (!context.HXY.Equals(checkhash))
            {
                throw new ChecksumFailureException("NTCP SessionCreated received HXY check failed!");
            }
        }
Пример #10
0
        internal static void Receive(DHHandshakeContext context, BufLen datastart)
        {
            var origbuf = new BufRefLen(datastart);
            var reader  = new BufRefLen(datastart);

            context.Dectryptor.ProcessBytes(datastart);

            var rilen = reader.ReadFlip16();
            var ribuf = reader.ReadBufRefLen(rilen);

            context.TimestampA = reader.ReadFlip32();

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

            context.RemoteRI = new I2PRouterIdentity(ribuf);
            context.RunContext.RemoteRouterIdentity = context.RemoteRI;

            var sizeofpayload = 2 + rilen + 4 + context.RemoteRI.Certificate.SignatureLength;
            var paddingsize   = BufUtils.Get16BytePadding(sizeofpayload);

            reader.Seek(paddingsize);

            var sigstart = new BufLen(reader, 0, context.RemoteRI.Certificate.SignatureLength);

            var needbytes = 2 + context.RemoteRI.Certificate.RouterIdentitySize + 4 + context.RemoteRI.Certificate.SignatureLength;

            needbytes += BufUtils.Get16BytePadding(needbytes);

            var writer   = new BufRef(origbuf, origbuf.Length);
            var gotbytes = writer - origbuf;

            if (gotbytes < needbytes)
            {
                Logging.LogDebugData($"SessionConfirmA recv not enough data: {datastart.Length}. I want {needbytes} bytes.");

                var buf = context.Client.BlockReceive(needbytes - gotbytes);
                writer.Write(buf);
            }

            if (needbytes - datastart.Length > 0)
            {
                context.Dectryptor.ProcessBytes(new BufLen(datastart, datastart.Length, needbytes - datastart.Length));
            }

            var signature = new I2PSignature(new BufRefLen(sigstart), context.RemoteRI.Certificate);

            if (!I2PSignature.SupportedSignatureType(context.RemoteRI.Certificate.SignatureType))
            {
                throw new SignatureCheckFailureException("NTCP SessionConfirmA recv not supported signature type: " +
                                                         context.RemoteRI.Certificate.SignatureType.ToString());
            }

            var sigok = I2PSignature.DoVerify(
                context.RemoteRI.SigningPublicKey,
                signature,
                context.XBuf,
                context.YBuf,
                RouterContext.Inst.MyRouterIdentity.IdentHash.Hash,
                new BufLen(BufUtils.Flip32B(context.TimestampA)),
                new BufLen(BufUtils.Flip32B(context.TimestampB))
                );

            Logging.LogTransport($"SessionConfirmA recv: {context.RemoteRI.Certificate.SignatureType} " +
                                 $"signature check: {sigok}.");

            if (!sigok)
            {
                throw new SignatureCheckFailureException("NTCP SessionConfirmA recv signature check fail");
            }
        }