kaie%netscape.com 00fd78d437 b=134992 Fix crash when displaying some S/Mime messages.
r=javi sr=alecf


git-svn-id: svn://10.0.0.236/trunk@119662 18797224-902f-48f8-a5cc-f745e15eee43
2002-04-24 00:40:49 +00:00

642 lines
20 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corp..
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Drinan <ddrinan@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.h"
#include "nsCMS.h"
#include "nsNSSHelper.h"
#include "nsNSSCertificate.h"
#include "smime.h"
#include "cms.h"
#include "prlog.h"
#ifdef PR_LOGGING
extern PRLogModuleInfo* gPIPNSSLog;
#endif
NS_IMPL_THREADSAFE_ISUPPORTS1(nsHash, nsIHash)
nsHash::nsHash() : m_ctxt(nsnull)
{
NS_INIT_ISUPPORTS();
}
nsHash::~nsHash()
{
if (m_ctxt) {
HASH_Destroy(m_ctxt);
}
}
NS_IMETHODIMP nsHash::ResultLen(PRInt16 aAlg, PRUint32 * aLen)
{
*aLen = HASH_ResultLen((HASH_HashType)aAlg);
return NS_OK;
}
NS_IMETHODIMP nsHash::Create(PRInt16 aAlg)
{
m_ctxt = HASH_Create((HASH_HashType)aAlg);
if (m_ctxt == nsnull) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP nsHash::Begin()
{
HASH_Begin(m_ctxt);
return NS_OK;
}
NS_IMETHODIMP nsHash::Update(unsigned char* aBuf, PRUint32 aLen)
{
HASH_Update(m_ctxt, (const unsigned char*)aBuf, aLen);
return NS_OK;
}
NS_IMETHODIMP nsHash::End(unsigned char* aBuf, PRUint32* aResultLen, PRUint32 aMaxResultLen)
{
HASH_End(m_ctxt, aBuf, aResultLen, aMaxResultLen);
return NS_OK;
}
NS_IMPL_THREADSAFE_ISUPPORTS1(nsCMSMessage, nsICMSMessage)
nsCMSMessage::nsCMSMessage()
{
NS_INIT_ISUPPORTS();
m_cmsMsg = nsnull;
}
nsCMSMessage::nsCMSMessage(NSSCMSMessage *aCMSMsg)
{
NS_INIT_ISUPPORTS();
m_cmsMsg = aCMSMsg;
}
nsCMSMessage::~nsCMSMessage()
{
if (m_cmsMsg) {
NSS_CMSMessage_Destroy(m_cmsMsg);
}
}
NS_IMETHODIMP nsCMSMessage::VerifySignature()
{
return CommonVerifySignature(nsnull, 0);
}
NSSCMSSignerInfo* nsCMSMessage::GetTopLevelSignerInfo()
{
if (!m_cmsMsg)
return nsnull;
if (!NSS_CMSMessage_IsSigned(m_cmsMsg))
return nsnull;
NSSCMSContentInfo *cinfo = NSS_CMSMessage_ContentLevel(m_cmsMsg, 0);
if (!cinfo)
return nsnull;
NSSCMSSignedData *sigd = (NSSCMSSignedData*)NSS_CMSContentInfo_GetContent(cinfo);
if (!sigd)
return nsnull;
PR_ASSERT(NSS_CMSSignedData_SignerInfoCount(sigd) > 0);
return NSS_CMSSignedData_GetSignerInfo(sigd, 0);
}
NS_IMETHODIMP nsCMSMessage::GetSignerEmailAddress(char * * aEmail)
{
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)
{
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(PRBool *isEncrypted)
{
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(PRBool *isSigned)
{
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)
{
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 = new nsNSSCertificate(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 != nsnull ? "yes" : "no") ));
*scert = nsnull;
}
return NS_OK;
}
NS_IMETHODIMP nsCMSMessage::GetEncryptionCert(nsIX509Cert **ecert)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsCMSMessage::VerifyDetachedSignature(unsigned char* aDigestData, PRUint32 aDigestDataLen)
{
if (!aDigestData || !aDigestDataLen)
return NS_ERROR_FAILURE;
return CommonVerifySignature(aDigestData, aDigestDataLen);
}
nsresult nsCMSMessage::CommonVerifySignature(unsigned char* aDigestData, PRUint32 aDigestDataLen)
{
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature, content level count %d\n", NSS_CMSMessage_ContentLevelCount(m_cmsMsg)));
NSSCMSContentInfo *cinfo = nsnull;
NSSCMSSignedData *sigd = nsnull;
NSSCMSSignerInfo *si;
PRInt32 nsigners;
nsresult rv = NS_ERROR_FAILURE;
if (NSS_CMSMessage_IsSigned(m_cmsMsg) == PR_FALSE) {
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(), certUsageEmailSigner, PR_TRUE) != SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - can not import certs\n"));
}
nsigners = NSS_CMSSignedData_SignerInfoCount(sigd);
PR_ASSERT(nsigners > 0);
si = NSS_CMSSignedData_GetSignerInfo(sigd, 0);
// 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\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::CreateEncrypted(nsISupportsArray * aRecipientCerts)
{
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateEncrypted\n"));
NSSCMSContentInfo *cinfo;
NSSCMSEnvelopedData *envd;
NSSCMSRecipientInfo *recipientInfo;
CERTCertificate **recipientCerts;
PLArenaPool *tmpPoolp = nsnull;
SECOidTag bulkAlgTag;
int keySize, i;
nsNSSCertificate *nssRecipientCert;
nsresult rv = NS_ERROR_FAILURE;
// Check the recipient certificates //
PRUint32 recipientCertCount;
aRecipientCerts->Count(&recipientCertCount);
PR_ASSERT(recipientCertCount > 0);
if ((tmpPoolp = PORT_NewArena(1024)) == nsnull) {
goto loser;
}
if ((recipientCerts = (CERTCertificate**)PORT_ArenaZAlloc(tmpPoolp,
(recipientCertCount+1)*sizeof(CERTCertificate*)))
== nsnull) {
goto loser;
}
for (i=0; i<recipientCertCount; i++) {
nssRecipientCert = NS_STATIC_CAST(nsNSSCertificate*, aRecipientCerts->ElementAt(i));
recipientCerts[i] = nssRecipientCert->GetCert();
}
recipientCerts[i] = nsnull;
// Find a bulk key algorithm //
if (NSS_SMIMEUtil_FindBulkAlgForRecipients(recipientCerts, &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(NULL);
if (m_cmsMsg == nsnull) {
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)) == nsnull) {
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, nsnull, PR_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; recipientCerts[i] != nsnull; i++) {
if ((recipientInfo = NSS_CMSRecipientInfo_Create(m_cmsMsg, recipientCerts[i])) == nsnull) {
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;
}
}
if (tmpPoolp) {
PORT_FreeArena(tmpPoolp, PR_FALSE);
}
return NS_OK;
loser:
if (m_cmsMsg) {
NSS_CMSMessage_Destroy(m_cmsMsg);
m_cmsMsg = nsnull;
}
if (tmpPoolp) {
PORT_FreeArena(tmpPoolp, PR_FALSE);
}
return rv;
}
NS_IMETHODIMP nsCMSMessage::CreateSigned(nsIX509Cert* aSigningCert, nsIX509Cert* aEncryptCert, unsigned char* aDigestData, PRUint32 aDigestDataLen)
{
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned\n"));
NSSCMSContentInfo *cinfo;
NSSCMSSignedData *sigd;
NSSCMSSignerInfo *signerinfo;
CERTCertificate *scert, *ecert;
nsresult rv = NS_ERROR_FAILURE;
/* Get the certs */
scert = NS_STATIC_CAST(nsNSSCertificate*, aSigningCert)->GetCert();
ecert = NS_STATIC_CAST(nsNSSCertificate*, aEncryptCert)->GetCert();
/*
* create the message object
*/
m_cmsMsg = NSS_CMSMessage_Create(NULL); /* create a message on its own pool */
if (m_cmsMsg == NULL) {
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)) == NULL) {
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, nsnull, PR_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, SEC_OID_SHA1))
== NULL) {
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 (NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs(signerinfo, ecert,
CERT_GetDefaultCertDB())
!= SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't add smime enc key prefs\n"));
goto loser;
}
if (NSS_CMSSignedData_AddCertificate(sigd, ecert) != 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 = nsnull;
}
return rv;
}
NS_IMPL_THREADSAFE_ISUPPORTS1(nsCMSDecoder, nsICMSDecoder)
nsCMSDecoder::nsCMSDecoder()
{
NS_INIT_ISUPPORTS();
}
nsCMSDecoder::~nsCMSDecoder()
{
}
/* void start (in NSSCMSContentCallback cb, in voidPtr arg); */
NS_IMETHODIMP nsCMSDecoder::Start(NSSCMSContentCallback cb, void * arg)
{
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, PRInt32 len)
{
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)
{
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSDecoder::Finish\n"));
NSSCMSMessage *cmsMsg;
cmsMsg = NSS_CMSDecoder_Finish(m_dcx);
if (cmsMsg) {
nsCOMPtr<nsICMSMessage> msg = new nsCMSMessage(cmsMsg);
*aCMSMsg = msg;
NS_ADDREF(*aCMSMsg);
}
return NS_OK;
}
NS_IMPL_THREADSAFE_ISUPPORTS1(nsCMSEncoder, nsICMSEncoder)
nsCMSEncoder::nsCMSEncoder()
{
NS_INIT_ISUPPORTS();
}
nsCMSEncoder::~nsCMSEncoder()
{
}
/* void start (); */
NS_IMETHODIMP nsCMSEncoder::Start(nsICMSMessage *aMsg, NSSCMSContentCallback cb, void * arg)
{
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSEncoder::Start\n"));
nsCMSMessage *cmsMsg = NS_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 == nsnull) {
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, PRInt32 aLen)
{
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()
{
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"));
return NS_ERROR_FAILURE;
}
return NS_OK;
}
/* void encode (in nsICMSMessage aMsg); */
NS_IMETHODIMP nsCMSEncoder::Encode(nsICMSMessage *aMsg)
{
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSEncoder::Encode\n"));
return NS_ERROR_NOT_IMPLEMENTED;
}