summaryrefslogtreecommitdiffstats
path: root/comm/mail/extensions/openpgp/content/modules/mimeEncrypt.jsm
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mail/extensions/openpgp/content/modules/mimeEncrypt.jsm')
-rw-r--r--comm/mail/extensions/openpgp/content/modules/mimeEncrypt.jsm760
1 files changed, 760 insertions, 0 deletions
diff --git a/comm/mail/extensions/openpgp/content/modules/mimeEncrypt.jsm b/comm/mail/extensions/openpgp/content/modules/mimeEncrypt.jsm
new file mode 100644
index 0000000000..dd4018d704
--- /dev/null
+++ b/comm/mail/extensions/openpgp/content/modules/mimeEncrypt.jsm
@@ -0,0 +1,760 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+/**
+ * Module for creating PGP/MIME signed and/or encrypted messages
+ * implemented as XPCOM component
+ */
+
+const EXPORTED_SYMBOLS = ["EnigmailMimeEncrypt"];
+
+const { XPCOMUtils } = ChromeUtils.importESModule(
+ "resource://gre/modules/XPCOMUtils.sys.mjs"
+);
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
+ EnigmailConstants: "chrome://openpgp/content/modules/constants.jsm",
+ EnigmailData: "chrome://openpgp/content/modules/data.jsm",
+ EnigmailEncryption: "chrome://openpgp/content/modules/encryption.jsm",
+ EnigmailFuncs: "chrome://openpgp/content/modules/funcs.jsm",
+ EnigmailLog: "chrome://openpgp/content/modules/log.jsm",
+ EnigmailMime: "chrome://openpgp/content/modules/mime.jsm",
+ jsmime: "resource:///modules/jsmime.jsm",
+});
+
+// our own contract IDs
+const PGPMIME_ENCRYPT_CID = Components.ID(
+ "{96fe88f9-d2cd-466f-93e0-3a351df4c6d2}"
+);
+const PGPMIME_ENCRYPT_CONTRACTID = "@enigmail.net/compose/mimeencrypt;1";
+
+const maxBufferLen = 102400;
+const MIME_SIGNED = 1; // only one MIME layer
+const MIME_ENCRYPTED = 2; // only one MIME layer, combined enc/sig data
+const MIME_OUTER_ENC_INNER_SIG = 3; // use two MIME layers
+
+var gDebugLogLevel = 1;
+
+function PgpMimeEncrypt(sMimeSecurityInfo) {
+ this.wrappedJSObject = this;
+
+ this.signMessage = false;
+ this.requireEncryptMessage = false;
+
+ // "securityInfo" variables
+ this.sendFlags = 0;
+ this.UIFlags = 0;
+ this.senderEmailAddr = "";
+ this.recipients = "";
+ this.bccRecipients = "";
+ this.originalSubject = null;
+ this.autocryptGossipHeaders = "";
+
+ try {
+ if (sMimeSecurityInfo) {
+ this.signMessage = sMimeSecurityInfo.signMessage;
+ this.requireEncryptMessage = sMimeSecurityInfo.requireEncryptMessage;
+ }
+ } catch (ex) {}
+}
+
+PgpMimeEncrypt.prototype = {
+ classDescription: "Enigmail JS Encryption Handler",
+ classID: PGPMIME_ENCRYPT_CID,
+ get contractID() {
+ return PGPMIME_ENCRYPT_CONTRACTID;
+ },
+ QueryInterface: ChromeUtils.generateQI([
+ "nsIMsgComposeSecure",
+ "nsIStreamListener",
+ ]),
+
+ signMessage: false,
+ requireEncryptMessage: false,
+
+ // private variables
+
+ inStream: Cc["@mozilla.org/scriptableinputstream;1"].createInstance(
+ Ci.nsIScriptableInputStream
+ ),
+ msgCompFields: null,
+ outStringStream: null,
+
+ // 0: processing headers
+ // 1: processing body
+ // 2: skipping header
+ inputMode: 0,
+ headerData: "",
+ encapsulate: null,
+ encHeader: null,
+ outerBoundary: null,
+ innerBoundary: null,
+ win: null,
+ //statusStr: "",
+ cryptoOutputLength: 0,
+ cryptoOutput: "",
+ hashAlgorithm: "SHA256", // TODO: coordinate with RNP.jsm
+ cryptoInputBuffer: "",
+ outgoingMessageBuffer: "",
+ mimeStructure: 0,
+ exitCode: -1,
+ inspector: null,
+
+ // nsIStreamListener interface
+ onStartRequest(request) {
+ lazy.EnigmailLog.DEBUG("mimeEncrypt.js: onStartRequest\n");
+ this.encHeader = null;
+ },
+
+ onDataAvailable(req, stream, offset, count) {
+ LOCAL_DEBUG("mimeEncrypt.js: onDataAvailable\n");
+ this.inStream.init(stream);
+ //var data = this.inStream.read(count);
+ //LOCAL_DEBUG("mimeEncrypt.js: >"+data+"<\n");
+ },
+
+ onStopRequest(request, status) {
+ lazy.EnigmailLog.DEBUG("mimeEncrypt.js: onStopRequest\n");
+ },
+
+ // nsIMsgComposeSecure interface
+ requiresCryptoEncapsulation(msgIdentity, msgCompFields) {
+ lazy.EnigmailLog.DEBUG("mimeEncrypt.js: requiresCryptoEncapsulation\n");
+ return (
+ (this.sendFlags &
+ (lazy.EnigmailConstants.SEND_SIGNED |
+ lazy.EnigmailConstants.SEND_ENCRYPTED |
+ lazy.EnigmailConstants.SEND_VERBATIM)) !==
+ 0
+ );
+ },
+
+ beginCryptoEncapsulation(
+ outStream,
+ recipientList,
+ msgCompFields,
+ msgIdentity,
+ sendReport,
+ isDraft
+ ) {
+ lazy.EnigmailLog.DEBUG("mimeEncrypt.js: beginCryptoEncapsulation\n");
+
+ if (!outStream) {
+ throw Components.Exception("", Cr.NS_ERROR_NULL_POINTER);
+ }
+
+ try {
+ this.outStream = outStream;
+ this.isDraft = isDraft;
+
+ this.msgCompFields = msgCompFields;
+ this.outStringStream = Cc[
+ "@mozilla.org/io/string-input-stream;1"
+ ].createInstance(Ci.nsIStringInputStream);
+
+ var windowManager = Services.wm;
+ this.win = windowManager.getMostRecentWindow(null);
+
+ if (this.sendFlags & lazy.EnigmailConstants.SEND_VERBATIM) {
+ this.recipientList = recipientList;
+ this.msgIdentity = msgIdentity;
+ this.msgCompFields = msgCompFields;
+ this.inputMode = 2;
+ return null;
+ }
+
+ if (this.sendFlags & lazy.EnigmailConstants.SEND_PGP_MIME) {
+ if (this.sendFlags & lazy.EnigmailConstants.SEND_ENCRYPTED) {
+ // applies to encrypted and signed & encrypted
+ if (this.sendFlags & lazy.EnigmailConstants.SEND_TWO_MIME_LAYERS) {
+ this.mimeStructure = MIME_OUTER_ENC_INNER_SIG;
+ this.innerBoundary = lazy.EnigmailMime.createBoundary();
+ } else {
+ this.mimeStructure = MIME_ENCRYPTED;
+ }
+ } else if (this.sendFlags & lazy.EnigmailConstants.SEND_SIGNED) {
+ this.mimeStructure = MIME_SIGNED;
+ }
+ } else {
+ throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED);
+ }
+
+ this.outerBoundary = lazy.EnigmailMime.createBoundary();
+ this.startCryptoHeaders();
+ } catch (ex) {
+ console.debug(ex);
+ lazy.EnigmailLog.writeException("mimeEncrypt.js", ex);
+ throw ex;
+ }
+
+ return null;
+ },
+
+ startCryptoHeaders() {
+ lazy.EnigmailLog.DEBUG("mimeEncrypt.js: startCryptoHeaders\n");
+
+ switch (this.mimeStructure) {
+ case MIME_SIGNED:
+ this.signedHeaders1(false);
+ break;
+ case MIME_ENCRYPTED:
+ case MIME_OUTER_ENC_INNER_SIG:
+ this.encryptedHeaders();
+ break;
+ }
+
+ this.writeSecureHeaders();
+ },
+
+ writeSecureHeaders() {
+ this.encHeader = lazy.EnigmailMime.createBoundary();
+
+ let allHdr = "";
+
+ let addrParser = lazy.jsmime.headerparser.parseAddressingHeader;
+ let newsParser = function (s) {
+ return lazy.jsmime.headerparser.parseStructuredHeader("Newsgroups", s);
+ };
+ let noParser = function (s) {
+ return s;
+ };
+
+ let h = {
+ from: {
+ field: "From",
+ parser: addrParser,
+ },
+ replyTo: {
+ field: "Reply-To",
+ parser: addrParser,
+ },
+ to: {
+ field: "To",
+ parser: addrParser,
+ },
+ cc: {
+ field: "Cc",
+ parser: addrParser,
+ },
+ newsgroups: {
+ field: "Newsgroups",
+ parser: newsParser,
+ },
+ followupTo: {
+ field: "Followup-To",
+ parser: addrParser,
+ },
+ messageId: {
+ field: "Message-Id",
+ parser: noParser,
+ },
+ subject: {
+ field: "Subject",
+ parser: noParser,
+ },
+ };
+
+ let alreadyAddedSubject = false;
+
+ if (
+ (this.mimeStructure == MIME_ENCRYPTED ||
+ this.mimeStructure == MIME_OUTER_ENC_INNER_SIG) &&
+ this.originalSubject &&
+ this.originalSubject.length > 0
+ ) {
+ alreadyAddedSubject = true;
+ allHdr += lazy.jsmime.headeremitter.emitStructuredHeader(
+ "subject",
+ this.originalSubject,
+ {}
+ );
+ }
+
+ for (let i in h) {
+ if (h[i].field == "Subject" && alreadyAddedSubject) {
+ continue;
+ }
+ if (this.msgCompFields[i] && this.msgCompFields[i].length > 0) {
+ allHdr += lazy.jsmime.headeremitter.emitStructuredHeader(
+ h[i].field,
+ h[i].parser(this.msgCompFields[i]),
+ {}
+ );
+ }
+ }
+
+ // special handling for references and in-reply-to
+
+ if (this.originalReferences && this.originalReferences.length > 0) {
+ allHdr += lazy.jsmime.headeremitter.emitStructuredHeader(
+ "references",
+ this.originalReferences,
+ {}
+ );
+
+ let bracket = this.originalReferences.lastIndexOf("<");
+ if (bracket >= 0) {
+ allHdr += lazy.jsmime.headeremitter.emitStructuredHeader(
+ "in-reply-to",
+ this.originalReferences.substr(bracket),
+ {}
+ );
+ }
+ }
+
+ let w = `Content-Type: multipart/mixed; boundary="${this.encHeader}"`;
+
+ if (allHdr.length > 0) {
+ w += `;\r\n protected-headers="v1"\r\n${allHdr}`;
+ } else {
+ w += "\r\n";
+ }
+
+ if (this.autocryptGossipHeaders) {
+ w += this.autocryptGossipHeaders;
+ }
+
+ w += `\r\n--${this.encHeader}\r\n`;
+ this.appendToCryptoInput(w);
+
+ if (this.mimeStructure == MIME_SIGNED) {
+ this.appendToMessage(w);
+ }
+ },
+
+ encryptedHeaders(isEightBit = false) {
+ lazy.EnigmailLog.DEBUG("mimeEncrypt.js: encryptedHeaders\n");
+ let subj = "";
+
+ if (this.sendFlags & lazy.EnigmailConstants.ENCRYPT_SUBJECT) {
+ subj = lazy.jsmime.headeremitter.emitStructuredHeader(
+ "subject",
+ lazy.EnigmailFuncs.getProtectedSubjectText(),
+ {}
+ );
+ }
+ this.appendToMessage(
+ subj +
+ "Content-Type: multipart/encrypted;\r\n" +
+ ' protocol="application/pgp-encrypted";\r\n' +
+ ' boundary="' +
+ this.outerBoundary +
+ '"\r\n' +
+ "\r\n" +
+ "This is an OpenPGP/MIME encrypted message (RFC 4880 and 3156)\r\n" +
+ "--" +
+ this.outerBoundary +
+ "\r\n" +
+ "Content-Type: application/pgp-encrypted\r\n" +
+ "Content-Description: PGP/MIME version identification\r\n" +
+ "\r\n" +
+ "Version: 1\r\n" +
+ "\r\n" +
+ "--" +
+ this.outerBoundary +
+ "\r\n" +
+ 'Content-Type: application/octet-stream; name="encrypted.asc"\r\n' +
+ "Content-Description: OpenPGP encrypted message\r\n" +
+ 'Content-Disposition: inline; filename="encrypted.asc"\r\n' +
+ "\r\n"
+ );
+ },
+
+ signedHeaders1(isEightBit = false) {
+ LOCAL_DEBUG("mimeEncrypt.js: signedHeaders1\n");
+ let boundary;
+ if (this.mimeStructure == MIME_OUTER_ENC_INNER_SIG) {
+ boundary = this.innerBoundary;
+ } else {
+ boundary = this.outerBoundary;
+ }
+ let sigHeader =
+ "Content-Type: multipart/signed; micalg=pgp-" +
+ this.hashAlgorithm.toLowerCase() +
+ ";\r\n" +
+ ' protocol="application/pgp-signature";\r\n' +
+ ' boundary="' +
+ boundary +
+ '"\r\n' +
+ (isEightBit ? "Content-Transfer-Encoding: 8bit\r\n\r\n" : "\r\n") +
+ "This is an OpenPGP/MIME signed message (RFC 4880 and 3156)\r\n" +
+ "--" +
+ boundary +
+ "\r\n";
+ if (this.mimeStructure == MIME_OUTER_ENC_INNER_SIG) {
+ this.appendToCryptoInput(sigHeader);
+ } else {
+ this.appendToMessage(sigHeader);
+ }
+ },
+
+ signedHeaders2() {
+ LOCAL_DEBUG("mimeEncrypt.js: signedHeaders2\n");
+ let boundary;
+ if (this.mimeStructure == MIME_OUTER_ENC_INNER_SIG) {
+ boundary = this.innerBoundary;
+ } else {
+ boundary = this.outerBoundary;
+ }
+ let sigHeader =
+ "\r\n--" +
+ boundary +
+ "\r\n" +
+ 'Content-Type: application/pgp-signature; name="OpenPGP_signature.asc"\r\n' +
+ "Content-Description: OpenPGP digital signature\r\n" +
+ 'Content-Disposition: attachment; filename="OpenPGP_signature.asc"\r\n\r\n';
+ if (this.mimeStructure == MIME_OUTER_ENC_INNER_SIG) {
+ this.appendToCryptoInput(sigHeader);
+ } else {
+ this.appendToMessage(sigHeader);
+ }
+ },
+
+ finishCryptoHeaders() {
+ lazy.EnigmailLog.DEBUG("mimeEncrypt.js: finishCryptoHeaders\n");
+
+ this.appendToMessage("\r\n--" + this.outerBoundary + "--\r\n");
+ },
+
+ finishCryptoEncapsulation(abort, sendReport) {
+ lazy.EnigmailLog.DEBUG("mimeEncrypt.js: finishCryptoEncapsulation\n");
+
+ if ((this.sendFlags & lazy.EnigmailConstants.SEND_VERBATIM) !== 0) {
+ this.flushOutput();
+ return;
+ }
+
+ if (this.encapsulate) {
+ this.appendToCryptoInput("--" + this.encapsulate + "--\r\n");
+ }
+
+ if (this.encHeader) {
+ this.appendToCryptoInput("\r\n--" + this.encHeader + "--\r\n");
+ if (this.mimeStructure == MIME_SIGNED) {
+ this.appendToMessage("\r\n--" + this.encHeader + "--\r\n");
+ }
+ }
+
+ let statusFlagsObj = {};
+ let errorMsgObj = {};
+ this.exitCode = 0;
+
+ if (this.mimeStructure == MIME_OUTER_ENC_INNER_SIG) {
+ // prepare the inner crypto layer (the signature)
+ let sendFlagsWithoutEncrypt =
+ this.sendFlags & ~lazy.EnigmailConstants.SEND_ENCRYPTED;
+
+ this.exitCode = lazy.EnigmailEncryption.encryptMessageStart(
+ this.win,
+ this.UIFlags,
+ this.senderEmailAddr,
+ this.recipients,
+ this.bccRecipients,
+ this.hashAlgorithm,
+ sendFlagsWithoutEncrypt,
+ this,
+ statusFlagsObj,
+ errorMsgObj
+ );
+ if (!this.exitCode) {
+ // success
+ let innerSignedMessage = this.cryptoInputBuffer;
+ this.cryptoInputBuffer = "";
+
+ this.signedHeaders1(false);
+ this.appendToCryptoInput(innerSignedMessage);
+ this.signedHeaders2();
+ this.cryptoOutput = this.cryptoOutput
+ .replace(/\r/g, "")
+ .replace(/\n/g, "\r\n"); // force CRLF
+ this.appendToCryptoInput(this.cryptoOutput);
+ this.appendToCryptoInput("\r\n--" + this.innerBoundary + "--\r\n");
+ this.cryptoOutput = "";
+ }
+ }
+
+ if (!this.exitCode) {
+ // no failure yet
+ let encryptionFlags = this.sendFlags;
+ if (this.mimeStructure == MIME_OUTER_ENC_INNER_SIG) {
+ // remove signature flag, because we already signed
+ encryptionFlags = encryptionFlags & ~lazy.EnigmailConstants.SEND_SIGNED;
+ }
+ this.exitCode = lazy.EnigmailEncryption.encryptMessageStart(
+ this.win,
+ this.UIFlags,
+ this.senderEmailAddr,
+ this.recipients,
+ this.bccRecipients,
+ this.hashAlgorithm,
+ encryptionFlags,
+ this,
+ statusFlagsObj,
+ errorMsgObj
+ );
+ }
+
+ try {
+ LOCAL_DEBUG(
+ "mimeEncrypt.js: finishCryptoEncapsulation: exitCode = " +
+ this.exitCode +
+ "\n"
+ );
+ if (this.exitCode !== 0) {
+ throw new Error(
+ "failure in finishCryptoEncapsulation, exitCode: " + this.exitCode
+ );
+ }
+
+ if (this.mimeStructure == MIME_SIGNED) {
+ this.signedHeaders2();
+ }
+
+ this.cryptoOutput = this.cryptoOutput
+ .replace(/\r/g, "")
+ .replace(/\n/g, "\r\n"); // force CRLF
+
+ this.appendToMessage(this.cryptoOutput);
+ this.finishCryptoHeaders();
+ this.flushOutput();
+ } catch (ex) {
+ console.debug(ex);
+ lazy.EnigmailLog.writeException("mimeEncrypt.js", ex);
+ throw ex;
+ }
+ },
+
+ mimeCryptoWriteBlock(buffer, length) {
+ if (gDebugLogLevel > 4) {
+ LOCAL_DEBUG("mimeEncrypt.js: mimeCryptoWriteBlock: " + length + "\n");
+ }
+
+ try {
+ let line = buffer.substr(0, length);
+ if (this.inputMode === 0) {
+ if ((this.sendFlags & lazy.EnigmailConstants.SEND_VERBATIM) !== 0) {
+ line = lazy.EnigmailData.decodeQuotedPrintable(
+ line.replace("=\r\n", "")
+ );
+ }
+
+ if (
+ (this.sendFlags & lazy.EnigmailConstants.SEND_VERBATIM) === 0 ||
+ line.match(
+ /^(From|To|Subject|Message-ID|Date|User-Agent|MIME-Version):/i
+ ) === null
+ ) {
+ this.headerData += line;
+ }
+
+ if (line.replace(/[\r\n]/g, "").length === 0) {
+ this.inputMode = 1;
+
+ if (
+ this.mimeStructure == MIME_ENCRYPTED ||
+ this.mimeStructure == MIME_OUTER_ENC_INNER_SIG
+ ) {
+ if (!this.encHeader) {
+ let ct = this.getHeader("content-type", false);
+ if (
+ ct.search(/text\/plain/i) === 0 ||
+ ct.search(/text\/html/i) === 0
+ ) {
+ this.encapsulate = lazy.EnigmailMime.createBoundary();
+ this.appendToCryptoInput(
+ 'Content-Type: multipart/mixed; boundary="' +
+ this.encapsulate +
+ '"\r\n\r\n'
+ );
+ this.appendToCryptoInput("--" + this.encapsulate + "\r\n");
+ }
+ }
+ } else if (this.mimeStructure == MIME_SIGNED) {
+ let ct = this.getHeader("content-type", true);
+ let hdr = lazy.EnigmailFuncs.getHeaderData(ct);
+ hdr.boundary = hdr.boundary || "";
+ hdr.boundary = hdr.boundary.replace(/^(['"])(.*)(\1)$/, "$2");
+ }
+
+ this.appendToCryptoInput(this.headerData);
+ if (
+ this.mimeStructure == MIME_SIGNED ||
+ (this.sendFlags & lazy.EnigmailConstants.SEND_VERBATIM) !== 0
+ ) {
+ this.appendToMessage(this.headerData);
+ }
+ }
+ } else if (this.inputMode == 1) {
+ if (this.mimeStructure == MIME_SIGNED) {
+ // special treatments for various special cases with PGP/MIME signed messages
+ if (line.substr(0, 5) == "From ") {
+ LOCAL_DEBUG("mimeEncrypt.js: added >From\n");
+ this.appendToCryptoInput(">");
+ }
+ }
+
+ this.appendToCryptoInput(line);
+ if (this.mimeStructure == MIME_SIGNED) {
+ this.appendToMessage(line);
+ } else if (
+ (this.sendFlags & lazy.EnigmailConstants.SEND_VERBATIM) !==
+ 0
+ ) {
+ this.appendToMessage(
+ lazy.EnigmailData.decodeQuotedPrintable(line.replace("=\r\n", ""))
+ );
+ }
+ } else if (this.inputMode == 2) {
+ if (line.replace(/[\r\n]/g, "").length === 0) {
+ this.inputMode = 0;
+ }
+ }
+ } catch (ex) {
+ console.debug(ex);
+ lazy.EnigmailLog.writeException("mimeEncrypt.js", ex);
+ throw ex;
+ }
+
+ return null;
+ },
+
+ appendToMessage(str) {
+ if (gDebugLogLevel > 4) {
+ LOCAL_DEBUG("mimeEncrypt.js: appendToMessage: " + str.length + "\n");
+ }
+
+ this.outgoingMessageBuffer += str;
+
+ if (this.outgoingMessageBuffer.length > maxBufferLen) {
+ this.flushOutput();
+ }
+ },
+
+ flushOutput() {
+ LOCAL_DEBUG(
+ "mimeEncrypt.js: flushOutput: " + this.outgoingMessageBuffer.length + "\n"
+ );
+
+ this.outStringStream.setData(
+ this.outgoingMessageBuffer,
+ this.outgoingMessageBuffer.length
+ );
+ var writeCount = this.outStream.writeFrom(
+ this.outStringStream,
+ this.outgoingMessageBuffer.length
+ );
+ if (writeCount < this.outgoingMessageBuffer.length) {
+ LOCAL_DEBUG(
+ "mimeEncrypt.js: flushOutput: wrote " +
+ writeCount +
+ " instead of " +
+ this.outgoingMessageBuffer.length +
+ " bytes\n"
+ );
+ }
+ this.outgoingMessageBuffer = "";
+ },
+
+ appendToCryptoInput(str) {
+ if (gDebugLogLevel > 4) {
+ LOCAL_DEBUG("mimeEncrypt.js: appendToCryptoInput: " + str.length + "\n");
+ }
+
+ this.cryptoInputBuffer += str;
+ },
+
+ getHeader(hdrStr, fullHeader) {
+ var res = "";
+ var hdrLines = this.headerData.split(/[\r\n]+/);
+ for (let i = 0; i < hdrLines.length; i++) {
+ if (hdrLines[i].length > 0) {
+ if (fullHeader && res !== "") {
+ if (hdrLines[i].search(/^\s+/) === 0) {
+ res += hdrLines[i].replace(/\s*[\r\n]*$/, "");
+ } else {
+ return res;
+ }
+ } else {
+ let j = hdrLines[i].indexOf(":");
+ if (j > 0) {
+ let h = hdrLines[i].substr(0, j).replace(/\s*$/, "");
+ if (h.toLowerCase() == hdrStr.toLowerCase()) {
+ res = hdrLines[i].substr(j + 1).replace(/^\s*/, "");
+ if (!fullHeader) {
+ return res;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return res;
+ },
+
+ getInputForCrypto() {
+ return this.cryptoInputBuffer;
+ },
+
+ addCryptoOutput(s) {
+ LOCAL_DEBUG("mimeEncrypt.js: addCryptoOutput:" + s.length + "\n");
+ this.cryptoOutput += s;
+ this.cryptoOutputLength += s.length;
+ },
+
+ getCryptoOutputLength() {
+ return this.cryptoOutputLength;
+ },
+
+ // API for decryptMessage Listener
+ stdin(pipe) {
+ throw new Error("unexpected");
+ },
+
+ stderr(s) {
+ throw new Error("unexpected");
+ //this.statusStr += s;
+ },
+};
+
+////////////////////////////////////////////////////////////////////
+// General-purpose functions, not exported
+
+function LOCAL_DEBUG(str) {
+ if (gDebugLogLevel) {
+ lazy.EnigmailLog.DEBUG(str);
+ }
+}
+
+function initModule() {
+ lazy.EnigmailLog.DEBUG("mimeEncrypt.jsm: initModule()\n");
+ let nspr_log_modules = Services.env.get("NSPR_LOG_MODULES");
+ let matches = nspr_log_modules.match(/mimeEncrypt:(\d+)/);
+
+ if (matches && matches.length > 1) {
+ gDebugLogLevel = matches[1];
+ LOCAL_DEBUG("mimeEncrypt.js: enabled debug logging\n");
+ }
+}
+
+var EnigmailMimeEncrypt = {
+ Handler: PgpMimeEncrypt,
+
+ startup(reason) {
+ initModule();
+ },
+ shutdown(reason) {},
+
+ createMimeEncrypt(sMimeSecurityInfo) {
+ return new PgpMimeEncrypt(sMimeSecurityInfo);
+ },
+
+ isEnigmailCompField(obj) {
+ return obj instanceof PgpMimeEncrypt;
+ },
+};