/// <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> /// Sends the decrypted client token back to the server for verification. /// </summary> /// <param name="token">Decrypted client token, obtained from <see cref="GetAndDecryptToken"/>.</param> private async Task VerifyToken(GpgAuthToken token) { var auth = new Dictionary <string, dynamic> { { "gpg_auth", new Dictionary <string, dynamic> { { "keyid", _clientKey.Fingerprint }, { "user_token_result", token.Token } } } }; var result = await _session.Post(URL_LOGIN, auth).SendAsync(); GpgAuthHeaders.Validate(result.Response.Headers, GpgAuthState.Complete); }
/// <summary> /// Retrieves a token from the server, and decrypts it. /// </summary> /// <param name="passphrase">The passphrase to use to decrypt the client key.</param> /// <returns>The decrypted token.</returns> private async Task <GpgAuthToken> GetAndDecryptToken(SecureString passphrase) { var auth = new Dictionary <string, dynamic> { { "gpg_auth", new Dictionary <string, dynamic> { { "keyid", _clientKey.Fingerprint }, } } }; var result = await _session.Post(URL_LOGIN, auth).SendAsync(); GpgAuthHeaders.Validate(result.Response.Headers, GpgAuthState.DecryptToken); // Decrypt the token var encrypted = result.Response.Headers.GetValue("X-GPGAuth-User-Auth-Token"); var decoded = WebUtility.UrlDecode(encrypted.Replace("\\+", " ")); var decrypted = await _pgp.DecryptStringAsync(decoded, _clientKey, passphrase); // Validate the token var token = new GpgAuthToken(decrypted); return(token); }
/// <summary> /// Validates the recieved headers are valid in this state. /// </summary> /// <param name="headers">The response headers.</param> /// <param name="state"></param> public static void Validate(HttpResponseHeaders headers, GpgAuthState state) { var validator = new GpgAuthHeaders(headers, state); validator.Validate(); }