Bug 611752: Remove XPCOM CMS interfaces (nsICMS* and nsISMimeCert), r=keeler

--HG--
extra : rebase_source : d5f70ff8b084fa9d53309d28d2ad478a478f4ff6
This commit is contained in:
Brian Smith 2014-06-15 20:51:51 -07:00
parent d779fddb49
commit d8d1c2c63a
19 changed files with 0 additions and 1707 deletions

View File

@ -48,7 +48,6 @@ nsNSSDialogs::~nsNSSDialogs()
}
NS_IMPL_ISUPPORTS(nsNSSDialogs, nsITokenPasswordDialogs,
nsICertificateDialogs,
nsIClientAuthDialogs,
nsICertPickDialogs,
nsITokenDialogs,

View File

@ -15,12 +15,6 @@ XPIDL_SOURCES += [
'nsICertOverrideService.idl',
'nsICertPickDialogs.idl',
'nsIClientAuthDialogs.idl',
'nsICMSDecoder.idl',
'nsICMSEncoder.idl',
'nsICMSMessage.idl',
'nsICMSMessage2.idl',
'nsICMSMessageErrors.idl',
'nsICMSSecureMessage.idl',
'nsIDataSignatureVerifier.idl',
'nsIDOMCryptoDialogs.idl',
'nsIFormSigningDialog.idl',
@ -39,7 +33,6 @@ XPIDL_SOURCES += [
'nsIProtectedAuthThread.idl',
'nsIRecentBadCertsService.idl',
'nsISignatureVerifier.idl',
'nsISMimeCert.idl',
'nsISSLErrorListener.idl',
'nsISSLStatus.idl',
'nsIStreamCipher.idl',

View File

@ -1,29 +0,0 @@
/* -*- 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 "nsISupports.idl"
%{ C++
typedef void (*NSSCMSContentCallback)(void *arg, const char *buf, unsigned long len);
#define NS_CMSDECODER_CONTRACTID "@mozilla.org/nsCMSDecoder;1"
%}
native NSSCMSContentCallback(NSSCMSContentCallback);
interface nsICMSMessage;
/**
* nsICMSDecoder
* Interface to decode an CMS message
*/
[uuid(65244a06-a342-11d5-ba47-00108303b117)]
interface nsICMSDecoder : nsISupports
{
void start(in NSSCMSContentCallback cb, in voidPtr arg);
void update(in string aBuf, in long aLen);
void finish(out nsICMSMessage msg);
};

View File

@ -1,30 +0,0 @@
/* -*- 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 "nsISupports.idl"
%{ C++
typedef void (*NSSCMSContentCallback)(void *arg, const char *buf, unsigned long len);
#define NS_CMSENCODER_CONTRACTID "@mozilla.org/nsCMSEncoder;1"
%}
native NSSCMSContentCallback(NSSCMSContentCallback);
interface nsICMSMessage;
/**
* nsICMSEncoder
* Interface to Encode an CMS message
*/
[uuid(a15789aa-8903-462b-81e9-4aa2cff4d5cb)]
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);
};

View File

@ -1,35 +0,0 @@
/* -*- 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 "nsISupports.idl"
%{ C++
#define NS_CMSMESSAGE_CONTRACTID "@mozilla.org/nsCMSMessage;1"
%}
[ptr] native UnsignedCharPtr(unsigned char);
interface nsIX509Cert;
interface nsIArray;
/**
* nsICMSMessage
* Interface to a CMS Message
*/
[uuid(a4557478-ae16-11d5-ba4b-00108303b117)]
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);
void verifySignature();
void verifyDetachedSignature(in UnsignedCharPtr aDigestData, in unsigned long aDigestDataLen);
void CreateEncrypted(in nsIArray aRecipientCerts);
void CreateSigned(in nsIX509Cert scert, in nsIX509Cert ecert, in UnsignedCharPtr aDigestData, in unsigned long aDigestDataLen);
};

View File

@ -1,64 +0,0 @@
/* 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 "nsISupports.idl"
interface nsISMimeVerificationListener;
[ptr] native UnsignedCharPtr(unsigned char);
/*
* 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)]
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.
*/
void asyncVerifySignature(in nsISMimeVerificationListener listener);
/**
* Async version of nsICMSMessage::VerifyDetachedSignature.
* Code will be executed on a background thread and
* availability of results will be notified using a
* call to nsISMimeVerificationListener.
*
* We are using "native unsigned char" ptr, because the function
* signatures of this one and nsICMSMessage::verifyDetachedSignature
* should be the identical. Cleaning up nsICMSMessages needs to be
* postponed, because this async version is needed on MOZILLA_1_8_BRANCH.
*
* Once both interfaces get cleaned up, the function signature should
* look like:
* [array, length_is(aDigestDataLen)]
* 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)]
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
*/
void notify(in nsICMSMessage2 verifiedMessage,
in nsresult verificationResultCode);
};

View File

@ -1,35 +0,0 @@
/* -*- 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 "nsISupports.idl"
/**
* nsICMSMessageErrors
* Scriptable error constants for nsICMSMessage
*/
[scriptable,uuid(f2aec680-60a0-49f0-afe5-6cf1d3f15e0d)]
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;
const long VERIFY_UNTRUSTED = 1029;
const long VERIFY_ERROR_UNVERIFIED = 1031;
const long VERIFY_ERROR_PROCESSING = 1032;
const long VERIFY_BAD_SIGNATURE = 1033;
const long VERIFY_DIGEST_MISMATCH = 1034;
const long VERIFY_UNKNOWN_ALGO = 1035;
const long VERIFY_UNSUPPORTED_ALGO = 1036;
const long VERIFY_MALFORMED_SIGNATURE = 1037;
const long VERIFY_HEADER_MISMATCH = 1038;
const long VERIFY_NOT_YET_ATTEMPTED = 1039;
const long VERIFY_CERT_WITHOUT_ADDRESS = 1040;
const long ENCRYPT_NO_BULK_ALG = 1056;
const long ENCRYPT_INCOMPLETE = 1057;
};

