/// <summary> /// Decrypt a Message and download the blobs of the Message (e.g. image or file) /// </summary> /// <param name="threemaId">Threema ID of the sender</param> /// <param name="messageId">Message ID</param> /// <param name="box">Encrypted box data of the file/image message</param> /// <param name="nonce">Nonce that was used for message encryption</param> /// <param name="outputFolder">Output folder for storing decrypted images/files</param> /// <returns>Result of message reception</returns> public ReceiveMessageResult ReceiveMessage(string threemaId, string messageId, byte[] box, byte[] nonce, string outputFolder) { //fetch public key byte[] publicKey = this.apiConnector.LookupKey(threemaId); if (publicKey == null) { throw new InvalidKeyException("invalid threema id"); } ThreemaMessage message = CryptTool.DecryptMessage(box, this.privateKey, publicKey, nonce); if (message == null) { return(null); } ReceiveMessageResult result = new ReceiveMessageResult(messageId, message); if (message.GetType() == typeof(ImageMessage)) { //download image ImageMessage imageMessage = (ImageMessage)message; byte[] fileData = this.apiConnector.DownloadFile(imageMessage.BlobId); if (fileData == null) { throw new MessageParseException(); } byte[] decryptedFileContent = CryptTool.Decrypt(fileData, privateKey, publicKey, imageMessage.Nonce); FileInfo imageFile = new FileInfo(outputFolder + "/" + messageId + ".jpg"); using (FileStream stream = File.OpenWrite(imageFile.FullName)) { stream.Write(decryptedFileContent, 0, decryptedFileContent.Length); stream.Close(); } result.Files.Add(imageFile); } else if (message.GetType() == typeof(FileMessage)) { //download file FileMessage fileMessage = (FileMessage)message; byte[] fileData = this.apiConnector.DownloadFile(fileMessage.BlobId); byte[] decryptedFileData = CryptTool.DecryptFileData(fileData, fileMessage.EncryptionKey); FileInfo file = new FileInfo(outputFolder + "/" + messageId + "-" + fileMessage.FileName); using (FileStream stream = File.OpenWrite(file.FullName)) { stream.Write(decryptedFileData, 0, decryptedFileData.Length); stream.Close(); } result.Files.Add(file); if (fileMessage.ThumbnailBlobId != null) { byte[] thumbnailData = this.apiConnector.DownloadFile(fileMessage.ThumbnailBlobId); byte[] decryptedThumbnailData = CryptTool.DecryptFileThumbnailData(thumbnailData, fileMessage.EncryptionKey); FileInfo thumbnailFile = new FileInfo(outputFolder + "/" + messageId + "-thumbnail.jpg"); using (FileStream stream = File.OpenWrite(thumbnailFile.FullName)) { stream.Write(decryptedThumbnailData, 0, decryptedThumbnailData.Length); stream.Close(); } result.Files.Add(thumbnailFile); } } return(result); }