b=177260 Fix known leaks in PSM, track blocking PSM UI, track open SSL sockets

r=javi sr=darin
This commit is contained in:
kaie%netscape.com 2003-01-06 22:23:49 +00:00
Родитель abd8e71173
Коммит 3c02966450
19 изменённых файлов: 536 добавлений и 159 удалений

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

@ -1068,6 +1068,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsPSMTracker.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSSLSocketProvider.cpp</PATH>
@ -1324,6 +1331,11 @@
<PATH>nsNSSModule.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsPSMTracker.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSSLSocketProvider.cpp</PATH>
@ -2469,6 +2481,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsPSMTracker.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSSLSocketProvider.cpp</PATH>
@ -2727,6 +2746,11 @@
<PATH>nsNSSModule.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsPSMTracker.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSSLSocketProvider.cpp</PATH>
@ -3112,6 +3136,12 @@
<PATH>nsNSSModule.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>PIPNSS.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsPSMTracker.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>PIPNSS.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>

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

@ -227,6 +227,8 @@ CrlImportFailureNetworkProblem=Download of the CRL failed due to Network problem
CrlImportFailureReasonUnknown=Error Importing CRL to local Database. Error Code:
CrlImportFailure2=Please ask your system administrator for assistance.
NSSInitProblem=Could not initialize the browser's security component. The most likely cause is problems with files in your browser's profile directory. Please check that this directory has no read/write restrictions and your hard disk is not full or close to full. It is recommended that you exit the browser and fix the problem. If you continue to use this browser session, you might see incorrect browser behaviour when accessing security features.
ProfileSwitchSocketsStillActive=The operation can not be completed because of an internal failure. A secure network communication has not been cleaned up correctly.
ProfileSwitchCryptoUIActive=This operation is impossible at the current time. Please complete the operation that requests your attention in one of the other open windows.
VerifyExpired=<Expired>
VerifyRevoked=<Revoked>
VerifyNotTrusted=<Not Trusted>

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

@ -78,6 +78,7 @@ CPPSRCS = \
nsOCSPResponder.cpp \
nsUsageArrayHelper.cpp \
nsCRLManager.cpp \
nsPSMTracker.cpp \
$(NULL)
REQUIRES = nspr \

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

