Beispiel #1
0
        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));
            });
        }
Beispiel #2
0
        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>();
 }
Beispiel #4
0
 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>();
 }
Beispiel #6
0
        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;
            }
        }
Beispiel #7
0
        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);
            });
        }
Beispiel #8
0
        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;
            }
        }