View File

@ -1,42 +0,0 @@
/* -*- 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 "nsISupports.idl"
interface nsIX509Cert;
/**
* nsICMSManager (service)
* Interface to access users certificate store
*/
[scriptable, uuid(14b4394a-1dd2-11b2-b4fd-ba4a194fe97e)]
interface nsICMSSecureMessage : nsISupports
{
/**
* getCertByPrefID - a BASE64 string representing a user's
* certificate (or NULL if there isn't one)
*/
string getCertByPrefID(in string certID);
/**
* decodeCert - decode a BASE64 string into an X509Certificate object
*/
nsIX509Cert decodeCert(in string value);
/**
* sendMessage - send a text message to the recipient indicated
* by the base64-encoded cert.
*/
string sendMessage(in string msg, in string cert);
/**
* receiveMessage - receive an encrypted (enveloped) message
*/
string receiveMessage(in string msg);
};
%{C++
#define NS_CMSSECUREMESSAGE_CONTRACTID "@mozilla.org/nsCMSSecureMessage;1"
%}

View File

@ -1,13 +0,0 @@
/* -*- 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 "nsISupports.idl"
[scriptable, uuid(66710f97-a4dd-49f1-a906-fe0ebc5924c0)]
interface nsISMimeCert : nsISupports {
void saveSMimeProfile();
};

View File

@ -24,8 +24,6 @@ SOURCES += [
'nsCertPicker.cpp',
'nsCertVerificationThread.cpp',
'nsClientAuthRemember.cpp',
'nsCMS.cpp',
'nsCMSSecureMessage.cpp',
'nsCrypto.cpp',
'nsDataSignatureVerifier.cpp',
'nsKeygenHandler.cpp',

View File

@ -1,893 +0,0 @@
/* -*- 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 "CertVerifier.h"
#include "pkix/pkixtypes.h"
#include "nsISupports.h"
#include "nsNSSHelper.h"
#include "nsNSSCertificate.h"
#include "smime.h"
#include "cms.h"
#include "nsICMSMessageErrors.h"
#include "nsIArray.h"
#include "nsArrayUtils.h"
#include "nsCertVerificationThread.h"
#include "prlog.h"
using namespace mozilla;
using namespace mozilla::psm;
#ifdef PR_LOGGING
extern PRLogModuleInfo* gPIPNSSLog;
#endif
using namespace mozilla;
NS_IMPL_ISUPPORTS(nsCMSMessage, nsICMSMessage, nsICMSMessage2)
nsCMSMessage::nsCMSMessage()
{
m_cmsMsg = nullptr;
}
nsCMSMessage::nsCMSMessage(NSSCMSMessage *aCMSMsg)
{
m_cmsMsg = aCMSMsg;
}
nsCMSMessage::~nsCMSMessage()
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown()) {
return;
}
destructorSafeDestroyNSSReference();
shutdown(calledFromObject);
}
void nsCMSMessage::virtualDestroyNSSReference()
{
destructorSafeDestroyNSSReference();
}
void nsCMSMessage::destructorSafeDestroyNSSReference()
{
if (m_cmsMsg) {
NSS_CMSMessage_Destroy(m_cmsMsg);
}
}
NS_IMETHODIMP nsCMSMessage::VerifySignature()
{
return CommonVerifySignature(nullptr, 0);
}
NSSCMSSignerInfo* nsCMSMessage::GetTopLevelSignerInfo()
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return nullptr;
if (!m_cmsMsg)
return nullptr;
if (!NSS_CMSMessage_IsSigned(m_cmsMsg))
return nullptr;
NSSCMSContentInfo *cinfo = NSS_CMSMessage_ContentLevel(m_cmsMsg, 0);
if (!cinfo)
return nullptr;
NSSCMSSignedData *sigd = (NSSCMSSignedData*)NSS_CMSContentInfo_GetContent(cinfo);
if (!sigd)
return nullptr;
PR_ASSERT(NSS_CMSSignedData_SignerInfoCount(sigd) > 0);
return NSS_CMSSignedData_GetSignerInfo(sigd, 0);
}
NS_IMETHODIMP nsCMSMessage::GetSignerEmailAddress(char * * aEmail)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::GetSignerEmailAddress\n"));
NS_ENSURE_ARG(aEmail);
NSSCMSSignerInfo *si = GetTopLevelSignerInfo();
if (!si)
return NS_ERROR_FAILURE;
*aEmail = NSS_CMSSignerInfo_GetSignerEmailAddress(si);
return NS_OK;
}
NS_IMETHODIMP nsCMSMessage::GetSignerCommonName(char ** aName)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::GetSignerCommonName\n"));
NS_ENSURE_ARG(aName);
NSSCMSSignerInfo *si = GetTopLevelSignerInfo();
if (!si)
return NS_ERROR_FAILURE;
*aName = NSS_CMSSignerInfo_GetSignerCommonName(si);
return NS_OK;
}
NS_IMETHODIMP nsCMSMessage::ContentIsEncrypted(bool *isEncrypted)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::ContentIsEncrypted\n"));
NS_ENSURE_ARG(isEncrypted);
if (!m_cmsMsg)
return NS_ERROR_FAILURE;
*isEncrypted = NSS_CMSMessage_IsEncrypted(m_cmsMsg);
return NS_OK;
}
NS_IMETHODIMP nsCMSMessage::ContentIsSigned(bool *isSigned)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::ContentIsSigned\n"));
NS_ENSURE_ARG(isSigned);
if (!m_cmsMsg)
return NS_ERROR_FAILURE;
*isSigned = NSS_CMSMessage_IsSigned(m_cmsMsg);
return NS_OK;
}
NS_IMETHODIMP nsCMSMessage::GetSignerCert(nsIX509Cert **scert)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
NSSCMSSignerInfo *si = GetTopLevelSignerInfo();
if (!si)
return NS_ERROR_FAILURE;
if (si->cert) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::GetSignerCert got signer cert\n"));
*scert = nsNSSCertificate::Create(si->cert);
if (*scert) {
(*scert)->AddRef();
}
}
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;
}
return NS_OK;
}
NS_IMETHODIMP nsCMSMessage::GetEncryptionCert(nsIX509Cert **ecert)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsCMSMessage::VerifyDetachedSignature(unsigned char* aDigestData, uint32_t aDigestDataLen)
{
if (!aDigestData || !aDigestDataLen)
return NS_ERROR_FAILURE;
return CommonVerifySignature(aDigestData, aDigestDataLen);
}
nsresult nsCMSMessage::CommonVerifySignature(unsigned char* aDigestData, uint32_t aDigestDataLen)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature, content level count %d\n", NSS_CMSMessage_ContentLevelCount(m_cmsMsg)));
NSSCMSContentInfo *cinfo = nullptr;
NSSCMSSignedData *sigd = nullptr;
NSSCMSSignerInfo *si;
int32_t nsigners;
RefPtr<SharedCertVerifier> certVerifier;
nsresult rv = NS_ERROR_FAILURE;
if (!NSS_CMSMessage_IsSigned(m_cmsMsg)) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - not signed\n"));
return NS_ERROR_CMS_VERIFY_NOT_SIGNED;
}
cinfo = NSS_CMSMessage_ContentLevel(m_cmsMsg, 0);
if (cinfo) {
// I don't like this hard cast. We should check in some way, that we really have this type.
sigd = (NSSCMSSignedData*)NSS_CMSContentInfo_GetContent(cinfo);
}
if (!sigd) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - no content info\n"));
rv = NS_ERROR_CMS_VERIFY_NO_CONTENT_INFO;
goto loser;
}
if (aDigestData && aDigestDataLen)
{
SECItem digest;
digest.data = aDigestData;
digest.len = aDigestDataLen;
if (NSS_CMSSignedData_SetDigestValue(sigd, SEC_OID_SHA1, &digest)) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - bad digest\n"));
rv = NS_ERROR_CMS_VERIFY_BAD_DIGEST;
goto loser;
}
}
// Import certs. Note that import failure is not a signature verification failure. //
if (NSS_CMSSignedData_ImportCerts(sigd, CERT_GetDefaultCertDB(), certUsageEmailRecipient, true) != SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - can not import certs\n"));
}
nsigners = NSS_CMSSignedData_SignerInfoCount(sigd);
PR_ASSERT(nsigners > 0);
NS_ENSURE_TRUE(nsigners > 0, NS_ERROR_UNEXPECTED);
si = NSS_CMSSignedData_GetSignerInfo(sigd, 0);
// See bug 324474. We want to make sure the signing cert is
// still valid at the current time.
certVerifier = GetDefaultCertVerifier();
NS_ENSURE_TRUE(certVerifier, NS_ERROR_UNEXPECTED);
{
SECStatus srv = certVerifier->VerifyCert(si->cert,
certificateUsageEmailSigner,
PR_Now(), nullptr /*XXX pinarg*/,
nullptr /*hostname*/);
if (srv != SECSuccess) {
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 //
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) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - signing cert not trusted at signing time\n"));
rv = NS_ERROR_CMS_VERIFY_UNTRUSTED;
}
else if(NSSCMSVS_Unverified == si->verificationStatus) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - can not verify\n"));
rv = NS_ERROR_CMS_VERIFY_ERROR_UNVERIFIED;
}
else if(NSSCMSVS_ProcessingError == si->verificationStatus) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - processing error\n"));
rv = NS_ERROR_CMS_VERIFY_ERROR_PROCESSING;
}
else if(NSSCMSVS_BadSignature == si->verificationStatus) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - bad signature\n"));
rv = NS_ERROR_CMS_VERIFY_BAD_SIGNATURE;
}
else if(NSSCMSVS_DigestMismatch == si->verificationStatus) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - digest mismatch\n"));
rv = NS_ERROR_CMS_VERIFY_DIGEST_MISMATCH;
}
else if(NSSCMSVS_SignatureAlgorithmUnknown == si->verificationStatus) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - algo unknown\n"));
rv = NS_ERROR_CMS_VERIFY_UNKNOWN_ALGO;
}
else if(NSSCMSVS_SignatureAlgorithmUnsupported == si->verificationStatus) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - algo not supported\n"));
rv = NS_ERROR_CMS_VERIFY_UNSUPPORTED_ALGO;
}
else if(NSSCMSVS_MalformedSignature == si->verificationStatus) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - malformed signature\n"));
rv = NS_ERROR_CMS_VERIFY_MALFORMED_SIGNATURE;
}
goto loser;
}
// Save the profile. Note that save import failure is not a signature verification failure. //
if (NSS_SMIMESignerInfo_SaveSMIMEProfile(si) != SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - unable to save smime profile\n"));
}
rv = NS_OK;
loser:
return rv;
}
NS_IMETHODIMP nsCMSMessage::AsyncVerifySignature(
nsISMimeVerificationListener *aListener)
{
return CommonAsyncVerifySignature(aListener, nullptr, 0);
}
NS_IMETHODIMP nsCMSMessage::AsyncVerifyDetachedSignature(
nsISMimeVerificationListener *aListener,
unsigned char* aDigestData, uint32_t aDigestDataLen)
{
if (!aDigestData || !aDigestDataLen)
return NS_ERROR_FAILURE;
return CommonAsyncVerifySignature(aListener, aDigestData, aDigestDataLen);
}
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;
}
class nsZeroTerminatedCertArray : public nsNSSShutDownObject
{
public:
nsZeroTerminatedCertArray()
:mCerts(nullptr), mPoolp(nullptr), mSize(0)
{
}
~nsZeroTerminatedCertArray()
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown()) {
return;
}
destructorSafeDestroyNSSReference();
shutdown(calledFromObject);
}
void virtualDestroyNSSReference()
{
destructorSafeDestroyNSSReference();
}
void destructorSafeDestroyNSSReference()
{
if (mCerts)
{
for (uint32_t i=0; i < mSize; i++) {
if (mCerts[i]) {
CERT_DestroyCertificate(mCerts[i]);
}
}
}
if (mPoolp)
PORT_FreeArena(mPoolp, false);
}
bool allocate(uint32_t count)
{
// only allow allocation once
if (mPoolp)
return false;
mSize = count;
if (!mSize)
return false;
mPoolp = PORT_NewArena(1024);
if (!mPoolp)
return false;
mCerts = (CERTCertificate**)PORT_ArenaZAlloc(
mPoolp, (count+1)*sizeof(CERTCertificate*));
if (!mCerts)
return false;
// null array, including zero termination
for (uint32_t i = 0; i < count+1; i++) {
mCerts[i] = nullptr;
}
return true;
}
void set(uint32_t i, CERTCertificate *c)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return;
if (i >= mSize)
return;
if (mCerts[i]) {
CERT_DestroyCertificate(mCerts[i]);
}
mCerts[i] = CERT_DupCertificate(c);
}
CERTCertificate *get(uint32_t i)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return nullptr;
if (i >= mSize)
return nullptr;
return CERT_DupCertificate(mCerts[i]);
}
CERTCertificate **getRawArray()
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return nullptr;
return mCerts;
}
private:
CERTCertificate **mCerts;
PLArenaPool *mPoolp;
uint32_t mSize;
};
NS_IMETHODIMP nsCMSMessage::CreateEncrypted(nsIArray * aRecipientCerts)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateEncrypted\n"));
NSSCMSContentInfo *cinfo;
NSSCMSEnvelopedData *envd;
NSSCMSRecipientInfo *recipientInfo;
nsZeroTerminatedCertArray recipientCerts;
SECOidTag bulkAlgTag;
int keySize;
uint32_t i;
nsCOMPtr<nsIX509Cert2> nssRecipientCert;
nsresult rv = NS_ERROR_FAILURE;
// Check the recipient certificates //
uint32_t recipientCertCount;
aRecipientCerts->GetLength(&recipientCertCount);
PR_ASSERT(recipientCertCount > 0);
if (!recipientCerts.allocate(recipientCertCount)) {
goto loser;
}
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());
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;
goto loser;
}
m_cmsMsg = NSS_CMSMessage_Create(nullptr);
if (!m_cmsMsg) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateEncrypted - can't create new cms message\n"));
rv = NS_ERROR_OUT_OF_MEMORY;
goto loser;
}
if ((envd = NSS_CMSEnvelopedData_Create(m_cmsMsg, bulkAlgTag, keySize)) == nullptr) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateEncrypted - can't create enveloped data\n"));
goto loser;
}
cinfo = NSS_CMSMessage_GetContentInfo(m_cmsMsg);
if (NSS_CMSContentInfo_SetContent_EnvelopedData(m_cmsMsg, cinfo, envd) != SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateEncrypted - can't create content enveloped data\n"));
goto loser;
}
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));
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;
}
}
return NS_OK;
loser:
if (m_cmsMsg) {
NSS_CMSMessage_Destroy(m_cmsMsg);
m_cmsMsg = nullptr;
}
return rv;
}
NS_IMETHODIMP nsCMSMessage::CreateSigned(nsIX509Cert* aSigningCert, nsIX509Cert* aEncryptCert, unsigned char* aDigestData, uint32_t aDigestDataLen)
{
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;
nsCOMPtr<nsIX509Cert2> aSigningCert2 = do_QueryInterface(aSigningCert);
nsresult rv = NS_ERROR_FAILURE;
/* Get the certs */
if (aSigningCert2) {
scert = aSigningCert2->GetCert();
}
if (!scert) {
return NS_ERROR_FAILURE;
}
if (aEncryptCert) {
nsCOMPtr<nsIX509Cert2> aEncryptCert2 = do_QueryInterface(aEncryptCert);
if (aEncryptCert2) {
ecert = aEncryptCert2->GetCert();
}
}
/*
* create the message object
*/
m_cmsMsg = NSS_CMSMessage_Create(nullptr); /* create a message on its own pool */
if (!m_cmsMsg) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't create new message\n"));
rv = NS_ERROR_OUT_OF_MEMORY;
goto loser;
}
/*
* build chain of objects: message->signedData->data
*/
if ((sigd = NSS_CMSSignedData_Create(m_cmsMsg)) == nullptr) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't create signed data\n"));
goto loser;
}
cinfo = NSS_CMSMessage_GetContentInfo(m_cmsMsg);
if (NSS_CMSContentInfo_SetContent_SignedData(m_cmsMsg, cinfo, sigd)
!= SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't set content signed data\n"));
goto loser;
}
cinfo = NSS_CMSSignedData_GetContentInfo(sigd);
/* we're always passing data in and detaching optionally */
if (NSS_CMSContentInfo_SetContent_Data(m_cmsMsg, cinfo, nullptr, true)
!= SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't set content data\n"));
goto loser;
}
/*
* create & attach signer information
*/
if ((signerinfo = NSS_CMSSignerInfo_Create(m_cmsMsg, scert.get(), SEC_OID_SHA1))
== nullptr) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't create signer info\n"));
goto loser;
}
/* we want the cert chain included for this one */
if (NSS_CMSSignerInfo_IncludeCerts(signerinfo, NSSCMSCM_CertChain,
certUsageEmailSigner)
!= SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't include signer cert chain\n"));
goto loser;
}
if (NSS_CMSSignerInfo_AddSigningTime(signerinfo, PR_Now())
!= SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't add signing time\n"));
goto loser;
}
if (NSS_CMSSignerInfo_AddSMIMECaps(signerinfo) != SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't add smime caps\n"));
goto loser;
}
if (ecert) {
if (NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs(signerinfo, ecert.get(),
CERT_GetDefaultCertDB())
!= SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't add smime enc key prefs\n"));
goto loser;
}
if (NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs(signerinfo, ecert.get(),
CERT_GetDefaultCertDB())
!= SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't add MS smime enc key prefs\n"));
goto loser;
}
// If signing and encryption cert are identical, don't add it twice.
bool addEncryptionCert =
(ecert && (!scert || !CERT_CompareCerts(ecert.get(), scert.get())));
if (addEncryptionCert &&
NSS_CMSSignedData_AddCertificate(sigd, ecert.get()) != SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't add own encryption certificate\n"));
goto loser;
}
}
if (NSS_CMSSignedData_AddSignerInfo(sigd, signerinfo) != SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't add signer info\n"));
goto loser;
}
// Finally, add the pre-computed digest if passed in
if (aDigestData) {
SECItem digest;
digest.data = aDigestData;
digest.len = aDigestDataLen;
if (NSS_CMSSignedData_SetDigestValue(sigd, SEC_OID_SHA1, &digest)) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't set digest value\n"));
goto loser;
}
}
return NS_OK;
loser:
if (m_cmsMsg) {
NSS_CMSMessage_Destroy(m_cmsMsg);
m_cmsMsg = nullptr;
}
return rv;
}
NS_IMPL_ISUPPORTS(nsCMSDecoder, nsICMSDecoder)
nsCMSDecoder::nsCMSDecoder()
: m_dcx(nullptr)
{
}
nsCMSDecoder::~nsCMSDecoder()
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown()) {
return;
}
destructorSafeDestroyNSSReference();
shutdown(calledFromObject);
}
void nsCMSDecoder::virtualDestroyNSSReference()
{
destructorSafeDestroyNSSReference();
}
void nsCMSDecoder::destructorSafeDestroyNSSReference()
{
if (m_dcx) {
NSS_CMSDecoder_Cancel(m_dcx);
m_dcx = nullptr;
}
}
/* void start (in NSSCMSContentCallback cb, in voidPtr arg); */
NS_IMETHODIMP nsCMSDecoder::Start(NSSCMSContentCallback cb, void * arg)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSDecoder::Start\n"));
m_ctx = new PipUIContext();
m_dcx = NSS_CMSDecoder_Start(0, cb, arg, 0, m_ctx, 0, 0);
if (!m_dcx) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSDecoder::Start - can't start decoder\n"));
return NS_ERROR_FAILURE;
}
return NS_OK;
}
/* void update (in string bug, in long len); */
NS_IMETHODIMP nsCMSDecoder::Update(const char *buf, int32_t len)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSDecoder::Update\n"));
NSS_CMSDecoder_Update(m_dcx, (char *)buf, len);
return NS_OK;
}
/* void finish (); */
NS_IMETHODIMP nsCMSDecoder::Finish(nsICMSMessage ** aCMSMsg)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSDecoder::Finish\n"));
NSSCMSMessage *cmsMsg;
cmsMsg = NSS_CMSDecoder_Finish(m_dcx);
m_dcx = nullptr;
if (cmsMsg) {
nsCMSMessage *obj = new nsCMSMessage(cmsMsg);
// The NSS object cmsMsg still carries a reference to the context
// we gave it on construction.
// Make sure the context will live long enough.
obj->referenceContext(m_ctx);
*aCMSMsg = obj;
NS_ADDREF(*aCMSMsg);
}
return NS_OK;
}
NS_IMPL_ISUPPORTS(nsCMSEncoder, nsICMSEncoder)
nsCMSEncoder::nsCMSEncoder()
: m_ecx(nullptr)
{
}
nsCMSEncoder::~nsCMSEncoder()
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown()) {
return;
}
destructorSafeDestroyNSSReference();
shutdown(calledFromObject);
}
void nsCMSEncoder::virtualDestroyNSSReference()
{
destructorSafeDestroyNSSReference();
}
void nsCMSEncoder::destructorSafeDestroyNSSReference()
{
if (m_ecx)
NSS_CMSEncoder_Cancel(m_ecx);
}
/* void start (); */
NS_IMETHODIMP nsCMSEncoder::Start(nsICMSMessage *aMsg, NSSCMSContentCallback cb, void * arg)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSEncoder::Start\n"));
nsCMSMessage *cmsMsg = static_cast<nsCMSMessage*>(aMsg);
m_ctx = new PipUIContext();
m_ecx = NSS_CMSEncoder_Start(cmsMsg->getCMS(), cb, arg, 0, 0, 0, m_ctx, 0, 0, 0, 0);
if (!m_ecx) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSEncoder::Start - can't start encoder\n"));
return NS_ERROR_FAILURE;
}
return NS_OK;
}
/* void update (in string aBuf, in long aLen); */
NS_IMETHODIMP nsCMSEncoder::Update(const char *aBuf, int32_t aLen)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSEncoder::Update\n"));
if (!m_ecx || NSS_CMSEncoder_Update(m_ecx, aBuf, aLen) != SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSEncoder::Update - can't update encoder\n"));
return NS_ERROR_FAILURE;
}
return NS_OK;
}
/* void finish (); */
NS_IMETHODIMP nsCMSEncoder::Finish()
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
nsresult rv = NS_OK;
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSEncoder::Finish\n"));
if (!m_ecx || NSS_CMSEncoder_Finish(m_ecx) != SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSEncoder::Finish - can't finish encoder\n"));
rv = NS_ERROR_FAILURE;
}
m_ecx = nullptr;
return rv;
}
/* void encode (in nsICMSMessage aMsg); */
NS_IMETHODIMP nsCMSEncoder::Encode(nsICMSMessage *aMsg)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSEncoder::Encode\n"));
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@ -1,103 +0,0 @@
/* -*- 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/. */
#ifndef __NS_CMS_H__
#define __NS_CMS_H__
#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 } }
class nsCMSMessage : public nsICMSMessage,
public nsICMSMessage2,
public nsNSSShutDownObject
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSICMSMESSAGE
NS_DECL_NSICMSMESSAGE2
nsCMSMessage();
nsCMSMessage(NSSCMSMessage* aCMSMsg);
virtual ~nsCMSMessage();
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 } }
class nsCMSDecoder : public nsICMSDecoder,
public nsNSSShutDownObject
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSICMSDECODER
nsCMSDecoder();
virtual ~nsCMSDecoder();
private:
nsCOMPtr<nsIInterfaceRequestor> m_ctx;
NSSCMSDecoderContext *m_dcx;
virtual void virtualDestroyNSSReference();
void destructorSafeDestroyNSSReference();
};
// ===============================================
// nsCMSEncoder - implementation of nsICMSEncoder
// ===============================================
#define NS_CMSENCODER_CID \
{ 0xa15789aa, 0x8903, 0x462b, { 0x81, 0xe9, 0x4a, 0xa2, 0xcf, 0xf4, 0xd5, 0xcb } }
class nsCMSEncoder : public nsICMSEncoder,
public nsNSSShutDownObject
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSICMSENCODER
nsCMSEncoder();
virtual ~nsCMSEncoder();
private:
nsCOMPtr<nsIInterfaceRequestor> m_ctx;
NSSCMSEncoderContext *m_ecx;
virtual void virtualDestroyNSSReference();
void destructorSafeDestroyNSSReference();
};
#endif

