Bug 284366 "PSM needs to handle Smart Cards seamlessly" r=timeless sr=jst
a=shaver
This commit is contained in:
relyea%netscape.com 2005-06-02 01:17:35 +00:00
Родитель a1da7c82a3
Коммит 3bf4387d1c
14 изменённых файлов: 499 добавлений и 142 удалений

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

@ -38,10 +38,11 @@
#include "domstubs.idl"
[scriptable, uuid(33276f5d-3499-4ab9-acea-d85a9fceeccd)]
[scriptable, uuid(d2b675a5-f05b-4172-bac2-24cc39ffd398)]
interface nsIDOMCrypto : nsISupports
{
readonly attribute DOMString version;
attribute boolean enableSmartCardEvents;
nsIDOMCRMFObject generateCRMFRequest(/* ... */);
DOMString importUserCertificates(in DOMString nickname,

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

@ -67,6 +67,7 @@ XPIDLSRCS = \
nsIDOMPopupBlockedEvent.idl \
nsIDOMBeforeUnloadEvent.idl \
nsIDOMNSEventTarget.idl \
nsIDOMSmartCardEvent.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

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

@ -332,6 +332,9 @@ enum nsDOMClassInfoID {
eDOMClassInfo_CanvasPattern_id,
#endif
// SmartCard Events
eDOMClassInfo_SmartCardEvent_id,
// This one better be the last one in this list
eDOMClassInfoIDCount
};

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

@ -207,6 +207,7 @@
#include "nsIDOMPopupBlockedEvent.h"
#include "nsIDOMBeforeUnloadEvent.h"
#include "nsIDOMMutationEvent.h"
#include "nsIDOMSmartCardEvent.h"
#include "nsIDOMNSDocumentStyle.h"
#include "nsIDOMDocumentRange.h"
#include "nsIDOMDocumentTraversal.h"
@ -1001,6 +1002,9 @@ static nsDOMClassInfoData sClassInfoData[] = {
NS_DEFINE_CLASSINFO_DATA(CanvasPattern, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
#endif // MOZ_ENABLE_CANVAS
NS_DEFINE_CLASSINFO_DATA(SmartCardEvent, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
};
nsIXPConnect *nsDOMClassInfo::sXPConnect = nsnull;
@ -1728,6 +1732,10 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_EVENT_MAP_ENTRIES
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(SmartCardEvent, nsIDOMSmartCardEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSmartCardEvent)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(MutationEvent, nsIDOMMutationEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMutationEvent)
DOM_CLASSINFO_EVENT_MAP_ENTRIES

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

@ -495,6 +495,11 @@ nsGlobalWindow::SetNewDocument(nsIDOMDocument* aDocument,
// Let go of the cached principal since we no longer need it.
mDocumentPrincipal = nsnull;
// clear smartcard events, our document has gone away.
if (mCrypto) {
mCrypto->SetEnableSmartCardEvents(PR_FALSE);
}
}
if (mFirstDocumentLoad) {

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

@ -87,6 +87,9 @@ CPPSRCS = \
nsCRLManager.cpp \
nsNSSShutDown.cpp \
nsNTLMAuthModule.cpp \
nsNSSEvent.cpp \
nsSmartCardMonitor.cpp \
nsSmartCardEvent.cpp \
$(NULL)
ifdef MOZ_XUL

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

@ -58,8 +58,6 @@
#include "nsIScriptContext.h"
#include "nsIScriptGlobalObject.h"
#include "nsIXPConnect.h"
#include "nsIEventQueueService.h"
#include "nsIEventQueue.h"
#include "nsIRunnable.h"
#include "nsIWindowWatcher.h"
#include "nsIPrompt.h"
@ -143,17 +141,6 @@ typedef struct nsKeyPairInfoStr {
nsKeyGenType keyGenType; /* What type of key gen are we doing.*/
} nsKeyPairInfo;
//
// This is the class we'll use to run the keygen done code
// as an nsIRunnable object;
//
struct CryptoRunnableEvent : PLEvent {
CryptoRunnableEvent(nsIRunnable* runnable);
~CryptoRunnableEvent();
nsIRunnable* mRunnable;
};
//This class is just used to pass arguments
//to the nsCryptoRunnable event.
@ -231,34 +218,19 @@ NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(nsPkcs11)
NS_IMPL_RELEASE(nsPkcs11)
// QueryInterface implementation for nsCryptoRunnable
NS_INTERFACE_MAP_BEGIN(nsCryptoRunnable)
NS_INTERFACE_MAP_ENTRY(nsIRunnable)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
// ISupports implementation for nsCryptoRunnable
NS_IMPL_ISUPPORTS1(nsCryptoRunnable, nsIRunnable);
NS_IMPL_ADDREF(nsCryptoRunnable)
NS_IMPL_RELEASE(nsCryptoRunnable)
// ISupports implementation for nsP12Runnable
NS_IMPL_ISUPPORTS1(nsP12Runnable, nsIRunnable);
// QueryInterface implementation for nsP12Runnable
NS_INTERFACE_MAP_BEGIN(nsP12Runnable)
NS_INTERFACE_MAP_ENTRY(nsIRunnable)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END_THREADSAFE
NS_IMPL_THREADSAFE_ADDREF(nsP12Runnable)
NS_IMPL_THREADSAFE_RELEASE(nsP12Runnable)
NS_INTERFACE_MAP_BEGIN(nsCryptoRunArgs)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END_THREADSAFE
NS_IMPL_THREADSAFE_ADDREF(nsCryptoRunArgs)
NS_IMPL_THREADSAFE_RELEASE(nsCryptoRunArgs)
// ISupports implementation for nsCryptoRunArgs
NS_IMPL_ISUPPORTS0(nsCryptoRunArgs);
static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
nsCrypto::nsCrypto()
nsCrypto::nsCrypto() :
mEnableSmartCardEvents(PR_FALSE)
{
}
@ -266,22 +238,31 @@ nsCrypto::~nsCrypto()
{
}
//Grab the UI event queue so that we can post some events to it.
nsIEventQueue*
nsCrypto::GetUIEventQueue()
NS_IMETHODIMP
nsCrypto::SetEnableSmartCardEvents(PRBool aEnable)
{
nsresult rv;
nsCOMPtr<nsIEventQueueService> service =
do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv))
return nsnull;
nsIEventQueue* result = nsnull;
rv = service->GetThreadEventQueue(NS_UI_THREAD, &result);
if (NS_FAILED(rv))
return nsnull;
return result;
// this has the side effect of starting the nssComponent (and initializing
// NSS) even if it isn't already going. Starting the nssComponent is a
// prerequisite for getting smartCard events.
if (aEnable) {
nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
}
if (NS_FAILED(rv)) {
return rv;
}
mEnableSmartCardEvents = aEnable;
return NS_OK;
}
NS_IMETHODIMP
nsCrypto::GetEnableSmartCardEvents(PRBool *aEnable)
{
*aEnable = mEnableSmartCardEvents;
return NS_OK;
}
//These next few functions are based on implementation in
@ -1424,6 +1405,7 @@ loser:
nsFreeCertReqMessages(certReqMsgs,numRequests);
return nsnull;;
}
//The top level method which is a member of nsIDOMCrypto
//for generate a base64 encoded CRMF request.
@ -1639,41 +1621,11 @@ nsCrypto::GenerateCRMFRequest(nsIDOMCRMFObject** aReturn)
if (!cryptoRunnable)
return NS_ERROR_OUT_OF_MEMORY;
CryptoRunnableEvent *runnable = new CryptoRunnableEvent(cryptoRunnable);
if (!runnable) {
nsresult rv = nsNSSEventPostToUIEventQueue(cryptoRunnable);
if (NS_FAILED(rv))
delete cryptoRunnable;
return NS_ERROR_OUT_OF_MEMORY;
}
nsCOMPtr<nsIEventQueue>uiQueue = dont_AddRef(GetUIEventQueue());
uiQueue->PostEvent(runnable);
return NS_OK;
}
//A wrapper for PLEvent that we can use to post
//our nsIRunnable Events.
static void PR_CALLBACK
handleCryptoRunnableEvent(CryptoRunnableEvent* aEvent)
{
aEvent->mRunnable->Run();
}
static void PR_CALLBACK
destroyCryptoRunnableEvent(CryptoRunnableEvent* aEvent)
{
delete aEvent;
}
CryptoRunnableEvent::CryptoRunnableEvent(nsIRunnable* runnable)
: mRunnable(runnable)
{
NS_ADDREF(mRunnable);
PL_InitEvent(this, nsnull, PLHandleEventProc(handleCryptoRunnableEvent),
PLDestroyEventProc(&destroyCryptoRunnableEvent));
}
CryptoRunnableEvent::~CryptoRunnableEvent()
{
NS_RELEASE(mRunnable);
return rv;
}
@ -2043,7 +1995,6 @@ nsCrypto::ImportUserCertificates(const nsAString& aNickname,
// later.
nsCOMPtr<nsIRunnable> p12Runnable = new nsP12Runnable(certArr, numResponses,
token);
CryptoRunnableEvent *runnable;
if (!p12Runnable) {
rv = NS_ERROR_FAILURE;
goto loser;
@ -2054,13 +2005,9 @@ nsCrypto::ImportUserCertificates(const nsAString& aNickname,
// memory on the way out.
certArr = nsnull;
runnable = new CryptoRunnableEvent(p12Runnable);
if (!runnable) {
rv = NS_ERROR_FAILURE;
rv = nsNSSEventPostToUIEventQueue(p12Runnable);
if (NS_FAILED(rv))
goto loser;
}
nsCOMPtr<nsIEventQueue>uiQueue = dont_AddRef(GetUIEventQueue());
uiQueue->PostEvent(runnable);
}
loser:
@ -2623,6 +2570,11 @@ nsPkcs11::Deletemodule(const nsAString& aModuleName, PRInt32* aReturn)
PRInt32 modType;
SECStatus srv = SECMOD_DeleteModule(modName, &modType);
if (srv == SECSuccess) {
SECMODModule *module = SECMOD_FindModule(modName);
if (module) {
nssComponent->ShutdownSmartCardThread(module);
SECMOD_DestroyModule(module);
}
if (modType == SECMOD_EXTERNAL) {
nssComponent->GetPIPNSSBundleString("DelModuleExtSuccess", errorMessage);
*aReturn = JS_OK_DEL_EXTERNAL_MOD;
@ -2692,6 +2644,14 @@ nsPkcs11::Addmodule(const nsAString& aModuleName,
PRUint32 cipherFlags = SECMOD_PubCipherFlagstoInternal(aCipherFlags);
SECStatus srv = SECMOD_AddNewModule(moduleName, fullPath,
mechFlags, cipherFlags);
if (srv == SECSuccess) {
SECMODModule *module = SECMOD_FindModule(moduleName);
if (module) {
nssComponent->LaunchSmartCardThread(module);
SECMOD_DestroyModule(module);
}
}
nsMemory::Free(moduleName);
nsMemory::Free(fullPath);

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

@ -42,9 +42,12 @@
#include "nsIDOMCRMFObject.h"
#include "nsIDOMCrypto.h"
#include "nsIDOMPkcs11.h"
#include "nsIRunnable.h"
#include "nsString.h"
#include "nsNSSEvent.h"
#include "jsapi.h"
#include "nsIPrincipal.h"
#include "plevent.h"
#define NS_CRYPTO_CLASSNAME "Crypto JavaScript Class"
#define NS_CRYPTO_CID \
@ -58,7 +61,6 @@
class nsIPSMComponent;
class nsIDOMScriptObjectFactory;
class nsIEventQueue;
class nsCRMFObject : public nsIDOMCRMFObject
@ -89,8 +91,10 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMCRYPTO
private:
static nsIPrincipal* GetScriptPrincipal(JSContext *cx);
static nsIEventQueue* GetUIEventQueue();
PRBool mEnableSmartCardEvents;
};
class nsPkcs11 : public nsIDOMPkcs11
@ -104,6 +108,17 @@ public:
};
//
// This is the class we'll use to post ui events
//
struct CryptoRunnableEvent : PLEvent {
CryptoRunnableEvent(nsIRunnable* runnable);
~CryptoRunnableEvent();
nsIRunnable* mRunnable;
};
#endif //_nsCrypto_h_

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

@ -44,6 +44,7 @@
#include "nsNSSComponent.h"
#include "nsNSSCallbacks.h"
#include "nsNSSIOLayer.h"
#include "nsNSSEvent.h"
#include "nsNetUtil.h"
#include "nsAppDirectoryServiceDefs.h"
@ -51,6 +52,7 @@
#include "nsIStreamListener.h"
#include "nsIStringBundle.h"
#include "nsIDirectoryService.h"
#include "nsIDOMNode.h"
#include "nsCURILoader.h"
#include "nsDirectoryServiceDefs.h"
#include "nsIProxyObjectManager.h"
@ -59,6 +61,7 @@
#include "nsIProfileChangeStatus.h"
#include "nsNSSCertificate.h"
#include "nsNSSHelper.h"
#include "nsSmartCardMonitor.h"
#include "prlog.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
@ -66,8 +69,15 @@
#include "nsIDateTimeFormat.h"
#include "nsDateTimeFormatCID.h"
#include "nsAutoLock.h"
#include "nsIEventQueueService.h"
#include "nsIEventQueue.h"
#include "nsIDOMEvent.h"
#include "nsIDOMDocument.h"
#include "nsIDOMDocumentEvent.h"
#include "nsIDOMWindow.h"
#include "nsIDOMWindowCollection.h"
#include "nsIDOMWindowInternal.h"
#include "nsIDOMSmartCardEvent.h"
#include "nsIDOMCrypto.h"
#include "nsIRunnable.h"
#include "plevent.h"
#include "nsCRT.h"
@ -89,6 +99,7 @@
#include "nsITokenPasswordDialogs.h"
#include "nsICRLManager.h"
#include "nsNSSShutDown.h"
#include "nsSmartCardEvent.h"
#include "nsICryptoHash.h"
#include "nss.h"
@ -205,9 +216,10 @@ struct CRLDownloadEvent : PLEvent {
nsCAutoString *urlString;
nsIStreamListener *psmDownloader;
};
//Note that nsNSSComponent is a singleton object across all threads, and automatic downloads
//are always scheduled sequentially - that is, once one crl download is complete, the next one
//is scheduled
// Note that nsNSSComponent is a singleton object across all threads,
// and automatic downloads are always scheduled sequentially - that is,
// once one crl download is complete, the next one is scheduled
static void PR_CALLBACK HandleCRLImportPLEvent(CRLDownloadEvent *aEvent)
{
nsresult rv;
@ -228,8 +240,43 @@ static void PR_CALLBACK DestroyCRLImportPLEvent(CRLDownloadEvent* aEvent)
delete aEvent;
}
//This class is used to run the callback code
//passed to the event handlers for smart card notification
class nsTokenEventRunnable : public nsIRunnable {
public:
nsTokenEventRunnable(const nsAString &aType, const nsAString &aTokenName);
virtual ~nsTokenEventRunnable();
NS_IMETHOD Run ();
NS_DECL_ISUPPORTS
private:
nsString mType;
nsString mTokenName;
};
// ISuuports implementation for nsTokenEventRunnable
NS_IMPL_THREADSAFE_ISUPPORTS1(nsTokenEventRunnable, nsIRunnable);
nsTokenEventRunnable::nsTokenEventRunnable(const nsAString &aType,
const nsAString &aTokenName): mType(aType), mTokenName(aTokenName) { }
nsTokenEventRunnable::~nsTokenEventRunnable() { }
//Implementation that runs the callback passed to
//crypto.generateCRMFRequest as an event.
NS_IMETHODIMP
nsTokenEventRunnable::Run()
{
nsresult rv;
nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
if (NS_FAILED(rv))
return rv;
return nssComponent->DispatchEvent(mType, mTokenName);
}
nsNSSComponent::nsNSSComponent()
:mNSSInitialized(PR_FALSE)
:mNSSInitialized(PR_FALSE), mThreadList(nsnull)
{
mutex = PR_NewLock();
@ -287,6 +334,160 @@ nsNSSComponent::~nsNSSComponent()
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsNSSComponent::dtor finished\n"));
}
NS_IMETHODIMP
nsNSSComponent::PostEvent(const nsAString &eventType,
const nsAString &tokenName)
{
nsresult rv;
nsTokenEventRunnable *runnable =
new nsTokenEventRunnable(eventType, tokenName);
if (!runnable) {
return NS_ERROR_OUT_OF_MEMORY;
}
rv = nsNSSEventPostToUIEventQueue(runnable);
if (NS_FAILED(rv))
delete runnable;
return rv;
}
NS_IMETHODIMP
nsNSSComponent::DispatchEvent(const nsAString &eventType,
const nsAString &tokenName)
{
// 'Dispatch' the event to all the windows. 'DispatchEventToWindow()' will
// first check to see if a given window has requested crypto events.
nsresult rv;
nsCOMPtr<nsIWindowWatcher> windowWatcher =
do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsISimpleEnumerator> enumerator;
rv = windowWatcher->GetWindowEnumerator(getter_AddRefs(enumerator));
if (NS_FAILED(rv)) {
return rv;
}
PRBool hasMoreWindows;
while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreWindows))
&& hasMoreWindows) {
nsCOMPtr<nsISupports> supports;
enumerator->GetNext(getter_AddRefs(supports));
nsCOMPtr<nsIDOMWindow> domWin(do_QueryInterface(supports));
if (domWin) {
nsresult rv2 = DispatchEventToWindow(domWin, eventType, tokenName);
if (NS_FAILED(rv2)) {
// return the last failure, don't let a single failure prevent
// continued delivery of events.
rv = rv2;
}
}
}
return rv;
}
nsresult
nsNSSComponent::DispatchEventToWindow(nsIDOMWindow *domWin,
const nsAString &eventType, const nsAString &tokenName)
{
// first walk the children and dispatch their events
{
nsresult rv;
nsCOMPtr<nsIDOMWindowCollection> frames;
rv = domWin->GetFrames(getter_AddRefs(frames));
if (NS_FAILED(rv)) {
return rv;
}
PRUint32 length;
frames->GetLength(&length);
PRUint32 i;
for (i = 0; i < length; i++) {
nsCOMPtr<nsIDOMWindow> childWin;
frames->Item(i, getter_AddRefs(childWin));
DispatchEventToWindow(childWin, eventType, tokenName);
}
}
// check if we've enabled smart card events on this window
// NOTE: it's not an error to say that we aren't going to dispatch
// the event.
{
nsCOMPtr<nsIDOMWindowInternal> intWindow = do_QueryInterface(domWin);
if (!intWindow) {
return NS_OK; // nope, it's not an internal window
}
nsCOMPtr<nsIDOMCrypto> crypto;
intWindow->GetCrypto(getter_AddRefs(crypto));
if (!crypto) {
return NS_OK; // nope, it doesn't have a crypto property
}
PRBool boolrv;
crypto->GetEnableSmartCardEvents(&boolrv);
if (!boolrv) {
return NS_OK; // nope, it's not enabled.
}
}
// dispatch the event ...
nsresult rv;
// find the document
nsCOMPtr<nsIDOMDocument> doc;
rv = domWin->GetDocument(getter_AddRefs(doc));
if (doc == nsnull) {
return NS_FAILED(rv) ? rv : NS_ERROR_FAILURE;
}
// create the event
nsCOMPtr<nsIDOMDocumentEvent> docEvent = do_QueryInterface(doc, &rv);
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIDOMEvent> event;
rv = docEvent->CreateEvent(NS_LITERAL_STRING("Events"),
getter_AddRefs(event));
if (NS_FAILED(rv)) {
return rv;
}
event->InitEvent(eventType, false, true);
// create the Smart Card Event;
nsCOMPtr<nsIDOMSmartCardEvent> smartCardEvent =
new nsSmartCardEvent(tokenName);
// init the smart card event, fail here if we can't complete the
// initialization.
if (!smartCardEvent) {
return NS_ERROR_OUT_OF_MEMORY;
}
rv = smartCardEvent->Init(event);
if (NS_FAILED(rv)) {
return rv;
}
// Send it
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(doc, &rv);
if (NS_FAILED(rv)) {
return rv;
}
PRBool boolrv;
rv = target->DispatchEvent(smartCardEvent, &boolrv);
return rv;
}
#ifdef XP_MAC
#ifdef DEBUG
#define LOADABLE_CERTS_MODULE NS_LITERAL_CSTRING("NSSckbiDebug.shlb")
@ -355,6 +556,62 @@ nsNSSComponent::SkipOcspOff()
return NS_OK;
}
void
nsNSSComponent::LaunchSmartCardThreads()
{
nsNSSShutDownPreventionLock locker;
{
SECMODModuleList *list = SECMOD_GetDefaultModuleList();
SECMODListLock *lock = SECMOD_GetDefaultModuleListLock();
SECMOD_GetReadLock(lock);
while (list) {
SECMODModule *module = list->module;
LaunchSmartCardThread(module);
list = list->next;
}
SECMOD_ReleaseReadLock(lock);
}
}
NS_IMETHODIMP
nsNSSComponent::LaunchSmartCardThread(SECMODModule *module)
{
SmartCardMonitoringThread *newThread;
if (SECMOD_HasRemovableSlots(module)) {
if (mThreadList == nsnull) {
mThreadList = new SmartCardThreadList();
if (!mThreadList) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
newThread = new SmartCardMonitoringThread(module);
if (!newThread) {
return NS_ERROR_OUT_OF_MEMORY;
}
// newThread is adopted by the add.
return mThreadList->Add(newThread);
}
return NS_OK;
}
NS_IMETHODIMP
nsNSSComponent::ShutdownSmartCardThread(SECMODModule *module)
{
if (!mThreadList) {
return NS_OK;
}
mThreadList->Remove(module);
return NS_OK;
}
void
nsNSSComponent::ShutdownSmartCardThreads()
{
delete mThreadList;
mThreadList = nsnull;
}
void
nsNSSComponent::InstallLoadableRoots()
{
@ -375,7 +632,7 @@ nsNSSComponent::InstallLoadableRoots()
PK11SlotInfo *slot = module->slots[i];
if (PK11_IsPresent(slot)) {
if (PK11_HasRootCerts(slot)) {
RootsModule = module;
RootsModule = SECMOD_ReferenceModule(module);
break;
}
}
@ -392,6 +649,7 @@ nsNSSComponent::InstallLoadableRoots()
CK_INFO info;
if (SECSuccess != PK11_GetModInfo(RootsModule, &info)) {
// Do not use this module
SECMOD_DestroyModule(RootsModule);
RootsModule = nsnull;
}
else {
@ -408,13 +666,16 @@ nsNSSComponent::InstallLoadableRoots()
) {
PRInt32 modType;
SECMOD_DeleteModule(RootsModule->commonName, &modType);
SECMOD_DestroyModule(RootsModule);
RootsModule = nsnull;
}
}
}
if (!RootsModule) {
if (RootsModule) {
SECMOD_DestroyModule(RootsModule);
} else { /* !RootsModule */
// Load roots module from our installation path
nsresult rv;
@ -621,9 +882,9 @@ static void setOCSPOptions(nsIPrefBranch * pref)
pref->GetIntPref("security.OCSP.enabled", &ocspEnabled);
switch (ocspEnabled) {
case 0:
CERT_DisableOCSPChecking(CERT_GetDefaultCertDB());
CERT_DisableOCSPDefaultResponder(CERT_GetDefaultCertDB());
break;
CERT_DisableOCSPChecking(CERT_GetDefaultCertDB());
CERT_DisableOCSPDefaultResponder(CERT_GetDefaultCertDB());
break;
case 1:
CERT_EnableOCSPChecking(CERT_GetDefaultCertDB());
break;
@ -644,15 +905,13 @@ static void setOCSPOptions(nsIPrefBranch * pref)
nsMemory::Free(signingCA);
nsMemory::Free(url);
}
break;
break;
}
}
nsresult
nsNSSComponent::PostCRLImportEvent(nsCAutoString *urlString, PSMContentDownloader *psmDownloader)
{
nsresult rv;
//Create the event
CRLDownloadEvent *event = new CRLDownloadEvent;
PL_InitEvent(event, this, (PLHandleEventProc)HandleCRLImportPLEvent, (PLDestroyEventProc)DestroyCRLImportPLEvent);
@ -660,17 +919,12 @@ nsNSSComponent::PostCRLImportEvent(nsCAutoString *urlString, PSMContentDownloade
event->psmDownloader = (nsIStreamListener *)psmDownloader;
//Get a handle to the ui event queue
nsCOMPtr<nsIEventQueueService> service =
do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv))
return rv;
nsIEventQueue* result = nsnull;
rv = service->GetThreadEventQueue(NS_UI_THREAD, &result);
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIEventQueue>uiQueue = dont_AddRef(result);
nsCOMPtr<nsIEventQueue>uiQueue = nsNSSEventGetUIEventQueue();
if (!uiQueue) {
return NS_ERROR_FAILURE;
}
//Post the event
return uiQueue->PostEvent(event);
@ -1212,6 +1466,8 @@ nsNSSComponent::InitializeNSS(PRBool showWarningBox)
InstallLoadableRoots();
LaunchSmartCardThreads();
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("NSS Initialization done\n"));
}
}
@ -1258,6 +1514,7 @@ nsNSSComponent::ShutdownNSS()
pbi->RemoveObserver("security.", this);
}
ShutdownSmartCardThreads();
SSL_ClearSessionCache();
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("evaporating psm resources\n"));
mShutdownObjectList->evaporateAllNSSResources();

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

