Changes for #89

Now it does not fetch the PGP signature, because validation was broken anyway.
Instead it validates multipart/signed according to RFC 3156 section 5 and returns details for the signed part:
* BodyPartId
* SigPartId
* MicAlg

So in the future several implementations (GnuPG, OpenPGP.js, etc.) can use the correct data for verification.
This commit is contained in:
the-djmaze 2022-01-17 15:58:23 +01:00
parent ba49d06d1a
commit 8dcd0cf833
14 changed files with 514 additions and 356 deletions

View file

@ -131,7 +131,7 @@ class ComposePopupView extends AbstractViewPopup {
this.bSkipNextHide = false;
this.capaOpenPGP = PgpUserStore.capaOpenPGP;
this.capaOpenPGP = !!PgpUserStore.openpgp;
this.identities = IdentityUserStore;
@ -552,7 +552,7 @@ class ComposePopupView extends AbstractViewPopup {
}
openOpenPgpPopup() {
if (PgpUserStore.capaOpenPGP() && !this.oEditor.isHtml()) {
if (PgpUserStore.openpgp && !this.oEditor.isHtml()) {
showScreenPopup(ComposeOpenPgpPopupView, [
result => this.editor(editor => editor.setPlain(result)),
this.oEditor.getData(false),

View file

@ -40,6 +40,67 @@ import Remote from 'Remote/User/Fetch';
import { decorateKoCommands, createCommand } from 'Knoin/Knoin';
import { AbstractViewRight } from 'Knoin/AbstractViews';
import { PgpUserStore } from 'Stores/User/Pgp';
function controlsHelper(dom, verControl, success, title, text)
{
dom.classList.toggle('error', !success);
dom.classList.toggle('success', success);
// verControl.classList.toggle('error', !success);
// verControl.classList.toggle('success', success);
dom.title = verControl.title = title;
if (undefined !== text) {
dom.textContent = text.trim();
}
}
function pgpClickHelper(dom, armoredMessage) {
if (dom.classList.contains('success') || dom.classList.contains('error')) {
return;
}
let message = null;
try {
message = PgpUserStore.openpgp.cleartext.readArmored(armoredMessage);
} catch (e) {
console.log(e);
}
if (message && message.getText && message.verify) {
PgpUserStore.verifyMessage(message, (validKey, signingKeyIds) => {
console.dir([validKey, signingKeyIds]);
/*
if (validKey) {
controlsHelper(
dom,
this,
true,
i18n('PGP_NOTIFICATIONS/GOOD_SIGNATURE', {
USER: validKey.user + ' (' + validKey.id + ')'
}),
message.getText()
);
} else {
const keyIds = arrayLength(signingKeyIds) ? signingKeyIds : null,
additional = keyIds
? keyIds.map(item => (item && item.toHex ? item.toHex() : null)).filter(v => v).join(', ')
: '';
controlsHelper(
dom,
this,
false,
i18n('PGP_NOTIFICATIONS/UNVERIFIRED_SIGNATURE') + (additional ? ' (' + additional + ')' : '')
);
}
*/
});
} else {
controlsHelper(dom, this, false, i18n('PGP_NOTIFICATIONS/DECRYPTION_ERROR'));
}
}
export class MailMessageView extends AbstractViewRight {
constructor() {
super('MailMessageView');
@ -176,6 +237,12 @@ export class MailMessageView extends AbstractViewRight {
return '';
},
pgpSigned: () => PgpUserStore.openpgp
&& MessageUserStore.message() && !!MessageUserStore.message().pgpSigned(),
pgpEncrypted: () => PgpUserStore.openpgp
&& MessageUserStore.message() && MessageUserStore.message().isPgpEncrypted(),
messageListOrViewLoading:
() => MessageUserStore.listIsLoading() | MessageUserStore.messageLoading()
});
@ -614,4 +681,14 @@ export class MailMessageView extends AbstractViewRight {
rl.app.reloadFlagsCurrentMessageListAndMessageFromCache();
}
}
pgpDecrypt(self/*, event*/) {
const message = self.message();
message && pgpClickHelper(message.body, message.plain(), message.getEmails(['from', 'to', 'cc']));
}
pgpVerify(self/*, event*/) {
const message = self.message();
message && pgpClickHelper(message.body, message.plain());
}
}