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"); } }
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); }
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); }
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)); }
internal override I2CPState MessageReceived(I2CPMessage msg) { try { switch (msg) { case CreateSessionMessage csm: Logging.LogDebug($"{this}: Received message {csm}."); var signok = I2PSignature.DoVerify( csm.Config.Destination.SigningPublicKey, csm.Config.Signature, csm.Config.SignedBuf); if (!signok) { Logging.LogWarning($"{this} CreateSessionMessage: Signature check failed."); Session.Send(new SessionStatusMessage(0, SessionStates.Invalid)); return(this); } var newdest = Router.CreateDestination( csm.Config.Destination, null, !csm.Config.DontPublishLeaseSet, out var alreadyrunning); if (alreadyrunning || newdest is null) { Logging.LogWarning($"{this}: Destination already running. {csm}"); Session.Send(new SessionStatusMessage(0, SessionStates.Refused)); return(this); } var newsession = Session.GenerateNewSessionId(); newsession.MyDestination = newdest; newsession.Config = csm.Config; UpdateConfiguration(newsession, csm.Config); Session.AttachDestination(newsession.MyDestination); Logging.LogDebug($"{this}: Creating session {newsession.SessionId}."); var reply = new SessionStatusMessage(newsession.SessionId, SessionStates.Created); Session.Send(reply); Session.SendPendingLeaseUpdates(true); break; case ReconfigureSessionMessage rcm: var rcms = Session.SessionIds[rcm.SessionId]; rcms.Config = rcm.Config; UpdateConfiguration(rcms, rcms.Config); break; case CreateLeaseSetMessage clsm: Logging.LogDebug($"{this}: {clsm} {clsm.PrivateKey}"); var s = Session.SessionIds[clsm.SessionId]; s.PrivateKey = clsm.PrivateKey; s.MyDestination.TemporaryPrivateKey = clsm.PrivateKey; s.LeaseInfo = clsm.Info; s.MyDestination.SignedLeases = clsm.Leases; Session.SendPendingLeaseUpdates(true); break; case DestLookupMessage dlum: Logging.LogDebug($"{this}: {dlum} {dlum.Ident.Id32Short}"); Session .SessionIds .First() .Value .MyDestination .LookupDestination(dlum.Ident, HandleDestinationLookupResult, null); break; case HostLookupMessage hlum: Logging.LogDebug($"{this}: {hlum} {hlum.SessionId} {hlum.RequestId} {hlum.Hash?.Id32Short}"); I2PIdentHash lookuphash; if (hlum.RequestType == HostLookupMessage.HostLookupTypes.HostName) { lookuphash = ParseHostName(hlum); if (lookuphash is null) { Session.Send(new HostReplyMessage( hlum.SessionId, hlum.RequestId, HostLookupResults.Failure)); break; } } else { lookuphash = hlum.Hash; } if (hlum.SessionId == 0xFFFF) { Router.LookupDestination( lookuphash, HandleHostLookupResult, new HostLookupInfo { RequestId = hlum.RequestId, SessionId = hlum.SessionId }); } else { var s2 = Session.SessionIds[hlum.SessionId]; s2.MyDestination.LookupDestination( lookuphash, HandleHostLookupResult, new HostLookupInfo { RequestId = hlum.RequestId, SessionId = hlum.SessionId }); } break; case SendMessageMessage smm: Logging.LogDebugData($"{this}: {smm} {smm.Destination.IdentHash.Id32Short} {smm.Payload}"); SendMessageToDestination( smm.Destination, smm.SessionId, smm.Payload, smm.Nonce); break; case SendMessageExpiresMessage smem: Logging.LogDebugData($"{this}: {smem} {smem.Destination.IdentHash.Id32Short} {(PayloadFormat)smem.Payload[9]} {smem.Payload}"); SendMessageToDestination( smem.Destination, smem.SessionId, smem.Payload, smem.Nonce); break; case DestroySessionMessage dsm: Logging.LogDebug($"{this}: {dsm}"); Session.Send(new SessionStatusMessage(dsm.SessionId, SessionStates.Destroyed)); return(null); default: Logging.LogWarning($"{this}: Unhandled message {msg}"); break; } return(this); } catch (Exception ex) { Logging.LogWarning($"{this} MessageReceived: {msg.MessageType} {ex}"); throw; } }