From 7969a2ca2e65e1f1eed30d27cf99f6c84d18c6b8 Mon Sep 17 00:00:00 2001 From: martgil Date: Fri, 25 Oct 2024 16:45:28 +0800 Subject: [PATCH] added detached signature verification? --- .../thunderbird/thunderbird-element-replacer.ts | 13 +++++++------ extension/js/service_worker/bg-handlers.ts | 6 +++++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/extension/js/content_scripts/webmail/thunderbird/thunderbird-element-replacer.ts b/extension/js/content_scripts/webmail/thunderbird/thunderbird-element-replacer.ts index fa48a23ffd8..6255965ea49 100644 --- a/extension/js/content_scripts/webmail/thunderbird/thunderbird-element-replacer.ts +++ b/extension/js/content_scripts/webmail/thunderbird/thunderbird-element-replacer.ts @@ -31,10 +31,10 @@ export class ThunderbirdElementReplacer extends WebmailElementReplacer { public handleThunderbirdMessageParsing = async () => { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this.acctEmail = (await BrowserMsg.send.bg.await.thunderbirdGetCurrentUser())!; - const emailBodyToParse = $('div.moz-text-plain').text().trim() || $('div.moz-text-html').text().trim(); - const { processableAttachments: fcAttachments, from: from } = await BrowserMsg.send.bg.await.thunderbirdGetDownloadableAttachment(); + const emailBodyToParse = $('div.moz-text-plain').text().trim() || $('div.moz-text-html').text().trim() || $('div.moz-text-flowed').text().trim(); + const { processableAttachments: fcAttachments, from: signerEmail } = await BrowserMsg.send.bg.await.thunderbirdGetDownloadableAttachment(); if (Catch.isThunderbirdMail()) { - const parsedPubs = (await ContactStore.getOneWithAllPubkeys(undefined, from))?.sortedPubkeys ?? []; + const parsedPubs = (await ContactStore.getOneWithAllPubkeys(undefined, signerEmail))?.sortedPubkeys ?? []; const verificationPubs = parsedPubs.map(key => KeyUtil.armor(key.pubkey)); if (this.resemblesAsciiArmoredMsg(emailBodyToParse)) { await this.messageDecrypt(verificationPubs, this.emailBodyFromThunderbirdMail); @@ -101,13 +101,13 @@ export class ThunderbirdElementReplacer extends WebmailElementReplacer { let pgpBlockContent = ''; if (result.content) { verificationStatus = result.match ? 'signed' : 'not signed'; - if (result.signerLongids) { + if (!result.signerLongids.length) { verificationStatus = `could not verify signature: missing pubkey ${result.signerLongids}`; } pgpBlockContent = result.content.toUtfStr(); } else if (result.error) { verificationStatus = `could not verify signature: ${result.error}`; - pgpBlockContent = detachedSignatureParams?.plaintext || ''; + pgpBlockContent = detachedSignatureParams?.plaintext || this.emailBodyFromThunderbirdMail; } const pgpBlock = this.generatePgpBlockTemplate('not encrypted', verificationStatus, pgpBlockContent); $('body').html(pgpBlock); // xss-sanitized @@ -122,10 +122,11 @@ export class ThunderbirdElementReplacer extends WebmailElementReplacer { !this.emailBodyFromThunderbirdMail ) { await this.messageDecrypt(verificationPubs, fcAttachment.data); + // detached signature verification } else if (fcAttachment.treatAs === 'signature') { const sigText = new TextDecoder('utf-8').decode(fcAttachment.data).trim(); if (this.resemblesSignedMsg(sigText)) { - await this.messageVerify(verificationPubs, { plaintext: emailBodyToParse, sigText }); + await this.messageVerify(verificationPubs, { plaintext: emailBodyToParse, sigText: sigText.replace('\n=3D', '\n=') }); } } }; diff --git a/extension/js/service_worker/bg-handlers.ts b/extension/js/service_worker/bg-handlers.ts index f9bc41fa04b..8a57f1af531 100644 --- a/extension/js/service_worker/bg-handlers.ts +++ b/extension/js/service_worker/bg-handlers.ts @@ -170,8 +170,12 @@ export class BgHandlers { let from = ''; if (tab.id && message?.id) { from = Str.parseEmail(message.author).email || ''; - const attachments = await messenger.messages.listAttachments(message.id); + const mimeMsg = await messenger.messages.getFull(message.id); + let attachments = await messenger.messages.listAttachments(message.id); const fcAttachments: Attachment[] = []; + if (mimeMsg.parts?.[0].contentType === 'multipart/signed' && mimeMsg.parts?.[0].parts?.length === 2) { + attachments = attachments.filter(file => file.contentType === 'application/pgp-signature'); + } // convert Thunderbird Attachments to FlowCrypt recognizable Attachments for (const attachment of attachments) { const file = await messenger.messages.getAttachmentFile(message.id, attachment.partName);