b=112524 Fixing crash when signing message with expired certificate

r=kaie sr=mscott
Checking in for ssaux
This commit is contained in:
kaie%netscape.com 2001-12-12 04:05:30 +00:00
Родитель 12a9531fc6
Коммит e8289872f0
7 изменённых файлов: 160 добавлений и 18 удалений

Просмотреть файл

@ -20,8 +20,10 @@
* Contributor(s):
* David Drinan <ddrinan@netscape.com>
* Scott MacGregor <mscott@netscape.com>
* Stephane Saux <ssaux@netscape.com>
*/
#include "nsIMsgSendReport.idl"
#include "nsISupports.idl"
interface nsIMsgCompFields;
@ -41,7 +43,7 @@ interface nsIMsgComposeSecure : nsISupports
// some encryption work. In the case of false, you can disregard the compose secure object.
boolean requiresCryptoEncapsulation(in nsIMsgIdentity aIdentity, in nsIMsgCompFields aCompFields);
void beginCryptoEncapsulation(in nsOutputFileStream aStream, in string aRecipients, in nsIMsgCompFields aCompFields, in nsIMsgIdentity aIdentity, in boolean aIsDraft);
void beginCryptoEncapsulation(in nsOutputFileStream aStream, in string aRecipients, in nsIMsgCompFields aCompFields, in nsIMsgIdentity aIdentity, in nsIMsgSendReport sendReport, in boolean aIsDraft);
void finishCryptoEncapsulation(in boolean aAbort);
void mimeCryptoWriteBlock(in string aBuf, in long aLen);
};

Просмотреть файл

@ -1290,7 +1290,12 @@ nsresult nsMsgComposeAndSend::BeginCryptoEncapsulation ()
FROB(mCompFields->GetNewsgroups())
// end section of code I'd like to move to the implementor.....
rv = m_crypto_closure->BeginCryptoEncapsulation(mOutputFile, recipients, mCompFields, mUserIdentity, (m_deliver_mode == nsMsgSaveAsDraft));
rv = m_crypto_closure->BeginCryptoEncapsulation(mOutputFile,
recipients,
mCompFields,
mUserIdentity,
mSendReport,
(m_deliver_mode == nsMsgSaveAsDraft));
PR_FREEIF(recipients);
}

Просмотреть файл

@ -38,6 +38,8 @@ REQUIRES = xpcom \
mime \
msgcompose \
pipnss \
necko \
intl \
$(NULL)
ifeq ($(USE_SHORT_LIBNAME),1)

Просмотреть файл

@ -1,3 +1,14 @@
## S/MIME error strings.
NoSenderSigningCert=You requested to digitally sign this message, but the application failed to find the signing certificate you specified in your Mail/News account preferences or the certificate has expired.
NoSenderEncryptionCert=You requested to encrypt this message, but the application failed to find the encryption certificate you specified in your Mail/News account preferences or the certificate has expired.
MissingRecipientEncryptionCert=You requested to encrypt this message, but the application failed to find an encryption cert for %S.
SignNoSenderEncryptionCert=You requested to sign this message, but the application failed to find an encryption cert to include in the signed message or the certificate has expired.
## Strings used for in the prefs.
prefPanel-smime=Secure Mail
smimeCertPrompt=Select the certificate that you want to use:

Просмотреть файл

@ -36,6 +36,8 @@ REQUIRES = xpcom \
mimetype \
pipnss \
msgcompose \
necko \
intl \
$(NULL)
CPPSRCS = \

Просмотреть файл

