Bug 1027241 - Import nsICMS* from Gecko to MailNews Core to fix bustage caused by their removal from Gecko, r=jcranmer, a=jcranmer to reopen CLOSED TREE
authorIan Neal <iann_bugzilla@blueyonder.co.uk>
Sun, 29 Jun 2014 11:52:00 -0500
changeset 16415 a900b3a64007c4b2944abc9948e112ec97acffe2
parent 16414 2e3af17556ad0513080a4cb9e47d6b4a091cf70c
child 16416 497ee03dc80b72ba3208a704f6f9e461f273de50
push id10226
push userPidgeot18@gmail.com
push dateSun, 29 Jun 2014 19:55:01 +0000
treeherdercomm-central@a900b3a64007 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjcranmer, jcranmer
bugs1027241
Bug 1027241 - Import nsICMS* from Gecko to MailNews Core to fix bustage caused by their removal from Gecko, r=jcranmer, a=jcranmer to reopen CLOSED TREE This patch also contains work by Hiroyuki Ikezoe, Brian Smith, and Joshua Cranmer.
mailnews/build/nsMailModule.cpp
mailnews/extensions/smime/src/nsMsgComposeSecure.cpp
mailnews/mime/public/moz.build
mailnews/mime/public/nsICMSDecoder.idl
mailnews/mime/public/nsICMSEncoder.idl
mailnews/mime/public/nsICMSMessage.idl
mailnews/mime/public/nsICMSMessage2.idl
mailnews/mime/public/nsICMSMessageErrors.idl
mailnews/mime/public/nsICMSSecureMessage.idl
mailnews/mime/src/moz.build
mailnews/mime/src/nsCMS.cpp
mailnews/mime/src/nsCMS.h
mailnews/mime/src/nsCMSSecureMessage.cpp
mailnews/mime/src/nsCMSSecureMessage.h
--- a/mailnews/build/nsMailModule.cpp
+++ b/mailnews/build/nsMailModule.cpp
@@ -271,16 +271,18 @@
 // mdn includes
 ///////////////////////////////////////////////////////////////////////////////
 #include "nsMsgMdnCID.h"
 #include "nsMsgMdnGenerator.h"
 
 ///////////////////////////////////////////////////////////////////////////////
 // smime includes
 ///////////////////////////////////////////////////////////////////////////////
+#include "nsCMS.h"
+#include "nsCMSSecureMessage.h"
 #include "nsMsgSMIMECID.h"
 #include "nsMsgComposeSecure.h"
 #include "nsSMimeJSHelper.h"
 #include "nsEncryptedSMIMEURIsService.h"
 
 ///////////////////////////////////////////////////////////////////////////////
 // vcard includes
 ///////////////////////////////////////////////////////////////////////////////
@@ -729,21 +731,29 @@ NS_DEFINE_NAMED_CID(NS_MSGMDNGENERATOR_C
 
 ////////////////////////////////////////////////////////////////////////////////
 // smime factories
 ////////////////////////////////////////////////////////////////////////////////
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgComposeSecure)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgSMIMEComposeFields)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSMimeJSHelper)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsEncryptedSMIMEURIsService)
+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsCMSDecoder, Init)
+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsCMSEncoder, Init)
+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsCMSMessage, Init)
+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsCMSSecureMessage, Init)
 
 NS_DEFINE_NAMED_CID(NS_MSGCOMPOSESECURE_CID);
 NS_DEFINE_NAMED_CID(NS_MSGSMIMECOMPFIELDS_CID);
 NS_DEFINE_NAMED_CID(NS_SMIMEJSJELPER_CID);
 NS_DEFINE_NAMED_CID(NS_SMIMEENCRYPTURISERVICE_CID);
+NS_DEFINE_NAMED_CID(NS_CMSDECODER_CID);
+NS_DEFINE_NAMED_CID(NS_CMSENCODER_CID);
+NS_DEFINE_NAMED_CID(NS_CMSMESSAGE_CID);
+NS_DEFINE_NAMED_CID(NS_CMSSECUREMESSAGE_CID);
 
 ////////////////////////////////////////////////////////////////////////////////
 // vcard factories
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_DEFINE_NAMED_CID(NS_VCARD_CONTENT_TYPE_HANDLER_CID);
 
 // XXX this vcard stuff needs cleaned up to use a generic factory constructor
