protected override void DHNegotiate() { #if LOG_ALL_TRANSPORT DebugUtils.Log("X1X +" + TransportInstance.ToString() + "+"); #endif DHHandshakeContext dhcontext = new DHHandshakeContext(this); dhcontext.RunContext = NTCPContext; SessionRequest.Receive(dhcontext, BlockReceive(288)); #if LOG_ALL_TRANSPORT DebugUtils.Log("X2X +" + TransportInstance.ToString() + "+"); #endif SendRaw(SessionCreated.Send(dhcontext)); SessionConfirmA.Receive(dhcontext, BlockReceiveAtLeast(448, 2048)); #if LOG_ALL_TRANSPORT DebugUtils.Log("X3X +" + TransportInstance.ToString() + "+"); #endif SendRaw(SessionConfirmB.Send(dhcontext)); #if LOG_ALL_TRANSPORT DebugUtils.Log("X4X +" + TransportInstance.ToString() + "+"); #endif NetDb.Inst.Statistics.SuccessfulConnect(NTCPContext.RemoteRouterIdentity.IdentHash); NTCPContext.SessionKey = dhcontext.SessionKey; NTCPContext.Encryptor = dhcontext.Encryptor; NTCPContext.Dectryptor = dhcontext.Dectryptor; }
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); }
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)); #if LOG_ALL_TRANSPORT DebugUtils.Log("SessionConfirmB: " + context.RemoteRI.Certificate.SignatureType.ToString() + " signature check: " + ok.ToString()); #endif if (!ok) { throw new SignatureCheckFailureException("NTCP SessionConfirmB recv sig check failure"); } }
protected override void DHNegotiate() { #if LOG_ALL_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_ALL_TRANSPORT Logging.LogTransport("2 +" + TransportInstance.ToString() + "+"); #endif SendRaw(SessionConfirmA.Send(dhcontext)); SessionConfirmB.Receive(dhcontext, NTCPContext.RemoteRouterIdentity); #if LOG_ALL_TRANSPORT Logging.LogTransport("3 +" + TransportInstance.ToString() + "+"); #endif NTCPContext.SessionKey = dhcontext.SessionKey; NTCPContext.Encryptor = dhcontext.Encryptor; NTCPContext.Dectryptor = dhcontext.Dectryptor; }
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); }
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.Random(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); }
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()); }
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."); } }
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!"); } }
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(); #if LOG_ALL_TRANSPORT DebugUtils.Log("SessionConfirmA recv TimestampA: " + (I2PDate.RefDate.AddSeconds(context.TimestampA).ToString())); DebugUtils.Log("SessionConfirmA recv TimestampB: " + (I2PDate.RefDate.AddSeconds(context.TimestampB).ToString())); #endif 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) { #if LOG_ALL_TRANSPORT DebugUtils.Log("SessionConfirmA recv not enough data: " + datastart.Length.ToString() + ". I want " + needbytes.ToString() + " bytes."); #endif 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)) ); #if LOG_ALL_TRANSPORT DebugUtils.Log("SessionConfirmA recv: " + context.RemoteRI.Certificate.SignatureType.ToString() + " signature check: " + sigok.ToString() + "."); #endif if (!sigok) { throw new SignatureCheckFailureException("NTCP SessionConfirmA recv signature check fail"); } }