public void Test_Attachment_DecryptFailOnBadKey()
        {
            string?cipherFile          = null;
            bool   hitCorrectException = false;

            try
            {
                byte[]        key            = Util.GetSecretBytes(64);
                byte[]        plaintextInput = Encoding.UTF8.GetBytes("Gwen Stacy");
                EncryptResult encryptResult  = EncryptData(plaintextInput, key);
                byte[]        badKey         = new byte[64];

                cipherFile = WriteToFile(encryptResult.ciphertext);

                using FileStream fileStream = File.Open(cipherFile, FileMode.Open);
                AttachmentCipherInputStream.CreateForAttachment(fileStream, plaintextInput.Length, badKey, encryptResult.digest);
            }
            catch (InvalidMessageException)
            {
                hitCorrectException = true;
            }
            finally
            {
                if (cipherFile != null)
                {
                    DeleteFile(cipherFile);
                }
            }

            Assert.IsTrue(hitCorrectException);
        }
        public void Test_Attachment_EncryptDecryptEmpty()
        {
            byte[]        key            = Util.GetSecretBytes(64);
            byte[]        plaintextInput = Encoding.UTF8.GetBytes(string.Empty);
            EncryptResult encryptResult  = EncryptData(plaintextInput, key);
            string        cipherFile     = WriteToFile(encryptResult.ciphertext);

            using Stream inputStream = AttachmentCipherInputStream.CreateForAttachment(File.Open(cipherFile, FileMode.Open), plaintextInput.Length, key, encryptResult.digest);
            byte[] plaintextOutput = ReadInputStreamFully(inputStream);

            CollectionAssert.AreEqual(plaintextInput, plaintextOutput);

            DeleteFile(cipherFile);
        }
        /// <summary>
        /// Retrieves a SignalServiceAttachment
        /// </summary>
        /// <param name="pointer">The <see cref="SignalServiceAttachmentPointer"/>
        /// received in a <see cref="SignalServiceDataMessage"/></param>
        /// <param name="destination">The download destination for this attachment.</param>
        /// <param name="maxSizeBytes"></param>
        /// <param name="listener">An optional listener (may be null) to receive callbacks on download progress.</param>
        /// <param name="token"></param>
        /// <exception cref="IOException"></exception>
        /// <exception cref="InvalidMessageException"></exception>
        public async Task <Stream> RetrieveAttachmentAsync(SignalServiceAttachmentPointer pointer, Stream destination, int maxSizeBytes, IProgressListener?listener, CancellationToken?token = null)
        {
            if (token == null)
            {
                token = CancellationToken.None;
            }

            if (pointer.Digest == null)
            {
                throw new InvalidMessageException("No attachment digest!");
            }

            await socket.RetrieveAttachmentAsync(pointer.CdnNumber, pointer.RemoteId, destination, maxSizeBytes, listener, token);

            destination.Position = 0;
            return(AttachmentCipherInputStream.CreateForAttachment(destination, pointer.Size != null ? pointer.Size.Value : 0, pointer.Key, pointer.Digest));
        }
        public void Test_Attachment_EncryptDecryptMultipleTimes()
        {
            // Test that the file passed to AttachmentCipherInputStream can be reused.
            byte[]        key            = Util.GetSecretBytes(64);
            byte[]        plaintextInput = Encoding.UTF8.GetBytes("Peter Parker");
            EncryptResult encryptResult  = EncryptData(plaintextInput, key);
            string        cipherFile     = WriteToFile(encryptResult.ciphertext);

            for (int i = 0; i < 10; i++)
            {
                using Stream inputStream = AttachmentCipherInputStream.CreateForAttachment(File.Open(cipherFile, FileMode.Open), plaintextInput.Length, key, encryptResult.digest);
                byte[] plaintextOutput = ReadInputStreamFully(inputStream);

                CollectionAssert.AreEqual(plaintextInput, plaintextOutput);
            }

            DeleteFile(cipherFile);
        }