/// <summary>
 /// Check the status of an HTTP response, and throw an exception if its an error.
 /// If we've received an error response, we try to decrypt the body so it can be
 /// logged and included in the thrown exception.
 /// </summary>
 /// <param name="body">The received HTTP response body.</param>
 /// <param name="response">The HttpResponseMessage object.</param>
 private void CheckStatusAndMaybeThrow(string body, HttpResponseMessage response)
 {
     if (!response.IsSuccessStatusCode)
     {
         log.Error($"failed request ({response.StatusCode}): body contents: \"{body}\"");
         try
         {
             EncryptedBody enc = JsonConvert.DeserializeObject <EncryptedBody>(body);
             if (enc != null && enc.encrypted_body != null)
             {
                 // we have an EncryptedBody object containing an encrypted response.
                 // split the text string into cipher text and IV, then decrypt.
                 string[] parts = enc.encrypted_body.Split('$');
                 body = Aes256.DecryptText(parts[0], parts[1], GetEncryptionKey());
                 //log.Error($"decrypted body: \"{body}\"");
             }
             log.Error($"failed request ({response.StatusCode}): body contents: \"{body}\"");
         }
         catch (Exception)
         {
             // ignore any exception that happens during the decryption attempt.
         }
         // include either the original or decrypted body as the exception message.
         throw new RequestException(body);
     }
 }
        public static void Encode(XdrDataOutputStream stream, EncryptedBody encodedEncryptedBody)
        {
            int EncryptedBodysize = encodedEncryptedBody.InnerValue.Length;

            stream.WriteInt(EncryptedBodysize);
            stream.Write(encodedEncryptedBody.InnerValue, 0, EncryptedBodysize);
        }
        public static EncryptedBody Decode(XdrDataInputStream stream)
        {
            EncryptedBody decodedEncryptedBody = new EncryptedBody();
            int           EncryptedBodysize    = stream.ReadInt();

            decodedEncryptedBody.InnerValue = new byte[EncryptedBodysize];
            stream.Read(decodedEncryptedBody.InnerValue, 0, EncryptedBodysize);
            return(decodedEncryptedBody);
        }
        private T DecryptBody <T>(string body)
        {
            // do not check _data.Encrypt to determine if the response is encrpyted, cause that
            // won't work in the initial stages (e.g., start, login). instead, see if the
            // deserialized object contains a property called "encryptedBody".
            EncryptedBody encBody = JsonConvert.DeserializeObject <EncryptedBody>(body);

            if (encBody == null || encBody.encrypted_body == null)
            {
                // deserialize directly into the expected type.
                log.Info($"clear-text body: \"{body}\"");
                return(JsonConvert.DeserializeObject <T>(body));
            }

            // we have an EncryptedBody object containing an encrypted response.
            // split the text string into cipher text and IV, then decrypt.
            log.Debug($"encrypted body: \"{body}\"");
            string[] parts = encBody.encrypted_body.Split('$');
            body = Aes256.DecryptText(parts[0], parts[1], GetEncryptionKey());
            log.Debug($"decrypted body: \"{body}\"");

            return(JsonConvert.DeserializeObject <T>(body));
        }