/// <summary> /// Validates the server's key by asking it to authenticate to the client. /// </summary> private async Task VerifyServer() { var token = GpgAuthToken.NewToken(); var encryptedToken = await _pgp.EncryptStringAsync(token.Token, _serverKey); var auth = new Dictionary <string, dynamic> { { "gpg_auth", new Dictionary <string, dynamic> { { "keyid", _clientKey.Fingerprint }, { "server_verify_token", encryptedToken } } } }; var result = await _session.Post(URL_LOGIN, auth).SendAsync(); result.ThrowIfFailed(); GpgAuthHeaders.Validate(result.Response.Headers, GpgAuthState.VerifyServer); var verifyToken = new GpgAuthToken(result.Response.Headers.GetValue("X-GPGAuth-Verify-Response")); if (verifyToken.Token != token.Token) { throw new Exception("The server failed to prove it can use the advertised OpenPGP key."); } }
/// <summary> /// Verifies the MFA challenge with the specified response. /// </summary> /// <param name="otp">The one-time password from the user's security token.</param> /// <returns>Whether the server accepted the response.</returns> public async Task <bool> VerifyMfaChallenge(string otp) { var response = await _session.Post(GetVerifyApiPath(), GetVerifyPostData(otp)) .WithCsrfToken() .SendAsync <JObject>(); if (!response.Response.IsSuccessStatusCode) { _session.Logger?.LogError($"There was a problem with MFA authentication. Server returned code {response.Response.StatusCode}."); return(false); } return(true); }