mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-08-31 21:19:21 +03:00
Verify S/MIME signed messages #259
This commit is contained in:
parent
4df3766231
commit
f53d9ed6c3
56 changed files with 769 additions and 433 deletions
|
|
@ -292,6 +292,8 @@ viewMessage = (oMessage, popup) => {
|
|||
class:'b-text-part'
|
||||
+ (oMessage.pgpSigned() ? ' openpgp-signed' : '')
|
||||
+ (oMessage.pgpEncrypted() ? ' openpgp-encrypted' : '')
|
||||
+ (oMessage.smimeSigned() ? ' smime-signed' : '')
|
||||
+ (oMessage.smimeEncrypted() ? ' smime-encrypted' : '')
|
||||
});
|
||||
MessageUserStore.purgeCache();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,6 +122,10 @@ export class MessageModel extends AbstractModel {
|
|||
pgpEncrypted: null,
|
||||
pgpDecrypted: false,
|
||||
|
||||
smimeSigned: null,
|
||||
smimeVerified: null,
|
||||
smimeEncrypted: null,
|
||||
|
||||
// rfc8621
|
||||
id: '',
|
||||
// threadId: ''
|
||||
|
|
|
|||
|
|
@ -14,11 +14,11 @@ import { AskPopupView } from 'View/Popup/Ask';
|
|||
import { Passphrases } from 'Storage/Passphrases';
|
||||
|
||||
const
|
||||
askPassphrase = async (privateKey, btnTxt = 'LABEL_SIGN') => {
|
||||
askPassphrase = async (privateKey, btnTxt = 'SIGN') => {
|
||||
const key = privateKey.id,
|
||||
pass = Passphrases.has(key)
|
||||
? {password:Passphrases.get(key), remember:false}
|
||||
: await AskPopupView.password('GnuPG key<br>' + key + ' ' + privateKey.emails[0], 'OPENPGP/'+btnTxt);
|
||||
: await AskPopupView.password('GnuPG key<br>' + key + ' ' + privateKey.emails[0], 'CRYPTO/'+btnTxt);
|
||||
pass && pass.remember && Passphrases.set(key, pass.password);
|
||||
return pass?.password;
|
||||
},
|
||||
|
|
@ -180,7 +180,7 @@ export const GnuPGUserStore = new class {
|
|||
uid: message.uid,
|
||||
partId: pgpInfo.partId,
|
||||
keyId: key.id,
|
||||
passphrase: await askPassphrase(key, 'BUTTON_DECRYPT'),
|
||||
passphrase: await askPassphrase(key, 'DECRYPT'),
|
||||
data: '' // message.plain() optional
|
||||
}
|
||||
if (null !== params.passphrase) {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ const
|
|||
key.emails.includes(query) || query == key.id || query == key.fingerprint
|
||||
),
|
||||
|
||||
decryptKey = async (privateKey, btnTxt = 'LABEL_SIGN') => {
|
||||
decryptKey = async (privateKey, btnTxt = 'SIGN') => {
|
||||
if (privateKey.key.isDecrypted()) {
|
||||
return privateKey.key;
|
||||
}
|
||||
|
|
@ -29,7 +29,7 @@ const
|
|||
? {password:Passphrases.get(key), remember:false}
|
||||
: await AskPopupView.password(
|
||||
'OpenPGP.js key<br>' + key + ' ' + privateKey.emails[0],
|
||||
'OPENPGP/'+btnTxt
|
||||
'CRYPTO/'+btnTxt
|
||||
);
|
||||
if (pass) {
|
||||
const passphrase = pass.password,
|
||||
|
|
@ -210,7 +210,7 @@ export const OpenPGPUserStore = new class {
|
|||
}
|
||||
}
|
||||
if (privateKey) try {
|
||||
const decryptedKey = await decryptKey(privateKey, 'BUTTON_DECRYPT');
|
||||
const decryptedKey = await decryptKey(privateKey, 'DECRYPT');
|
||||
if (decryptedKey) {
|
||||
const publicKey = findOpenPGPKey(this.publicKeys, sender/*, sign*/);
|
||||
return await openpgp.decrypt({
|
||||
|
|
|
|||
|
|
@ -1538,7 +1538,7 @@ export class ComposePopupView extends AbstractViewPopup {
|
|||
} else if (this.canSMimeSign()) {
|
||||
params.signCertificate = identity.smimeCertificate();
|
||||
params.signPrivateKey = identity.smimeKey();
|
||||
const pass = await AskPopupView.password('S/MIME key', 'OPENPGP/LABEL_SIGN');
|
||||
const pass = await AskPopupView.password('S/MIME key', 'CRYPTO/SIGN');
|
||||
params.signPassphrase = pass?.password;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -600,7 +600,7 @@ export class MailMessageView extends AbstractViewRight {
|
|||
}
|
||||
/*
|
||||
if (result?.success) {
|
||||
i18n('OPENPGP/GOOD_SIGNATURE', {
|
||||
i18n('CRYPTO/GOOD_SIGNATURE', {
|
||||
USER: validKey.user + ' (' + validKey.id + ')'
|
||||
});
|
||||
message.getText()
|
||||
|
|
@ -610,7 +610,8 @@ export class MailMessageView extends AbstractViewRight {
|
|||
? keyIds.map(item => item?.toHex?.()).filter(v => v).join(', ')
|
||||
: '';
|
||||
|
||||
i18n('OPENPGP/ERROR', {
|
||||
i18n('CRYPTO/ERROR', {
|
||||
TYPE: 'OpenPGP',
|
||||
ERROR: 'message'
|
||||
}) + (additional ? ' (' + additional + ')' : '');
|
||||
}
|
||||
|
|
@ -618,4 +619,25 @@ export class MailMessageView extends AbstractViewRight {
|
|||
});
|
||||
}
|
||||
|
||||
smimeVerify(/*self, event*/) {
|
||||
const message = currentMessage();
|
||||
let data = message.smimeSigned(); // { partId: "1", micAlg: "pgp-sha256" }
|
||||
if (data) {
|
||||
data = { ...data }; // clone
|
||||
data.folder = message.folder;
|
||||
data.uid = message.uid;
|
||||
data.bodyPart = data.bodyPart?.raw;
|
||||
Remote.post('MessageSMimeVerify', null, data).then(response => {
|
||||
if (response?.Result) {
|
||||
if (response.Result.body) {
|
||||
MimeToMessage(response.Result.body, message);
|
||||
message.html() ? message.viewHtml() : message.viewPlain();
|
||||
response.Result.body = null;
|
||||
}
|
||||
message.smimeVerified(response.Result);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue