in mail/extensions/openpgp/content/ui/enigmailMessengerOverlay.js [944:1243]
async messageParseCallback(
msgText,
msgDate,
contentEncoding,
charset,
interactive,
importOnly,
messageUrl,
signature,
retry,
head,
tail,
msgUriSpec,
isAuto,
pbMessageIndex
) {
if (!msgText) {
return;
}
EnigmailCore.init();
var plainText;
var exitCode;
var newSignature = "";
var statusFlags = 0;
var extStatusFlags = 0;
var errorMsgObj = {
value: "",
};
var keyIdObj = {};
var userIdObj = {};
var sigDetailsObj = {};
var extraDetailsObj = {};
var blockSeparationObj = {
value: "",
};
if (importOnly) {
// Import public key
await this.importKeyFromMsgBody(msgText);
return;
}
// See https://www.rfc-editor.org/rfc/rfc4880#section-6
// An implementation MAY implement this key and any
// translations it cares to; an implementation MAY ignore it and
// assume all text is UTF-8.
const armorHeaders = EnigmailArmor.getArmorHeaders(msgText);
if ("charset" in armorHeaders) {
charset = armorHeaders.charset;
}
var exitCodeObj = {};
var statusFlagsObj = {};
var signatureObj = {};
signatureObj.value = signature;
var uiFlags = interactive
? EnigmailConstants.UI_INTERACTIVE |
// EnigmailConstants.UI_ALLOW_KEY_IMPORT |
EnigmailConstants.UI_UNVERIFIED_ENC_OK
: 0;
plainText = await EnigmailDecryption.decryptMessage(
window,
uiFlags,
msgText,
msgDate,
signatureObj,
exitCodeObj,
statusFlagsObj,
keyIdObj,
userIdObj,
sigDetailsObj,
errorMsgObj,
blockSeparationObj,
extraDetailsObj
);
exitCode = exitCodeObj.value;
newSignature = signatureObj.value;
if (plainText === "" && exitCode === 0) {
plainText = " ";
}
statusFlags = statusFlagsObj.value;
extStatusFlags = statusFlagsObj.ext;
var errorMsg = errorMsgObj.value;
if (importOnly) {
if (interactive && errorMsg) {
Services.prompt.alert(window, null, errorMsg);
}
return;
}
var displayedUriSpec = Enigmail.msg.getCurrentMsgUriSpec();
if (!msgUriSpec || displayedUriSpec == msgUriSpec) {
if (exitCode && !statusFlags) {
// Failure, but we don't know why it failed.
// Peek inside msgText, and check what kind of content it is,
// so we can show a minimal error.
const msgType = Enigmail.msg.getFirstPGPMessageType(msgText);
if (msgType == "encrypted") {
statusFlags = EnigmailConstants.DECRYPTION_FAILED;
} else if (msgType == "signed") {
statusFlags = EnigmailConstants.BAD_SIGNATURE;
}
}
Enigmail.hdrView.updatePgpStatus(
exitCode,
statusFlags,
extStatusFlags,
keyIdObj.value,
userIdObj.value,
sigDetailsObj.value,
errorMsg,
null, // blockSeparation
extraDetailsObj.value
);
}
var noSecondTry =
EnigmailConstants.GOOD_SIGNATURE |
EnigmailConstants.EXPIRED_SIGNATURE |
EnigmailConstants.EXPIRED_KEY_SIGNATURE |
EnigmailConstants.EXPIRED_KEY |
EnigmailConstants.REVOKED_KEY |
EnigmailConstants.NO_PUBKEY |
EnigmailConstants.NO_SECKEY |
EnigmailConstants.IMPORTED_KEY |
EnigmailConstants.MISSING_PASSPHRASE |
EnigmailConstants.BAD_PASSPHRASE |
EnigmailConstants.UNKNOWN_ALGO |
EnigmailConstants.DECRYPTION_OKAY |
EnigmailConstants.OVERFLOWED;
if (exitCode !== 0 && !(statusFlags & noSecondTry)) {
// Bad signature/armor
if (retry == 1) {
msgText = MailStringUtils.stringToByteString(msgText);
console.warn(`Retrying decrypt; retry=${retry}, msgText=${msgText}`);
await Enigmail.msg.messageParseCallback(
msgText,
msgDate,
contentEncoding,
charset,
interactive,
importOnly,
messageUrl,
signature,
retry + 1,
head,
tail,
msgUriSpec,
isAuto,
pbMessageIndex
);
return;
} else if (retry == 2) {
console.warn(`Retrying decrypt; retry=${retry} - direct decrypt`);
// Try to verify signature by accessing raw message text directly
// (avoid recursion by setting retry parameter to false on callback)
newSignature = "";
await Enigmail.msg.msgDirectDecrypt(
interactive,
importOnly,
contentEncoding,
charset,
newSignature,
0,
head,
tail,
msgUriSpec,
msgDate,
Enigmail.msg.messageParseCallback,
isAuto
);
return;
} else if (retry == 3) {
msgText = MailStringUtils.stringToByteString(msgText);
console.warn(`Retrying decrypt; retry=${retry}, msgText=${msgText}`);
await Enigmail.msg.messageParseCallback(
msgText,
msgDate,
contentEncoding,
charset,
interactive,
importOnly,
messageUrl,
null,
retry + 1,
head,
tail,
msgUriSpec,
isAuto,
pbMessageIndex
);
return;
}
}
if (!plainText) {
// Show the subset that we cannot process, together with status.
plainText = msgText;
}
if (retry >= 2) {
plainText = EnigmailData.convertFromUnicode(
MailStringUtils.byteStringToString(plainText),
charset
);
}
// TODO: what is blockSeparation ? How to emulate with RNP?
/*
if (blockSeparationObj.value.includes(" ")) {
var blocks = blockSeparationObj.value.split(/ /);
var blockInfo = blocks[0].split(/:/);
plainText =
"*Parts of the message have NOT been signed nor encrypted*",
"\n\n" +
plainText.substr(0, blockInfo[1]) +
"\n\n" +
"*Multiple message blocks found -- decryption/verification aborted*";
}
*/
// Save decrypted message status, headers, and content
var headerList = {
subject: "",
from: "",
date: "",
to: "",
cc: "",
};
if (!gViewAllHeaders) {
for (let index = 0; index < headerList.length; index++) {
headerList[index] = "";
}
} else {
for (let index = 0; index < gExpandedHeaderList.length; index++) {
headerList[gExpandedHeaderList[index].name] = "";
}
for (const headerName in currentHeaderData) {
headerList[headerName] = "";
}
}
for (const headerName in headerList) {
if (currentHeaderData[headerName]) {
headerList[headerName] = currentHeaderData[headerName].headerValue;
}
}
// WORKAROUND
if (headerList.cc == headerList.to) {
headerList.cc = "";
}
var hasAttachments = currentAttachments && currentAttachments.length;
var attachmentsEncrypted = true;
for (const attachment of currentAttachments) {
if (!Enigmail.msg.checkEncryptedAttach(attachment)) {
if (
!EnigmailMsgRead.checkSignedAttachment(attachment, currentAttachments)
) {
attachmentsEncrypted = false;
}
}
}
// don't display decrypted message if message selection has changed
displayedUriSpec = Enigmail.msg.getCurrentMsgUriSpec();
if (msgUriSpec && displayedUriSpec && displayedUriSpec != msgUriSpec) {
return;
}
let msgContent = "";
if (hasAttachments && !attachmentsEncrypted) {
msgContent =
"\r\n" +
EnigmailData.convertFromUnicode(
l10n.formatValueSync("enig-content-note"),
charset
) +
"\r\n\r\n";
}
msgContent += plainText;
msgContent = MailStringUtils.byteStringToString(msgContent, charset);
this.setDisplayToText(msgContent);
},