View File

@ -1,346 +0,0 @@
/* -*- 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 "nsXPIDLString.h"
#include "nsCOMPtr.h"
#include "nsISupports.h"
#include "nsIInterfaceRequestor.h"
#include "nsCRT.h"
#include "nsICMSSecureMessage.h"
#include "nsCMSSecureMessage.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"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "prlog.h"
#ifdef PR_LOGGING
extern PRLogModuleInfo* gPIPNSSLog;
#endif
// Standard ISupports implementation
// NOTE: Should these be the thread-safe versions?
/*****
* nsCMSSecureMessage
*****/
// Standard ISupports implementation
NS_IMPL_ISUPPORTS(nsCMSSecureMessage, nsICMSSecureMessage)
// nsCMSSecureMessage constructor
nsCMSSecureMessage::nsCMSSecureMessage()
{
// initialize superclass
}
// nsCMSMessage destructor
nsCMSSecureMessage::~nsCMSSecureMessage()
{
}
/* 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;
nsXPIDLCString nickname;
nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext();
*_retval = 0;
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) {
goto done;
}
rv = prefs->GetCharPref(certID,
getter_Copies(nickname));
if (NS_FAILED(rv)) goto done;
/* Find a good cert in the user's database */
cert = CERT_FindUserCertByUsage(CERT_GetDefaultCertDB(), const_cast<char*>(nickname.get()),
certUsageEmailRecipient, true, ctx);
if (!cert) {
/* Success, but no value */
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSSecureMessage::GetCertByPrefID - can't find user cert\n"));
goto done;
}
/* Convert the DER to a BASE64 String */
encode(cert->derCert.data, cert->derCert.len, _retval);
done:
if (cert) CERT_DestroyCertificate(cert);
return rv;
}
// nsCMSSecureMessage::DecodeCert
nsresult nsCMSSecureMessage::
DecodeCert(const char *value, nsIX509Cert ** _retval)
{
nsNSSShutDownPreventionLock locker;
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSSecureMessage::DecodeCert\n"));
nsresult rv = NS_OK;
int32_t length;
unsigned char *data = 0;
*_retval = 0;
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);
if (cert) {
*_retval = cert;
NS_ADDREF(*_retval);
}
else {
rv = NS_ERROR_FAILURE;
}
free((char*)data);
return rv;
}
// nsCMSSecureMessage::SendMessage
nsresult nsCMSSecureMessage::
SendMessage(const char *msg, const char *base64Cert, char ** _retval)
{
nsNSSShutDownPreventionLock locker;
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSSecureMessage::SendMessage\n"));
nsresult rv = NS_OK;
CERTCertificate *cert = 0;
NSSCMSMessage *cmsMsg = 0;
unsigned char *certDER = 0;
int32_t derLen;
NSSCMSEnvelopedData *env;
NSSCMSContentInfo *cinfo;
NSSCMSRecipientInfo *rcpt;
SECItem output;
PLArenaPool *arena = PORT_NewArena(1024);
SECStatus s;
nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext();
/* Step 0. Create a CMS Message */
cmsMsg = NSS_CMSMessage_Create(nullptr);
if (!cmsMsg) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSSecureMessage::SendMessage - can't create NSSCMSMessage\n"));
rv = NS_ERROR_FAILURE;
goto done;
}
/* Step 1. Import the certificate into NSS */
rv = decode(base64Cert, &certDER, &derLen);
if (NS_FAILED(rv)) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSSecureMessage::SendMessage - can't decode / import cert into NSS\n"));
goto done;
}
cert = CERT_DecodeCertFromPackage((char *)certDER, derLen);
if (!cert) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSSecureMessage::SendMessage - can't decode cert from package\n"));
rv = NS_ERROR_FAILURE;
goto done;
}
/* Step 2. Get a signature cert */
/* Step 3. Build inner (signature) content */
/* Step 4. Build outer (enveloped) content */
env = NSS_CMSEnvelopedData_Create(cmsMsg, SEC_OID_DES_EDE3_CBC, 0);
if (!env) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSSecureMessage::SendMessage - can't create envelope data\n"));
rv = NS_ERROR_FAILURE;
goto done;
}
cinfo = NSS_CMSEnvelopedData_GetContentInfo(env);
s = NSS_CMSContentInfo_SetContent_Data(cmsMsg, cinfo, 0, false);
if (s != SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSSecureMessage::SendMessage - can't set content data\n"));
rv = NS_ERROR_FAILURE;
goto done;
}
rcpt = NSS_CMSRecipientInfo_Create(cmsMsg, cert);
if (!rcpt) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSSecureMessage::SendMessage - can't create recipient info\n"));
rv = NS_ERROR_FAILURE;
goto done;
}
s = NSS_CMSEnvelopedData_AddRecipient(env, rcpt);
if (s != SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSSecureMessage::SendMessage - can't add recipient\n"));
rv = NS_ERROR_FAILURE;
goto done;
}
/* Step 5. Add content to message */
cinfo = NSS_CMSMessage_GetContentInfo(cmsMsg);
s = NSS_CMSContentInfo_SetContent_EnvelopedData(cmsMsg, cinfo, env);
if (s != SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSSecureMessage::SendMessage - can't set content enveloped data\n"));
rv = NS_ERROR_FAILURE;
goto done;
}
/* Step 6. Encode */
NSSCMSEncoderContext *ecx;
output.data = 0; output.len = 0;
ecx = NSS_CMSEncoder_Start(cmsMsg, 0, 0, &output, arena,
0, ctx, 0, 0, 0, 0);
if (!ecx) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSSecureMessage::SendMessage - can't start cms encoder\n"));
rv = NS_ERROR_FAILURE;
goto done;
}
s = NSS_CMSEncoder_Update(ecx, msg, strlen(msg));
if (s != SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSSecureMessage::SendMessage - can't update encoder\n"));
rv = NS_ERROR_FAILURE;
goto done;
}
s = NSS_CMSEncoder_Finish(ecx);
if (s != SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSSecureMessage::SendMessage - can't finish encoder\n"));
rv = NS_ERROR_FAILURE;
goto done;
}
/* Step 7. Base64 encode and return the result */
rv = encode(output.data, output.len, _retval);
done:
if (certDER) free((char *)certDER);
if (cert) CERT_DestroyCertificate(cert);
if (cmsMsg) NSS_CMSMessage_Destroy(cmsMsg);
if (arena) PORT_FreeArena(arena, false); /* false? */
return rv;
}
/*
* nsCMSSecureMessage::ReceiveMessage
*/
nsresult nsCMSSecureMessage::
ReceiveMessage(const char *msg, char **_retval)
{
nsNSSShutDownPreventionLock locker;
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSSecureMessage::ReceiveMessage\n"));
nsresult rv = NS_OK;
NSSCMSDecoderContext *dcx;
unsigned char *der = 0;
int32_t derLen;
NSSCMSMessage *cmsMsg = 0;
SECItem *content;
nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext();
/* Step 1. Decode the base64 wrapper */
rv = decode(msg, &der, &derLen);
if (NS_FAILED(rv)) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSSecureMessage::ReceiveMessage - can't base64 decode\n"));
goto done;
}
dcx = NSS_CMSDecoder_Start(0, 0, 0, /* pw */ 0, ctx, /* key */ 0, 0);
if (!dcx) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSSecureMessage::ReceiveMessage - can't start decoder\n"));
rv = NS_ERROR_FAILURE;
goto done;
}
(void)NSS_CMSDecoder_Update(dcx, (char *)der, derLen);
cmsMsg = NSS_CMSDecoder_Finish(dcx);
if (!cmsMsg) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSSecureMessage::ReceiveMessage - can't finish decoder\n"));
rv = NS_ERROR_FAILURE;
/* Memory leak on dcx?? */
goto done;
}
content = NSS_CMSMessage_GetContent(cmsMsg);
if (!content) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSSecureMessage::ReceiveMessage - can't get content\n"));
rv = NS_ERROR_FAILURE;
goto done;
}
/* Copy the data */
*_retval = (char*)malloc(content->len+1);
memcpy(*_retval, content->data, content->len);
(*_retval)[content->len] = 0;
done:
if (der) free(der);
if (cmsMsg) NSS_CMSMessage_Destroy(cmsMsg);
return rv;
}
nsresult nsCMSSecureMessage::
encode(const unsigned char *data, int32_t dataLen, char **_retval)
{
nsresult rv = NS_OK;
*_retval = PL_Base64Encode((const char *)data, dataLen, nullptr);
if (!*_retval) { rv = NS_ERROR_OUT_OF_MEMORY; goto loser; }
loser:
return rv;
}
nsresult nsCMSSecureMessage::
decode(const char *data, unsigned char **result, int32_t * _retval)
{
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSSecureMessage::decode\n"));
nsresult rv = NS_OK;
uint32_t len = strlen(data);
int adjust = 0;
/* Compute length adjustment */
if (data[len-1] == '=') {
adjust++;
if (data[len-2] == '=') adjust++;
}
*result = (unsigned char *)PL_Base64Decode(data, len, nullptr);
if (!*result) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSSecureMessage::decode - error decoding base64\n"));
rv = NS_ERROR_ILLEGAL_VALUE;
goto loser;
}
*_retval = (len*3)/4 - adjust;
loser:
return rv;
}

