Пример #1
0
        public static bool Parse(byte[] data, byte maxAllowedDifficilty, out ServerHello p)
        {
            if (data.Length != 64) // 32 bytes of nonce ignored
            {
                p = null;
                return(false);
            }

            var difficulty = data[32];

            if (difficulty > maxAllowedDifficilty)
            {
                p = null;
                return(false);
            }

            p = new ServerHello
            {
                proofOfWorkDetails = new ProofOfWorkDetails
                {
                    difficulty = difficulty,
                    challenge  = data.Extract(33)
                }
            };

            return(true);
        }
Пример #2
0
        public bool Connect(int timeout = 3000)
        {
            if (_webSocket != null)
            {
                _webSocket.Close();
            }

            // -1- Open Websocket
            UpdateState(ConnectionState.Connecting);
            var signal      = new AutoResetEvent(false);
            var canContinue = true;

            void onOpenHandler(object sender, EventArgs e)
            {
                UpdateState(ConnectionState.Open);
                signal.Set();
            }

            void onCloseHandler(object sender, CloseEventArgs e)
            {
                UpdateState(ConnectionState.Closed);
                canContinue = false;
                //signal.Set(); Force wait until timeout to avoid quick reconnection loops
            }

            void onErrorHandler(object sender, ErrorEventArgs e)
            {
                UpdateState(ConnectionState.Closed);
                canContinue = false;
                //signal.Set(); Force wait until timeout to avoid quick reconnection loops
            }

            EventHandler <MessageEventArgs> onMessageHandler;

            _webSocket = new WebSocket(_config.secretarium.endPoint, "pair1.sp.nanomsg.org");
            _webSocket.SslConfiguration.EnabledSslProtocols = SslProtocols.Tls12;
            _webSocket.Compression = CompressionMethod.None;
            _webSocket.OnOpen     += onOpenHandler;
            _webSocket.OnClose    += onCloseHandler;
            _webSocket.OnError    += onErrorHandler;
            _webSocket.Connect();

            if (!signal.WaitOne(timeout) || !canContinue)
            {
                _webSocket.Close();
                return(false);
            }

            _webSocket.OnOpen -= onOpenHandler;

            // -2- Send Client Hello
            UpdateState(ConnectionState.SecureConnectionInProgress);
            var         clientEphCngKey = ECDHHelper.CreateCngKey();
            var         clientEphCng    = ECDHHelper.CreateECDiffieHellmanCngSha256(clientEphCngKey);
            var         clientEphPub    = clientEphCngKey.ExportPublicKeyRaw();
            var         clientHello     = ByteHelper.Combine(_hop, clientEphPub);
            ServerHello serverHello     = null;

            onMessageHandler = (sender, e) =>
            {
                if (!ServerHello.Parse(e.RawData.Extract(4), MaxAllowedPoWDifficilty, out serverHello))
                {
                    canContinue = false;
                }
                signal.Set();
            };
            _webSocket.OnMessage += onMessageHandler;
            _webSocket.Send(clientHello);

            if (!signal.WaitOne(timeout) || !canContinue)
            {
                _webSocket.Close();
                return(false);
            }

            _webSocket.OnMessage -= onMessageHandler;

            // -3- Send Client Proof Of Work
            if (!DiffieHellmanHelper.ComputeProofOfWork(serverHello.proofOfWorkDetails, out byte[] proofOfWork))