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