View File

@ -1,36 +0,0 @@
/* -*- 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/. */
#ifndef _NSCMSSECUREMESSAGE_H_
#define _NSCMSSECUREMESSAGE_H_
#include "nsICMSSecureMessage.h"
#include "cms.h"
// ===============================================
// nsCMSManager - implementation of nsICMSManager
// ===============================================
#define NS_CMSSECUREMESSAGE_CID \
{ 0x5fb907e0, 0x1dd2, 0x11b2, { 0xa7, 0xc0, 0xf1, 0x4c, 0x41, 0x6a, 0x62, 0xa1 } }
class nsCMSSecureMessage
: public nsICMSSecureMessage
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSICMSSECUREMESSAGE
nsCMSSecureMessage();
virtual ~nsCMSSecureMessage();
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_ */

View File

@ -69,22 +69,6 @@ void nsCertVerificationJob::Run()
NS_DispatchToMainThread(r);
}
void nsSMimeVerificationJob::Run()
{
if (!mMessage || !mListener)
return;
nsresult rv;
if (digest_data)
rv = mMessage->VerifyDetachedSignature(digest_data, digest_len);
else
rv = mMessage->VerifySignature();
nsCOMPtr<nsICMSMessage2> m2 = do_QueryInterface(mMessage);
mListener->Notify(m2, rv);
}
nsCertVerificationThread::nsCertVerificationThread()
: mJobQ(nullptr)
{

View File

@ -20,7 +20,6 @@
#include "nsPK11TokenDB.h"
#include "nsIX509Cert.h"
#include "nsIX509Cert3.h"
#include "nsISMimeCert.h"
#include "nsNSSASN1Object.h"
#include "nsString.h"
#include "nsXPIDLString.h"
@ -73,7 +72,6 @@ NS_IMPL_ISUPPORTS(nsNSSCertificate,
nsIX509Cert2,
nsIX509Cert3,
nsIIdentityInfo,
nsISMimeCert,
nsISerializable,
nsIClassInfo)
@ -1389,19 +1387,6 @@ nsNSSCertificate::Equals(nsIX509Cert* other, bool* result)
return NS_OK;
}
NS_IMETHODIMP
nsNSSCertificate::SaveSMimeProfile()
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
if (SECSuccess != CERT_SaveSMimeProfile(mCert.get(), nullptr, nullptr))
return NS_ERROR_FAILURE;
else
return NS_OK;
}
#ifndef MOZ_NO_EV_CERTS
nsresult

