/// <summary> /// Actually verifies received verification data (initiated locally) /// </summary> /// <param name="verification"></param> private Boolean VerificationOfPassiveParty(NetSRP.Verification verification) { if ((Handshake.State.AllowVerification & this.HandshakeState) != this.HandshakeState) { return(false); } // Hello I am the one that tries to connect. So let's generate the // value M2 I should have in the SRPPackedData Object. Byte[] M2 = NetSRP.CalcM2(_cache.A, _verification.M, _cache.K); // Compare if (!NetUtility.ArraysEqual(M2, verification.M2)) { this.HandshakeState = Handshake.State.Failed; throw new NetSRP.HandShakeException("Username or password invalid.", new ArgumentException("Generated M2 does not match received M2")); } // Check expiration if (_cache.ExpirationTime.CompareTo(DateTime.Now) < 0) { this.HandshakeState = Handshake.State.Expired; throw new NetSRP.HandShakeException("Hand was not shaken before it expired."); } return(true); }
/// <summary> /// Actually verifies received verification data (initiated remotely) + generates response /// </summary> /// <param name="verification"></param> private NetSRP.Verification VerificationOfActiveParty(NetSRP.Verification verification) { if ((Handshake.State.AllowVerificating & this.HandshakeState) != this.HandshakeState) { return(_verification); // double } // Set State this.HandshakeState = Handshake.State.Verificating; // Hello I am the one that is being connected to. So let's generate // the value M I should have in the SRPPackedData Object. Byte[] M = NetSRP.CalcM(N, g, _request.Username, _response.Salt, _request.A, _cache.B, _cache.K); // Compare if (!NetUtility.ArraysEqual(M, verification.M)) { this.HandshakeState = Handshake.State.Denied | State.Failed; throw new NetSRP.HandShakeException("Invalid proof of Key. Username or password invalid.", new InvalidOperationException("Generated M does not match received M")); } // Ok, so their verification passed. Now let's proof that mine will to. _verification = new NetSRP.Verification(NetSRP.CalcM2(_request.A, verification.M, _cache.K)); // Check expiration (maybe use timer?) if (_cache.ExpirationTime.CompareTo(DateTime.Now) < 0) { this.HandshakeState = Handshake.State.Expired; throw new NetSRP.HandShakeException("Hand was not shaken before it expired."); } return(_verification); }
/// <summary> /// Finishes the handshake by processing the verification data received /// </summary> /// <param name="msg">Incomming message with verification data</param> internal static NetSRP.Verification FinishHandshakeFromActive(NetIncomingMessage msg) { // Get Verification NetSRP.Verification verification = new NetSRP.Verification(); verification.ExtractPacketData(msg); // Try to verify data return((msg.SenderConnection.Tag as Handshake).VerificationOfActiveParty(verification)); }
/// <summary> /// Finishes the handshake by processing the verification data received /// </summary> /// <param name="msg">Incomming message with verification data</param> internal static Boolean FinishHandshakeFromPassive(NetIncomingMessage msg) { // Get Verification NetSRP.Verification verification = new NetSRP.Verification(); verification.ExtractPacketData(msg); // Try to verify data return (msg.SenderConnection.Tag as Handshake).VerificationOfPassiveParty(verification); }
/// <summary> /// Generates Session key from response /// </summary> /// <param name="response"></param> /// <response></response> private NetSRP.Verification KeyFromResponse(NetSRP.Response response) { if ((Handshake.State.AllowVerificating & this.HandshakeState) != this.HandshakeState) { return(_verification); // Double Request } // When we get the response, get their public key B if (response.B.Mod(N).IntValue == 0) { this.HandshakeState = Handshake.State.Failed; throw new NetSRP.HandShakeException("Response contains invalid data", new ArgumentException("B mod N is zero.")); } // Shared random scrambler NetBigInteger u = NetSRP.Calcu(_cache.A, response.B); if (u.IntValue == 0) { this.HandshakeState = Handshake.State.Failed; throw new NetSRP.HandShakeException("Response contains invalid data", new ArgumentException("u is zero.")); } // Private key x NetBigInteger x = NetSRP.Calcx(response.Salt, _request.Username, _cache.UserData); // Cache Response; _response = response; // Session key _cache.S = NetSRP.CalcSClient(N, g, response.B, k, x, _cache.a, u); _cache.K = NetSRP.CalcK(_cache.S); // Create the verification _verification = new NetSRP.Verification(NetSRP.CalcM(N, g, _request.Username, response.Salt, _cache.A, response.B, _cache.K)); // Set State this.HandshakeState = Handshake.State.Verificating; return(_verification); }
/// <summary> /// Generates Session key from response /// </summary> /// <param name="response"></param> /// <response></response> private NetSRP.Verification KeyFromResponse(NetSRP.Response response) { if ((Handshake.State.AllowVerificating & this.HandshakeState) != this.HandshakeState) return _verification; // Double Request // When we get the response, get their public key B if (response.B.Mod(N).IntValue == 0) { this.HandshakeState = Handshake.State.Failed; throw new NetSRP.HandShakeException("Response contains invalid data", new ArgumentException("B mod N is zero.")); } // Shared random scrambler NetBigInteger u = NetSRP.Calcu(_cache.A, response.B); if (u.IntValue == 0) { this.HandshakeState = Handshake.State.Failed; throw new NetSRP.HandShakeException("Response contains invalid data", new ArgumentException("u is zero.")); } // Private key x NetBigInteger x = NetSRP.Calcx(response.Salt, _request.Username, _cache.UserData); // Cache Response; _response = response; // Session key _cache.S = NetSRP.CalcSClient(N, g, response.B, k, x, _cache.a, u); _cache.K = NetSRP.CalcK(_cache.S); // Create the verification _verification = new NetSRP.Verification(NetSRP.CalcM(N, g, _request.Username, response.Salt, _cache.A, response.B, _cache.K)); // Set State this.HandshakeState = Handshake.State.Verificating; return _verification; }
/// <summary> /// Actually verifies received verification data (initiated remotely) + generates response /// </summary> /// <param name="verification"></param> private NetSRP.Verification VerificationOfActiveParty(NetSRP.Verification verification) { if ((Handshake.State.AllowVerificating & this.HandshakeState) != this.HandshakeState) return _verification; // double // Set State this.HandshakeState = Handshake.State.Verificating; // Hello I am the one that is being connected to. So let's generate // the value M I should have in the SRPPackedData Object. Byte[] M = NetSRP.CalcM(N, g, _request.Username, _response.Salt, _request.A, _cache.B, _cache.K); // Compare if (!NetUtility.ArraysEqual(M, verification.M)) { this.HandshakeState = Handshake.State.Denied | State.Failed; throw new NetSRP.HandShakeException("Invalid proof of Key. Username or password invalid.", new InvalidOperationException("Generated M does not match received M")); } // Ok, so their verification passed. Now let's proof that mine will to. _verification = new NetSRP.Verification(NetSRP.CalcM2(_request.A, verification.M, _cache.K)); // Check expiration (maybe use timer?) if (_cache.ExpirationTime.CompareTo(DateTime.Now) < 0) { this.HandshakeState = Handshake.State.Expired; throw new NetSRP.HandShakeException("Hand was not shaken before it expired."); } return _verification; }