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"); } }
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"); } }
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)); }