@ -49,6 +49,9 @@
extern PRLogModuleInfo* gPIPNSSLog;
#endif
#include "nsNSSCleaner.h"
NSSCleanupAutoPtrClass(CERTCertificate, CERT_DestroyCertificate)
NS_IMPL_THREADSAFE_ISUPPORTS1(nsHash, nsIHash)
nsHash::nsHash() : m_ctxt(nsnull)
@ -61,6 +64,7 @@ nsHash::~nsHash()
{
if (m_ctxt) {
HASH_Destroy(m_ctxt);
m_ctxt = nsnull;
}
}
@ -333,14 +337,96 @@ loser:
return rv;
}
class nsZeroTerminatedCertArray
{
public:
nsZeroTerminatedCertArray()
:mCerts(nsnull), mPoolp(nsnull), mSize(0)
{
}
~nsZeroTerminatedCertArray()
{
if (mCerts)
{
for (PRUint32 i=0; i < mSize; i++) {
if (mCerts[i]) {
CERT_DestroyCertificate(mCerts[i]);
}
}
}
if (mPoolp)
PORT_FreeArena(mPoolp, PR_FALSE);
}
PRBool allocate(PRUint32 count)
{
// only allow allocation once
if (mPoolp)
return PR_FALSE;
mSize = count;
if (!mSize)
return PR_FALSE;
mPoolp = PORT_NewArena(1024);
if (!mPoolp)
return PR_FALSE;
mCerts = (CERTCertificate**)PORT_ArenaZAlloc(
mPoolp, (count+1)*sizeof(CERTCertificate*));
if (!mCerts)
return PR_FALSE;
// null array, including zero termination
for (PRUint32 i = 0; i < count+1; i++) {
mCerts[i] = nsnull;
}
return PR_TRUE;
}
void set(PRUint32 i, CERTCertificate *c)
{
if (i >= mSize)
return;
if (mCerts[i]) {
CERT_DestroyCertificate(mCerts[i]);
}
mCerts[i] = CERT_DupCertificate(c);
}
CERTCertificate *get(PRUint32 i)
{
if (i >= mSize)
return nsnull;
return CERT_DupCertificate(mCerts[i]);
}
CERTCertificate **getRawArray()
{
return mCerts;
}
private:
CERTCertificate **mCerts;
PLArenaPool *mPoolp;
PRUint32 mSize;
};
NS_IMETHODIMP nsCMSMessage::CreateEncrypted(nsIArray * aRecipientCerts)
{
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateEncrypted\n"));
NSSCMSContentInfo *cinfo;
NSSCMSEnvelopedData *envd;
NSSCMSRecipientInfo *recipientInfo;
CERTCertificate **recipientCerts;
PLArenaPool *tmpPoolp = nsnull;
nsZeroTerminatedCertArray recipientCerts;
SECOidTag bulkAlgTag;
int keySize;
PRUint32 i;
@ -352,13 +438,7 @@ NS_IMETHODIMP nsCMSMessage::CreateEncrypted(nsIArray * aRecipientCerts)
aRecipientCerts->GetLength(&recipientCertCount);
PR_ASSERT(recipientCertCount > 0);
if ((tmpPoolp = PORT_NewArena(1024)) == nsnull) {
goto loser;
}
if ((recipientCerts = (CERTCertificate**)PORT_ArenaZAlloc(tmpPoolp,
(recipientCertCount+1)*sizeof(CERTCertificate*)))
== nsnull) {
if (!recipientCerts.allocate(recipientCertCount)) {
goto loser;
}
@ -372,12 +452,11 @@ NS_IMETHODIMP nsCMSMessage::CreateEncrypted(nsIArray * aRecipientCerts)
if (!nssRecipientCert)
return NS_ERROR_FAILURE;
recipientCerts[i] = nssRecipientCert->GetCert();
recipientCerts.set(i, nssRecipientCert->GetCert());
}
recipientCerts[i] = nsnull;
// Find a bulk key algorithm //
if (NSS_SMIMEUtil_FindBulkAlgForRecipients(recipientCerts, &bulkAlgTag,
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;
@ -409,8 +488,10 @@ NS_IMETHODIMP nsCMSMessage::CreateEncrypted(nsIArray * aRecipientCerts)
}
// Create and attach recipient information //
for (i=0; recipientCerts[i] != nsnull; i++) {
if ((recipientInfo = NSS_CMSRecipientInfo_Create(m_cmsMsg, recipientCerts[i])) == nsnull) {
for (i=0; i < recipientCertCount; i++) {
CERTCertificate *rc = recipientCerts.get(i);
CERTCertificateCleaner rcCleaner(rc);
if ((recipientInfo = NSS_CMSRecipientInfo_Create(m_cmsMsg, rc)) == nsnull) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateEncrypted - can't create recipient info\n"));
goto loser;
}
@ -420,19 +501,12 @@ NS_IMETHODIMP nsCMSMessage::CreateEncrypted(nsIArray * aRecipientCerts)
}
}
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;
}
@ -456,6 +530,9 @@ NS_IMETHODIMP nsCMSMessage::CreateSigned(nsIX509Cert* aSigningCert, nsIX509Cert*
ecert = NS_STATIC_CAST(nsNSSCertificate*, aEncryptCert)->GetCert();
}
CERTCertificateCleaner ecertCleaner(ecert);
CERTCertificateCleaner scertCleaner(scert);
/*
* create the message object
*/
@ -574,6 +651,10 @@ nsCMSDecoder::nsCMSDecoder()
nsCMSDecoder::~nsCMSDecoder()
{
if (m_dcx) {
NSS_CMSDecoder_Cancel(m_dcx);
m_dcx = nsnull;
}
}
/* void start (in NSSCMSContentCallback cb, in voidPtr arg); */
@ -604,6 +685,7 @@ NS_IMETHODIMP nsCMSDecoder::Finish(nsICMSMessage ** aCMSMsg)
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSDecoder::Finish\n"));
NSSCMSMessage *cmsMsg;
cmsMsg = NSS_CMSDecoder_Finish(m_dcx);
m_dcx = nsnull;
if (cmsMsg) {
nsCMSMessage *obj = new nsCMSMessage(cmsMsg);
// The NSS object cmsMsg still carries a reference to the context
@ -625,6 +707,8 @@ nsCMSEncoder::nsCMSEncoder()
nsCMSEncoder::~nsCMSEncoder()
{
if (m_ecx)
NSS_CMSEncoder_Cancel(m_ecx);
}
/* void start (); */
@ -656,12 +740,14 @@ NS_IMETHODIMP nsCMSEncoder::Update(const char *aBuf, PRInt32 aLen)
/* void finish (); */
NS_IMETHODIMP nsCMSEncoder::Finish()
{
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"));
return NS_ERROR_FAILURE;
rv = NS_ERROR_FAILURE;
}
return NS_OK;
m_ecx = nsnull;
return rv;
}
/* void encode (in nsICMSMessage aMsg); */

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

@ -46,6 +46,7 @@
#include "nsIPrompt.h"
#include "nsICertificateDialogs.h"
#include "nsArray.h"
#include "nsPSMTracker.h"
#include "nsNSSCertHeader.h"
@ -191,18 +192,30 @@ done:
message.Append(NS_LITERAL_STRING("\n").get());
message.Append(temp);
if(prompter)
prompter->Alert(0, message.get());
if(prompter) {
nsPSMUITracker tracker;
if (!tracker.isUIForbidden()) {
prompter->Alert(0, message.get());
}
}
}
} else {
nsCOMPtr<nsICertificateDialogs> certDialogs;
// Not being able to display the success dialog should not
// be a fatal error, so don't return a failure code.
if (NS_SUCCEEDED(::getNSSDialogs(getter_AddRefs(certDialogs),
NS_GET_IID(nsICertificateDialogs),
NS_CERTIFICATEDIALOGS_CONTRACTID))) {
nsCOMPtr<nsIInterfaceRequestor> cxt = new PipUIContext();
certDialogs->CrlImportStatusDialog(cxt, crlData);
{
nsPSMUITracker tracker;
if (tracker.isUIForbidden()) {
rv = NS_ERROR_NOT_AVAILABLE;
}
else {
rv = ::getNSSDialogs(getter_AddRefs(certDialogs),
NS_GET_IID(nsICertificateDialogs), NS_CERTIFICATEDIALOGS_CONTRACTID);
}
}
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIInterfaceRequestor> cxt = new PipUIContext();
certDialogs->CrlImportStatusDialog(cxt, crlData);
}
}
} else {

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

@ -45,6 +45,7 @@
#include "nsReadableUtils.h"
#include "nsNSSCleaner.h"
#include "nsICertPickDialogs.h"
#include "nsPSMTracker.h"
NSSCleanupAutoPtrClass(CERTCertNicknames, CERT_FreeNicknames)
NSSCleanupAutoPtrClass(CERTCertList, CERT_DestroyCertList)
@ -173,10 +174,16 @@ NS_IMETHODIMP nsCertPicker::PickByUsage(nsIInterfaceRequestor *ctx,
NS_CERTPICKDIALOGS_CONTRACTID);
if (NS_SUCCEEDED(rv)) {
/* Throw up the cert picker dialog and get back the index of the selected cert */
rv = dialogs->PickCertificate(ctx,
(const PRUnichar**)certNicknameList, (const PRUnichar**)certDetailsList,
CertsToUse, &selectedIndex, canceled);
nsPSMUITracker tracker;
if (tracker.isUIForbidden()) {
rv = NS_ERROR_NOT_AVAILABLE;
}
else {
/* Throw up the cert picker dialog and get back the index of the selected cert */
rv = dialogs->PickCertificate(ctx,
(const PRUnichar**)certNicknameList, (const PRUnichar**)certDetailsList,
CertsToUse, &selectedIndex, canceled);
}
NS_RELEASE(dialogs);
}

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

@ -21,6 +21,7 @@
* Javier Delgadillo <javi@netscape.com>
*/
#include "nsNSSComponent.h"
#include "nsPSMTracker.h"
#include "nsCrypto.h"
#include "nsKeygenHandler.h"
#include "nsKeygenThread.h"
@ -660,11 +661,18 @@ cryptojs_generateOneKeyPair(JSContext *cx, nsKeyPairInfo *keyPairInfo,
runnable = do_QueryInterface(KeygenRunnable);
if (runnable) {
rv = dialogs->DisplayGeneratingKeypairInfo(uiCxt, runnable);
// We call join on the thread,
// so we can be sure that no simultaneous access to the passed parameters will happen.
KeygenRunnable->Join();
{
nsPSMUITracker tracker;
if (tracker.isUIForbidden()) {
rv = NS_ERROR_NOT_AVAILABLE;
}
else {
rv = dialogs->DisplayGeneratingKeypairInfo(uiCxt, runnable);
// We call join on the thread,
// so we can be sure that no simultaneous access to the passed parameters will happen.
KeygenRunnable->Join();
}
}
NS_RELEASE(dialogs);
if (NS_SUCCEEDED(rv)) {
@ -1480,7 +1488,15 @@ nsCrypto::GenerateCRMFRequest(nsIDOMCRMFObject** aReturn)
return rv;
PRBool okay=PR_FALSE;
dialogs->ConfirmKeyEscrow(nssCert, &okay);
{
nsPSMUITracker tracker;
if (tracker.isUIForbidden()) {
okay = PR_FALSE;
}
else {
dialogs->ConfirmKeyEscrow(nssCert, &okay);
}
}
if (!okay)
return NS_OK;
willEscrow = PR_TRUE;
@ -1632,7 +1648,10 @@ alertUser(const PRUnichar *message)
wwatch->GetNewPrompter(0, getter_AddRefs(prompter));
if (prompter) {
prompter->Alert(0, message);
nsPSMUITracker tracker;
if (!tracker.isUIForbidden()) {
prompter->Alert(0, message);
}
}
}
@ -1641,15 +1660,10 @@ NS_IMETHODIMP
nsP12Runnable::Run()
{
NS_ASSERTION(mCertArr, "certArr is NULL while trying to back up");
nsCOMPtr<nsIDOMCryptoDialogs> dialogs;
nsresult rv = getNSSDialogs(getter_AddRefs(dialogs),
NS_GET_IID(nsIDOMCryptoDialogs),
NS_DOMCRYPTODIALOGS_CONTRACTID);
if (NS_FAILED(rv))
return rv;
nsString final;
nsString temp;
nsresult rv;
nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
if (NS_FAILED(rv))
@ -2094,7 +2108,10 @@ confirm_user(const PRUnichar *message)
wwatch->GetNewPrompter(0, getter_AddRefs(prompter));
if (prompter) {
prompter->Confirm(0, message, &confirmation);
nsPSMUITracker tracker;
if (!tracker.isUIForbidden()) {
prompter->Confirm(0, message, &confirmation);
}
}
return confirmation;

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

@ -45,6 +45,7 @@ extern "C" {
#include "nsCRT.h"
#include "nsITokenDialogs.h"
#include "nsIGenKeypairInfoDlg.h"
#include "nsPSMTracker.h"
//These defines are taken from the PKCS#11 spec
#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000
@ -316,7 +317,15 @@ GetSlotWithMechanism(PRUint32 aMechanism,
if (NS_FAILED(rv)) goto loser;
rv = dialogs->ChooseToken(nsnull, (const PRUnichar**)tokenNameList, numSlots, &unicodeTokenChosen, &canceled);
{
nsPSMUITracker tracker;
if (tracker.isUIForbidden()) {
rv = NS_ERROR_NOT_AVAILABLE;
}
else {
rv = dialogs->ChooseToken(nsnull, (const PRUnichar**)tokenNameList, numSlots, &unicodeTokenChosen, &canceled);
}
}
NS_RELEASE(dialogs);
if (NS_FAILED(rv)) goto loser;
@ -480,11 +489,18 @@ found_match:
runnable = do_QueryInterface(KeygenRunnable);
if (runnable) {
rv = dialogs->DisplayGeneratingKeypairInfo(m_ctx, runnable);
// We call join on the thread,
// so we can be sure that no simultaneous access to the passed parameters will happen.
KeygenRunnable->Join();
{
nsPSMUITracker tracker;
if (tracker.isUIForbidden()) {
rv = NS_ERROR_NOT_AVAILABLE;
}
else {
rv = dialogs->DisplayGeneratingKeypairInfo(m_ctx, runnable);
// We call join on the thread,
// so we can be sure that no simultaneous access to the passed parameters will happen.
KeygenRunnable->Join();
}
}
NS_RELEASE(dialogs);
if (NS_SUCCEEDED(rv)) {
@ -549,7 +565,6 @@ loser:
if ( sec_rv != SECSuccess ) {
if ( privateKey ) {
PK11_DestroyTokenObject(privateKey->pkcs11Slot,privateKey->pkcs11ID);
SECKEY_DestroyPrivateKey(privateKey);
}
if ( publicKey ) {
PK11_DestroyTokenObject(publicKey->pkcs11Slot,publicKey->pkcs11ID);
@ -561,6 +576,9 @@ loser:
if ( publicKey ) {
SECKEY_DestroyPublicKey(publicKey);
}
if ( privateKey ) {
SECKEY_DestroyPrivateKey(privateKey);
}
if ( arena ) {
PORT_FreeArena(arena, PR_TRUE);
}

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

@ -37,6 +37,7 @@
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsCRT.h"
#include "nsPSMTracker.h"
#include "ssl.h"
#include "cert.h"
@ -177,8 +178,17 @@ PK11PasswordPrompt(PK11SlotInfo* slot, PRBool retry, void* arg) {
if (NS_FAILED(rv))
return nsnull;
rv = proxyPrompt->PromptPassword(nsnull, promptString.get(),
&password, nsnull, nsnull, &value);
{
nsPSMUITracker tracker;
if (tracker.isUIForbidden()) {
rv = NS_ERROR_NOT_AVAILABLE;
}
else {
rv = proxyPrompt->PromptPassword(nsnull, promptString.get(),
&password, nsnull, nsnull, &value);
}
}
if (NS_SUCCEEDED(rv) && value) {
char* str = ToNewCString(nsDependentString(password));
Recycle(password);
@ -248,7 +258,10 @@ void PR_CALLBACK HandshakeCallback(PRFileDesc* fd, void* client_data) {
nsCOMPtr<nsSSLStatus> status = new nsSSLStatus();
CERTCertificate *serverCert = SSL_PeerCertificate(fd);
if (serverCert) status->mServerCert = new nsNSSCertificate(serverCert);
if (serverCert) {
status->mServerCert = new nsNSSCertificate(serverCert);
CERT_DestroyCertificate(serverCert);
}
status->mKeyLength = keyLength;
status->mSecretKeyLength = encryptBits;

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

@ -107,22 +107,13 @@ nsNSSCertificate::ConstructFromDER(char *certDER, int derLen)
aCert->dbhandle = CERT_GetDefaultCertDB();
}
// We don't want the new NSS cert to be dupped, therefore we create our instance
// with a NULL pointer first, and set the contained cert later.
nsNSSCertificate *newObject = new nsNSSCertificate(nsnull);
if (!newObject)
{
CERT_DestroyCertificate(aCert);
return nsnull;
}
newObject->mCert = aCert;
nsNSSCertificate *newObject = new nsNSSCertificate(aCert);
CERT_DestroyCertificate(aCert);
return newObject;
}
nsNSSCertificate::nsNSSCertificate(CERTCertificate *cert) :
mCert(nsnull),
mPermDelete(PR_FALSE),
mCertType(nsIX509Cert::UNKNOWN_CERT)
{
@ -140,16 +131,16 @@ nsNSSCertificate::~nsNSSCertificate()
if (mCertType == nsNSSCertificate::USER_CERT) {
nsCOMPtr<nsIInterfaceRequestor> cxt = new PipUIContext();
PK11_DeleteTokenCertAndKey(mCert, cxt);
CERT_DestroyCertificate(mCert);
} else if (!PK11_IsReadOnly(mCert->slot)) {
// If the cert isn't a user cert and it is on an external token,
// then we'll just leave it as untrusted, but won't delete it
// from the cert db.
SEC_DeletePermCertificate(mCert);
}
} else {
if (mCert)
CERT_DestroyCertificate(mCert);
}
if (mCert) {
CERT_DestroyCertificate(mCert);
}
}

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

@ -49,9 +49,8 @@
#include "nsPK11TokenDB.h"
#include "nsOCSPResponder.h"
#include "nsReadableUtils.h"
#include "nsIWindowWatcher.h"
#include "nsIPrompt.h"
#include "nsArray.h"
#include "nsPSMTracker.h"
#include "nspr.h"
extern "C" {
@ -114,6 +113,7 @@ nsNSSCertificateDB::FindCertByNickname(nsISupports *aToken,
if (cert) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("got it\n"));
nsCOMPtr<nsIX509Cert> pCert = new nsNSSCertificate(cert);
CERT_DestroyCertificate(cert);
*_rvCert = pCert;
NS_ADDREF(*_rvCert);
return NS_OK;
@ -151,6 +151,7 @@ nsNSSCertificateDB::FindCertByDBKey(const char *aDBkey, nsISupports *aToken,
PR_FREEIF(keyItem.data);
if (cert) {
nsNSSCertificate *nssCert = new nsNSSCertificate(cert);
CERT_DestroyCertificate(cert);
if (nssCert == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(nssCert);
@ -345,7 +346,10 @@ nsNSSCertificateDB::handleCACertDownload(nsIArray *x509Certs,
CERTCertificateCleaner tmpCertCleaner(tmpCert);
if (tmpCert->isperm) {
dialogs->NotifyCACertExists(ctx);
nsPSMUITracker tracker;
if (!tracker.isUIForbidden()) {
dialogs->NotifyCACertExists(ctx);
}
return NS_ERROR_FAILURE;
}
@ -513,6 +517,8 @@ nsNSSCertificateDB::ImportEmailCertificate(PRUint8 * data, PRUint32 length,
srv = CERT_SaveSMimeProfile(cert, NULL, NULL);
PORT_Free(rawCerts);
loser:
if (cert)
CERT_DestroyCertificate(cert);
if (arena)
PORT_FreeArena(arena, PR_TRUE);
return nsrv;
@ -576,6 +582,8 @@ nsNSSCertificateDB::ImportServerCertificate(PRUint8 * data, PRUint32 length,
}
loser:
PORT_Free(rawCerts);
if (cert)
CERT_DestroyCertificate(cert);
if (arena)
PORT_FreeArena(arena, PR_TRUE);
return nsrv;
@ -660,6 +668,7 @@ nsNSSCertificateDB::DeleteCertificate(nsIX509Cert *aCert)
nsNSSCertificate *nssCert = NS_STATIC_CAST(nsNSSCertificate*, aCert);
CERTCertificate *cert = nssCert->GetCert();
if (!cert) return NS_ERROR_FAILURE;
CERTCertificateCleaner certCleaner(cert);
SECStatus srv = SECSuccess;
PRUint32 certType = getCertType(cert);
@ -699,6 +708,7 @@ nsNSSCertificateDB::SetCertTrust(nsIX509Cert *cert,
nsNSSCertTrust trust;
nsNSSCertificate *pipCert = NS_STATIC_CAST(nsNSSCertificate *, cert);
CERTCertificate *nsscert = pipCert->GetCert();
CERTCertificateCleaner certCleaner(nsscert);
if (type == nsIX509Cert::CA_CERT) {
// always start with untrusted and move up
trust.SetValidCA();
@ -741,6 +751,7 @@ nsNSSCertificateDB::IsCertTrusted(nsIX509Cert *cert,
CERTCertTrust nsstrust;
srv = CERT_GetCertTrust(nsscert, &nsstrust);
nsNSSCertTrust trust(&nsstrust);
CERT_DestroyCertificate(nsscert);
if (certType == nsIX509Cert::CA_CERT) {
if (trustType & nsIX509CertDB::TRUSTED_SSL) {
*_isTrusted = trust.HasTrustedCA(PR_TRUE, PR_FALSE, PR_FALSE);
@ -903,13 +914,16 @@ GetOCSPResponders (CERTCertificate *aCert,
// Get the AIA and nickname //
serviceURL = CERT_GetOCSPAuthorityInfoAccessLocation(aCert);
if (serviceURL) {
url = ToNewUnicode(NS_ConvertUTF8toUCS2(serviceURL));
url = ToNewUnicode(NS_ConvertUTF8toUCS2(serviceURL));
PORT_Free(serviceURL);
}
nickname = aCert->nickname;
nn = ToNewUnicode(NS_ConvertUTF8toUCS2(nickname));
nsCOMPtr<nsIOCSPResponder> new_entry = new nsOCSPResponder(nn, url);
nsMemory::Free(nn);
nsMemory::Free(url);
// Sort the items according to nickname //
rv = array->GetLength(&count);

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

@ -70,6 +70,7 @@
#include "nsILocalFile.h"
#include "nsITokenPasswordDialogs.h"
#include "nsICRLManager.h"
#include "nsPSMTracker.h"
#include "nss.h"
#include "pk11func.h"
@ -226,6 +227,7 @@ nsNSSComponent::nsNSSComponent()
NS_ASSERTION( (0 == mInstanceCount), "nsNSSComponent is a singleton, but instantiated multiple times!");
++mInstanceCount;
hashTableCerts = nsnull;
mPSMTracker = nsPSMTracker::construct();
}
nsNSSComponent::~nsNSSComponent()
@ -254,6 +256,7 @@ nsNSSComponent::~nsNSSComponent()
ShutdownNSS();
nsSSLIOLayerFreeTLSIntolerantSites();
--mInstanceCount;
delete mPSMTracker;
if (mutex) {
PR_DestroyLock(mutex);
@ -901,8 +904,6 @@ nsNSSComponent::InitializeNSS()
return NS_ERROR_FAILURE;
}
mNSSInitialized = PR_TRUE;
hashTableCerts = PL_NewHashTable( 0, certHashtable_keyHash, certHashtable_keyCompare,
certHashtable_valueCompare, 0, 0 );
@ -970,6 +971,9 @@ nsNSSComponent::InitializeNSS()
// init phase 3, only if phase 2 was successful
if (problem_no_security_at_all != which_nss_problem) {
mNSSInitialized = PR_TRUE;
::NSS_SetDomesticPolicy();
// SSL_EnableCipher(SSL_RSA_WITH_NULL_MD5, SSL_ALLOWED);
@ -1020,39 +1024,7 @@ nsNSSComponent::InitializeNSS()
// We might want to use different messages, depending on what failed.
// For now, let's use the same message.
nsresult rv = GetPIPNSSBundleString(NS_LITERAL_STRING("NSSInitProblem").get(), message);
if (NS_SUCCEEDED(rv)) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("can't get error string\n"));
nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
if (!wwatch) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("can't get window watcher\n"));
}
else {
nsCOMPtr<nsIPrompt> prompter;
wwatch->GetNewPrompter(0, getter_AddRefs(prompter));
if (!prompter) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("can't get window prompter\n"));
}
else {
nsCOMPtr<nsIProxyObjectManager> proxyman(do_GetService(NS_XPCOMPROXY_CONTRACTID));
if (!proxyman) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("can't get proxy manager\n"));
}
else {
nsCOMPtr<nsIPrompt> proxyPrompt;
proxyman->GetProxyForObject(NS_UI_THREAD_EVENTQ, NS_GET_IID(nsIPrompt),
prompter, PROXY_SYNC, getter_AddRefs(proxyPrompt));
if (!proxyPrompt) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("can't get proxy for nsIPrompt\n"));
}
else {
proxyPrompt->Alert(nsnull, message.get());
}
}
}
}
}
ShowAlert(ai_nss_init_problem);
}
return NS_OK;
@ -1087,13 +1059,18 @@ nsNSSComponent::ShutdownNSS()
SSL_ClearSessionCache();
#if 0
// temporarily disable this call until bug 181230 gets fixed
::NSS_Shutdown();
if (SECSuccess != ::NSS_Shutdown()) {
PR_LOG(gPIPNSSLog, PR_LOG_ALWAYS, ("NSS SHUTDOWN FAILURE\n"));
}
else {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("NSS shutdown =====>> OK <<=====\n"));
}
#endif
}
return NS_OK;
}
NS_IMETHODIMP
nsNSSComponent::Init()
{
@ -1364,11 +1341,13 @@ nsNSSComponent::PrefChanged(const char* prefName)
#define PROFILE_CHANGE_NET_RESTORE_TOPIC NS_LITERAL_CSTRING("profile-change-net-restore").get()
#endif
#define PROFILE_APPROVE_CHANGE_TOPIC NS_LITERAL_CSTRING("profile-approve-change").get()
#define PROFILE_CHANGE_TEARDOWN_TOPIC NS_LITERAL_CSTRING("profile-change-teardown").get()
#define PROFILE_CHANGE_TEARDOWN_VETO_TOPIC NS_LITERAL_CSTRING("profile-change-teardown-veto").get()
#define PROFILE_BEFORE_CHANGE_TOPIC NS_LITERAL_CSTRING("profile-before-change").get()
#define PROFILE_AFTER_CHANGE_TOPIC NS_LITERAL_CSTRING("profile-after-change").get()
#define SESSION_LOGOUT_TOPIC NS_LITERAL_CSTRING("session-logout").get()
NS_IMETHODIMP
nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic,
const PRUnichar *someData)
@ -1377,7 +1356,41 @@ nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic,
static PRBool isNetworkDown = PR_FALSE;
#endif
if (nsCRT::strcmp(aTopic, PROFILE_BEFORE_CHANGE_TOPIC) == 0) {
if (nsCRT::strcmp(aTopic, PROFILE_APPROVE_CHANGE_TOPIC) == 0) {
if (mPSMTracker->isUIActive()) {
ShowAlert(ai_crypto_ui_active);
nsCOMPtr<nsIProfileChangeStatus> status = do_QueryInterface(aSubject);
if (status) {
status->VetoChange();
}
}
}
else if (nsCRT::strcmp(aTopic, PROFILE_CHANGE_TEARDOWN_TOPIC) == 0) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("in PSM code, receiving change-teardown\n"));
PRBool callVeto = PR_FALSE;
if (!mPSMTracker->ifPossibleDisallowUI()) {
callVeto = PR_TRUE;
ShowAlert(ai_crypto_ui_active);
}
else if (mPSMTracker->areSSLSocketsActive()) {
callVeto = PR_TRUE;
ShowAlert(ai_sockets_still_active);
}
if (callVeto) {
nsCOMPtr<nsIProfileChangeStatus> status = do_QueryInterface(aSubject);
if (status) {
status->VetoChange();
}
}
}
else if (nsCRT::strcmp(aTopic, PROFILE_CHANGE_TEARDOWN_VETO_TOPIC) == 0) {
mPSMTracker->allowUI();
}
else if (nsCRT::strcmp(aTopic, PROFILE_BEFORE_CHANGE_TOPIC) == 0) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("receiving profile change topic\n"));
#ifdef DEBUG
NS_ASSERTION(isNetworkDown, "nsNSSComponent relies on profile manager to wait for synchronous shutdown of all network activity");
#endif
@ -1400,6 +1413,8 @@ nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic,
if (needsCleanup) {
ShutdownNSS();
}
mPSMTracker->allowUI();
}
else if (nsCRT::strcmp(aTopic, PROFILE_AFTER_CHANGE_TOPIC) == 0) {
@ -1457,9 +1472,11 @@ nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic,
#ifdef DEBUG
else if (nsCRT::strcmp(aTopic, PROFILE_CHANGE_NET_TEARDOWN_TOPIC) == 0) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("receiving network teardown topic\n"));
isNetworkDown = PR_TRUE;
}
else if (nsCRT::strcmp(aTopic, PROFILE_CHANGE_NET_RESTORE_TOPIC) == 0) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("receiving network restore topic\n"));
isNetworkDown = PR_FALSE;
}
#endif
@ -1467,6 +1484,61 @@ nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic,
return NS_OK;
}
void nsNSSComponent::ShowAlert(AlertIdentifier ai)
{
nsString message;
nsresult rv;
switch (ai) {
case ai_nss_init_problem:
rv = GetPIPNSSBundleString(NS_LITERAL_STRING("NSSInitProblem").get(), message);
break;
case ai_sockets_still_active:
rv = GetPIPNSSBundleString(NS_LITERAL_STRING("ProfileSwitchSocketsStillActive").get(), message);
break;
case ai_crypto_ui_active:
rv = GetPIPNSSBundleString(NS_LITERAL_STRING("ProfileSwitchCryptoUIActive").get(), message);
break;
case ai_incomplete_logout:
rv = GetPIPNSSBundleString(NS_LITERAL_STRING("LogoutIncompleteUIActive").get(), message);
break;
default:
return;
}
if (NS_FAILED(rv))
return;
nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
if (!wwatch) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("can't get window watcher\n"));
}
else {
nsCOMPtr<nsIPrompt> prompter;
wwatch->GetNewPrompter(0, getter_AddRefs(prompter));
if (!prompter) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("can't get window prompter\n"));
}
else {
nsCOMPtr<nsIProxyObjectManager> proxyman(do_GetService(NS_XPCOMPROXY_CONTRACTID));
if (!proxyman) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("can't get proxy manager\n"));
}
else {
nsCOMPtr<nsIPrompt> proxyPrompt;
proxyman->GetProxyForObject(NS_UI_THREAD_EVENTQ, NS_GET_IID(nsIPrompt),
prompter, PROXY_SYNC, getter_AddRefs(proxyPrompt));
if (!proxyPrompt) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("can't get proxy for nsIPrompt\n"));
}
else {
proxyPrompt->Alert(nsnull, message.get());
}
}
}
}
}
nsresult
nsNSSComponent::RegisterObservers()
{
@ -1487,6 +1559,9 @@ nsNSSComponent::RegisterObservers()
observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE);
observerService->AddObserver(this, PROFILE_APPROVE_CHANGE_TOPIC, PR_FALSE);
observerService->AddObserver(this, PROFILE_CHANGE_TEARDOWN_TOPIC, PR_FALSE);
observerService->AddObserver(this, PROFILE_CHANGE_TEARDOWN_VETO_TOPIC, PR_FALSE);
observerService->AddObserver(this, PROFILE_BEFORE_CHANGE_TOPIC, PR_FALSE);
observerService->AddObserver(this, PROFILE_AFTER_CHANGE_TOPIC, PR_FALSE);
observerService->AddObserver(this, SESSION_LOGOUT_TOPIC, PR_FALSE);
@ -1617,9 +1692,17 @@ setPassword(PK11SlotInfo *slot, nsIInterfaceRequestor *ctx)
if (NS_FAILED(rv)) goto loser;
rv = dialogs->SetPassword(ctx,
tokenName.get(),
&canceled);
{
nsPSMUITracker tracker;
if (tracker.isUIForbidden()) {
rv = NS_ERROR_NOT_AVAILABLE;
}
else {
rv = dialogs->SetPassword(ctx,
tokenName.get(),
&canceled);
}
}
NS_RELEASE(dialogs);
if (NS_FAILED(rv)) goto loser;
@ -1823,8 +1906,12 @@ PSMContentDownloader::handleContentDownloadError(nsresult errCode)
message.Append(NS_LITERAL_STRING("\n").get());
message.Append(tmpMessage);
if(prompter)
prompter->Alert(0, message.get());
if(prompter) {
nsPSMUITracker tracker;
if (!tracker.isUIForbidden()) {
prompter->Alert(0, message.get());
}
}
}
}
break;

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