@@ -1017,16 +1027,20 @@ const mozilla::Module::CIDEntry kMailNew
   { &kNS_MSGMAILVIEWLIST_CID, false, NULL, nsMsgMailViewListConstructor },
   // mdn Entries
   { &kNS_MSGMDNGENERATOR_CID, false, NULL, nsMsgMdnGeneratorConstructor },
   // SMime Entries
   { &kNS_MSGCOMPOSESECURE_CID, false, NULL, nsMsgComposeSecureConstructor },
   { &kNS_MSGSMIMECOMPFIELDS_CID, false, NULL, nsMsgSMIMEComposeFieldsConstructor },
   { &kNS_SMIMEJSJELPER_CID, false, NULL, nsSMimeJSHelperConstructor },
   { &kNS_SMIMEENCRYPTURISERVICE_CID, false, NULL, nsEncryptedSMIMEURIsServiceConstructor },
+  { &kNS_CMSDECODER_CID, false, NULL, nsCMSDecoderConstructor },
+  { &kNS_CMSENCODER_CID, false, NULL, nsCMSEncoderConstructor },
+  { &kNS_CMSMESSAGE_CID, false, NULL, nsCMSMessageConstructor },
+  { &kNS_CMSSECUREMESSAGE_CID, false, NULL, nsCMSSecureMessageConstructor },
   // Vcard Entries
   { &kNS_VCARD_CONTENT_TYPE_HANDLER_CID, false, NULL, nsVCardMimeContentTypeHandlerConstructor},
   // PGP/MIME Entries
   { &kNS_PGPMIME_CONTENT_TYPE_HANDLER_CID, false, NULL, nsPgpMimeMimeContentTypeHandlerConstructor },
   { &kNS_PGPMIMEPROXY_CID, false, NULL, nsPgpMimeProxyConstructor },
   // i18n Entries
   { &kNS_ICHARSETCONVERTERMANAGER_CID, false, nullptr, nsCharsetConverterManagerConstructor },
   { &kNS_UTF7TOUNICODE_CID, false, nullptr, nsUTF7ToUnicodeConstructor },
@@ -1251,16 +1265,20 @@ const mozilla::Module::ContractIDEntry k
   { NS_MSGMAILVIEWLIST_CONTRACTID, &kNS_MSGMAILVIEWLIST_CID },
   // mdn Entries
   { NS_MSGMDNGENERATOR_CONTRACTID, &kNS_MSGMDNGENERATOR_CID },
   // SMime Entries
   { NS_MSGCOMPOSESECURE_CONTRACTID, &kNS_MSGCOMPOSESECURE_CID },
   { NS_MSGSMIMECOMPFIELDS_CONTRACTID, &kNS_MSGSMIMECOMPFIELDS_CID },
   { NS_SMIMEJSHELPER_CONTRACTID, &kNS_SMIMEJSJELPER_CID },
   { NS_SMIMEENCRYPTURISERVICE_CONTRACTID, &kNS_SMIMEENCRYPTURISERVICE_CID },
+  { NS_CMSSECUREMESSAGE_CONTRACTID, &kNS_CMSSECUREMESSAGE_CID },
+  { NS_CMSDECODER_CONTRACTID, &kNS_CMSDECODER_CID },
+  { NS_CMSENCODER_CONTRACTID, &kNS_CMSENCODER_CID },
+  { NS_CMSMESSAGE_CONTRACTID, &kNS_CMSMESSAGE_CID },
   // Vcard Entries
   { "@mozilla.org/mimecth;1?type=text/x-vcard", &kNS_VCARD_CONTENT_TYPE_HANDLER_CID },
   // PGP/MIME Entries
   { "@mozilla.org/mimecth;1?type=multipart/encrypted", &kNS_PGPMIME_CONTENT_TYPE_HANDLER_CID },
   { NS_PGPMIMEPROXY_CONTRACTID, &kNS_PGPMIMEPROXY_CID },
   // i18n Entries
   { NS_CHARSETCONVERTERMANAGER_CONTRACTID, &kNS_ICHARSETCONVERTERMANAGER_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "UTF-7", &kNS_UTF7TOUNICODE_CID },
--- a/mailnews/extensions/smime/src/nsMsgComposeSecure.cpp
+++ b/mailnews/extensions/smime/src/nsMsgComposeSecure.cpp
@@ -4,32 +4,35 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsMsgComposeSecure.h"
 
 #include "msgCore.h"
 #include "nsIMsgCompFields.h"
 #include "nsIMsgIdentity.h"
-#include "nsISMimeCert.h"
 #include "nsIX509CertDB.h"
 #include "nsMimeTypes.h"
 #include "nsMsgMimeCID.h"
 #include "nspr.h"
 #include "nsComponentManagerUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsMemory.h"
 #include "nsAlgorithm.h"
+#include "mozilla/RefPtr.h"
 #include "mozilla/Services.h"
 #include "mozilla/mailnews/MimeEncoder.h"
 #include "mozilla/mailnews/MimeHeaderParser.h"
 #include "nsIMimeConverter.h"
+#include "nsIX509Cert2.h"
+#include "ScopedNSSTypes.h"
 #include <algorithm>
 
 using namespace mozilla::mailnews;