@ -50,11 +50,13 @@
#include "nsIEntropyCollector.h"
#include "nsString.h"
#include "nsIStringBundle.h"
#include "nsIDOMEventTarget.h"
#include "nsIPrefBranch.h"
#include "nsIObserver.h"
#include "nsIObserverService.h"
#include "nsWeakReference.h"
#include "nsIScriptSecurityManager.h"
#include "nsSmartCardMonitor.h"
#include "nsITimer.h"
#include "nsNetUtil.h"
#include "nsHashtable.h"
@ -147,6 +149,14 @@ class NS_NO_VTABLE nsINSSComponent : public nsISupports {
NS_IMETHOD DownloadCRLDirectly(nsAutoString, nsAutoString) = 0;
NS_IMETHOD LogoutAuthenticatedPK11() = 0;
NS_IMETHOD LaunchSmartCardThread(SECMODModule *module) = 0;
NS_IMETHOD ShutdownSmartCardThread(SECMODModule *module) = 0;
NS_IMETHOD PostEvent(const nsAString &eventType, const nsAString &token) = 0;
NS_IMETHOD DispatchEvent(const nsAString &eventType, const nsAString &token) = 0;
};
@ -205,6 +215,11 @@ public:
NS_IMETHOD RememberCert(CERTCertificate *cert);
static nsresult GetNSSCipherIDFromPrefString(const nsACString &aPrefString, PRUint16 &aCipherId);
NS_IMETHOD LaunchSmartCardThread(SECMODModule *module);
NS_IMETHOD ShutdownSmartCardThread(SECMODModule *module);
NS_IMETHOD PostEvent(const nsAString &eventType, const nsAString &token);
NS_IMETHOD DispatchEvent(const nsAString &eventType, const nsAString &token);
private:
nsresult InitializeNSS(PRBool showWarningBox);
@ -223,6 +238,8 @@ private:
void ShowAlert(AlertIdentifier ai);
void InstallLoadableRoots();
void LaunchSmartCardThreads();
void ShutdownSmartCardThreads();
nsresult InitializePIPNSSBundle();
nsresult ConfigureInternalPKCS11Token();
nsresult RegisterPSMContentListener();
@ -230,6 +247,7 @@ private:
nsresult DownloadCrlSilently();
nsresult PostCRLImportEvent(nsCAutoString *urlString, PSMContentDownloader *psmDownloader);
nsresult getParamsForNextCrlToDownload(nsAutoString *url, PRTime *time, nsAutoString *key);
nsresult DispatchEventToWindow(nsIDOMWindow *domWin, const nsAString &eventType, const nsAString &token);
PRLock *mutex;
nsCOMPtr<nsIScriptSecurityManager> mScriptSecurityManager;
@ -248,6 +266,7 @@ private:
PRBool mUpdateTimerInitialized;
static int mInstanceCount;
nsNSSShutDownList *mShutdownObjectList;
SmartCardThreadList *mThreadList;
};
class PSMContentListener : public nsIURIContentListener,

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