@ -129,6 +129,7 @@ class NS_NO_VTABLE nsINSSComponent : public nsISupports {
};
struct PRLock;
class nsPSMTracker;
// Implementation of the PSM component interface.
class nsNSSComponent : public nsISignatureVerifier,
@ -173,6 +174,15 @@ private:
nsresult InitializeNSS();
nsresult ShutdownNSS();
enum AlertIdentifier {
ai_nss_init_problem,
ai_sockets_still_active,
ai_crypto_ui_active,
ai_incomplete_logout
};
void ShowAlert(AlertIdentifier ai);
void InstallLoadableRoots();
nsresult InitializePIPNSSBundle();
nsresult ConfigureInternalPKCS11Token();
@ -200,6 +210,7 @@ private:
PRBool crlDownloadTimerOn;
PRBool mUpdateTimerInitialized;
static int mInstanceCount;
nsPSMTracker *mPSMTracker;
};
class PSMContentListener : public nsIURIContentListener,

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

@ -59,6 +59,7 @@
#include "nsHashSets.h"
#include "nsCRT.h"
#include "nsPrintfCString.h"
#include "nsPSMTracker.h"
#include "ssl.h"
#include "secerr.h"
@ -135,16 +136,6 @@ void MyLogFunction(const char *fmt, ...)
static NS_DEFINE_CID(kDateTimeFormatCID, NS_DATETIMEFORMAT_CID);
static PRFileDesc*
nsSSLIOLayerImportFD(PRFileDesc *fd,
nsNSSSocketInfo *infoObject,
const char *host);
static nsresult
nsSSLIOLayerSetOptions(PRFileDesc *fd, PRBool forSTARTTLS,
const char *proxyHost, const char *host, PRInt32 port,
nsNSSSocketInfo *infoObject);
nsNSSSocketInfo::nsNSSSocketInfo()
: mFd(nsnull),
mSecurityState(nsIWebProgressListener::STATE_IS_INSECURE),
@ -815,8 +806,16 @@ nsHandleSSLError(nsNSSSocketInfo *socketInfo, PRInt32 err)
}
rv = displayAlert(formattedString, socketInfo);
return rv;
{
nsPSMUITracker tracker;
if (tracker.isUIForbidden()) {
rv = NS_ERROR_NOT_AVAILABLE;
}
else {
rv = displayAlert(formattedString, socketInfo);
}
}
return rv;
}
@ -824,6 +823,7 @@ static PRStatus PR_CALLBACK
nsSSLIOLayerConnect(PRFileDesc* fd, const PRNetAddr* addr,
PRIntervalTime timeout)
{
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("[%p] connecting SSL socket\n", (void*)fd));
if (!fd || !fd->lower)
return PR_FAILURE;
@ -914,6 +914,7 @@ nsSSLIOLayerClose(PRFileDesc *fd)
return PR_FAILURE;
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("[%p] Shutting down socket\n", (void*)fd));
nsPSMTracker::decreaseSSLSocketCounter();
PRFileDesc* popped = PR_PopIOLayer(fd, PR_TOP_IO_LAYER);
nsNSSSocketInfo *infoObject = (nsNSSSocketInfo *)popped->secret;
@ -1270,21 +1271,45 @@ nsContinueDespiteCertError(nsNSSSocketInfo *infoObject,
this in future - need to define a proper ui for this situation
*/
case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
rv = badCertHandler->ConfirmUnknownIssuer(csi, callBackCert, &addType, &retVal);
{
nsPSMUITracker tracker;
if (tracker.isUIForbidden()) {
rv = NS_ERROR_NOT_AVAILABLE;
}
else {
rv = badCertHandler->ConfirmUnknownIssuer(csi, callBackCert, &addType, &retVal);
}
}
break;
case SSL_ERROR_BAD_CERT_DOMAIN:
{
nsXPIDLCString url; url.Adopt(SSL_RevealURL(sslSocket));
NS_ASSERTION(url.get(), "could not find valid URL in ssl socket");
rv = badCertHandler->ConfirmMismatchDomain(csi, url,
callBackCert, &retVal);
{
nsPSMUITracker tracker;
if (tracker.isUIForbidden()) {
rv = NS_ERROR_NOT_AVAILABLE;
}
else {
rv = badCertHandler->ConfirmMismatchDomain(csi, url,
callBackCert, &retVal);
}
}
if (NS_SUCCEEDED(rv) && retVal) {
rv = CERT_AddOKDomainName(peerCert, url);
}
}
break;
case SEC_ERROR_EXPIRED_CERTIFICATE:
rv = badCertHandler->ConfirmCertExpired(csi, callBackCert, & retVal);
{
nsPSMUITracker tracker;
if (tracker.isUIForbidden()) {
rv = NS_ERROR_NOT_AVAILABLE;
}
else {
rv = badCertHandler->ConfirmCertExpired(csi, callBackCert, & retVal);
}
}
if (rv == SECSuccess && retVal) {
// XXX We need an NSS API for this equivalent functionality.
// Having to reach inside the cert is evil.
@ -1295,7 +1320,15 @@ nsContinueDespiteCertError(nsNSSSocketInfo *infoObject,
{
nsXPIDLCString url; url.Adopt(SSL_RevealURL(sslSocket));
NS_ASSERTION(url, "could not find valid URL in ssl socket");
rv = badCertHandler->NotifyCrlNextupdate(csi, url, callBackCert);
{
nsPSMUITracker tracker;
if (tracker.isUIForbidden()) {
rv = NS_ERROR_NOT_AVAILABLE;
}
else {
rv = badCertHandler->NotifyCrlNextupdate(csi, url, callBackCert);
}
}
retVal = PR_FALSE;
}
break;
@ -2045,9 +2078,17 @@ SECStatus nsNSS_SSLGetClientAuthData(void* arg, PRFileDesc* socket,
if (NS_FAILED(rv)) goto loser;
rv = dialogs->ChooseCertificate(info, cn.get(), org.get(), issuer.get(),
(const PRUnichar**)certNicknameList, (const PRUnichar**)certDetailsList,
CertsToUse, &selectedIndex, &canceled);
{
nsPSMUITracker tracker;
if (tracker.isUIForbidden()) {
rv = NS_ERROR_NOT_AVAILABLE;
}
else {
rv = dialogs->ChooseCertificate(info, cn.get(), org.get(), issuer.get(),
(const PRUnichar**)certNicknameList, (const PRUnichar**)certDetailsList,
CertsToUse, &selectedIndex, &canceled);
}
}
int i;
for (i = 0; i < CertsToUse; ++i) {
@ -2291,6 +2332,8 @@ nsSSLIOLayerAddToSocket(const char* host,
goto loser;
}
nsPSMTracker::increaseSSLSocketCounter();
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("[%p] Socket set up\n", (void*)sslSock));
infoObject->QueryInterface(NS_GET_IID(nsISupports), (void**) (info));

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

@ -233,6 +233,7 @@ nsPKCS11Module::FindSlotByName(const PRUnichar *aName,
for (int i=0; i<mModule->slotCount; i++) {
if (nsCRT::strcmp(asciiname, PK11_GetSlotName(mModule->slots[i])) == 0) {
slotinfo = PK11_ReferenceSlot(mModule->slots[i]);
break;
}
}
if (!slotinfo) {
@ -248,6 +249,7 @@ nsPKCS11Module::FindSlotByName(const PRUnichar *aName,
}
nsMemory::Free(asciiname);
nsCOMPtr<nsIPKCS11Slot> slot = new nsPKCS11Slot(slotinfo);
PK11_FreeSlot(slotinfo);
if (!slot)
return NS_ERROR_OUT_OF_MEMORY;
*_retval = slot;
@ -290,9 +292,10 @@ nsPKCS11ModuleDB::~nsPKCS11ModuleDB()
NS_IMETHODIMP
nsPKCS11ModuleDB::GetInternal(nsIPKCS11Module **_retval)
{
nsCOMPtr<nsIPKCS11Module> module =
new nsPKCS11Module(SECMOD_CreateModule(NULL,SECMOD_INT_NAME,
NULL,SECMOD_INT_FLAGS));
SECMODModule *nssMod =
SECMOD_CreateModule(NULL,SECMOD_INT_NAME, NULL,SECMOD_INT_FLAGS);
nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(nssMod);
SECMOD_DestroyModule(nssMod);
if (!module)
return NS_ERROR_OUT_OF_MEMORY;
*_retval = module;
@ -304,9 +307,10 @@ nsPKCS11ModuleDB::GetInternal(nsIPKCS11Module **_retval)
NS_IMETHODIMP
nsPKCS11ModuleDB::GetInternalFIPS(nsIPKCS11Module **_retval)
{
nsCOMPtr<nsIPKCS11Module> module =
new nsPKCS11Module(SECMOD_CreateModule(NULL, SECMOD_FIPS_NAME, NULL,
SECMOD_FIPS_FLAGS));
SECMODModule *nssMod =
SECMOD_CreateModule(NULL, SECMOD_FIPS_NAME, NULL, SECMOD_FIPS_FLAGS);
nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(nssMod);
SECMOD_DestroyModule(nssMod);
if (!module)
return NS_ERROR_OUT_OF_MEMORY;
*_retval = module;
@ -325,6 +329,7 @@ nsPKCS11ModuleDB::FindModuleByName(const PRUnichar *aName,
if (!mod)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(mod);
SECMOD_DestroyModule(mod);
if (!module)
return NS_ERROR_OUT_OF_MEMORY;
*_retval = module;
@ -346,6 +351,7 @@ nsPKCS11ModuleDB::FindSlotByName(const PRUnichar *aName,
if (!slotinfo)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIPKCS11Slot> slot = new nsPKCS11Slot(slotinfo);
PK11_FreeSlot(slotinfo);
if (!slot)
return NS_ERROR_OUT_OF_MEMORY;
*_retval = slot;

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

@ -31,7 +31,7 @@
* may use your version of this file under either the MPL or the
* GPL.
*
* $Id: nsPKCS12Blob.cpp,v 1.32 2002-11-14 00:49:56 kaie%netscape.com Exp $
* $Id: nsPKCS12Blob.cpp,v 1.33 2003-01-06 22:23:48 kaie%netscape.com Exp $
*/
#include "prmem.h"
@ -58,6 +58,7 @@
#include "nsKeygenHandler.h" //For GetSlotWithMechanism
#include "nsPK11TokenDB.h"
#include "nsICertificateDialogs.h"
#include "nsPSMTracker.h"
#include "pk11func.h"
#include "secerr.h"
@ -66,6 +67,9 @@
extern PRLogModuleInfo* gPIPNSSLog;
#endif
#include "nsNSSCleaner.h"
NSSCleanupAutoPtrClass(CERTCertificate, CERT_DestroyCertificate)
static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
#define PIP_PKCS12_TMPFILENAME NS_LITERAL_CSTRING(".pip_p12tmp")
@ -107,6 +111,7 @@ nsPKCS12Blob::SetToken(nsIPK11Token *token)
mToken = 0;
} else {
mToken = new nsPK11Token(slot);
PK11_FreeSlot(slot);
}
}
mTokenSet = PR_TRUE;
@ -220,6 +225,8 @@ finish:
} else if (NS_FAILED(rv)) {
handleError(PIP_PKCS12_RESTORE_FAILED);
}
if (slot)
PK11_FreeSlot(slot);
// finish the decoder
if (dcx)
SEC_PKCS12DecoderFinish(dcx);
@ -254,13 +261,13 @@ nsPKCS12Blob::LoadCerts(const PRUnichar **certNames, int numCerts)
else continue; /* user may request to keep going */
}
nsCOMPtr<nsIX509Cert> cert = new nsNSSCertificate(nssCert);
CERT_DestroyCertificate(nssCert);
if (!cert) {
if (!handleError())
return NS_ERROR_OUT_OF_MEMORY;
} else {
mCertArray->AppendElement(cert);
}
CERT_DestroyCertificate(nssCert);
}
return NS_OK;
}
@ -330,6 +337,7 @@ nsPKCS12Blob::ExportToFile(nsILocalFile *file,
nsNSSCertificate *cert = (nsNSSCertificate *)certs[i];
// get it as a CERTCertificate XXX
CERTCertificate *nssCert = NULL;
CERTCertificateCleaner nssCertCleaner(nssCert);
nssCert = cert->GetCert();
if (!nssCert) {
rv = NS_ERROR_FAILURE;
@ -341,8 +349,6 @@ nsPKCS12Blob::ExportToFile(nsILocalFile *file,
// shape or form) from the card. So let's punt if
// the cert is not in the internal db.
if (nssCert->slot && !PK11_IsInternal(nssCert->slot)) {
CERT_DestroyCertificate(nssCert);
if (!InformedUserNoSmartcardBackup) {
InformedUserNoSmartcardBackup = PR_TRUE;
handleError(PIP_PKCS12_NOSMARTCARD_EXPORT);
@ -371,7 +377,6 @@ nsPKCS12Blob::ExportToFile(nsILocalFile *file,
SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC);
if (srv) goto finish;
// cert was dup'ed, so release it
CERT_DestroyCertificate(nssCert);
++numCertsExported;
}
@ -456,7 +461,15 @@ nsPKCS12Blob::newPKCS12FilePassword(SECItem *unicodePw)
NS_CERTIFICATEDIALOGS_CONTRACTID);
if (NS_FAILED(rv)) return rv;
PRBool pressedOK;
rv = certDialogs->SetPKCS12FilePassword(mUIContext, password, &pressedOK);
{
nsPSMUITracker tracker;
if (tracker.isUIForbidden()) {
rv = NS_ERROR_NOT_AVAILABLE;
}
else {
rv = certDialogs->SetPKCS12FilePassword(mUIContext, password, &pressedOK);
}
}
if (NS_FAILED(rv) || !pressedOK) return rv;
unicodeToItem(password.get(), unicodePw);
return NS_OK;
@ -477,7 +490,15 @@ nsPKCS12Blob::getPKCS12FilePassword(SECItem *unicodePw)
NS_CERTIFICATEDIALOGS_CONTRACTID);
if (NS_FAILED(rv)) return rv;
PRBool pressedOK;
rv = certDialogs->GetPKCS12FilePassword(mUIContext, password, &pressedOK);
{
nsPSMUITracker tracker;
if (tracker.isUIForbidden()) {
rv = NS_ERROR_NOT_AVAILABLE;
}
else {
rv = certDialogs->GetPKCS12FilePassword(mUIContext, password, &pressedOK);
}
}
if (NS_FAILED(rv) || !pressedOK) return rv;
unicodeToItem(password.get(), unicodePw);
return NS_OK;
@ -713,6 +734,11 @@ pip_ucs2_ascii_conversion_fn(PRBool toUnicode,
PRBool
nsPKCS12Blob::handleError(int myerr)
{
nsPSMUITracker tracker;
if (tracker.isUIForbidden()) {
return PR_FALSE;
}
nsresult rv;
PRBool keepGoing = PR_FALSE;
int prerr = PORT_GetError();

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

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

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

@ -40,10 +40,14 @@
#include "nsISecretDecoderRing.h"
#include "nsSDR.h"
#include "nsNSSComponent.h"
#include "nsPSMTracker.h"
#include "pk11func.h"
#include "pk11sdr.h" // For PK11SDR_Encrypt, PK11SDR_Decrypt
#include "nsNSSCleaner.h"
NSSCleanupAutoPtrClass(PK11SlotInfo, PK11_FreeSlot)
//
// Implementation of an nsIInterfaceRequestor for use
// as context for NSS calls
@ -119,6 +123,7 @@ Encrypt(unsigned char * data, PRInt32 dataLen, unsigned char * *result, PRInt32
{
nsresult rv = NS_OK;
PK11SlotInfo *slot = 0;
PK11SlotInfoCleaner tmpSlotCleaner(slot);
SECItem keyid;
SECItem request;
SECItem reply;
@ -150,7 +155,6 @@ Encrypt(unsigned char * data, PRInt32 dataLen, unsigned char * *result, PRInt32
*_retval = reply.len;
loser:
if (slot) PK11_FreeSlot(slot);
return rv;
}
@ -160,6 +164,7 @@ Decrypt(unsigned char * data, PRInt32 dataLen, unsigned char * *result, PRInt32
{
nsresult rv = NS_OK;
PK11SlotInfo *slot = 0;
PK11SlotInfoCleaner tmpSlotCleaner(slot);
SECStatus s;
SECItem request;
SECItem reply;
@ -190,7 +195,6 @@ Decrypt(unsigned char * data, PRInt32 dataLen, unsigned char * *result, PRInt32
*_retval = reply.len;
loser:
if (slot) PK11_FreeSlot(slot);
return rv;
}
@ -284,7 +288,15 @@ ChangePassword()
nsCOMPtr<nsIInterfaceRequestor> ctx = new nsSDRContext();
PRBool canceled;
rv = dialogs->SetPassword(ctx, tokenName.get(), &canceled);
{
nsPSMUITracker tracker;
if (tracker.isUIForbidden()) {
rv = NS_ERROR_NOT_AVAILABLE;
}
else {
rv = dialogs->SetPassword(ctx, tokenName.get(), &canceled);
}
}
/* canceled is ignored */