+using namespace mozilla;
 
 #define MK_MIME_ERROR_WRITING_FILE -1
 
 #define SMIME_STRBUNDLE_URL "chrome://messenger/locale/am-smime.properties"
 
 // It doesn't make sense to encode the message because the message will be
 // displayed only if the MUA doesn't support MIME.
 // We need to consider what to do in case the server doesn't support 8BITMIME.
@@ -795,20 +798,29 @@ nsresult nsMsgComposeSecure::MimeCryptoH
     SetError(sendReport, MOZ_UTF16("NoSenderEncryptionCert"));
     return NS_ERROR_FAILURE;
   }
 
 
   if (aEncrypt && mSelfEncryptionCert) {
     // Make sure self's configured cert is prepared for being used
     // as an email recipient cert.
-    
-    nsCOMPtr<nsISMimeCert> sc = do_QueryInterface(mSelfEncryptionCert);
-    if (sc) {
-      sc->SaveSMimeProfile();
+    nsCOMPtr<nsIX509Cert2> cert2 = do_QueryInterface(mSelfEncryptionCert);
+    if (!cert2) {
+      return NS_ERROR_FAILURE;
+    }
+
+    mozilla::ScopedCERTCertificate nsscert;
+    nsscert = cert2->GetCert();
+    if (!nsscert) {
+      return NS_ERROR_FAILURE;
+    }
+    // XXX: This does not respect the nsNSSShutDownObject protocol.
+    if (CERT_SaveSMimeProfile(nsscert, nullptr, nullptr) != SECSuccess) {
+      return NS_ERROR_FAILURE;
     }
   }
 
   /* If the message is to be encrypted, then get the recipient certs */
   if (aEncrypt) {
     nsTArray<nsCString> mailboxes;
     ExtractEmails(EncodedHeader(nsDependentCString(aRecipients)),
       UTF16ArrayAdapter<>(mailboxes));
--- a/mailnews/mime/public/moz.build
+++ b/mailnews/mime/public/moz.build
@@ -1,14 +1,20 @@
 # vim: set filetype=python:
 # 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 http://mozilla.org/MPL/2.0/.
 
 XPIDL_SOURCES += [
+    'nsICMSDecoder.idl',
+    'nsICMSEncoder.idl',
+    'nsICMSMessage.idl',
+    'nsICMSMessage2.idl',
+    'nsICMSMessageErrors.idl',
+    'nsICMSSecureMessage.idl',
     'nsIMimeConverter.idl',
     'nsIMimeEmitter.idl',
     'nsIMimeHeaders.idl',
     'nsIMimeMiscStatus.idl',
     'nsIMimeStreamConverter.idl',
     'nsIMsgHeaderParser.idl',
     'nsIPgpMimeProxy.idl',
     'nsISimpleMimeConverter.idl',
--- a/mailnews/mime/public/nsICMSDecoder.idl
+++ b/mailnews/mime/public/nsICMSDecoder.idl
@@ -14,16 +14,16 @@ typedef void (*NSSCMSContentCallback)(vo
 native NSSCMSContentCallback(NSSCMSContentCallback);
 
 interface nsICMSMessage;
 
 /**
  * nsICMSDecoder
  *  Interface to decode an CMS message
  */
-[uuid(65244a06-a342-11d5-ba47-00108303b117)]
+[uuid(c7c7033b-f341-4065-aadd-7eef55ce0dda)]
 interface nsICMSDecoder : nsISupports
 {
   void start(in NSSCMSContentCallback cb, in voidPtr arg);
   void update(in string aBuf, in long aLen);
   void finish(out nsICMSMessage msg);
 };
 
--- a/mailnews/mime/public/nsICMSEncoder.idl
+++ b/mailnews/mime/public/nsICMSEncoder.idl
@@ -14,17 +14,17 @@ typedef void (*NSSCMSContentCallback)(vo
 native NSSCMSContentCallback(NSSCMSContentCallback);
 
 interface nsICMSMessage;
 
 /**
  * nsICMSEncoder
  *  Interface to Encode an CMS message
  */
-[uuid(a15789aa-8903-462b-81e9-4aa2cff4d5cb)]
+[uuid(17dc4fb4-e379-4e56-a4a4-57cdcc74816f)]
 interface nsICMSEncoder : nsISupports
 {
   void start(in nsICMSMessage aMsg, in NSSCMSContentCallback cb, in voidPtr arg);
   void update(in string aBuf, in long aLen);
   void finish();
   void encode(in nsICMSMessage aMsg);
 };
 
--- a/mailnews/mime/public/nsICMSMessage.idl
+++ b/mailnews/mime/public/nsICMSMessage.idl
@@ -13,17 +13,17 @@
 
 interface nsIX509Cert;
 interface nsIArray;
 
 /**
  * nsICMSMessage
  *  Interface to a CMS Message
  */
-[uuid(a4557478-ae16-11d5-ba4b-00108303b117)]
+[uuid(cfd6af3d-8ac6-401a-afc8-3f94275c1c11)]
 interface nsICMSMessage : nsISupports
 {
   void contentIsSigned(out boolean aSigned);
   void contentIsEncrypted(out boolean aEncrypted);
   void getSignerCommonName(out string aName);
   void getSignerEmailAddress(out string aEmail);
   void getSignerCert(out nsIX509Cert scert);
   void getEncryptionCert(out nsIX509Cert ecert);
--- a/mailnews/mime/public/nsICMSMessage2.idl
+++ b/mailnews/mime/public/nsICMSMessage2.idl
@@ -10,17 +10,17 @@ interface nsISMimeVerificationListener;
 
 /*
  * This interface is currently not marked scriptable,
  * because its verification functions are meant to look like those
  * in nsICMSMessage. At the time the ptr type is eliminated in both 
  * interfaces, both should be made scriptable.
  */
 
-[uuid(a99a3203-39e3-45e1-909c-175b0e471c2b)]
+[uuid(b21a3636-2287-4b9f-9a22-25f245981ef0)]
 interface nsICMSMessage2 : nsISupports
 {
   /**
     * Async version of nsICMSMessage::VerifySignature.
     * Code will be executed on a background thread and
     * availability of results will be notified using a 
     * call to nsISMimeVerificationListener.
    */
@@ -43,17 +43,17 @@ interface nsICMSMessage2 : nsISupports
     *     in octet aDigestData,
     *     in unsigned long aDigestDataLen);
    */
   void asyncVerifyDetachedSignature(in nsISMimeVerificationListener listener,
                                      in UnsignedCharPtr aDigestData, 
                                      in unsigned long aDigestDataLen);
 };
 
-[uuid(56310af6-dffc-48b4-abca-85eae4059064)]
+[uuid(5226d698-0773-4f25-b94c-7944b3fc01d3)]
 interface nsISMimeVerificationListener : nsISupports {
 
   /**
    *  Notify that results are ready, that have been requested
    *  using nsICMSMessage2::asyncVerify[Detached]Signature()
    *
    *  verificationResultCode matches synchronous result code from
    *  nsICMSMessage::verify[Detached]Signature
--- a/mailnews/mime/public/nsICMSMessageErrors.idl
+++ b/mailnews/mime/public/nsICMSMessageErrors.idl
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 /**
  * nsICMSMessageErrors
  *  Scriptable error constants for nsICMSMessage
  */
-[scriptable,uuid(f2aec680-60a0-49f0-afe5-6cf1d3f15e0d)]
+[scriptable,uuid(267f1a5b-88f7-413b-bc49-487e745282f1)]
 interface nsICMSMessageErrors : nsISupports
 {
   const long SUCCESS = 0;
   const long GENERAL_ERROR = 1;
   const long VERIFY_NOT_SIGNED = 1024;
   const long VERIFY_NO_CONTENT_INFO = 1025;
   const long VERIFY_BAD_DIGEST = 1026;
   const long VERIFY_NOCERT = 1028;
--- a/mailnews/mime/public/nsICMSSecureMessage.idl
+++ b/mailnews/mime/public/nsICMSSecureMessage.idl
@@ -6,17 +6,17 @@
 #include "nsISupports.idl"
 
 interface nsIX509Cert;
 
 /**
  * nsICMSManager (service)
  *  Interface to access users certificate store
  */
-[scriptable, uuid(14b4394a-1dd2-11b2-b4fd-ba4a194fe97e)]
+[scriptable, uuid(17103436-0111-4819-a751-0fc4aa6e3d79)]
 interface nsICMSSecureMessage : nsISupports
 {
   /**
    * getCertByPrefID - a BASE64 string representing a user's
    *   certificate (or NULL if there isn't one)
    */
   string getCertByPrefID(in string certID);
 
--- a/mailnews/mime/src/moz.build
+++ b/mailnews/mime/src/moz.build
@@ -57,21 +57,29 @@ SOURCES += [
     'mimetext.cpp',
     'mimethpl.cpp',
     'mimethsa.cpp',
     'mimethtm.cpp',
     'mimetpfl.cpp',
     'mimetpla.cpp',
     'mimetric.cpp',
     'mimeunty.cpp',
+    'nsCMS.cpp',
+    'nsCMSSecureMessage.cpp',
     'nsMimeObjectClassAccess.cpp',
     'nsSimpleMimeConverterStub.cpp',
     'nsStreamConverter.cpp',
 ]
 
+LOCAL_INCLUDES += [
+     '/mozilla/security/certverifier',
+     '/mozilla/security/manager/ssl/src',
+     '/mozilla/security/pkix/include',
+]
+
 EXTRA_COMPONENTS += [
     'mimeJSComponents.js',
     'msgMime.manifest',
 ]
 
 EXTRA_JS_MODULES += [
     'jsmime.jsm',
     'mimeParser.jsm'
--- a/mailnews/mime/src/nsCMS.cpp
+++ b/mailnews/mime/src/nsCMS.cpp
@@ -1,26 +1,33 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 http://mozilla.org/MPL/2.0/. */
 
 #include "nsCMS.h"
 
+#include "nsIX509CertDB.h"
 #include "CertVerifier.h"
+#include "CryptoTask.h"
+#include "mozilla/RefPtr.h"
 #include "pkix/pkixtypes.h"
 #include "nsISupports.h"
 #include "nsNSSHelper.h"
 #include "nsNSSCertificate.h"
+#include "ScopedNSSTypes.h"
 #include "smime.h"
 #include "cms.h"
+#include "nsNSSComponent.h"
 #include "nsICMSMessageErrors.h"
 #include "nsIArray.h"
 #include "nsArrayUtils.h"
 #include "nsCertVerificationThread.h"
+#include "nsServiceManagerUtils.h"
+#include "mozilla/RefPtr.h"
 
 #include "prlog.h"
 
 using namespace mozilla;
 using namespace mozilla::psm;
 
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* gPIPNSSLog;
@@ -44,16 +51,23 @@ nsCMSMessage::~nsCMSMessage()
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     return;
   }
   destructorSafeDestroyNSSReference();
   shutdown(calledFromObject);
 }
 
+nsresult nsCMSMessage::Init()
+{
+  nsresult rv;
+  nsCOMPtr<nsISupports> nssInitialized = do_GetService("@mozilla.org/psm;1", &rv);
+  return rv;
+}
+
 void nsCMSMessage::virtualDestroyNSSReference()
 {
   destructorSafeDestroyNSSReference();
 }
 
 void nsCMSMessage::destructorSafeDestroyNSSReference()
 {
   if (m_cmsMsg) {
@@ -163,31 +177,34 @@ NS_IMETHODIMP nsCMSMessage::GetSignerCer
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown())
     return NS_ERROR_NOT_AVAILABLE;
 
   NSSCMSSignerInfo *si = GetTopLevelSignerInfo();
   if (!si)
     return NS_ERROR_FAILURE;
 
+  nsCOMPtr<nsIX509Cert> cert;
   if (si->cert) {
     PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::GetSignerCert got signer cert\n"));
 
-    *scert = nsNSSCertificate::Create(si->cert);
-    if (*scert) {
-      (*scert)->AddRef();
-    }
+    nsCOMPtr<nsIX509CertDB> certdb = do_GetService(NS_X509CERTDB_CONTRACTID);
+    certdb->ConstructX509(reinterpret_cast<const char *>(si->cert->derCert.data),
+                          si->cert->derCert.len,
+                          getter_AddRefs(cert));
   }
   else {
     PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::GetSignerCert no signer cert, do we have a cert list? %s\n",
       (si->certList ? "yes" : "no") ));
 
     *scert = nullptr;
   }
-  
+
+  cert.forget(scert);
+
   return NS_OK;
 }
 
 NS_IMETHODIMP nsCMSMessage::GetEncryptionCert(nsIX509Cert **ecert)
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown())
     return NS_ERROR_NOT_AVAILABLE;
@@ -272,16 +289,21 @@ nsresult nsCMSMessage::CommonVerifySigna
       PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
              ("nsCMSMessage::CommonVerifySignature - signing cert not trusted now\n"));
       rv = NS_ERROR_CMS_VERIFY_UNTRUSTED;
       goto loser;
     }
   }
 
   // We verify the first signer info,  only //
+  // XXX: NSS_CMSSignedData_VerifySignerInfo calls CERT_VerifyCert, which
+  // requires NSS's certificate verification configuration to be done in
+  // order to work well (e.g. honoring OCSP preferences and proxy settings
+  // for OCSP requests), but Gecko stopped doing that configuration. Something
+  // similar to what was done for Gecko bug 1028643 needs to be done here too.
   if (NSS_CMSSignedData_VerifySignerInfo(sigd, 0, CERT_GetDefaultCertDB(), certUsageEmailSigner) != SECSuccess) {
     PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - unable to verify signature\n"));
 
     if (NSSCMSVS_SigningCertNotFound == si->verificationStatus) {
       PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - signing cert not found\n"));
       rv = NS_ERROR_CMS_VERIFY_NOCERT;
     }
     else if(NSSCMSVS_SigningCertNotTrusted == si->verificationStatus) {
@@ -341,40 +363,64 @@ NS_IMETHODIMP nsCMSMessage::AsyncVerifyD
                               unsigned char* aDigestData, uint32_t aDigestDataLen)
 {
   if (!aDigestData || !aDigestDataLen)
     return NS_ERROR_FAILURE;
 
   return CommonAsyncVerifySignature(aListener, aDigestData, aDigestDataLen);
 }
 
+class SMimeVerificationTask MOZ_FINAL : public CryptoTask
+{
+public:
+  SMimeVerificationTask(nsICMSMessage *aMessage,
+                        nsISMimeVerificationListener *aListener,
+                        unsigned char *aDigestData, uint32_t aDigestDataLen)
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    mMessage = aMessage;
+    mListener = aListener;
+    mDigestData.Assign(reinterpret_cast<char *>(aDigestData), aDigestDataLen);
+  }
+
+private:
+  virtual void ReleaseNSSResources() MOZ_OVERRIDE {}
+  virtual nsresult CalculateResult() MOZ_OVERRIDE
+  {
+    MOZ_ASSERT(!NS_IsMainThread());
+
+    nsresult rv;
+    if (!mDigestData.IsEmpty()) {
+      rv = mMessage->VerifyDetachedSignature(
+        reinterpret_cast<uint8_t*>(const_cast<char *>(mDigestData.get())),
+        mDigestData.Length());
+    } else {
+      rv = mMessage->VerifySignature();
+    }
+
+    return rv;
+  }
+  virtual void CallCallback(nsresult rv) MOZ_OVERRIDE
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+
+    nsCOMPtr<nsICMSMessage2> m2 = do_QueryInterface(mMessage);
+    mListener->Notify(m2, rv);
+  }
+
+  nsCOMPtr<nsICMSMessage> mMessage;
+  nsCOMPtr<nsISMimeVerificationListener> mListener;
+  nsCString mDigestData;
+};
+
 nsresult nsCMSMessage::CommonAsyncVerifySignature(nsISMimeVerificationListener *aListener,
                                                   unsigned char* aDigestData, uint32_t aDigestDataLen)
 {
-  nsSMimeVerificationJob *job = new nsSMimeVerificationJob;
-  
-  if (aDigestData)
-  {
-    job->digest_data = new unsigned char[aDigestDataLen];
-    memcpy(job->digest_data, aDigestData, aDigestDataLen);
-  }
-  else
-  {
-    job->digest_data = nullptr;
-  }
-  
-  job->digest_len = aDigestDataLen;
-  job->mMessage = this;
-  job->mListener = aListener;
-
-  nsresult rv = nsCertVerificationThread::addJob(job);
-  if (NS_FAILED(rv))
-    delete job;
-
-  return rv;
+  RefPtr<CryptoTask> task = new SMimeVerificationTask(this, aListener, aDigestData, aDigestDataLen);
+  return task->Dispatch("SMimeVerify");
 }
 
 class nsZeroTerminatedCertArray : public nsNSSShutDownObject
 {
 public:
   nsZeroTerminatedCertArray()
   :mCerts(nullptr), mPoolp(nullptr), mSize(0)
   {
@@ -511,17 +557,17 @@ NS_IMETHODIMP nsCMSMessage::CreateEncryp
   for (i=0; i<recipientCertCount; i++) {
     nsCOMPtr<nsIX509Cert> x509cert = do_QueryElementAt(aRecipientCerts, i);
 
     nssRecipientCert = do_QueryInterface(x509cert);
 
     if (!nssRecipientCert)
       return NS_ERROR_FAILURE;
 
-    mozilla::pkix::ScopedCERTCertificate c(nssRecipientCert->GetCert());
+    mozilla::ScopedCERTCertificate c(nssRecipientCert->GetCert());
     recipientCerts.set(i, c.get());
   }
   
   // Find a bulk key algorithm //
   if (NSS_SMIMEUtil_FindBulkAlgForRecipients(recipientCerts.getRawArray(), &bulkAlgTag,
                                             &keySize) != SECSuccess) {
     PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateEncrypted - can't find bulk alg for recipients\n"));
     rv = NS_ERROR_CMS_ENCRYPT_NO_BULK_ALG;
@@ -549,17 +595,17 @@ NS_IMETHODIMP nsCMSMessage::CreateEncryp
   cinfo = NSS_CMSEnvelopedData_GetContentInfo(envd);
   if (NSS_CMSContentInfo_SetContent_Data(m_cmsMsg, cinfo, nullptr, false) != SECSuccess) {
     PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateEncrypted - can't set content data\n"));
     goto loser;
   }
 
   // Create and attach recipient information //
   for (i=0; i < recipientCertCount; i++) {
-    mozilla::pkix::ScopedCERTCertificate rc(recipientCerts.get(i));
+    mozilla::ScopedCERTCertificate rc(recipientCerts.get(i));
     if ((recipientInfo = NSS_CMSRecipientInfo_Create(m_cmsMsg, rc.get())) == nullptr) {
       PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateEncrypted - can't create recipient info\n"));
       goto loser;
     }
     if (NSS_CMSEnvelopedData_AddRecipient(envd, recipientInfo) != SECSuccess) {
       PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateEncrypted - can't add recipient info\n"));
       goto loser;
     }
@@ -580,18 +626,18 @@ NS_IMETHODIMP nsCMSMessage::CreateSigned
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown())
     return NS_ERROR_NOT_AVAILABLE;
 
   PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned\n"));
   NSSCMSContentInfo *cinfo;
   NSSCMSSignedData *sigd;
   NSSCMSSignerInfo *signerinfo;
-  mozilla::pkix::ScopedCERTCertificate scert;
-  mozilla::pkix::ScopedCERTCertificate ecert;
+  mozilla::ScopedCERTCertificate scert;
+  mozilla::ScopedCERTCertificate ecert;
   nsCOMPtr<nsIX509Cert2> aSigningCert2 = do_QueryInterface(aSigningCert);
   nsresult rv = NS_ERROR_FAILURE;
 
   /* Get the certs */
   if (aSigningCert2) {
     scert = aSigningCert2->GetCert();
   }
   if (!scert) {
@@ -731,16 +777,23 @@ nsCMSDecoder::~nsCMSDecoder()
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     return;
   }
   destructorSafeDestroyNSSReference();
   shutdown(calledFromObject);
 }
 
+nsresult nsCMSDecoder::Init()
+{
+  nsresult rv;
+  nsCOMPtr<nsISupports> nssInitialized = do_GetService("@mozilla.org/psm;1", &rv);
+  return rv;
+}
+
 void nsCMSDecoder::virtualDestroyNSSReference()
 {
   destructorSafeDestroyNSSReference();
 }
 
 void nsCMSDecoder::destructorSafeDestroyNSSReference()
 {
   if (m_dcx) {
@@ -814,16 +867,23 @@ nsCMSEncoder::~nsCMSEncoder()
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     return;
   }
   destructorSafeDestroyNSSReference();
   shutdown(calledFromObject);
 }
 
+nsresult nsCMSEncoder::Init()
+{
+  nsresult rv;
+  nsCOMPtr<nsISupports> nssInitialized = do_GetService("@mozilla.org/psm;1", &rv);
+  return rv;
+}
+
 void nsCMSEncoder::virtualDestroyNSSReference()
 {
   destructorSafeDestroyNSSReference();
 }
 
 void nsCMSEncoder::destructorSafeDestroyNSSReference()
 {
   if (m_ecx)
--- a/mailnews/mime/src/nsCMS.h
+++ b/mailnews/mime/src/nsCMS.h
@@ -8,17 +8,16 @@
 
 #include "nsISupports.h"
 #include "nsCOMPtr.h"
 #include "nsXPIDLString.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsICMSMessage.h"
 #include "nsICMSMessage2.h"
 #include "nsIX509Cert3.h"
-#include "nsVerificationJob.h"
 #include "nsICMSEncoder.h"
 #include "nsICMSDecoder.h"
 #include "sechash.h"
 #include "cms.h"
 #include "nsNSSShutDown.h"
 
 #define NS_CMSMESSAGE_CID \
   { 0xa4557478, 0xae16, 0x11d5, { 0xba,0x4b,0x00,0x10,0x83,0x03,0xb1,0x17 } }
@@ -30,32 +29,32 @@ class nsCMSMessage : public nsICMSMessag
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSICMSMESSAGE
   NS_DECL_NSICMSMESSAGE2
 
   nsCMSMessage();
   nsCMSMessage(NSSCMSMessage* aCMSMsg);
   virtual ~nsCMSMessage();
-  
+  nsresult Init();
+
   void referenceContext(nsIInterfaceRequestor* aContext) {m_ctx = aContext;}
   NSSCMSMessage* getCMS() {return m_cmsMsg;}
 private:
   nsCOMPtr<nsIInterfaceRequestor> m_ctx;
   NSSCMSMessage * m_cmsMsg;
   NSSCMSSignerInfo* GetTopLevelSignerInfo();
   nsresult CommonVerifySignature(unsigned char* aDigestData, uint32_t aDigestDataLen);
 
   nsresult CommonAsyncVerifySignature(nsISMimeVerificationListener *aListener,
                                       unsigned char* aDigestData, uint32_t aDigestDataLen);
 
   virtual void virtualDestroyNSSReference();
   void destructorSafeDestroyNSSReference();
 
-friend class nsSMimeVerificationJob;
 };
 
 // ===============================================
 // nsCMSDecoder - implementation of nsICMSDecoder
 // ===============================================
 
 #define NS_CMSDECODER_CID \
   { 0x9dcef3a4, 0xa3bc, 0x11d5, { 0xba, 0x47, 0x00, 0x10, 0x83, 0x03, 0xb1, 0x17 } }
@@ -64,16 +63,17 @@ class nsCMSDecoder : public nsICMSDecode
                      public nsNSSShutDownObject
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSICMSDECODER
 
   nsCMSDecoder();
   virtual ~nsCMSDecoder();
+  nsresult Init();
 
 private:
   nsCOMPtr<nsIInterfaceRequestor> m_ctx;
   NSSCMSDecoderContext *m_dcx;
   virtual void virtualDestroyNSSReference();
   void destructorSafeDestroyNSSReference();
 };
 
@@ -87,16 +87,17 @@ class nsCMSEncoder : public nsICMSEncode
                      public nsNSSShutDownObject
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSICMSENCODER
 
   nsCMSEncoder();
   virtual ~nsCMSEncoder();
+  nsresult Init();
 
 private:
   nsCOMPtr<nsIInterfaceRequestor> m_ctx;
   NSSCMSEncoderContext *m_ecx;
   virtual void virtualDestroyNSSReference();
   void destructorSafeDestroyNSSReference();
 };
 