@ -19,6 +19,7 @@
*
* Contributor(s):
* David Drinan <ddrinan@netscape.com>
* Stephane Saux <ssaux@netscape.com>
*/
#include "nsMsgComposeSecure.h"
@ -38,6 +39,9 @@
#include "nsIMsgIdentity.h"
#include "nsIMsgCompFields.h"
// String bundle for smime. Class static.
nsCOMPtr<nsIStringBundle> nsMsgComposeSecure::mSMIMEBundle = nsnull;
static NS_DEFINE_CID(kMsgHeaderParserCID, NS_MSGHEADERPARSER_CID);
// XXX These strings should go in properties file XXX //
@ -47,7 +51,7 @@ static NS_DEFINE_CID(kMsgHeaderParserCID, NS_MSGHEADERPARSER_CID);
#define MK_MIME_ERROR_WRITING_FILE -1
#define SEC_ERROR_NO_EMAIL_CERT -100
#define SMIME_STRBUNDLE_URL "chrome://messenger/locale/am-smime.properties"
static void mime_crypto_write_base64 (void *closure, const char *buf,
unsigned long size);
@ -277,6 +281,70 @@ NS_IMETHODIMP nsMsgComposeSecure::RequiresCryptoEncapsulation(nsIMsgIdentity * a
return NS_OK;
}
nsresult nsMsgComposeSecure::GetSMIMEBundleString(const PRUnichar *name,
PRUnichar **outString)
{
nsresult rv = NS_ERROR_FAILURE;
*outString = nsnull;
if ( ! mSMIMEBundle ) {
InitializeSMIMEBundle();
if ( ! mSMIMEBundle ) {
return rv;
}
}
if (name) {
rv = mSMIMEBundle->GetStringFromName(name, outString);
if (NS_SUCCEEDED(rv)) {
rv = NS_OK;
}
}
return rv;
}
nsresult
nsMsgComposeSecure::
SMIMEBundleFormatStringFromName(const PRUnichar *name,
const PRUnichar **params,
PRUint32 numParams,
PRUnichar **outString)
{
nsresult rv = NS_ERROR_FAILURE;
if ( ! mSMIMEBundle ) {
InitializeSMIMEBundle();
if ( ! mSMIMEBundle ) {
return rv;
}
}
if (name) {
rv = mSMIMEBundle->FormatStringFromName(name, params,
numParams, outString);
}
return rv;
}
void nsMsgComposeSecure::InitializeSMIMEBundle()
{
nsresult rv;
nsCOMPtr<nsIStringBundleService> bundleService(do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv));
if ( NS_FAILED(rv) ) {
return;
}
bundleService->CreateBundle(SMIME_STRBUNDLE_URL,
getter_AddRefs(mSMIMEBundle));
}
nsresult nsMsgComposeSecure::ExtractEncryptionState(nsIMsgIdentity * aIdentity, nsIMsgCompFields * aComposeFields, PRBool * aSignMessage, PRBool * aEncrypt)
{
if (!aComposeFields && !aIdentity)
@ -305,7 +373,12 @@ nsresult nsMsgComposeSecure::ExtractEncryptionState(nsIMsgIdentity * aIdentity,
}
/* void beginCryptoEncapsulation (in nsOutputFileStream aStream, in boolean aEncrypt, in boolean aSign, in string aRecipeints, in boolean aIsDraft); */
NS_IMETHODIMP nsMsgComposeSecure::BeginCryptoEncapsulation(nsOutputFileStream * aStream, const char * aRecipients, nsIMsgCompFields * aCompFields, nsIMsgIdentity * aIdentity, PRBool aIsDraft)
NS_IMETHODIMP nsMsgComposeSecure::BeginCryptoEncapsulation(nsOutputFileStream * aStream,
const char * aRecipients,
nsIMsgCompFields * aCompFields,
nsIMsgIdentity * aIdentity,
nsIMsgSendReport *sendReport,
PRBool aIsDraft)
{
nsresult rv = NS_OK;
@ -330,7 +403,7 @@ NS_IMETHODIMP nsMsgComposeSecure::BeginCryptoEncapsulation(nsOutputFileStream *
aIdentity->GetUnicharAttribute("signing_cert_name", getter_Copies(mSigningCertName));
aIdentity->GetUnicharAttribute("encryption_cert_name", getter_Copies(mEncryptionCertName));
rv = MimeCryptoHackCerts(aRecipients, encryptMessages, signMessage);
rv = MimeCryptoHackCerts(aRecipients, sendReport, encryptMessages, signMessage);
if (NS_FAILED(rv)) {
goto FAIL;
}
@ -705,13 +778,15 @@ nsresult nsMsgComposeSecure::MimeFinishEncryption (PRBool aSign)
/* Used to figure out what certs should be used when encrypting this message.
*/
nsresult nsMsgComposeSecure::MimeCryptoHackCerts(const char *aRecipients, PRBool aEncrypt, PRBool aSign)
nsresult nsMsgComposeSecure::MimeCryptoHackCerts(const char *aRecipients,
nsIMsgSendReport *sendReport,
PRBool aEncrypt,
PRBool aSign)
{
int status = 0;
char *all_mailboxes = 0, *mailboxes = 0, *mailbox_list = 0;
const char *mailbox = 0;
PRUint32 count = 0;
PRUint32 numCerts;
nsCOMPtr<nsIX509CertDB> certdb = do_GetService(NS_X509CERTDB_CONTRACTID);
nsCOMPtr<nsIMsgHeaderParser> pHeader;
nsresult res = nsComponentManager::CreateInstance(kMsgHeaderParserCID,
@ -722,18 +797,38 @@ nsresult nsMsgComposeSecure::MimeCryptoHackCerts(const char *aRecipients, PRBool
return res;
}
nsXPIDLString errorString;
PRBool no_clearsigning_p = PR_FALSE;
PR_ASSERT(aEncrypt || aSign);
certdb->GetEmailEncryptionCert(mEncryptionCertName, getter_AddRefs(mSelfEncryptionCert));
certdb->GetEmailSigningCert(mSigningCertName, getter_AddRefs(mSelfSigningCert));
// must have both the signing and encryption certs to sign
if ((mSelfSigningCert == nsnull) && aSign) {
status = SEC_ERROR_NO_EMAIL_CERT;
res = GetSMIMEBundleString(NS_LITERAL_STRING("NoSenderSigningCert").get(),
getter_Copies(errorString));
if ( NS_SUCCEEDED(res) ) {
res = NS_ERROR_FAILURE;
}
goto FAIL;
}
if ((mSelfEncryptionCert == nsnull) && aSign) {
res = GetSMIMEBundleString(NS_LITERAL_STRING("SignNoSenderEncryptionCert").get(),
getter_Copies(errorString));
if ( NS_SUCCEEDED(res) ) {
res = NS_ERROR_FAILURE;
}
goto FAIL;
}
if ((mSelfEncryptionCert == nsnull) && aEncrypt) {
status = SEC_ERROR_NO_EMAIL_CERT;
res = GetSMIMEBundleString(NS_LITERAL_STRING("NoSenderEncriptionCert").get(),
getter_Copies(errorString));
if ( NS_SUCCEEDED(res) ) {
res = NS_ERROR_FAILURE;
}
goto FAIL;
}
@ -754,8 +849,22 @@ nsresult nsMsgComposeSecure::MimeCryptoHackCerts(const char *aRecipients, PRBool
nsCOMPtr<nsIX509Cert> cert;
certdb->GetCertByEmailAddress(nsnull, mailbox, getter_AddRefs(cert));
if (!cert) {
mailbox += nsCRT::strlen(mailbox) + 1;
continue;
// failure to find an encryption cert is
// fatal for now. We won't be able to encrypt anyway
// ssaux 12/03/2001.
const PRUnichar *params[1];
// here I assume that mailbox contains ascii rather than utf8.
params[0]= NS_ConvertASCIItoUCS2(mailbox).get();
res =
SMIMEBundleFormatStringFromName(NS_LITERAL_STRING("MissingRecipientEncryptionCert").get(),
params,
1,
getter_Copies(errorString));
if ( NS_SUCCEEDED(res) ) {
res = NS_ERROR_FAILURE;
}
goto FAIL;
}
/* #### see if recipient requests `signedData'.
@ -767,14 +876,16 @@ nsresult nsMsgComposeSecure::MimeCryptoHackCerts(const char *aRecipients, PRBool
mCerts->AppendElement(cert);
mailbox += nsCRT::strlen(mailbox) + 1;
}
mCerts->Count(&numCerts);
if (numCerts == 0) {
res = NS_ERROR_FAILURE; // XXX We should set a specific error in this case XXX //
goto FAIL;
}
}
FAIL:
PR_FREEIF(mailbox_list);
if (NS_FAILED(res) && errorString.get() && sendReport) {
sendReport->SetMessage(nsIMsgSendReport::process_Current,
errorString.get(),
PR_TRUE);
}
return res;
}

Просмотреть файл

@ -28,6 +28,7 @@
#include "nsICMS.h"
#include "nsIX509Cert.h"
#include "nsIMimeConverter.h"
#include "nsIStringBundle.h"
class nsIMsgCompFields;
@ -68,8 +69,14 @@ private:
nsresult MimeInitEncryption(PRBool aSign);
nsresult MimeFinishMultipartSigned (PRBool aOuter);
nsresult MimeFinishEncryption (PRBool aSign);
nsresult MimeCryptoHackCerts(const char *aRecipients, PRBool aEncrypt, PRBool aSign);
nsresult MimeCryptoHackCerts(const char *aRecipients, nsIMsgSendReport *sendReport, PRBool aEncrypt, PRBool aSign);
static void InitializeSMIMEBundle();
nsresult GetSMIMEBundleString(const PRUnichar *name,
PRUnichar **outString);
nsresult SMIMEBundleFormatStringFromName(const PRUnichar *name,
const PRUnichar **params,
PRUint32 numParams,
PRUnichar **outString);
nsresult ExtractEncryptionState(nsIMsgIdentity * aIdentity, nsIMsgCompFields * aComposeFields, PRBool * aSignMessage, PRBool * aEncrypt);
mimeDeliveryCryptoState mCryptoState;
@ -85,6 +92,8 @@ private:
nsCOMPtr<nsISupportsArray> mCerts;
nsCOMPtr<nsICMSMessage> mEncryptionCinfo;
nsCOMPtr<nsICMSEncoder> mEncryptionContext;
static nsCOMPtr<nsIStringBundle> mSMIMEBundle;
MimeEncoderData *mCryptoEncoderData;
PRBool mIsDraft;
};