View File

@ -12,7 +12,6 @@
#include "nsIX509CertDB.h"
#include "nsIX509CertList.h"
#include "nsIASN1Object.h"
#include "nsISMimeCert.h"
#include "nsIIdentityInfo.h"
#include "nsCOMPtr.h"
#include "nsNSSShutDown.h"
@ -28,7 +27,6 @@ class nsIASN1Sequence;
class nsNSSCertificate : public nsIX509Cert3,
public nsIIdentityInfo,
public nsISMimeCert,
public nsISerializable,
public nsIClassInfo,
public nsNSSShutDownObject
@ -39,7 +37,6 @@ public:
NS_DECL_NSIX509CERT2
NS_DECL_NSIX509CERT3
NS_DECL_NSIIDENTITYINFO
NS_DECL_NSISMIMECERT
NS_DECL_NSISERIALIZABLE
NS_DECL_NSICLASSINFO

View File

@ -19,7 +19,6 @@
#include "nsNSSCertificateFakeTransport.h"
#include "nsNSSCertificateDB.h"
#include "nsNSSCertCache.h"
#include "nsCMS.h"
#ifdef MOZ_XUL
#include "nsCertTree.h"
#endif
@ -28,7 +27,6 @@
//For the NS_CRYPTO_CONTRACTID define
#include "nsDOMCID.h"
#include "nsNetCID.h"
#include "nsCMSSecureMessage.h"
#include "nsCertPicker.h"
#include "nsCURILoader.h"
#include "nsICategoryManager.h"
@ -194,10 +192,6 @@ NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsCertTree)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsCrypto)
#endif
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsPkcs11)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsCMSSecureMessage)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsCMSDecoder)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsCMSEncoder)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsCMSMessage)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsCertPicker)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssEnsure, nsNTLMAuthModule, InitTest)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsCryptoHash)
@ -234,10 +228,6 @@ NS_DEFINE_NAMED_CID(NS_PKCS11_CID);
#ifndef MOZ_DISABLE_CRYPTOLEGACY
NS_DEFINE_NAMED_CID(NS_CRYPTO_CID);
#endif
NS_DEFINE_NAMED_CID(NS_CMSSECUREMESSAGE_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_CRYPTO_HASH_CID);
NS_DEFINE_NAMED_CID(NS_CRYPTO_HMAC_CID);
NS_DEFINE_NAMED_CID(NS_CERT_PICKER_CID);
@ -273,10 +263,6 @@ static const mozilla::Module::CIDEntry kNSSCIDs[] = {
#ifndef MOZ_DISABLE_CRYPTOLEGACY
{ &kNS_CRYPTO_CID, false, nullptr, nsCryptoConstructor },
#endif
{ &kNS_CMSSECUREMESSAGE_CID, false, nullptr, nsCMSSecureMessageConstructor },
{ &kNS_CMSDECODER_CID, false, nullptr, nsCMSDecoderConstructor },
{ &kNS_CMSENCODER_CID, false, nullptr, nsCMSEncoderConstructor },
{ &kNS_CMSMESSAGE_CID, false, nullptr, nsCMSMessageConstructor },
{ &kNS_CRYPTO_HASH_CID, false, nullptr, nsCryptoHashConstructor },
{ &kNS_CRYPTO_HMAC_CID, false, nullptr, nsCryptoHMACConstructor },
{ &kNS_CERT_PICKER_CID, false, nullptr, nsCertPickerConstructor },
@ -315,10 +301,6 @@ static const mozilla::Module::ContractIDEntry kNSSContracts[] = {
#ifndef MOZ_DISABLE_CRYPTOLEGACY
{ NS_CRYPTO_CONTRACTID, &kNS_CRYPTO_CID },
#endif
{ NS_CMSSECUREMESSAGE_CONTRACTID, &kNS_CMSSECUREMESSAGE_CID },
{ NS_CMSDECODER_CONTRACTID, &kNS_CMSDECODER_CID },
{ NS_CMSENCODER_CONTRACTID, &kNS_CMSENCODER_CID },
{ NS_CMSMESSAGE_CONTRACTID, &kNS_CMSMESSAGE_CID },
{ NS_CRYPTO_HASH_CONTRACTID, &kNS_CRYPTO_HASH_CID },
{ NS_CRYPTO_HMAC_CONTRACTID, &kNS_CRYPTO_HMAC_CID },
{ NS_CERT_PICKER_CONTRACTID, &kNS_CERT_PICKER_CID },

View File

@ -11,8 +11,6 @@
#include "nsIX509Cert.h"
#include "nsIX509Cert3.h"
#include "nsICMSMessage.h"
#include "nsICMSMessage2.h"
#include "nsProxyRelease.h"
class nsBaseVerificationJob
@ -49,21 +47,4 @@ private:
friend class nsCertVerificationJob;
};
class nsSMimeVerificationJob : public nsBaseVerificationJob
{
public:
nsSMimeVerificationJob() { digest_data = nullptr; digest_len = 0; }
~nsSMimeVerificationJob() { delete [] digest_data; }
nsCOMPtr<nsICMSMessage> mMessage;
nsCOMPtr<nsISMimeVerificationListener> mListener;
unsigned char *digest_data;
uint32_t digest_len;
void Run();
};
#endif