private void InitializeChannel(IChannel channel, ConnectionDirection connectionDirection, NodeId remoteId = null, string remoteHost = null, int?remotePort = null, INodeStats nodeStats = null) { if (connectionDirection == ConnectionDirection.In) { Metrics.IncomingConnections++; } else { Metrics.OutgoingConnections++; } P2PSession session = new P2PSession( LocalNodeId, remoteId, _localPort, connectionDirection, _serializationService, _synchronizationManager, _nodeStatsProvider, nodeStats, _logManager, channel, _perfService, _blockTree, _transactionPool, _timestamp); if (connectionDirection == ConnectionDirection.Out) { if (_logger.IsTrace) { _logger.Trace($"Initializing {connectionDirection.ToString().ToUpper()} channel{(connectionDirection == ConnectionDirection.Out ? $": {remoteId}@{remoteHost}:{remotePort}" : string.Empty)}"); } // this is the first moment we get confirmed publicKey of remote node in case of outgoing connections session.RemoteNodeId = remoteId; session.RemoteHost = remoteHost; session.RemotePort = remotePort; } SessionCreated?.Invoke(this, new SessionEventArgs(session)); HandshakeRole role = connectionDirection == ConnectionDirection.In ? HandshakeRole.Recipient : HandshakeRole.Initiator; var handshakeHandler = new NettyHandshakeHandler(_encryptionHandshakeService, session, role, remoteId, _logManager); IChannelPipeline pipeline = channel.Pipeline; pipeline.AddLast(new LoggingHandler(connectionDirection.ToString().ToUpper(), DotNetty.Handlers.Logging.LogLevel.TRACE)); pipeline.AddLast("enc-handshake-dec", new LengthFieldBasedFrameDecoder(ByteOrder.BigEndian, ushort.MaxValue, 0, 2, 0, 0, true)); pipeline.AddLast("enc-handshake-handler", handshakeHandler); channel.CloseCompletion.ContinueWith(async x => { if (_logger.IsTrace) { _logger.Trace($"Channel disconnected: {session.RemoteNodeId}"); } await session.DisconnectAsync(DisconnectReason.ClientQuitting, DisconnectType.Remote); SessionClosing?.Invoke(this, new SessionEventArgs(session)); }); }
private void SetSecrets(EncryptionHandshake handshake, HandshakeRole handshakeRole) { byte[] ephemeralSharedSecret = Proxy.EcdhSerialized(handshake.RemoteEphemeralPublicKey.Bytes, handshake.EphemeralPrivateKey.KeyBytes); byte[] nonceHash = Keccak.Compute(Bytes.Concat(handshake.RecipientNonce, handshake.InitiatorNonce)).Bytes; byte[] sharedSecret = Keccak.Compute(Bytes.Concat(ephemeralSharedSecret, nonceHash)).Bytes; byte[] token = Keccak.Compute(sharedSecret).Bytes; byte[] aesSecret = Keccak.Compute(Bytes.Concat(ephemeralSharedSecret, sharedSecret)).Bytes; Array.Clear(sharedSecret, 0, sharedSecret.Length); // TODO: it was passed in the concat for Keccak so not good enough byte[] macSecret = Keccak.Compute(Bytes.Concat(ephemeralSharedSecret, aesSecret)).Bytes; Array.Clear(ephemeralSharedSecret, 0, ephemeralSharedSecret.Length); // TODO: it was passed in the concat for Keccak so not good enough handshake.Secrets = new EncryptionSecrets(); handshake.Secrets.Token = token; handshake.Secrets.AesSecret = aesSecret; handshake.Secrets.MacSecret = macSecret; KeccakDigest mac1 = new KeccakDigest(MacBitsSize); mac1.BlockUpdate(macSecret.Xor(handshake.RecipientNonce), 0, macSecret.Length); mac1.BlockUpdate(handshake.AuthPacket.Data, 0, handshake.AuthPacket.Data.Length); KeccakDigest mac2 = new KeccakDigest(MacBitsSize); mac2.BlockUpdate(macSecret.Xor(handshake.InitiatorNonce), 0, macSecret.Length); mac2.BlockUpdate(handshake.AckPacket.Data, 0, handshake.AckPacket.Data.Length); if (handshakeRole == HandshakeRole.Initiator) { handshake.Secrets.EgressMac = mac1; handshake.Secrets.IngressMac = mac2; } else { handshake.Secrets.EgressMac = mac2; handshake.Secrets.IngressMac = mac1; } if (_logger.IsTrace) { _logger.Trace($"Agreed secrets with {handshake.RemoteNodeId}"); } #if DEBUG if (_logger.IsTrace) { _logger.Trace($"{handshake.RemoteNodeId} ephemeral private key {handshake.EphemeralPrivateKey}"); _logger.Trace($"{handshake.RemoteNodeId} initiator nonce {handshake.InitiatorNonce.ToHexString()}"); _logger.Trace($"{handshake.RemoteNodeId} recipient nonce {handshake.RecipientNonce.ToHexString()}"); _logger.Trace($"{handshake.RemoteNodeId} remote ephemeral public key {handshake.RemoteEphemeralPublicKey}"); _logger.Trace($"{handshake.RemoteNodeId} remote public key {handshake.RemoteNodeId}"); _logger.Trace($"{handshake.RemoteNodeId} auth packet {handshake.AuthPacket.Data.ToHexString()}"); _logger.Trace($"{handshake.RemoteNodeId} ack packet {handshake.AckPacket.Data.ToHexString()}"); } #endif }
public NettyHandshakeHandler( IEncryptionHandshakeService service, ISession session, HandshakeRole role, ILogManager logManager, IEventExecutorGroup group) { _role = role; _logManager = logManager ?? throw new ArgumentNullException(nameof(NettyHandshakeHandler)); _group = @group; _logger = logManager.GetClassLogger <NettyHandshakeHandler>(); _service = service; _session = session; _initCompletionSource = new TaskCompletionSource <object>(); }
public NettyHandshakeHandler( IEncryptionHandshakeService service, ISession session, HandshakeRole role, PublicKey remoteId, ILogManager logManager) { _handshake.RemoteNodeId = remoteId; _role = role; _remoteId = remoteId; _logManager = logManager ?? throw new ArgumentNullException(nameof(NettyHandshakeHandler)); _logger = logManager.GetClassLogger <NettyHandshakeHandler>(); _service = service; _session = session; _initCompletionSource = new TaskCompletionSource <object>(); }
public NettyHandshakeHandler( IMessageSerializationService serializationService, IHandshakeService handshakeService, ISession session, HandshakeRole role, ILogManager logManager, IEventExecutorGroup group) { _serializationService = serializationService ?? throw new ArgumentNullException(nameof(serializationService)); _logManager = logManager ?? throw new ArgumentNullException(nameof(logManager)); _logger = logManager.GetClassLogger <NettyHandshakeHandler>(); _role = role; _group = group; _service = handshakeService ?? throw new ArgumentNullException(nameof(handshakeService)); _session = session ?? throw new ArgumentNullException(nameof(session)); _initCompletionSource = new TaskCompletionSource <object>(); }
public static void SetSecrets(EncryptionHandshake handshake, HandshakeRole handshakeRole) { Span <byte> tempConcat = stackalloc byte[64]; Span <byte> ephemeralSharedSecret = Proxy.EcdhSerialized(handshake.RemoteEphemeralPublicKey.Bytes, handshake.EphemeralPrivateKey.KeyBytes); Span <byte> nonceHash = ValueKeccak.Compute(Bytes.Concat(handshake.RecipientNonce, handshake.InitiatorNonce)).BytesAsSpan; ephemeralSharedSecret.CopyTo(tempConcat.Slice(0, 32)); nonceHash.CopyTo(tempConcat.Slice(32, 32)); Span <byte> sharedSecret = ValueKeccak.Compute(tempConcat).BytesAsSpan; // byte[] token = Keccak.Compute(sharedSecret).Bytes; sharedSecret.CopyTo(tempConcat.Slice(32, 32)); byte[] aesSecret = Keccak.Compute(tempConcat).Bytes; sharedSecret.Clear(); aesSecret.CopyTo(tempConcat.Slice(32, 32)); byte[] macSecret = Keccak.Compute(tempConcat).Bytes; ephemeralSharedSecret.Clear(); handshake.Secrets = new EncryptionSecrets(); // handshake.Secrets.Token = token; handshake.Secrets.AesSecret = aesSecret; handshake.Secrets.MacSecret = macSecret; KeccakDigest mac1 = new KeccakDigest(MacBitsSize); mac1.BlockUpdate(macSecret.Xor(handshake.RecipientNonce), 0, macSecret.Length); mac1.BlockUpdate(handshake.AuthPacket.Data, 0, handshake.AuthPacket.Data.Length); KeccakDigest mac2 = new KeccakDigest(MacBitsSize); mac2.BlockUpdate(macSecret.Xor(handshake.InitiatorNonce), 0, macSecret.Length); mac2.BlockUpdate(handshake.AckPacket.Data, 0, handshake.AckPacket.Data.Length); if (handshakeRole == HandshakeRole.Initiator) { handshake.Secrets.EgressMac = mac1; handshake.Secrets.IngressMac = mac2; } else { handshake.Secrets.EgressMac = mac2; handshake.Secrets.IngressMac = mac1; } }
private void InitializeChannel(IChannel channel, ISession session) { if (session.Direction == ConnectionDirection.In) { Metrics.IncomingConnections++; } else { Metrics.OutgoingConnections++; } if (_logger.IsTrace) { _logger.Trace($"Initializing {session.Direction.ToString().ToUpper()} channel{(session.Direction == ConnectionDirection.Out ? $": {session.RemoteNodeId}@{session.RemoteHost}:{session.RemotePort}" : string.Empty)}"); } _sessionMonitor.AddSession(session); session.Disconnected += SessionOnPeerDisconnected; SessionCreated?.Invoke(this, new SessionEventArgs(session)); HandshakeRole role = session.Direction == ConnectionDirection.In ? HandshakeRole.Recipient : HandshakeRole.Initiator; var handshakeHandler = new NettyHandshakeHandler(_encryptionHandshakeService, session, role, session.RemoteNodeId, _logManager); IChannelPipeline pipeline = channel.Pipeline; // pipeline.AddLast(new LoggingHandler(session.Direction.ToString().ToUpper(), DotNetty.Handlers.Logging.LogLevel.TRACE)); pipeline.AddLast("enc-handshake-dec", new LengthFieldBasedFrameDecoder(ByteOrder.BigEndian, ushort.MaxValue, 0, 2, 0, 0, true)); pipeline.AddLast("enc-handshake-handler", handshakeHandler); channel.CloseCompletion.ContinueWith(x => { if (_logger.IsTrace) { _logger.Trace($"Channel disconnected: {session.RemoteNodeId}"); } session.Disconnect(DisconnectReason.ClientQuitting, DisconnectType.Remote); }); }
public static void SetSecrets(EncryptionHandshake handshake, HandshakeRole handshakeRole) { byte[] ephemeralSharedSecret = Proxy.EcdhSerialized(handshake.RemoteEphemeralPublicKey.Bytes, handshake.EphemeralPrivateKey.KeyBytes); byte[] nonceHash = Keccak.Compute(Bytes.Concat(handshake.RecipientNonce, handshake.InitiatorNonce)).Bytes; byte[] sharedSecret = Keccak.Compute(Bytes.Concat(ephemeralSharedSecret, nonceHash)).Bytes; byte[] token = Keccak.Compute(sharedSecret).Bytes; byte[] aesSecret = Keccak.Compute(Bytes.Concat(ephemeralSharedSecret, sharedSecret)).Bytes; Array.Clear(sharedSecret, 0, sharedSecret.Length); // TODO: it was passed in the concat for Keccak so not good enough byte[] macSecret = Keccak.Compute(Bytes.Concat(ephemeralSharedSecret, aesSecret)).Bytes; Array.Clear(ephemeralSharedSecret, 0, ephemeralSharedSecret.Length); // TODO: it was passed in the concat for Keccak so not good enough handshake.Secrets = new EncryptionSecrets(); handshake.Secrets.Token = token; handshake.Secrets.AesSecret = aesSecret; handshake.Secrets.MacSecret = macSecret; KeccakDigest mac1 = new KeccakDigest(MacBitsSize); mac1.BlockUpdate(macSecret.Xor(handshake.RecipientNonce), 0, macSecret.Length); mac1.BlockUpdate(handshake.AuthPacket.Data, 0, handshake.AuthPacket.Data.Length); KeccakDigest mac2 = new KeccakDigest(MacBitsSize); mac2.BlockUpdate(macSecret.Xor(handshake.InitiatorNonce), 0, macSecret.Length); mac2.BlockUpdate(handshake.AckPacket.Data, 0, handshake.AckPacket.Data.Length); if (handshakeRole == HandshakeRole.Initiator) { handshake.Secrets.EgressMac = mac1; handshake.Secrets.IngressMac = mac2; } else { handshake.Secrets.EgressMac = mac2; handshake.Secrets.IngressMac = mac1; } }