@ -61,8 +61,16 @@ nsPK11Token::nsPK11Token(PK11SlotInfo *slot)
PK11_ReferenceSlot(slot);
mSlot = slot;
mTokenName = NS_ConvertUTF8toUCS2(PK11_GetTokenName(slot));
mSeries = PK11_GetSlotSeries(slot);
refreshTokenInfo();
mUIContext = new PipUIContext();
}
void
nsPK11Token::refreshTokenInfo()
{
mTokenName = NS_ConvertUTF8toUTF16(PK11_GetTokenName(mSlot));
SECStatus srv;
@ -103,7 +111,6 @@ nsPK11Token::nsPK11Token(PK11SlotInfo *slot)
mTokenSerialNum.Trim(" ", PR_FALSE, PR_TRUE);
}
mUIContext = new PipUIContext();
}
nsPK11Token::~nsPK11Token()
@ -135,6 +142,10 @@ void nsPK11Token::destructorSafeDestroyNSSReference()
/* readonly attribute wstring tokenName; */
NS_IMETHODIMP nsPK11Token::GetTokenName(PRUnichar * *aTokenName)
{
// handle removals/insertions
if (mSeries != PK11_GetSlotSeries(mSlot)) {
refreshTokenInfo();
}
*aTokenName = ToNewUnicode(mTokenName);
if (!*aTokenName) return NS_ERROR_OUT_OF_MEMORY;
@ -144,6 +155,10 @@ NS_IMETHODIMP nsPK11Token::GetTokenName(PRUnichar * *aTokenName)
/* readonly attribute wstring tokenDesc; */
NS_IMETHODIMP nsPK11Token::GetTokenLabel(PRUnichar **aTokLabel)
{
// handle removals/insertions
if (mSeries != PK11_GetSlotSeries(mSlot)) {
refreshTokenInfo();
}
*aTokLabel = ToNewUnicode(mTokenLabel);
if (!*aTokLabel) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
@ -152,6 +167,10 @@ NS_IMETHODIMP nsPK11Token::GetTokenLabel(PRUnichar **aTokLabel)
/* readonly attribute wstring tokenManID; */
NS_IMETHODIMP nsPK11Token::GetTokenManID(PRUnichar **aTokManID)
{
// handle removals/insertions
if (mSeries != PK11_GetSlotSeries(mSlot)) {
refreshTokenInfo();
}
*aTokManID = ToNewUnicode(mTokenManID);
if (!*aTokManID) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
@ -160,6 +179,10 @@ NS_IMETHODIMP nsPK11Token::GetTokenManID(PRUnichar **aTokManID)
/* readonly attribute wstring tokenHWVersion; */
NS_IMETHODIMP nsPK11Token::GetTokenHWVersion(PRUnichar **aTokHWVersion)
{
// handle removals/insertions
if (mSeries != PK11_GetSlotSeries(mSlot)) {
refreshTokenInfo();
}
*aTokHWVersion = ToNewUnicode(mTokenHWVersion);
if (!*aTokHWVersion) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
@ -168,6 +191,10 @@ NS_IMETHODIMP nsPK11Token::GetTokenHWVersion(PRUnichar **aTokHWVersion)
/* readonly attribute wstring tokenFWVersion; */
NS_IMETHODIMP nsPK11Token::GetTokenFWVersion(PRUnichar **aTokFWVersion)
{
// handle removals/insertions
if (mSeries != PK11_GetSlotSeries(mSlot)) {
refreshTokenInfo();
}
*aTokFWVersion = ToNewUnicode(mTokenFWVersion);
if (!*aTokFWVersion) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
@ -176,6 +203,10 @@ NS_IMETHODIMP nsPK11Token::GetTokenFWVersion(PRUnichar **aTokFWVersion)
/* readonly attribute wstring tokenSerialNumber; */
NS_IMETHODIMP nsPK11Token::GetTokenSerialNumber(PRUnichar **aTokSerialNum)
{
// handle removals/insertions
if (mSeries != PK11_GetSlotSeries(mSlot)) {
refreshTokenInfo();
}
*aTokSerialNum = ToNewUnicode(mTokenSerialNum);
if (!*aTokSerialNum) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;

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

@ -63,11 +63,13 @@ public:
private:
friend class nsPK11TokenDB;
void refreshTokenInfo();
nsString mTokenName;
nsString mTokenLabel, mTokenManID, mTokenHWVersion, mTokenFWVersion;
nsString mTokenSerialNum;
PK11SlotInfo *mSlot;
int mSeries;
nsCOMPtr<nsIInterfaceRequestor> mUIContext;
virtual void virtualDestroyNSSReference();
void destructorSafeDestroyNSSReference();

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

@ -60,7 +60,13 @@ nsPKCS11Slot::nsPKCS11Slot(PK11SlotInfo *slot)
PK11_ReferenceSlot(slot);
mSlot = slot;
mSeries = PK11_GetSlotSeries(slot);
refreshSlotInfo();
}
void
nsPKCS11Slot::refreshSlotInfo()
{
CK_SLOT_INFO slot_info;
if (PK11_GetSlotInfo(mSlot, &slot_info) == SECSuccess) {
// Set the Description field
@ -78,10 +84,12 @@ nsPKCS11Slot::nsPKCS11Slot(PK11SlotInfo *slot)
mSlotManID = NS_ConvertUTF8toUCS2(cManID);
mSlotManID.Trim(" ", PR_FALSE, PR_TRUE);
// Set the Hardware Version field
mSlotHWVersion = EmptyString();
mSlotHWVersion.AppendInt(slot_info.hardwareVersion.major);
mSlotHWVersion.AppendLiteral(".");
mSlotHWVersion.AppendInt(slot_info.hardwareVersion.minor);
// Set the Firmware Version field
mSlotFWVersion = EmptyString();
mSlotFWVersion.AppendInt(slot_info.firmwareVersion.major);
mSlotFWVersion.AppendLiteral(".");
mSlotFWVersion.AppendInt(slot_info.firmwareVersion.minor);
@ -127,7 +135,7 @@ nsPKCS11Slot::GetName(PRUnichar **aName)
if (*csn) {
*aName = ToNewUnicode(NS_ConvertUTF8toUCS2(csn));
} else if (PK11_HasRootCerts(mSlot)) {
// This is a workaround to an NSS bug - the root certs module has
// This is a workaround to an Root Module bug - the root certs module has
// no slot name. Not bothering to localize, because this is a workaround
// and for now all the slot names returned by NSS are char * anyway.
*aName = ToNewUnicode(NS_LITERAL_STRING("Root Certificates"));
@ -147,6 +155,10 @@ nsPKCS11Slot::GetDesc(PRUnichar **aDesc)
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
if (mSeries != PK11_GetSlotSeries(mSlot)) {
refreshSlotInfo();
}
*aDesc = ToNewUnicode(mSlotDesc);
if (!*aDesc) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
@ -156,6 +168,9 @@ nsPKCS11Slot::GetDesc(PRUnichar **aDesc)
NS_IMETHODIMP
nsPKCS11Slot::GetManID(PRUnichar **aManID)
{
if (mSeries != PK11_GetSlotSeries(mSlot)) {
refreshSlotInfo();
}
*aManID = ToNewUnicode(mSlotManID);
if (!*aManID) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
@ -165,6 +180,9 @@ nsPKCS11Slot::GetManID(PRUnichar **aManID)
NS_IMETHODIMP
nsPKCS11Slot::GetHWVersion(PRUnichar **aHWVersion)
{
if (mSeries != PK11_GetSlotSeries(mSlot)) {
refreshSlotInfo();
}
*aHWVersion = ToNewUnicode(mSlotHWVersion);
if (!*aHWVersion) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
@ -174,6 +192,9 @@ nsPKCS11Slot::GetHWVersion(PRUnichar **aHWVersion)
NS_IMETHODIMP
nsPKCS11Slot::GetFWVersion(PRUnichar **aFWVersion)
{
if (mSeries != PK11_GetSlotSeries(mSlot)) {
refreshSlotInfo();
}
*aFWVersion = ToNewUnicode(mSlotFWVersion);
if (!*aFWVersion) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
@ -203,6 +224,16 @@ nsPKCS11Slot::GetTokenName(PRUnichar **aName)
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
if (!PK11_IsPresent(mSlot)) {
*aName = nsnull;
return NS_OK;
}
if (mSeries != PK11_GetSlotSeries(mSlot)) {
refreshSlotInfo();
}
*aName = ToNewUnicode(NS_ConvertUTF8toUCS2(PK11_GetTokenName(mSlot)));
if (!*aName) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
@ -305,30 +336,35 @@ nsPKCS11Module::FindSlotByName(const PRUnichar *aName,
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
char *asciiname = NULL;
asciiname = ToNewUTF8String(nsDependentString(aName));
char *asciiname = ToNewUTF8String(nsDependentString(aName));
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("Getting \"%s\"\n", asciiname));
PK11SlotInfo *slotinfo = SECMOD_FindSlot(mModule, asciiname);
if (!slotinfo) {
// XXX *sigh* if token is present, SECMOD_FindSlot goes by token
// name (huh?) reimplement it here for the fun of it.
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) {
// XXX another workaround - the builtin module has no name
if (nsCRT::strcmp(asciiname, "Root Certificates") == 0) {
slotinfo = PK11_ReferenceSlot(mModule->slots[0]);
} else {
// give up
nsMemory::Free(asciiname);
return NS_ERROR_FAILURE;
}
}
PK11SlotInfo *slotinfo = NULL;
PK11SlotList *slotList = PK11_FindSlotsByNames(mModule->dllName,
asciiname /* slotName */, NULL /* token Name */, PR_FALSE);
if (!slotList) {
/* name must be the token name */
slotList = PK11_FindSlotsByNames(mModule->dllName,
NULL /*slot Name */, asciiname /* token Name */, PR_FALSE);
}
if (slotList) {
/* should only be one */
if (slotList->head && slotList->head->slot) {
slotinfo = PK11_ReferenceSlot(slotList->head->slot);
}
PK11_FreeSlotList(slotList);
}
if (!slotinfo) {
// workaround - the builtin module has no name
if (asciiname == nsnull) {
return NS_ERROR_FAILURE;
} else if (nsCRT::strcmp(asciiname, "Root Certificates") == 0) {
slotinfo = PK11_ReferenceSlot(mModule->slots[0]);
} else {
// give up
nsMemory::Free(asciiname);
return NS_ERROR_FAILURE;
}
}
nsMemory::Free(asciiname);
nsCOMPtr<nsIPKCS11Slot> slot = new nsPKCS11Slot(slotinfo);
PK11_FreeSlot(slotinfo);
@ -353,12 +389,19 @@ nsPKCS11Module::ListSlots(nsIEnumerator **_retval)
nsCOMPtr<nsISupportsArray> array;
rv = NS_NewISupportsArray(getter_AddRefs(array));
if (NS_FAILED(rv)) return rv;
/* applications which allow new slot creation (which Firefox now does
* since it uses the WaitForSlotEvent call) need to hold the
* ModuleList Read lock to prevent the slot array from changing out
* from under it. */
SECMODListLock *lock = SECMOD_GetDefaultModuleListLock();
SECMOD_GetReadLock(lock);
for (i=0; i<mModule->slotCount; i++) {
if (mModule->slots[i]) {
nsCOMPtr<nsIPKCS11Slot> slot = new nsPKCS11Slot(mModule->slots[i]);
array->AppendElement(slot);
}
}
SECMOD_ReleaseReadLock(lock);
rv = array->Enumerate(_retval);
return rv;
}
@ -468,6 +511,13 @@ nsPKCS11ModuleDB::ListModules(nsIEnumerator **_retval)
array->AppendElement(module);
list = list->next;
}
/* Get the modules in the database that didn't load */
list = SECMOD_GetDeadModuleList();
while (list) {
nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(list->module);
array->AppendElement(module);
list = list->next;
}
SECMOD_ReleaseReadLock(lock);
rv = array->Enumerate(_retval);
return rv;

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

@ -63,9 +63,11 @@ private:
PK11SlotInfo *mSlot;
nsString mSlotDesc, mSlotManID, mSlotHWVersion, mSlotFWVersion;
int mSeries;
virtual void virtualDestroyNSSReference();
void destructorSafeDestroyNSSReference();
void refreshSlotInfo();
};
class nsPKCS11Module : public nsIPKCS11Module,