--- a/mailnews/mime/src/nsCMSSecureMessage.cpp
+++ b/mailnews/mime/src/nsCMSSecureMessage.cpp
@@ -3,22 +3,24 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsXPIDLString.h"
 #include "nsCOMPtr.h"
 #include "nsISupports.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsCRT.h"
+#include "nsIX509CertDB.h"
 
 #include "nsICMSSecureMessage.h"
 
 #include "nsCMSSecureMessage.h"
+#include "nsIX509Cert.h"
+#include "nsNSSHelper.h"
 #include "nsNSSCertificate.h"
-#include "nsNSSHelper.h"
 #include "nsNSSShutDown.h"
 
 #include <string.h>
 #include "plbase64.h"
 #include "cert.h"
 #include "cms.h"
 
 #include "nsIServiceManager.h"
@@ -46,16 +48,23 @@ nsCMSSecureMessage::nsCMSSecureMessage()
   // initialize superclass
 }
 
 // nsCMSMessage destructor
 nsCMSSecureMessage::~nsCMSSecureMessage()
 {
 }
 
+nsresult nsCMSSecureMessage::Init()
+{
+  nsresult rv;
+  nsCOMPtr<nsISupports> nssInitialized = do_GetService("@mozilla.org/psm;1", &rv);
+  return rv;
+}
+
 /* string getCertByPrefID (in string certID); */
 NS_IMETHODIMP nsCMSSecureMessage::
 GetCertByPrefID(const char *certID, char **_retval)
 {
   nsNSSShutDownPreventionLock locker;
   PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSSecureMessage::GetCertByPrefID\n"));
   nsresult rv = NS_OK;
   CERTCertificate *cert = 0;
@@ -107,17 +116,23 @@ DecodeCert(const char *value, nsIX509Cer
   if (!value) { return NS_ERROR_FAILURE; }
 
   rv = decode(value, &data, &length);
   if (NS_FAILED(rv)) {
     PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSSecureMessage::DecodeCert - can't decode cert\n"));
     return rv;
   }
 
-  nsCOMPtr<nsIX509Cert> cert =  nsNSSCertificate::ConstructFromDER((char *)data, length);
+  nsCOMPtr<nsIX509CertDB> certdb = do_GetService(NS_X509CERTDB_CONTRACTID);
+  if (!certdb) {
+    return NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<nsIX509Cert> cert;
+  certdb->ConstructX509(reinterpret_cast<char *>(data), length, getter_AddRefs(cert));
 
   if (cert) {
     *_retval = cert;
     NS_ADDREF(*_retval);
   }
   else {
     rv = NS_ERROR_FAILURE;
   }
--- a/mailnews/mime/src/nsCMSSecureMessage.h
+++ b/mailnews/mime/src/nsCMSSecureMessage.h
@@ -21,16 +21,17 @@ class nsCMSSecureMessage
 : public nsICMSSecureMessage
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSICMSSECUREMESSAGE
 
   nsCMSSecureMessage();
   virtual ~nsCMSSecureMessage();
+  nsresult Init();
 
 private:
   NS_METHOD encode(const unsigned char *data, int32_t dataLen, char **_retval);
   NS_METHOD decode(const char *data, unsigned char **result, int32_t * _retval);
 };
 
 
 #endif /* _NSCMSMESSAGE_H_ */