Skip to content

Commit 262e9e4

Browse files
committed
Added decryption of attachments. | #118.
1 parent 4a4643f commit 262e9e4

File tree

1 file changed

+58
-8
lines changed

1 file changed

+58
-8
lines changed

FlowCrypt/src/main/java/com/flowcrypt/email/service/attachment/AttachmentDownloadManagerService.java

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,18 @@
3434
import com.flowcrypt.email.database.dao.source.AccountDao;
3535
import com.flowcrypt.email.database.dao.source.AccountDaoSource;
3636
import com.flowcrypt.email.database.dao.source.imap.ImapLabelsDaoSource;
37+
import com.flowcrypt.email.js.Js;
38+
import com.flowcrypt.email.js.PgpDecrypted;
39+
import com.flowcrypt.email.security.SecurityStorageConnector;
3740
import com.flowcrypt.email.util.GeneralUtil;
3841
import com.sun.mail.imap.IMAPFolder;
3942

4043
import org.apache.commons.io.FileUtils;
44+
import org.apache.commons.io.FilenameUtils;
4145
import org.apache.commons.io.IOUtils;
4246

4347
import java.io.File;
48+
import java.io.FileInputStream;
4449
import java.io.IOException;
4550
import java.io.InputStream;
4651
import java.io.OutputStream;
@@ -470,10 +475,9 @@ public void run() {
470475
attachmentInfo.getId());
471476

472477
if (attachment != null) {
473-
InputStream input = attachment.getInputStream();
474-
OutputStream output = FileUtils.openOutputStream(attachmentFile);
478+
InputStream inputStream = attachment.getInputStream();
475479

476-
try {
480+
try (OutputStream outputStream = FileUtils.openOutputStream(attachmentFile)) {
477481
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
478482
double count = 0;
479483
double size = attachmentInfo.getEncodedSize();
@@ -483,9 +487,9 @@ public void run() {
483487
long startTime, elapsedTime;
484488
long lastUpdateTime = startTime = System.currentTimeMillis();
485489
updateProgress(currentPercentage, 0);
486-
while (IOUtils.EOF != (numberOfReadBytes = input.read(buffer))) {
490+
while (IOUtils.EOF != (numberOfReadBytes = inputStream.read(buffer))) {
487491
if (!Thread.currentThread().isInterrupted()) {
488-
output.write(buffer, 0, numberOfReadBytes);
492+
outputStream.write(buffer, 0, numberOfReadBytes);
489493
count += numberOfReadBytes;
490494
currentPercentage = (int) ((count / size) * 100f);
491495
if (currentPercentage - lastPercentage >= 1
@@ -505,15 +509,15 @@ public void run() {
505509
if (!Thread.currentThread().isInterrupted()) {
506510
updateProgress(100, 0);
507511
}
508-
509-
output.close();
510512
} finally {
511-
IOUtils.closeQuietly(output);
512513
if (Thread.currentThread().isInterrupted()) {
513514
removeNotCompleteDownloadFile(attachmentFile);
514515
}
515516
}
516517

518+
attachmentFile = decryptFileIfNeed(context, attachmentFile);
519+
attachmentInfo.setName(attachmentFile.getName());
520+
517521
if (!Thread.currentThread().isInterrupted()) {
518522
if (onDownloadAttachmentListener != null) {
519523
onDownloadAttachmentListener.onAttachmentSuccessDownloaded(startId, attachmentInfo,
@@ -538,6 +542,52 @@ public void setOnDownloadAttachmentListener(OnDownloadAttachmentListener onDownl
538542
this.onDownloadAttachmentListener = onDownloadAttachmentListener;
539543
}
540544

545+
/**
546+
* Do decryption of the downloaded file if it need.
547+
*
548+
* @param context Interface to global information about an application environment;
549+
* @param file The downloaded file which can be encrypted.
550+
* @return The decrypted or the original file.
551+
*/
552+
private File decryptFileIfNeed(Context context, File file) throws IOException {
553+
if (file == null) {
554+
return null;
555+
}
556+
557+
if (!"pgp".equalsIgnoreCase(FilenameUtils.getExtension(file.getName()))) {
558+
return file;
559+
}
560+
561+
try (InputStream inputStream = new FileInputStream(file)) {
562+
PgpDecrypted pgpDecrypted = new Js(context, new SecurityStorageConnector(context))
563+
.crypto_message_decrypt(IOUtils.toByteArray(inputStream));
564+
byte[] decryptedBytes = pgpDecrypted.getBytes();
565+
566+
File decryptedFile = new File(file.getParent(),
567+
file.getName().substring(0, file.getName().lastIndexOf(".")));
568+
569+
boolean isInnerExceptionHappened = false;
570+
571+
try (OutputStream outputStream = FileUtils.openOutputStream(decryptedFile)) {
572+
IOUtils.write(decryptedBytes, outputStream);
573+
return decryptedFile;
574+
} catch (IOException e) {
575+
if (!decryptedFile.delete()) {
576+
Log.d(TAG, "Cannot delete file: " + file);
577+
}
578+
579+
isInnerExceptionHappened = true;
580+
throw e;
581+
} finally {
582+
if (!isInnerExceptionHappened) {
583+
if (!file.delete()) {
584+
Log.d(TAG, "Cannot delete file: " + file);
585+
}
586+
}
587+
}
588+
}
589+
}
590+
541591
/**
542592
* Remove the file which not downloaded fully.
543593
*

0 commit comments

Comments
 (0)